PageSourceSearch

https://www.yourwaymagazine.com/wp-content/themes/forceful-light-1.0.8/js/masonry.pkgd.js

js yourwaymagazine.com collected 2026-10-02 07:13:45 UTC 74,618 bytes, 2,837 lines download raw bytes

1/*!
2 * Masonry PACKAGED v3.1.2
3 * Cascading grid layout library
4 * http://masonry.desandro.com
5 * MIT License
6 * by David DeSandro
7 */
8
9/*!
10 * getStyleProperty by kangax
11 * http://perfectionkills.com/feature-testing-css-properties/
12 */
13
14/*jshint browser: true, strict: true, undef: true */
15/*globals define: false */
16
17( function( window ) {
18
19'use strict';
20
21var prefixes = 'Webkit Moz ms Ms O'.split(' ');
22var docElemStyle = document.documentElement.style;
23
24function getStyleProperty( propName ) {
25  if ( !propName ) {
26    return;
27  }
28
29  // test standard property first
30  if ( typeof docElemStyle[ propName ] === 'string' ) {
31    return propName;
32  }
33
34  // capitalize
35  propName = propName.charAt(0).toUpperCase() + propName.slice(1);
36
37  // test vendor specific properties
38  var prefixed;
39  for ( var i=0, len = prefixes.length; i < len; i++ ) {
40    prefixed = prefixes[i] + propName;
41    if ( typeof docElemStyle[ prefixed ] === 'string' ) {
42      return prefixed;
43    }
44  }
45}
46
47// transport
48if ( typeof define === 'function' && define.amd ) {
49  // AMD
50  define( function() {
51    return getStyleProperty;
52  });
53} else {
54  // browser global
55  window.getStyleProperty = getStyleProperty;
56}
57
58})( window );
59
60/**
61 * getSize v1.1.5
62 * measure size of elements
63 */
64
65/*jshint browser: true, strict: true, undef: true, unused: true */
66/*global define: false */
67
68( function( window, undefined ) {
69
70'use strict';
71
72// -------------------------- helpers -------------------------- //
73
74var defView = document.defaultView;
75var isComputedStyle = defView && defView.getComputedStyle;
76
77var getStyle = isComputedStyle ?
78  function( elem ) {
79    return defView.getComputedStyle( elem, null );
80  } :
81  function( elem ) {
82    return elem.currentStyle;
83  };
84
85// get a number from a string, not a percentage
86function getStyleSize( value ) {
87  var num = parseFloat( value );
88  // not a percent like '100%', and a number
89  var isValid = value.indexOf('%') === -1 && !isNaN( num );
90  return isValid && num;
91}
92
93// -------------------------- measurements -------------------------- //
94
95var measurements = [
96  'paddingLeft',
97  'paddingRight',
98  'paddingTop',
99  'paddingBottom',
100  'marginLeft',
101  'marginRight',
102  'marginTop',
103  'marginBottom',
104  'borderLeftWidth',
105  'borderRightWidth',
106  'borderTopWidth',
107  'borderBottomWidth'
108];
109
110function getZeroSize() {
111  var size = {
112    width: 0,
113    height: 0,
114    innerWidth: 0,
115    innerHeight: 0,
116    outerWidth: 0,
117    outerHeight: 0
118  };
119  for ( var i=0, len = measurements.length; i < len; i++ ) {
120    var measurement = measurements[i];
121    size[ measurement ] = 0;
122  }
123  return size;
124}
125
126
127
128function defineGetSize( getStyleProperty ) {
129
130// -------------------------- box sizing -------------------------- //
131
132var boxSizingProp = getStyleProperty('boxSizing');
133var isBoxSizeOuter;
134
135/**
136 * WebKit measures the outer-width on style.width on border-box elems
137 * IE & Firefox measures the inner-width
138 */
139( function() {
140  if ( !boxSizingProp ) {
141    return;
142  }
143
144  var div = document.createElement('div');
145  div.style.width = '200px';
146  div.style.padding = '1px 2px 3px 4px';
147  div.style.borderStyle = 'solid';
148  div.style.borderWidth = '1px 2px 3px 4px';
149  div.style[ boxSizingProp ] = 'border-box';
150
151  var body = document.body || document.documentElement;
152  body.appendChild( div );
153  var style = getStyle( div );
154
155  isBoxSizeOuter = getStyleSize( style.width ) === 200;
156  body.removeChild( div );
157})();
158
159
160// -------------------------- getSize -------------------------- //
161
162function getSize( elem ) {
163  // use querySeletor if elem is string
164  if ( typeof elem === 'string' ) {
165    elem = document.querySelector( elem );
166  }
167
168  // do not proceed on non-objects
169  if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
170    return;
171  }
172
173  var style = getStyle( elem );
174
175  // if hidden, everything is 0
176  if ( style.display === 'none' ) {
177    return getZeroSize();
178  }
179
180  var size = {};
181  size.width = elem.offsetWidth;
182  size.height = elem.offsetHeight;
183
184  var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
185    style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
186
187  // get all measurements
188  for ( var i=0, len = measurements.length; i < len; i++ ) {
189    var measurement = measurements[i];
190    var value = style[ measurement ];
191    value = mungeNonPixel( elem, value );
192    var num = parseFloat( value );
193    // any 'auto', 'medium' value will be 0
194    size[ measurement ] = !isNaN( num ) ? num : 0;
195  }
196
197  var paddingWidth = size.paddingLeft + size.paddingRight;
198  var paddingHeight = size.paddingTop + size.paddingBottom;
199  var marginWidth = size.marginLeft + size.marginRight;
200  var marginHeight = size.marginTop + size.marginBottom;
201  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
202  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
203
204  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
205
206  // overwrite width and height if we can get it from style
207  var styleWidth = getStyleSize( style.width );
208  if ( styleWidth !== false ) {
209    size.width = styleWidth +
210      // add padding and border unless it's already including it
211      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
212  }
213
214  var styleHeight = getStyleSize( style.height );
215  if ( styleHeight !== false ) {
216    size.height = styleHeight +
217      // add padding and border unless it's already including it
218      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
219  }
220
221  size.innerWidth = size.width - ( paddingWidth + borderWidth );
222  size.innerHeight = size.height - ( paddingHeight + borderHeight );
223
224  size.outerWidth = size.width + marginWidth;
225  size.outerHeight = size.height + marginHeight;
226
227  return size;
228}
229
230// IE8 returns percent values, not pixels
231// taken from jQuery's curCSS
232function mungeNonPixel( elem, value ) {
233  // IE8 and has percent value
234  if ( isComputedStyle || value.indexOf('%') === -1 ) {
235    return value;
236  }
237  var style = elem.style;
238	// Remember the original values
239	var left = style.left;
240	var rs = elem.runtimeStyle;
241	var rsLeft = rs && rs.left;
242
243	// Put in the new values to get a computed value out
244	if ( rsLeft ) {
245		rs.left = elem.currentStyle.left;
246	}
247	style.left = value;
248	value = style.pixelLeft;
249
250	// Revert the changed values
251	style.left = left;
252	if ( rsLeft ) {
253		rs.left = rsLeft;
254	}
255
256  return value;
257}
258
259return getSize;
260
261}
262
263// transport
264if ( typeof define === 'function' && define.amd ) {
265  // AMD
266  define( [ 'get-style-property/get-style-property' ], defineGetSize );
267} else {
268  // browser global
269  window.getSize = defineGetSize( window.getStyleProperty );
270}
271
272})( window );
273
274/*!
275 * eventie v1.0.3
276 * event binding helper
277 *   eventie.bind( elem, 'click', myFn )
278 *   eventie.unbind( elem, 'click', myFn )
279 */
280
281/*jshint browser: true, undef: true, unused: true */
282/*global define: false */
283
284( function( window ) {
285
286'use strict';
287
288var docElem = document.documentElement;
289
290var bind = function() {};
291
292if ( docElem.addEventListener ) {
293  bind = function( obj, type, fn ) {
294    obj.addEventListener( type, fn, false );
295  };
296} else if ( docElem.attachEvent ) {
297  bind = function( obj, type, fn ) {
298    obj[ type + fn ] = fn.handleEvent ?
299      function() {
300        var event = window.event;
301        // add event.target
302        event.target = event.target || event.srcElement;
303        fn.handleEvent.call( fn, event );
304      } :
305      function() {
306        var event = window.event;
307        // add event.target
308        event.target = event.target || event.srcElement;
309        fn.call( obj, event );
310      };
311    obj.attachEvent( "on" + type, obj[ type + fn ] );
312  };
313}
314
315var unbind = function() {};
316
317if ( docElem.removeEventListener ) {
318  unbind = function( obj, type, fn ) {
319    obj.removeEventListener( type, fn, false );
320  };
321} else if ( docElem.detachEvent ) {
322  unbind = function( obj, type, fn ) {
323    obj.detachEvent( "on" + type, obj[ type + fn ] );
324    try {
325      delete obj[ type + fn ];
326    } catch ( err ) {
327      // can't delete window object properties
328      obj[ type + fn ] = undefined;
329    }
330  };
331}
332
333var eventie = {
334  bind: bind,
335  unbind: unbind
336};
337
338// transport
339if ( typeof define === 'function' && define.amd ) {
340  // AMD
341  define( eventie );
342} else {
343  // browser global
344  window.eventie = eventie;
345}
346
347})( this );
348
349/*!
350 * docReady
351 * Cross browser DOMContentLoaded event emitter
352 */
353
354/*jshint browser: true, strict: true, undef: true, unused: true*/
355/*global define: false */
356
357( function( window ) {
358
359'use strict';
360
361var document = window.document;
362// collection of functions to be triggered on ready
363var queue = [];
364
365function docReady( fn ) {
366  // throw out non-functions
367  if ( typeof fn !== 'function' ) {
368    return;
369  }
370
371  if ( docReady.isReady ) {
372    // ready now, hit it
373    fn();
374  } else {
375    // queue function when ready
376    queue.push( fn );
377  }
378}
379
380docReady.isReady = false;
381
382// triggered on various doc ready events
383function init( event ) {
384  // bail if IE8 document is not ready just yet
385  var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete';
386  if ( docReady.isReady || isIE8NotReady ) {
387    return;
388  }
389  docReady.isReady = true;
390
391  // process queue
392  for ( var i=0, len = queue.length; i < len; i++ ) {
393    var fn = queue[i];
394    fn();
395  }
396}
397
398function defineDocReady( eventie ) {
399  eventie.bind( document, 'DOMContentLoaded', init );
400  eventie.bind( document, 'readystatechange', init );
401  eventie.bind( window, 'load', init );
402
403  return docReady;
404}
405
406// transport
407if ( typeof define === 'function' && define.amd ) {
408  // AMD
409  // if RequireJS, then doc is already ready
410  docReady.isReady = typeof requirejs === 'function';
411  define( [ 'eventie/eventie' ], defineDocReady );
412} else {
413  // browser global
414  window.docReady = defineDocReady( window.eventie );
415}
416
417})( this );
418
419/*!
420 * EventEmitter v4.2.4 - git.io/ee
421 * Oliver Caldwell
422 * MIT license
423 * @preserve
424 */
425
426(function () {
427	'use strict';
428
429	/**
430	 * Class for managing events.
431	 * Can be extended to provide event functionality in other classes.
432	 *
433	 * @class EventEmitter Manages event registering and emitting.
434	 */
435	function EventEmitter() {}
436
437	// Shortcuts to improve speed and size
438
439	// Easy access to the prototype
440	var proto = EventEmitter.prototype;
441
442	/**
443	 * Finds the index of the listener for the event in it's storage array.
444	 *
445	 * @param {Function[]} listeners Array of listeners to search through.
446	 * @param {Function} listener Method to look for.
447	 * @return {Number} Index of the specified listener, -1 if not found
448	 * @api private
449	 */
450	function indexOfListener(listeners, listener) {
451		var i = listeners.length;
452		while (i--) {
453			if (listeners[i].listener === listener) {
454				return i;
455			}
456		}
457
458		return -1;
459	}
460
461	/**
462	 * Alias a method while keeping the context correct, to allow for overwriting of target method.
463	 *
464	 * @param {String} name The name of the target method.
465	 * @return {Function} The aliased method
466	 * @api private
467	 */
468	function alias(name) {
469		return function aliasClosure() {
470			return this[name].apply(this, arguments);
471		};
472	}
473
474	/**
475	 * Returns the listener array for the specified event.
476	 * Will initialise the event object and listener arrays if required.
477	 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object c
vendor: 10,814 bytes, lines 477-770
477ontaining bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
478	 * Each property in the object response is an array of listener functions.
479	 *
480	 * @param {String|RegExp} evt Name of the event to return the listeners from.
481	 * @return {Function[]|Object} All listener functions for the event.
482	 */
483	proto.getListeners = function getListeners(evt) {
484		var events = this._getEvents();
485		var response;
486		var key;
487
488		// Return a concatenated array of all matching events if
489		// the selector is a regular expression.
490		if (typeof evt === 'object') {
491			response = {};
492			for (key in events) {
493				if (events.hasOwnProperty(key) && evt.test(key)) {
494					response[key] = events[key];
495				}
496			}
497		}
498		else {
499			response = events[evt] || (events[evt] = []);
500		}
501
502		return response;
503	};
504
505	/**
506	 * Takes a list of listener objects and flattens it into a list of listener functions.
507	 *
508	 * @param {Object[]} listeners Raw listener objects.
509	 * @return {Function[]} Just the listener functions.
510	 */
511	proto.flattenListeners = function flattenListeners(listeners) {
512		var flatListeners = [];
513		var i;
514
515		for (i = 0; i < listeners.length; i += 1) {
516			flatListeners.push(listeners[i].listener);
517		}
518
519		return flatListeners;
520	};
521
522	/**
523	 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
524	 *
525	 * @param {String|RegExp} evt Name of the event to return the listeners from.
526	 * @return {Object} All listener functions for an event in an object.
527	 */
528	proto.getListenersAsObject = function getListenersAsObject(evt) {
529		var listeners = this.getListeners(evt);
530		var response;
531
532		if (listeners instanceof Array) {
533			response = {};
534			response[evt] = listeners;
535		}
536
537		return response || listeners;
538	};
539
540	/**
541	 * Adds a listener function to the specified event.
542	 * The listener will not be added if it is a duplicate.
543	 * If the listener returns true then it will be removed after it is called.
544	 * If you pass a regular expression as the event name then the listener will be added to all events that match it.
545	 *
546	 * @param {String|RegExp} evt Name of the event to attach the listener to.
547	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
548	 * @return {Object} Current instance of EventEmitter for chaining.
549	 */
550	proto.addListener = function addListener(evt, listener) {
551		var listeners = this.getListenersAsObject(evt);
552		var listenerIsWrapped = typeof listener === 'object';
553		var key;
554
555		for (key in listeners) {
556			if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
557				listeners[key].push(listenerIsWrapped ? listener : {
558					listener: listener,
559					once: false
560				});
561			}
562		}
563
564		return this;
565	};
566
567	/**
568	 * Alias of addListener
569	 */
570	proto.on = alias('addListener');
571
572	/**
573	 * Semi-alias of addListener. It will add a listener that will be
574	 * automatically removed after it's first execution.
575	 *
576	 * @param {String|RegExp} evt Name of the event to attach the listener to.
577	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
578	 * @return {Object} Current instance of EventEmitter for chaining.
579	 */
580	proto.addOnceListener = function addOnceListener(evt, listener) {
581		return this.addListener(evt, {
582			listener: listener,
583			once: true
584		});
585	};
586
587	/**
588	 * Alias of addOnceListener.
589	 */
590	proto.once = alias('addOnceListener');
591
592	/**
593	 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
594	 * You need to tell it what event names should be matched by a regex.
595	 *
596	 * @param {String} evt Name of the event to create.
597	 * @return {Object} Current instance of EventEmitter for chaining.
598	 */
599	proto.defineEvent = function defineEvent(evt) {
600		this.getListeners(evt);
601		return this;
602	};
603
604	/**
605	 * Uses defineEvent to define multiple events.
606	 *
607	 * @param {String[]} evts An array of event names to define.
608	 * @return {Object} Current instance of EventEmitter for chaining.
609	 */
610	proto.defineEvents = function defineEvents(evts) {
611		for (var i = 0; i < evts.length; i += 1) {
612			this.defineEvent(evts[i]);
613		}
614		return this;
615	};
616
617	/**
618	 * Removes a listener function from the specified event.
619	 * When passed a regular expression as the event name, it will remove the listener from all events that match it.
620	 *
621	 * @param {String|RegExp} evt Name of the event to remove the listener from.
622	 * @param {Function} listener Method to remove from the event.
623	 * @return {Object} Current instance of EventEmitter for chaining.
624	 */
625	proto.removeListener = function removeListener(evt, listener) {
626		var listeners = this.getListenersAsObject(evt);
627		var index;
628		var key;
629
630		for (key in listeners) {
631			if (listeners.hasOwnProperty(key)) {
632				index = indexOfListener(listeners[key], listener);
633
634				if (index !== -1) {
635					listeners[key].splice(index, 1);
636				}
637			}
638		}
639
640		return this;
641	};
642
643	/**
644	 * Alias of removeListener
645	 */
646	proto.off = alias('removeListener');
647
648	/**
649	 * Adds listeners in bulk using the manipulateListeners method.
650	 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
651	 * You can also pass it a regular expression to add the array of listeners to all events that match it.
652	 * Yeah, this function does quite a bit. That's probably a bad thing.
653	 *
654	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
655	 * @param {Function[]} [listeners] An optional array of listener functions to add.
656	 * @return {Object} Current instance of EventEmitter for chaining.
657	 */
658	proto.addListeners = function addListeners(evt, listeners) {
659		// Pass through to manipulateListeners
660		return this.manipulateListeners(false, evt, listeners);
661	};
662
663	/**
664	 * Removes listeners in bulk using the manipulateListeners method.
665	 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
666	 * You can also pass it an event name and an array of listeners to be removed.
667	 * You can also pass it a regular expression to remove the listeners from all events that match it.
668	 *
669	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
670	 * @param {Function[]} [listeners] An optional array of listener functions to remove.
671	 * @return {Object} Current instance of EventEmitter for chaining.
672	 */
673	proto.removeListeners = function removeListeners(evt, listeners) {
674		// Pass through to manipulateListeners
675		return this.manipulateListeners(true, evt, listeners);
676	};
677
678	/**
679	 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
680	 * The first argument will determine if the listeners are removed (true) or added (false).
681	 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
682	 * You can also pass it an event name and an array of listeners to be added/removed.
683	 * You can also pass it a regular expression to manipulate the listeners of all events that match it.
684	 *
685	 * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
686	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
687	 * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
688	 * @return {Object} Current instance of EventEmitter for chaining.
689	 */
690	proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
691		var i;
692		var value;
693		var single = remove ? this.removeListener : this.addListener;
694		var multiple = remove ? this.removeListeners : this.addListeners;
695
696		// If evt is an object then pass each of it's properties to this method
697		if (typeof evt === 'object' && !(evt instanceof RegExp)) {
698			for (i in evt) {
699				if (evt.hasOwnProperty(i) && (value = evt[i])) {
700					// Pass the single listener straight through to the singular method
701					if (typeof value === 'function') {
702						single.call(this, i, value);
703					}
704					else {
705						// Otherwise pass back to the multiple function
706						multiple.call(this, i, value);
707					}
708				}
709			}
710		}
711		else {
712			// So evt must be a string
713			// And listeners must be an array of listeners
714			// Loop over it and pass each one to the multiple method
715			i = listeners.length;
716			while (i--) {
717				single.call(this, evt, listeners[i]);
718			}
719		}
720
721		return this;
722	};
723
724	/**
725	 * Removes all listeners from a specified event.
726	 * If you do not specify an event then all listeners will be removed.
727	 * That means every event will be emptied.
728	 * You can also pass a regex to remove all events that match it.
729	 *
730	 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
731	 * @return {Object} Current instance of EventEmitter for chaining.
732	 */
733	proto.removeEvent = function removeEvent(evt) {
734		var type = typeof evt;
735		var events = this._getEvents();
736		var key;
737
738		// Remove different things depending on the state of evt
739		if (type === 'string') {
740			// Remove all listeners for the specified event
741			delete events[evt];
742		}
743		else if (type === 'object') {
744			// Remove all events matching the regex.
745			for (key in events) {
746				if (events.hasOwnProperty(key) && evt.test(key)) {
747					delete events[key];
748				}
749			}
750		}
751		else {
752			// Remove all listeners in all events
753			delete this._events;
754		}
755
756		return this;
757	};
758
759	/**
760	 * Alias of removeEvent.
761	 *
762	 * Added to mirror the node API.
763	 */
764	proto.removeAllListeners = alias('removeEvent');
765
766	/**
767	 * Emits an event of your choice.
768	 * When emitted, every listener attached to that event will be executed.
769	 * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
770	 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
771	 * So they will not arrive within the array on the other side, they will be separate.
772	 * You can also pass a regular expression to emit to all events that match it.
773	 *
774	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
775	 * @param {Array} [args] Optional array of arguments to be passed to each listener.
776	 * @return {Object} Current instance of EventEmitter for chaining.
777	 */
778	proto.emitEvent = function emitEvent(evt, args) {
779		var listeners = this.getListenersAsObject(evt);
780		var listener;
781		var i;
782		var key;
783		var response;
784
785		for (key in listeners) {
786			if (listeners.hasOwnProperty(key)) {
787				i = listeners[key].length;
788
789				while (i--) {
790					// If the listener returns true then it shall be removed from the event
791					// The function is executed either with a basic call or an apply if there is an args array
792					listener = listeners[key][i];
793
794					if (listener.once === true) {
795						this.removeListener(evt, listener.listener);
796					}
797
798					response = listener.listener.apply(this, args || []);
799
800					if (response === this._getOnceReturnValue()) {
801						this.removeListener(evt, listener.listener);
802					}
803				}
804			}
805		}
806
807		return this;
808	};
809
810	/**
811	 * Alias of emitEvent
812	 */
813	proto.trigger = alias('emitEvent');
814
815	/**
816	 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
817	 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
818	 *
819	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
820	 * @param {...*} Optional additional arguments to be passed to each listener.
821	 * @return {Object} Current instance of EventEmitter for chaining.
822	 */
823	proto.emit = function emit(evt) {
824		var args = Array.prototype.slice.call(arguments, 1);
825		return this.emitEvent(evt, args);
826	};
827
828	/**
829	 * Sets the current value to check against when executing listeners. If a
830	 * listeners return value matches the one set here then it will be removed
831	 * after execution. This value defaults to true.
832	 *
833	 * @param {*} value The new value to check for when executing listeners.
834	 * @return {Object} Current instance of EventEmitter for chaining.
835	 */
836	proto.setOnceReturnValue = function setOnceReturnValue(value) {
837		this._onceReturnValue = value;
838		return this;
839	};
840
841	/**
842	 * Fetches the current value to check against when executing listeners. If
843	 * the listeners return value matches this one then it should be removed
844	 * automatically. It will return true by default.
845	 *
846	 * @return {*|Boolean} The current value to check for or the default, true.
847	 * @api private
848	 */
849	proto._getOnceReturnValue = function _getOnceReturnValue() {
850		if (this.hasOwnProperty('_onceReturnValue')) {
851			return this._onceReturnValue;
852		}
853		else {
854			return true;
855		}
856	};
857
858	/**
859	 * Fetches the events object and creates one if required.
860	 *
861	 * @return {Object} The events storage object.
862	 * @api private
863	 */
864	proto._getEvents = function _getEvents() {
865		return this._events || (this._events = {});
866	};
867
868	// Expose the class either via AMD, CommonJS or the global object
869	if (typeof define === 'function' && define.amd) {
870		define(function () {
871			return EventEmitter;
872		});
873	}
874	else if (typeof module === 'object' && module.exports){
875		module.exports = EventEmitter;
876	}
877	else {
878		this.EventEmitter = EventEmitter;
879	}
880}.call(this));
881
882/**
883 * Bridget makes jQuery widgets
884 * v1.0.0
885 */
886
887( function( window ) {
888
889'use strict';
890
891// -------------------------- utils -------------------------- //
892
893var slice = Array.prototype.slice;
894
895function noop() {}
896
897// -------------------------- definition -------------------------- //
898
899function defineBridget( $ ) {
900
901// bail if no jQuery
902if ( !$ ) {
903  return;
904}
905
906// -------------------------- addOptionMethod -------------------------- //
907
908/**
909 * adds option method -> $().plugin('option', {...})
910 * @param {Function} PluginClass - constructor class
911 */
912function addOptionMethod( PluginClass ) {
913  // don't overwrite original option method
914  if ( PluginClass.prototype.option ) {
915    return;
916  }
917
918  // option setter
919  PluginClass.prototype.option = function( opts ) {
920    // bail out if not an object
921    if ( !$.isPlainObject( opts ) ){
922      return;
923    }
924    this.options = $.extend( true, this.options, opts );
925  };
926}
927
928
929// -------------------------- plugin bridge -------------------------- //
930
931// helper function for logging errors
932// $.error breaks jQuery chaining
933var logError = typeof console === 'undefined' ? noop :
934  function( message ) {
935    console.error( message );
936  };
937
938/**
939 * jQuery plugin bridge, access methods like $elem.plugin('method')
940 * @param {String} namespace - plugin name
941 * @param {Function} PluginClass - constructor class
942 */
943function bridge( namespace, PluginClass ) {
944  // add to jQuery fn namespace
945  $.fn[ namespace ] = function( options ) {
946    if ( typeof options === 'string' ) {
947      // call plugin method when first argument is a string
948      // get arguments for method
949      var args = slice.call( arguments, 1 );
950
951      for ( var i=0, len = this.length; i < len; i++ ) {
952        var elem = this[i];
953        var instance = $.data( elem, namespace );
954        if ( !instance ) {
955          logError( "cannot call methods on " + namespace + " prior to initialization; " +
956            "attempted to call '" + options + "'" );
957          continue;
958        }
959        if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {
960          logError( "no such method '" + options + "' for " + namespace + " instance" );
961          continue;
962        }
963
964        // trigger method with arguments
965        var returnValue = instance[ options ].apply( instance, args );
966
967        // break look and return first value if provided
968        if ( returnValue !== undefined ) {
969          return returnValue;
970        }
971      }
972      // return this if no return value
973      return this;
974    } else {
975      return this.each( function() {
976        var instance = $.data( this, namespace );
977        if ( instance ) {
978          // apply options & init
979          instance.option( options );
980          instance._init();
981        } else {
982          // initialize new instance
983          instance = new PluginClass( this, options );
984          $.data( this, namespace, instance );
985        }
986      });
987    }
988  };
989
990}
991
992// -------------------------- bridget -------------------------- //
993
994/**
995 * converts a Prototypical class into a proper jQuery plugin
996 *   the class must have a ._init method
997 * @param {String} namespace - plugin name, used in $().pluginName
998 * @param {Function} PluginClass - constructor class
999 */
1000$.bridget = function( namespace, PluginClass ) {
1001  addOptionMethod( PluginClass );
1002  bridge( namespace, PluginClass );
1003};
1004
1005}
1006
1007// transport
1008if ( typeof define === 'function' && define.amd ) {
1009  // AMD
1010  define( [ 'jquery' ], defineBridget );
1011} else {
1012  // get jquery from browser global
1013  defineBridget( window.jQuery );
1014}
1015
1016})( window );
1017
1018/**
1019 * matchesSelector helper v1.0.1
1020 *
1021 * @name matchesSelector
1022 *   @param {Element} elem
1023 *   @param {String} selector
1024 */
1025
1026/*jshint browser: true, strict: true, undef: true, unused: true */
1027/*global define: false */
1028
1029( function( global, ElemProto ) {
1030
1031  'use strict';
1032
1033  var matchesMethod = ( function() {
1034    // check un-prefixed
1035    if ( ElemProto.matchesSelector ) {
1036      return 'matchesSelector';
1037    }
1038    // check vendor prefixes
1039    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
1040
1041    for ( var i=0, len = prefixes.length; i < len; i++ ) {
1042      var prefix = prefixes[i];
1043      var method = prefix + 'MatchesSelector';
1044      if ( ElemProto[ method ] ) {
1045        return method;
1046      }
1047    }
1048  })();
1049
1050  // ----- match ----- //
1051
1052  function match( elem, selector ) {
1053    return elem[ matchesMethod ]( selector );
1054  }
1055
1056  // ----- appendToFragment ----- //
1057
1058  function checkParent( elem ) {
1059    // not needed if already has parent
1060    if ( elem.parentNode ) {
1061      return;
1062    }
1063    var fragment = document.createDocumentFragment();
1064    fragment.appendChild( elem );
1065  }
1066
1067  // ----- query ----- //
1068
1069  // fall back to using QSA
1070  // thx @jonathantneal https://gist.github.com/3062955
1071  function query( elem, selector ) {
1072    // append to fragment if no parent
1073    checkParent( elem );
1074
1075    // match elem with all selected elems of parent
1076    var elems = elem.parentNode.querySelectorAll( selector );
1077    for ( var i=0, len = elems.length; i < len; i++ ) {
1078      // return true if match
1079      if ( elems[i] === elem ) {
1080        return true;
1081      }
1082    }
1083    // otherwise return false
1084    return false;
1085  }
1086
1087  // ----- matchChild ----- //
1088
1089  function matchChild( elem, selector ) {
1090    checkParent( elem );
1091    return match( elem, selector );
1092  }
1093
1094  // ----- matchesSelector ----- //
1095
1096  var matchesSelector;
1097
1098  if ( matchesMethod ) {
1099    // IE9 supports matchesSelector, but doesn't work on orphaned elems
1100    // check for that
1101    var div = document.createElement('div');
1102    var supportsOrphans = match( div, 'div' );
1103    matchesSelector = supportsOrphans ? match : matchChild;
1104  } else {
1105    matchesSelector = query;
1106  }
1107
1108  // transport
1109  if ( typeof define === 'function' && define.amd ) {
1110    // AMD
1111    define( function() {
1112      return matchesSelector;
1113    });
1114  } else {
1115    // browser global
1116    window.matchesSelector = matchesSelector;
1117  }
1118
1119})( this, Element.prototype );
1120
1121/**
1122 * Outlayer Item
1123**/
1124
1125( function( window ) {
1126
1127'use strict';
1128
1129// ----- get style ----- //
1130
1131var defView = document.defaultView;
1132
1133var getStyle = defView && defView.getComputedStyle ?
1134  function( elem ) {
1135    return defView.getComputedStyle( elem, null );
1136  } :
1137  function( elem ) {
1138    return elem.currentStyle;
1139  };
1140
1141
1142// extend objects
1143function extend( a, b ) {
1144  for ( var prop in b ) {
1145    a[ prop ] = b[ prop ];
1146  }
1147  return a;
1148}
1149
1150function isEmptyObj( obj ) {
1151  for ( var prop in obj ) {
1152    return false;
1153  }
1154  prop = null;
1155  return true;
1156}
1157
1158// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1159function toDash( str ) {
1160  return str.replace( /([A-Z])/g, function( $1 ){
1161    return '-' + $1.toLowerCase();
1162  });
1163}
1164
1165// -------------------------- Outlayer definition -------------------------- //
1166
1167function outlayerItemDefinition( EventEmitter, getSize, getStyleProperty ) {
1168
1169// -------------------------- CSS3 support -------------------------- //
1170
1171var transitionProperty = getStyleProperty('transition');
1172var transformProperty = getStyleProperty('transform');
1173var supportsCSS3 = transitionProperty && transformProperty;
1174var is3d = !!getStyleProperty('perspective');
1175
1176var transitionEndEvent = {
1177  WebkitTransition: 'webkitTransitionEnd',
1178  MozTransition: 'transitionend',
1179  OTransition: 'otransitionend',
1180  transition: 'transitionend'
1181}[ transitionProperty ];
1182
1183// properties that could have vendor prefix
1184var prefixableProperties = [
1185  'transform',
1186  'transition',
1187  'transitionDuration',
1188  'transitionProperty'
1189];
1190
1191// cache all vendor properties
1192var vendorProperties = ( function() {
1193  var cache = {};
1194  for ( var i=0, len = prefixableProperties.length; i < len; i++ ) {
1195    var prop = prefixableProperties[i];
1196    var supportedProp = getStyleProperty( prop );
1197    if ( supportedProp && supportedProp !== prop ) {
1198      cache[ prop ] = supportedProp;
1199    }
1200  }
1201  return cache;
1202})();
1203
1204// -------------------------- Item -------------------------- //
1205
1206function Item( element, layout ) {
1207  if ( !element ) {
1208    return;
1209  }
1210
1211  this.element = element;
1212  // parent layout class, i.e. Masonry, Isotope, or Packery
1213  this.layout = layout;
1214  this.position = {
1215    x: 0,
1216    y: 0
1217  };
1218
1219  this._create();
1220}
1221
1222// inherit EventEmitter
1223extend( Item.prototype, EventEmitter.prototype );
1224
1225Item.prototype._create = function() {
1226  // transition objects
1227  this._transition = {
1228    ingProperties: {},
1229    clean: {},
1230    onEnd: {}
1231  };
1232
1233  this.css({
1234    position: 'absolute'
1235  });
1236};
1237
1238// trigger specified handler for event type
1239Item.prototype.handleEvent = function( event ) {
1240  var method = 'on' + event.type;
1241  if ( this[ method ] ) {
1242    this[ method ]( event );
1243  }
1244};
1245
1246Item.prototype.getSize = function() {
1247  this.size = getSize( this.element );
1248};
1249
1250/**
1251 * apply CSS styles to element
1252 * @param {Object} style
1253 */
1254Item.prototype.css = function( style ) {
1255  var elemStyle = this.element.style;
1256
1257  for ( var prop in style ) {
1258    // use vendor property if available
1259    var supportedProp = vendorProperties[ prop ] || prop;
1260    elemStyle[ supportedProp ] = style[ prop ];
1261  }
1262};
1263
1264 // measure position, and sets it
1265Item.prototype.getPosition = function() {
1266  var style = getStyle( this.element );
1267  var layoutOptions = this.layout.options;
1268  var isOriginLeft = layoutOptions.isOriginLeft;
1269  var isOriginTop = layoutOptions.isOriginTop;
1270  var x = parseInt( style[ isOriginLeft ? 'left' : 'right' ], 10 );
1271  var y = parseInt( style[ isOriginTop ? 'top' : 'bottom' ], 10 );
1272
1273  // clean up 'auto' or other non-integer values
1274  x = isNaN( x ) ? 0 : x;
1275  y = isNaN( y ) ? 0 : y;
1276  // remove padding from measurement
1277  var layoutSize = this.layout.size;
1278  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
1279  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
1280
1281  this.position.x = x;
1282  this.position.y = y;
1283};
1284
1285// set settled position, apply padding
1286Item.prototype.layoutPosition = function() {
1287  var layoutSize = this.layout.size;
1288  var layoutOptions = this.layout.options;
1289  var style = {};
1290
1291  if ( layoutOptions.isOriginLeft ) {
1292    style.left = ( this.position.x + layoutSize.paddingLeft ) + 'px';
1293    // reset other property
1294    style.right = '';
1295  } else {
1296    style.right = ( this.position.x + layoutSize.paddingRight ) + 'px';
1297    style.left = '';
1298  }
1299
1300  if ( layoutOptions.isOriginTop ) {
1301    style.top = ( this.position.y + layoutSize.paddingTop ) + 'px';
1302    style.bottom = '';
1303  } else {
1304    style.bottom = ( this.position.y + layoutSize.paddingBottom ) + 'px';
1305    style.top = '';
1306  }
1307
1308  this.css( style );
1309  this.emitEvent( 'layout', [ this ] );
1310};
1311
1312
1313// transform translate function
1314var translate = is3d ?
1315  function( x, y ) {
1316    return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
1317  } :
1318  function( x, y ) {
1319    return 'translate(' + x + 'px, ' + y + 'px)';
1320  };
1321
1322
1323Item.prototype._transitionTo = function( x, y ) {
1324  this.getPosition();
1325  // get current x & y from top/left
1326  var curX = this.position.x;
1327  var curY = this.position.y;
1328
1329  var compareX = parseInt( x, 10 );
1330  var compareY = parseInt( y, 10 );
1331  var didNotMove = compareX === this.position.x && compareY === this.position.y;
1332
1333  // save end position
1334  this.setPosition( x, y );
1335
1336  // if did not move and not transitioning, just go to layout
1337  if ( didNotMove && !this.isTransitioning ) {
1338    this.layoutPosition();
1339    return;
1340  }
1341
1342  var transX = x - curX;
1343  var transY = y - curY;
1344  var transitionStyle = {};
1345  // flip cooridinates if origin on right or bottom
1346  var layoutOptions = this.layout.options;
1347  transX = layoutOptions.isOriginLeft ? transX : -transX;
1348  transY = layoutOptions.isOriginTop ? transY : -transY;
1349  transitionStyle.transform = translate( transX, transY );
1350
1351  this.transition({
1352    to: transitionStyle,
1353    onTransitionEnd: {
1354      transform: this.layoutPosition
1355    },
1356    isCleaning: true
1357  });
1358};
1359
1360// non transition + transform support
1361Item.prototype.goTo = function( x, y ) {
1362  this.setPosition( x, y );
1363  this.layoutPosition();
1364};
1365
1366// use transition and transforms if supported
1367Item.prototype.moveTo = supportsCSS3 ?
1368  Item.prototype._transitionTo : Item.prototype.goTo;
1369
1370Item.prototype.setPosition = function( x, y ) {
1371  this.position.x = parseInt( x, 10 );
1372  this.position.y = parseInt( y, 10 );
1373};
1374
1375// ----- transition ----- //
1376
1377/**
1378 * @param {Object} style - CSS
1379 * @param {Function} onTransitionEnd
1380 */
1381
1382// non transition, just trigger callback
1383Item.prototype._nonTransition = function( args ) {
1384  this.css( args.to );
1385  if ( args.isCleaning ) {
1386    this._removeStyles( args.to );
1387  }
1388  for ( var prop in args.onTransitionEnd ) {
1389    args.onTransitionEnd[ prop ].call( this );
1390  }
1391};
1392
1393/**
1394 * proper transition
1395 * @param {Object} args - arguments
1396 *   @param {Object} to - style to transition to
1397 *   @param {Object} from - style to start transition from
1398 *   @param {Boolean} isCleaning - removes transition styles after transition
1399 *   @param {Function} onTransitionEnd - callback
1400 */
1401Item.prototype._transition = function( args ) {
1402  // redirect to nonTransition if no transition duration
1403  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1404    this._nonTransition( args );
1405    return;
1406  }
1407
1408  var _transition = this._transition;
1409  // keep track of onTransitionEnd callback by css property
1410  for ( var prop in args.onTransitionEnd ) {
1411    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
1412  }
1413  // keep track of properties that are transitioning
1414  for ( prop in args.to ) {
1415    _transition.ingProperties[ prop ] = true;
1416    // keep track of properties to clean up when transition is done
1417    if ( args.isCleaning ) {
1418      _transition.clean[ prop ] = true;
1419    }
1420  }
1421
1422  // set from styles
1423  if ( args.from ) {
1424    this.css( args.from );
1425    // force redraw. http://blog.alexmaccaw.com/css-transitions
1426    var h = this.element.offsetHeight;
1427    // hack for JSHint to hush about unused var
1428    h = null;
1429  }
1430  // enable transition
1431  this.enableTransition( args.to );
1432  // set styles that are transitioning
1433  this.css( args.to );
1434
1435  this.isTransitioning = true;
1436
1437};
1438
1439var itemTransitionProperties = transformProperty && ( toDash( transformProperty ) +
1440  ',opacity' );
1441
1442Item.prototype.enableTransition = function(/* style */) {
1443  // only enable if not already transitioning
1444  // bug in IE10 were re-setting transition style will prevent
1445  // transitionend event from triggering
1446  if ( this.isTransitioning ) {
1447    return;
1448  }
1449
1450  // make transition: foo, bar, baz from style object
1451  // TODO uncomment this bit when IE10 bug is resolved
1452  // var transitionValue = [];
1453  // for ( var prop in style ) {
1454  //   // dash-ify camelCased properties like WebkitTransition
1455  //   transitionValue.push( toDash( prop ) );
1456  // }
1457  // enable transition styles
1458  // HACK always enable transform,opacity for IE10
1459  this.css({
1460    transitionProperty: itemTransitionProperties,
1461    transitionDuration: this.layout.options.transitionDuration
1462  });
1463  // listen for transition end event
1464  this.element.addEventListener( transitionEndEvent, this, false );
1465};
1466
1467Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ];
1468
1469// ----- events ----- //
1470
1471Item.prototype.onwebkitTransitionEnd = function( event ) {
1472  this.ontransitionend( event );
1473};
1474
1475Item.prototype.onotransitionend = function( event ) {
1476  this.ontransitionend( event );
1477};
1478
1479// properties that I munge to make my life easier
1480var dashedVendorProperties = {
1481  '-webkit-transform': 'transform',
1482  '-moz-transform': 'transform',
1483  '-o-transform': 'transform'
1484};
1485
1486Item.prototype.ontransitionend = function( event ) {
1487  // disregard bubbled events from children
1488  if ( event.target !== this.element ) {
1489    return;
1490  }
1491  var _transition = this._transition;
1492  // get property name of transitioned property, convert to prefix-free
1493  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
1494
1495  // remove property that has completed transitioning
1496  delete _transition.ingProperties[ propertyName ];
1497  // check if any properties are still transitioning
1498  if ( isEmptyObj( _transition.ingProperties ) ) {
1499    // all properties have completed transitioning
1500    this.disableTransition();
1501  }
1502  // clean style
1503  if ( propertyName in _transition.clean ) {
1504    // clean up style
1505    this.element.style[ event.propertyName ] = '';
1506    delete _transition.clean[ propertyName ];
1507  }
1508  // trigger onTransitionEnd callback
1509  if ( propertyName in _transition.onEnd ) {
1510    var onTransitionEnd = _transition.onEnd[ propertyName ];
1511    onTransitionEnd.call( this );
1512    delete _transition.onEnd[ propertyName ];
1513  }
1514
1515  this.emitEvent( 'transitionEnd', [ this ] );
1516};
1517
1518Item.prototype.disableTransition = function() {
1519  this.removeTransitionStyles();
1520  this.element.removeEventListener( transitionEndEvent, this, false );
1521  this.isTransitioning = false;
1522};
1523
1524/**
1525 * removes style property from element
1526 * @param {Object} style
1527**/
1528Item.prototype._removeStyles = function( style ) {
1529  // clean up transition styles
1530  var cleanStyle = {};
1531  for ( var prop in style ) {
1532    cleanStyle[ prop ] = '';
1533  }
1534  this.css( cleanStyle );
1535};
1536
1537var cleanTransitionStyle = {
1538  transitionProperty: '',
1539  transitionDuration: ''
1540};
1541
1542Item.prototype.removeTransitionStyles = function() {
1543  // remove transition
1544  this.css( cleanTransitionStyle );
1545};
1546
1547// ----- show/hide/remove ----- //
1548
1549// remove element from DOM
1550Item.prototype.removeElem = function() {
1551  this.element.parentNode.removeChild( this.element );
1552  this.emitEvent( 'remove', [ this ] );
1553};
1554
1555Item.prototype.remove = function() {
1556  // just remove element if no transition support or no transition
1557  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1558    this.removeElem();
1559    return;
1560  }
1561
1562  // start transition
1563  var _this = this;
1564  this.on( 'transitionEnd', function() {
1565    _this.removeElem();
1566    return true; // bind once
1567  });
1568  this.hide();
1569};
1570
1571Item.prototype.reveal = function() {
1572  delete this.isHidden;
1573  // remove display: none
1574  this.css({ display: '' });
1575
1576  var options = this.layout.options;
1577  this.transition({
1578    from: options.hiddenStyle,
1579    to: options.visibleStyle,
1580    isCleaning: true
1581  });
1582};
1583
1584Item.prototype.hide = function() {
1585  // set flag
1586  this.isHidden = true;
1587  // remove display: none
1588  this.css({ display: '' });
1589
1590  var options = this.layout.options;
1591  this.transition({
1592    from: options.visibleStyle,
1593    to: options.hiddenStyle,
1594    // keep hidden stuff hidden
1595    isCleaning: true,
1596    onTransitionEnd: {
1597      opacity: function() {
1598        this.css({ display: 'none' });
1599      }
1600    }
1601  });
1602};
1603
1604Item.prototype.destroy = function() {
1605  this.css({
1606    position: '',
1607    left: '',
1608    right: '',
1609    top: '',
1610    bottom: '',
1611    transition: '',
1612    transform: ''
1613  });
1614};
1615
1616return Item;
1617
1618}
1619
1620// -------------------------- transport -------------------------- //
1621
1622if ( typeof define === 'function' && define.amd ) {
1623  // AMD
1624  define( [
1625      'eventEmitter/EventEmitter',
1626      'get-size/get-size',
1627      'get-style-property/get-style-property'
1628    ],
1629    outlayerItemDefinition );
1630} else {
1631  // browser global
1632  window.Outlayer = {};
1633  window.Outlayer.Item = outlayerItemDefinition(
1634    window.EventEmitter,
1635    window.getSize,
1636    window.getStyleProperty
1637  );
1638}
1639
1640})( window );
1641
1642/*!
1643 * Outlayer v1.1.8
1644 * the brains and guts of a layout library
1645 */
1646
1647( function( window ) {
1648
1649'use strict';
1650
1651// ----- vars ----- //
1652
1653var document = window.document;
1654var console = window.console;
1655var jQuery = window.jQuery;
1656
1657var noop = function() {};
1658
1659// -------------------------- helpers -------------------------- //
1660
1661// extend objects
1662function extend( a, b ) {
1663  for ( var prop in b ) {
1664    a[ prop ] = b[ prop ];
1665  }
1666  return a;
1667}
1668
1669
1670var objToString = Object.prototype.toString;
1671function isArray( obj ) {
1672  return objToString.call( obj ) === '[object Array]';
1673}
1674
1675// turn element or nodeList into an array
1676function makeArray( obj ) {
1677  var ary = [];
1678  if ( isArray( obj ) ) {
1679    // use object if already an array
1680    ary = obj;
1681  } else if ( obj && typeof obj.length === 'number' ) {
1682    // convert nodeList to array
1683    for ( var i=0, len = obj.length; i < len; i++ ) {
1684      ary.push( obj[i] );
1685    }
1686  } else {
1687    // array of single index
1688    ary.push( obj );
1689  }
1690  return ary;
1691}
1692
1693// http://stackoverflow.com/a/384380/182183
1694var isElement = ( typeof HTMLElement === 'object' ) ?
1695  function isElementDOM2( obj ) {
1696    return obj instanceof HTMLElement;
1697  } :
1698  function isElementQuirky( obj ) {
1699    return obj && typeof obj === 'object' &&
1700      obj.nodeType === 1 && typeof obj.nodeName === 'string';
1701  };
1702
1703// index of helper cause IE8
1704var indexOf = Array.prototype.indexOf ? function( ary, obj ) {
1705    return ary.indexOf( obj );
1706  } : function( ary, obj ) {
1707    for ( var i=0, len = ary.length; i < len; i++ ) {
1708      if ( ary[i] === obj ) {
1709        return i;
1710      }
1711    }
1712    return -1;
1713  };
1714
1715function removeFrom( obj, ary ) {
1716  var index = indexOf( ary, obj );
1717  if ( index !== -1 ) {
1718    ary.splice( index, 1 );
1719  }
1720}
1721
1722// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1723function toDashed( str ) {
1724  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
1725    return $1 + '-' + $2;
1726  }).toLowerCase();
1727}
1728
1729
1730function outlayerDefinition( eventie, docReady, EventEmitter, getSize, matchesSelector, Item ) {
1731
1732// -------------------------- Outlayer -------------------------- //
1733
1734// globally unique identifiers
1735var GUID = 0;
1736// internal store of all Outlayer intances
1737var instances = {};
1738
1739
1740/**
1741 * @param {Element, String} element
1742 * @param {Object} options
1743 * @constructor
1744 */
1745function Outlayer( element, options ) {
1746  // use element as selector string
1747  if ( typeof element === 'string' ) {
1748    element = document.querySelector( element );
1749  }
1750
1751  // bail out if not proper element
1752  if ( !element || !isElement( element ) ) {
1753    if ( console ) {
1754      console.error( 'Bad ' + this.settings.namespace + ' element: ' + element );
1755    }
1756    return;
1757  }
1758
1759  this.element = element;
1760
1761  // options
1762  this.options = extend( {}, this.options );
1763  this.option( options );
1764
1765  // add id for Outlayer.getFromElement
1766  var id = ++GUID;
1767  this.element.outlayerGUID = id; // expando
1768  instances[ id ] = this; // associate via id
1769
1770  // kick it off
1771  this._create();
1772
1773  if ( this.options.isInitLayout ) {
1774    this.layout();
1775  }
1776}
1777
1778// settings are for internal use only
1779Outlayer.prototype.settings = {
1780  namespace: 'outlayer',
1781  item: Item
1782};
1783
1784// default options
1785Outlayer.prototype.options = {
1786  containerStyle: {
1787    position: 'relative'
1788  },
1789  isInitLayout: true,
1790  isOriginLeft: true,
1791  isOriginTop: true,
1792  isResizeBound: true,
1793  // item options
1794  transitionDuration: '0.4s',
1795  hiddenStyle: {
1796    opacity: 0,
1797    transform: 'scale(0.001)'
1798  },
1799  visibleStyle: {
1800    opacity: 1,
1801    transform: 'scale(1)'
1802  }
1803};
1804
1805// inherit EventEmitter
1806extend( Outlayer.prototype, EventEmitter.prototype );
1807
1808/**
1809 * set options
1810 * @param {Object} opts
1811 */
1812Outlayer.prototype.option = function( opts ) {
1813  extend( this.options, opts );
1814};
1815
1816Outlayer.prototype._create = function() {
1817  // get items from children
1818  this.reloadItems();
1819  // elements that affect layout, but are not laid out
1820  this.stamps = [];
1821  this.stamp( this.options.stamp );
1822  // set container style
1823  extend( this.element.style, this.options.containerStyle );
1824
1825  // bind resize method
1826  if ( this.options.isResizeBound ) {
1827    this.bindResize();
1828  }
1829};
1830
1831// goes through all children again and gets bricks in proper order
1832Outlayer.prototype.reloadItems = function() {
1833  // collection of item elements
1834  this.items = this._itemize( this.element.children );
1835};
1836
1837
1838/**
1839 * turn elements into Outlayer.Items to be used in layout
1840 * @param {Array or NodeList or HTMLElement} elems
1841 * @returns {Array} items - collection of new Outlayer Items
1842 */
1843Outlayer.prototype._itemize = function( elems ) {
1844
1845  var itemElems = this._filterFindItemElements( elems );
1846  var Item = this.settings.item;
1847
1848  // create new Outlayer Items for collection
1849  var items = [];
1850  for ( var i=0, len = itemElems.length; i < len; i++ ) {
1851    var elem = itemElems[i];
1852    var item = new Item( elem, this );
1853    items.push( item );
1854  }
1855
1856  return items;
1857};
1858
1859/**
1860 * get item elements to be used in layout
1861 * @param {Array or NodeList or HTMLElement} elems
1862 * @returns {Array} items - item elements
1863 */
1864Outlayer.prototype._filterFindItemElements = function( elems ) {
1865  // make array of elems
1866  elems = makeArray( elems );
1867  var itemSelector = this.options.itemSelector;
1868  var itemElems = [];
1869
1870  for ( var i=0, len = elems.length; i < len; i++ ) {
1871    var elem = elems[i];
1872    // check that elem is an actual element
1873    if ( !isElement( elem ) ) {
1874      continue;
1875    }
1876    // filter & find items if we have an item selector
1877    if ( itemSelector ) {
1878      // filter siblings
1879      if ( matchesSelector( elem, itemSelector ) ) {
1880        itemElems.push( elem );
1881      }
1882      // find children
1883      var childElems = elem.querySelectorAll( itemSelector );
1884      // concat childElems to filterFound array
1885      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
1886        itemElems.push( childElems[j] );
1887      }
1888    } else {
1889      itemElems.push( elem );
1890    }
1891  }
1892
1893  return itemElems;
1894};
1895
1896/**
1897 * getter method for getting item elements
1898 * @returns {Array} elems - collection of item elements
1899 */
1900Outlayer.prototype.getItemElements = function() {
1901  var elems = [];
1902  for ( var i=0, len = this.items.length; i < len; i++ ) {
1903    elems.push( this.items[i].element );
1904  }
1905  return elems;
1906};
1907
1908// ----- init & layout ----- //
1909
1910/**
1911 * lays out all items
1912 */
1913Outlayer.prototype.layout = function() {
1914  this._resetLayout();
1915  this._manageStamps();
1916
1917  // don't animate first layout
1918  var isInstant = this.options.isLayoutInstant !== undefined ?
1919    this.options.isLayoutInstant : !this._isLayoutInited;
1920  this.layoutItems( this.items, isInstant );
1921
1922  // flag for initalized
1923  this._isLayoutInited = true;
1924};
1925
1926// _init is alias for layout
1927Outlayer.prototype._init = Outlayer.prototype.layout;
1928
1929/**
1930 * logic before any new layout
1931 */
1932Outlayer.prototype._resetLayout = function() {
1933  this.getSize();
1934};
1935
1936
1937Outlayer.prototype.getSize = function() {
1938  this.size = getSize( this.element );
1939};
1940
1941/**
1942 * get measurement from option, for columnWidth, rowHeight, gutter
1943 * if option is String -> get element from selector string, & get size of element
1944 * if option is Element -> get size of element
1945 * else use option as a number
1946 *
1947 * @param {String} measurement
1948 * @param {String} size - width or height
1949 * @private
1950 */
1951Outlayer.prototype._getMeasurement = function( measurement, size ) {
1952  var option = this.options[ measurement ];
1953  var elem;
1954  if ( !option ) {
1955    // default to 0
1956    this[ measurement ] = 0;
1957  } else {
1958    if ( typeof option === 'string' ) {
1959      elem = this.element.querySelector( option );
1960    } else if ( isElement( option ) ) {
1961      elem = option;
1962    }
1963    // use size of element, if element
1964    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
1965  }
1966};
1967
1968/**
1969 * layout a collection of item elements
1970 * @api public
1971 */
1972Outlayer.prototype.layoutItems = function( items, isInstant ) {
1973  items = this._getItemsForLayout( items );
1974
1975  this._layoutItems( items, isInstant );
1976
1977  this._postLayout();
1978};
1979
1980/**
1981 * get the items to be laid out
1982 * you may want to skip over some items
1983 * @param {Array} items
1984 * @returns {Array} items
1985 */
1986Outlayer.prototype._getItemsForLayout = function( items ) {
1987  var layoutItems = [];
1988  for ( var i=0, len = items.length; i < len; i++ ) {
1989    var item = items[i];
1990    if ( !item.isIgnored ) {
1991      layoutItems.push( item );
1992    }
1993  }
1994  return layoutItems;
1995};
1996
1997/**
1998 * layout items
1999 * @param {Array} items
2000 * @param {Boolean} isInstant
2001 */
2002Outlayer.prototype._layoutItems = function( items, isInstant ) {
2003  if ( !items || !items.length ) {
2004    // no items, emit event with empty array
2005    this.emitEvent( 'layoutComplete', [ this, items ] );
2006    return;
2007  }
2008
2009  // emit layoutComplete when done
2010  this._itemsOn( items, 'layout', function onItemsLayout() {
2011    this.emitEvent( 'layoutComplete', [ this, items ] );
2012  });
2013
2014  var queue = [];
2015
2016  for ( var i=0, len = items.length; i < len; i++ ) {
2017    var item = items[i];
2018    // get x/y object from method
2019    var position = this._getItemLayoutPosition( item );
2020    // enqueue
2021    position.item = item;
2022    position.isInstant = isInstant;
2023    queue.push( position );
2024  }
2025
2026  this._processLayoutQueue( queue );
2027};
2028
2029/**
2030 * get item layout position
2031 * @param {Outlayer.Item} item
2032 * @returns {Object} x and y position
2033 */
2034Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) {
2035  return {
2036    x: 0,
2037    y: 0
2038  };
2039};
2040
2041/**
2042 * iterate over array and position each item
2043 * Reason being - separating this logic prevents 'layout invalidation'
2044 * thx @paul_irish
2045 * @param {Array} queue
2046 */
2047Outlayer.prototype._processLayoutQueue = function( queue ) {
2048  for ( var i=0, len = queue.length; i < len; i++ ) {
2049    var obj = queue[i];
2050    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant );
2051  }
2052};
2053
2054/**
2055 * Sets position of item in DOM
2056 * @param {Outlayer.Item} item
2057 * @param {Number} x - horizontal position
2058 * @param {Number} y - vertical position
2059 * @param {Boolean} isInstant - disables transitions
2060 */
2061Outlayer.prototype._positionItem = function( item, x, y, isInstant ) {
2062  if ( isInstant ) {
2063    // if not transition, just set CSS
2064    item.goTo( x, y );
2065  } else {
2066    item.moveTo( x, y );
2067  }
2068};
2069
2070/**
2071 * Any logic you want to do after each layout,
2072 * i.e. size the container
2073 */
2074Outlayer.prototype._postLayout = function() {
2075  var size = this._getContainerSize();
2076  if ( size ) {
2077    this._setContainerMeasure( size.width, true );
2078    this._setContainerMeasure( size.height, false );
2079  }
2080};
2081
2082/**
2083 * @returns {Object} size
2084 *   @param {Number} width
2085 *   @param {Number} height
2086 */
2087Outlayer.prototype._getContainerSize = noop;
2088
2089/**
2090 * @param {Number} measure - size of width or height
2091 * @param {Boolean} isWidth
2092 */
2093Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) {
2094  if ( measure === undefined ) {
2095    return;
2096  }
2097
2098  var elemSize = this.size;
2099  // add padding and border width if border box
2100  if ( elemSize.isBorderBox ) {
2101    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
2102      elemSize.borderLeftWidth + elemSize.borderRightWidth :
2103      elemSize.paddingBottom + elemSize.paddingTop +
2104      elemSize.borderTopWidth + elemSize.borderBottomWidth;
2105  }
2106
2107  measure = Math.max( measure, 0 );
2108  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
2109};
2110
2111/**
2112 * trigger a callback for a collection of items events
2113 * @param {Array} items - Outlayer.Items
2114 * @param {String} eventName
2115 * @param {Function} callback
2116 */
2117Outlayer.prototype._itemsOn = function( items, eventName, callback ) {
2118  var doneCount = 0;
2119  var count = items.length;
2120  // event callback
2121  var _this = this;
2122  function tick() {
2123    doneCount++;
2124    if ( doneCount === count ) {
2125      callback.call( _this );
2126    }
2127    return true; // bind once
2128  }
2129  // bind callback
2130  for ( var i=0, len = items.length; i < len; i++ ) {
2131    var item = items[i];
2132    item.on( eventName, tick );
2133  }
2134};
2135
2136// -------------------------- ignore & stamps -------------------------- //
2137
2138
2139/**
2140 * keep item in collection, but do not lay it out
2141 * ignored items do not get skipped in layout
2142 * @param {Element} elem
2143 */
2144Outlayer.prototype.ignore = function( elem ) {
2145  var item = this.getItem( elem );
2146  if ( item ) {
2147    item.isIgnored = true;
2148  }
2149};
2150
2151/**
2152 * return item to layout collection
2153 * @param {Element} elem
2154 */
2155Outlayer.prototype.unignore = function( elem ) {
2156  var item = this.getItem( elem );
2157  if ( item ) {
2158    delete item.isIgnored;
2159  }
2160};
2161
2162/**
2163 * adds elements to stamps
2164 * @param {NodeList, Array, Element, or String} elems
2165 */
2166Outlayer.prototype.stamp = function( elems ) {
2167  elems = this._find( elems );
2168  if ( !elems ) {
2169    return;
2170  }
2171
2172  this.stamps = this.stamps.concat( elems );
2173  // ignore
2174  for ( var i=0, len = elems.length; i < len; i++ ) {
2175    var elem = elems[i];
2176    this.ignore( elem );
2177  }
2178};
2179
2180/**
2181 * removes elements to stamps
2182 * @param {NodeList, Array, or Element} elems
2183 */
2184Outlayer.prototype.unstamp = function( elems ) {
2185  elems = this._find( elems );
2186  if ( !elems ){
2187    return;
2188  }
2189
2190  for ( var i=0, len = elems.length; i < len; i++ ) {
2191    var elem = elems[i];
2192    // filter out removed stamp elements
2193    removeFrom( elem, this.stamps );
2194    this.unignore( elem );
2195  }
2196
2197};
2198
2199/**
2200 * finds child elements
2201 * @param {NodeList, Array, Element, or String} elems
2202 * @returns {Array} elems
2203 */
2204Outlayer.prototype._find = function( elems ) {
2205  if ( !elems ) {
2206    return;
2207  }
2208  // if string, use argument as selector string
2209  if ( typeof elems === 'string' ) {
2210    elems = this.element.querySelectorAll( elems );
2211  }
2212  elems = makeArray( elems );
2213  return elems;
2214};
2215
2216Outlayer.prototype._manageStamps = function() {
2217  if ( !this.stamps || !this.stamps.length ) {
2218    return;
2219  }
2220
2221  this._getBoundingRect();
2222
2223  for ( var i=0, len = this.stamps.length; i < len; i++ ) {
2224    var stamp = this.stamps[i];
2225    this._manageStamp( stamp );
2226  }
2227};
2228
2229// update boundingLeft / Top
2230Outlayer.prototype._getBoundingRect = function() {
2231  // get bounding rect for container element
2232  var boundingRect = this.element.getBoundingClientRect();
2233  var size = this.size;
2234  this._boundingRect = {
2235    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
2236    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
2237    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
2238    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
2239  };
2240};
2241
2242/**
2243 * @param {Element} stamp
2244**/
2245Outlayer.prototype._manageStamp = noop;
2246
2247/**
2248 * get x/y position of element relative to container element
2249 * @param {Element} elem
2250 * @returns {Object} offset - has left, top, right, bottom
2251 */
2252Outlayer.prototype._getElementOffset = function( elem ) {
2253  var boundingRect = elem.getBoundingClientRect();
2254  var thisRect = this._boundingRect;
2255  var size = getSize( elem );
2256  var offset = {
2257    left: boundingRect.left - thisRect.left - size.marginLeft,
2258    top: boundingRect.top - thisRect.top - size.marginTop,
2259    right: thisRect.right - boundingRect.right - size.marginRight,
2260    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
2261  };
2262  return offset;
2263};
2264
2265// -------------------------- resize -------------------------- //
2266
2267// enable event handlers for listeners
2268// i.e. resize -> onresize
2269Outlayer.prototype.handleEvent = function( event ) {
2270  var method = 'on' + event.type;
2271  if ( this[ method ] ) {
2272    this[ method ]( event );
2273  }
2274};
2275
2276/**
2277 * Bind layout to window resizing
2278 */
2279Outlayer.prototype.bindResize = function() {
2280  // bind just one listener
2281  if ( this.isResizeBound ) {
2282    return;
2283  }
2284  eventie.bind( window, 'resize', this );
2285  this.isResizeBound = true;
2286};
2287
2288/**
2289 * Unbind layout to window resizing
2290 */
2291Outlayer.prototype.unbindResize = function() {
2292  eventie.unbind( window, 'resize', this );
2293  this.isResizeBound = false;
2294};
2295
2296// original debounce by John Hann
2297// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
2298
2299// this fires every resize
2300Outlayer.prototype.onresize = function() {
2301  if ( this.resizeTimeout ) {
2302    clearTimeout( this.resizeTimeout );
2303  }
2304
2305  var _this = this;
2306  function delayed() {
2307    _this.resize();
2308    delete _this.resizeTimeout;
2309  }
2310
2311  this.resizeTimeout = setTimeout( delayed, 100 );
2312};
2313
2314// debounced, layout on resize
2315Outlayer.prototype.resize = function() {
2316  // don't trigger if size did not change
2317  var size = getSize( this.element );
2318  // check that this.size and size are there
2319  // IE8 triggers resize on body size change, so they might not be
2320  var hasSizes = this.size && size;
2321  if ( hasSizes && size.innerWidth === this.size.innerWidth ) {
2322    return;
2323  }
2324
2325  this.layout();
2326};
2327
2328
2329// -------------------------- methods -------------------------- //
2330
2331/**
2332 * add items to Outlayer instance
2333 * @param {Array or NodeList or Element} elems
2334 * @returns {Array} items - Outlayer.Items
2335**/
2336Outlayer.prototype.addItems = function( elems ) {
2337  var items = this._itemize( elems );
2338  // add items to collection
2339  if ( items.length ) {
2340    this.items = this.items.concat( items );
2341  }
2342  return items;
2343};
2344
2345/**
2346 * Layout newly-appended item elements
2347 * @param {Array or NodeList or Element} elems
2348 */
2349Outlayer.prototype.appended = function( elems ) {
2350  var items = this.addItems( elems );
2351  if ( !items.length ) {
2352    return;
2353  }
2354  // layout and reveal just the new items
2355  this.layoutItems( items, true );
2356  this.reveal( items );
2357};
2358
2359/**
2360 * Layout prepended elements
2361 * @param {Array or NodeList or Element} elems
2362 */
2363Outlayer.prototype.prepended = function( elems ) {
2364  var items = this._itemize( elems );
2365  if ( !items.length ) {
2366    return;
2367  }
2368  // add items to beginning of collection
2369  var previousItems = this.items.slice(0);
2370  this.items = items.concat( previousItems );
2371  // start new layout
2372  this._resetLayout();
2373  this._manageStamps();
2374  // layout new stuff without transition
2375  this.layoutItems( items, true );
2376  this.reveal( items );
2377  // layout previous items
2378  this.layoutItems( previousItems );
2379};
2380
2381/**
2382 * reveal a collection of items
2383 * @param {Array of Outlayer.Items} items
2384 */
2385Outlayer.prototype.reveal = function( items ) {
2386  if ( !items || !items.length ) {
2387    return;
2388  }
2389  for ( var i=0, len = items.length; i < len; i++ ) {
2390    var item = items[i];
2391    item.reveal();
2392  }
2393};
2394
2395/**
2396 * hide a collection of items
2397 * @param {Array of Outlayer.Items} items
2398 */
2399Outlayer.prototype.hide = function( items ) {
2400  if ( !items || !items.length ) {
2401    return;
2402  }
2403  for ( var i=0, len = items.length; i < len; i++ ) {
2404    var item = items[i];
2405    item.hide();
2406  }
2407};
2408
2409/**
2410 * get Outlayer.Item, given an Element
2411 * @param {Element} elem
2412 * @param {Function} callback
2413 * @returns {Outlayer.Item} item
2414 */
2415Outlayer.prototype.getItem = function( elem ) {
2416  // loop through items to get the one that matches
2417  for ( var i=0, len = this.items.length; i < len; i++ ) {
2418    var item = this.items[i];
2419    if ( item.element === elem ) {
2420      // return item
2421      return item;
2422    }
2423  }
2424};
2425
2426/**
2427 * get collection of Outlayer.Items, given Elements
2428 * @param {Array} elems
2429 * @returns {Array} items - Outlayer.Items
2430 */
2431Outlayer.prototype.getItems = function( elems ) {
2432  if ( !elems || !elems.length ) {
2433    return;
2434  }
2435  var items = [];
2436  for ( var i=0, len = elems.length; i < len; i++ ) {
2437    var elem = elems[i];
2438    var item = this.getItem( elem );
2439    if ( item ) {
2440      items.push( item );
2441    }
2442  }
2443
2444  return items;
2445};
2446
2447/**
2448 * remove element(s) from instance and DOM
2449 * @param {Array or NodeList or Element} elems
2450 */
2451Outlayer.prototype.remove = function( elems ) {
2452  elems = makeArray( elems );
2453
2454  var removeItems = this.getItems( elems );
2455  // bail if no items to remove
2456  if ( !removeItems || !removeItems.length ) {
2457    return;
2458  }
2459
2460  this._itemsOn( removeItems, 'remove', function() {
2461    this.emitEvent( 'removeComplete', [ this, removeItems ] );
2462  });
2463
2464  for ( var i=0, len = removeItems.length; i < len; i++ ) {
2465    var item = removeItems[i];
2466    item.remove();
2467    // remove item from collection
2468    removeFrom( item, this.items );
2469  }
2470};
2471
2472// ----- destroy ----- //
2473
2474// remove and disable Outlayer instance
2475Outlayer.prototype.destroy = function() {
2476  // clean up dynamic styles
2477  var style = this.element.style;
2478  style.height = '';
2479  style.position = '';
2480  style.width = '';
2481  // destroy items
2482  for ( var i=0, len = this.items.length; i < len; i++ ) {
2483    var item = this.items[i];
2484    item.destroy();
2485  }
2486
2487  this.unbindResize();
2488
2489  delete this.element.outlayerGUID;
2490  // remove data for jQuery
2491  if ( jQuery ) {
2492    jQuery.removeData( this.element, this.settings.namespace );
2493  }
2494
2495};
2496
2497// -------------------------- data -------------------------- //
2498
2499/**
2500 * get Outlayer instance from element
2501 * @param {Element} elem
2502 * @returns {Outlayer}
2503 */
2504Outlayer.data = function( elem ) {
2505  var id = elem && elem.outlayerGUID;
2506  return id && instances[ id ];
2507};
2508
2509// --------------------------  -------------------------- //
2510
2511// copy an object on the Outlayer prototype
2512// used in options and settings
2513function copyOutlayerProto( obj, property ) {
2514  obj.prototype[ property ] = extend( {}, Outlayer.prototype[ property ] );
2515}
2516
2517// -------------------------- create Outlayer class -------------------------- //
2518
2519/**
2520 * create a layout class
2521 * @param {String} namespace
2522 */
2523Outlayer.create = function( namespace, options ) {
2524  // sub-class Outlayer
2525  function Layout() {
2526    Outlayer.apply( this, arguments );
2527  }
2528
2529  extend( Layout.prototype, Outlayer.prototype );
2530
2531  copyOutlayerProto( Layout, 'options' );
2532  copyOutlayerProto( Layout, 'settings' );
2533
2534  extend( Layout.prototype.options, options );
2535
2536  Layout.prototype.settings.namespace = namespace;
2537
2538  Layout.data = Outlayer.data;
2539
2540  // sub-class Item
2541  Layout.Item = function LayoutItem() {
2542    Item.apply( this, arguments );
2543  };
2544
2545  Layout.Item.prototype = new Item();
2546
2547  Layout.prototype.settings.item = Layout.Item;
2548
2549  // -------------------------- declarative -------------------------- //
2550
2551  /**
2552   * allow user to initialize Outlayer via .js-namespace class
2553   * options are parsed from data-namespace-option attribute
2554   */
2555  docReady( function() {
2556    var dashedNamespace = toDashed( namespace );
2557    var elems = document.querySelectorAll( '.js-' + dashedNamespace );
2558    var dataAttr = 'data-' + dashedNamespace + '-options';
2559
2560    for ( var i=0, len = elems.length; i < len; i++ ) {
2561      var elem = elems[i];
2562      var attr = elem.getAttribute( dataAttr );
2563      var options;
2564      try {
2565        options = attr && JSON.parse( attr );
2566      } catch ( error ) {
2567        // log error, do not initialize
2568        if ( console ) {
2569          console.error( 'Error parsing ' + dataAttr + ' on ' +
2570            elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +
2571            error );
2572        }
2573        continue;
2574      }
2575      // initialize
2576      var instance = new Layout( elem, options );
2577      // make available via $().data('layoutname')
2578      if ( jQuery ) {
2579        jQuery.data( elem, namespace, instance );
2580      }
2581    }
2582  });
2583
2584  // -------------------------- jQuery bridge -------------------------- //
2585
2586  // make into jQuery plugin
2587  if ( jQuery && jQuery.bridget ) {
2588    jQuery.bridget( namespace, Layout );
2589  }
2590
2591  return Layout;
2592};
2593
2594// ----- fin ----- //
2595
2596// back in global
2597Outlayer.Item = Item;
2598
2599return Outlayer;
2600
2601}
2602
2603// -------------------------- transport -------------------------- //
2604
2605if ( typeof define === 'function' && define.amd ) {
2606  // AMD
2607  define( [
2608      'eventie/eventie',
2609      'doc-ready/doc-ready',
2610      'eventEmitter/EventEmitter',
2611      'get-size/get-size',
2612      'matches-selector/matches-selector',
2613      './item'
2614    ],
2615    outlayerDefinition );
2616} else {
2617  // browser global
2618  window.Outlayer = outlayerDefinition(
2619    window.eventie,
2620    window.docReady,
2621    window.EventEmitter,
2622    window.getSize,
2623    window.matchesSelector,
2624    window.Outlayer.Item
2625  );
2626}
2627
2628})( window );
2629
2630/*!
2631 * Masonry v3.1.2
2632 * Cascading grid layout library
2633 * http://masonry.desandro.com
2634 * MIT License
2635 * by David DeSandro
2636 */
2637
2638( function( window ) {
2639
2640'use strict';
2641
2642// -------------------------- helpers -------------------------- //
2643
2644var indexOf = Array.prototype.indexOf ?
2645  function( items, value ) {
2646    return items.indexOf( value );
2647  } :
2648  function ( items, value ) {
2649    for ( var i=0, len = items.length; i < len; i++ ) {
2650      var item = items[i];
2651      if ( item === value ) {
2652        return i;
2653      }
2654    }
2655    return -1;
2656  };
2657
2658// -------------------------- masonryDefinition -------------------------- //
2659
2660// used for AMD definition and requires
2661function masonryDefinition( Outlayer, getSize ) {
2662  // create an Outlayer layout class
2663  var Masonry = Outlayer.create('masonry');
2664
2665  Masonry.prototype._resetLayout = function() {
2666    this.getSize();
2667    this._getMeasurement( 'columnWidth', 'outerWidth' );
2668    this._getMeasurement( 'gutter', 'outerWidth' );
2669    this.measureColumns();
2670
2671    // reset column Y
2672    var i = this.cols;
2673    this.colYs = [];
2674    while (i--) {
2675      this.colYs.push( 0 );
2676    }
2677
2678    this.maxY = 0;
2679  };
2680
2681  Masonry.prototype.measureColumns = function() {
2682    this.getContainerWidth();
2683    // if columnWidth is 0, default to outerWidth of first item
2684    if ( !this.columnWidth ) {
2685      var firstItem = this.items[0];
2686      var firstItemElem = firstItem && firstItem.element;
2687      // columnWidth fall back to item of first element
2688      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
2689        // if first elem has no width, default to size of container
2690        this.containerWidth;
2691    }
2692
2693    this.columnWidth += this.gutter;
2694
2695    this.cols = Math.floor( ( this.containerWidth + this.gutter ) / this.columnWidth );
2696    this.cols = Math.max( this.cols, 1 );
2697  };
2698
2699  Masonry.prototype.getContainerWidth = function() {
2700    // container is parent if fit width
2701    var container = this.options.isFitWidth ? this.element.parentNode : this.element;
2702    // check that this.size and size are there
2703    // IE8 triggers resize on body size change, so they might not be
2704    var size = getSize( container );
2705    this.containerWidth = size && size.innerWidth;
2706  };
2707
2708  Masonry.prototype._getItemLayoutPosition = function( item ) {
2709    item.getSize();
2710    // how many columns does this brick span
2711    var colSpan = Math.ceil( item.size.outerWidth / this.columnWidth );
2712    colSpan = Math.min( colSpan, this.cols );
2713
2714    var colGroup = this._getColGroup( colSpan );
2715    // get the minimum Y value from the columns
2716    var minimumY = Math.min.apply( Math, colGroup );
2717    var shortColIndex = indexOf( colGroup, minimumY );
2718
2719    // position the brick
2720    var position = {
2721      x: this.columnWidth * shortColIndex,
2722      y: minimumY
2723    };
2724
2725    // apply setHeight to necessary columns
2726    var setHeight = minimumY + item.size.outerHeight;
2727    var setSpan = this.cols + 1 - colGroup.length;
2728    for ( var i = 0; i < setSpan; i++ ) {
2729      this.colYs[ shortColIndex + i ] = setHeight;
2730    }
2731
2732    return position;
2733  };
2734
2735  /**
2736   * @param {Number} colSpan - number of columns the element spans
2737   * @returns {Array} colGroup
2738   */
2739  Masonry.prototype._getColGroup = function( colSpan ) {
2740    if ( colSpan < 2 ) {
2741      // if brick spans only one column, use all the column Ys
2742      return this.colYs;
2743    }
2744
2745    var colGroup = [];
2746    // how many different places could this brick fit horizontally
2747    var groupCount = this.cols + 1 - colSpan;
2748    // for each group potential horizontal position
2749    for ( var i = 0; i < groupCount; i++ ) {
2750      // make an array of colY values for that one group
2751      var groupColYs = this.colYs.slice( i, i + colSpan );
2752      // and get the max value of the array
2753      colGroup[i] = Math.max.apply( Math, groupColYs );
2754    }
2755    return colGroup;
2756  };
2757
2758  Masonry.prototype._manageStamp = function( stamp ) {
2759    var stampSize = getSize( stamp );
2760    var offset = this._getElementOffset( stamp );
2761    // get the columns that this stamp affects
2762    var firstX = this.options.isOriginLeft ? offset.left : offset.right;
2763    var lastX = firstX + stampSize.outerWidth;
2764    var firstCol = Math.floor( firstX / this.columnWidth );
2765    firstCol = Math.max( 0, firstCol );
2766    var lastCol = Math.floor( lastX / this.columnWidth );
2767    lastCol = Math.min( this.cols - 1, lastCol );
2768    // set colYs to bottom of the stamp
2769    var stampMaxY = ( this.options.isOriginTop ? offset.top : offset.bottom ) +
2770      stampSize.outerHeight;
2771    for ( var i = firstCol; i <= lastCol; i++ ) {
2772      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
2773    }
2774  };
2775
2776  Masonry.prototype._getContainerSize = function() {
2777    this.maxY = Math.max.apply( Math, this.colYs );
2778    var size = {
2779      height: this.maxY
2780    };
2781
2782    if ( this.options.isFitWidth ) {
2783      size.width = this._getContainerFitWidth();
2784    }
2785
2786    return size;
2787  };
2788
2789  Masonry.prototype._getContainerFitWidth = function() {
2790    var unusedCols = 0;
2791    // count unused columns
2792    var i = this.cols;
2793    while ( --i ) {
2794      if ( this.colYs[i] !== 0 ) {
2795        break;
2796      }
2797      unusedCols++;
2798    }
2799    // fit container to columns that have been used
2800    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
2801  };
2802
2803  // debounced, layout on resize
2804  // HEADS UP this overwrites Outlayer.resize
2805  // Any changes in Outlayer.resize need to be manually added here
2806  Masonry.prototype.resize = function() {
2807    // don't trigger if size did not change
2808    var previousWidth = this.containerWidth;
2809    this.getContainerWidth();
2810    if ( previousWidth === this.containerWidth ) {
2811      return;
2812    }
2813
2814    this.layout();
2815  };
2816
2817  return Masonry;
2818}
2819
2820// -------------------------- transport -------------------------- //
2821
2822if ( typeof define === 'function' && define.amd ) {
2823  // AMD
2824  define( [
2825      'outlayer/outlayer',
2826      'get-size/get-size'
2827    ],
2828    masonryDefinition );
2829} else {
2830  // browser global
2831  window.Masonry = masonryDefinition(
2832    window.Outlayer,
2833    window.getSize
2834  );
2835}
2836
2837})( window );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.