PageSourceSearch

https://guardianmosquitoandpestcontrol.com/wp-content/themes/woodmart/js/libs/isotope-bundle.js?ver=7.0.4

js guardianmosquitoandpestcontrol.com collected 2026-10-04 03:16:13 UTC 132,854 bytes, 4,265 lines download raw bytes

1/*!
2 * Isotope PACKAGED v2.2.2
3 *
4 * Licensed GPLv3 for open source use
5 * or Isotope Commercial License for commercial use
6 *
7 * http://isotope.metafizzy.co
8 * Copyright 2015 Metafizzy
9 */
10
11/**
12 * Bridget makes jQuery widgets
13 * v1.1.0
14 * MIT license
15 */
16
17( function( window ) {
18
19
20
21  // -------------------------- utils -------------------------- //
22
23  var slice = Array.prototype.slice;
24
25  function noop() {}
26
27  // -------------------------- definition -------------------------- //
28
29  function defineBridget( $ ) {
30
31    // bail if no jQuery
32    if ( !$ ) {
33      return;
34    }
35
36    // -------------------------- addOptionMethod -------------------------- //
37
38    /**
39     * adds option method -> $().plugin('option', {...})
40     * @param {Function} PluginClass - constructor class
41     */
42    function addOptionMethod( PluginClass ) {
43      // don't overwrite original option method
44      if ( PluginClass.prototype.option ) {
45        return;
46      }
47
48      // option setter
49      PluginClass.prototype.option = function( opts ) {
50        // bail out if not an object
51        if ( !$.isPlainObject( opts ) ){
52          return;
53        }
54        this.options = $.extend( true, this.options, opts );
55      };
56    }
57
58    // -------------------------- plugin bridge -------------------------- //
59
60    // helper function for logging errors
61    // $.error breaks jQuery chaining
62    var logError = typeof console === 'undefined' ? noop :
63        function( message ) {
64          console.error( message );
65        };
66
67    /**
68     * jQuery plugin bridge, access methods like $elem.plugin('method')
69     * @param {String} namespace - plugin name
70     * @param {Function} PluginClass - constructor class
71     */
72    function bridge( namespace, PluginClass ) {
73      // add to jQuery fn namespace
74      $.fn[ namespace ] = function( options ) {
75        if ( typeof options === 'string' ) {
76          // call plugin method when first argument is a string
77          // get arguments for method
78          var args = slice.call( arguments, 1 );
79
80          for ( var i=0, len = this.length; i < len; i++ ) {
81            var elem = this[i];
82            var instance = $.data( elem, namespace );
83            if ( !instance ) {
84              logError( "cannot call methods on " + namespace + " prior to initialization; " +
85                  "attempted to call '" + options + "'" );
86              continue;
87            }
88            if ( typeof instance[options] !== "function" || options.charAt(0) === '_' ) {
89              logError( "no such method '" + options + "' for " + namespace + " instance" );
90              continue;
91            }
92
93            // trigger method with arguments
94            var returnValue = instance[ options ].apply( instance, args );
95
96            // break look and return first value if provided
97            if ( returnValue !== undefined ) {
98              return returnValue;
99            }
100          }
101          // return this if no return value
102          return this;
103        } else {
104          return this.each( function() {
105            var instance = $.data( this, namespace );
106            if ( instance ) {
107              // apply options & init
108              instance.option( options );
109              instance._init();
110            } else {
111              // initialize new instance
112              instance = new PluginClass( this, options );
113              $.data( this, namespace, instance );
114            }
115          });
116        }
117      };
118
119    }
120
121    // -------------------------- bridget -------------------------- //
122
123    /**
124     * converts a Prototypical class into a proper jQuery plugin
125     *   the class must have a ._init method
126     * @param {String} namespace - plugin name, used in $().pluginName
127     * @param {Function} PluginClass - constructor class
128     */
129    $.bridget = function( namespace, PluginClass ) {
130      addOptionMethod( PluginClass );
131      bridge( namespace, PluginClass );
132    };
133
134    return $.bridget;
135
136  }
137
138  // transport
139  if ( typeof define === 'function' && define.amd ) {
140    // AMD
141    define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget );
142  } else if ( typeof exports === 'object' ) {
143    defineBridget( require('jquery') );
144  } else {
145    // get jquery from browser global
146    defineBridget( window.jQuery );
147  }
148
149})( window );
150
151/*!
152 * eventie v1.0.6
153 * event binding helper
154 *   eventie.bind( elem, 'click', myFn )
155 *   eventie.unbind( elem, 'click', myFn )
156 * MIT license
157 */
158
159/*jshint browser: true, undef: true, unused: true */
160/*global define: false, module: false */
161
162( function( window ) {
163
164
165
166  var docElem = document.documentElement;
167
168  var bind = function() {};
169
170  function getIEEvent( obj ) {
171    var event = window.event;
172    // add event.target
173    event.target = event.target || event.srcElement || obj;
174    return event;
175  }
176
177  if ( docElem.addEventListener ) {
178    bind = function( obj, type, fn ) {
179      obj.addEventListener( type, fn, false );
180    };
181  } else if ( docElem.attachEvent ) {
182    bind = function( obj, type, fn ) {
183      obj[ type + fn ] = fn.handleEvent ?
184          function() {
185            var event = getIEEvent( obj );
186            fn.handleEvent.call( fn, event );
187          } :
188          function() {
189            var event = getIEEvent( obj );
190            fn.call( obj, event );
191          };
192      obj.attachEvent( "on" + type, obj[ type + fn ] );
193    };
194  }
195
196  var unbind = function() {};
197
198  if ( docElem.removeEventListener ) {
199    unbind = function( obj, type, fn ) {
200      obj.removeEventListener( type, fn, false );
201    };
202  } else if ( docElem.detachEvent ) {
203    unbind = function( obj, type, fn ) {
204      obj.detachEvent( "on" + type, obj[ type + fn ] );
205      try {
206        delete obj[ type + fn ];
207      } catch ( err ) {
208        // can't delete window object properties
209        obj[ type + fn ] = undefined;
210      }
211    };
212  }
213
214  var eventie = {
215    bind: bind,
216    unbind: unbind
217  };
218
219  // ----- module definition ----- //
220
221  if ( typeof define === 'function' && define.amd ) {
222    // AMD
223    define( 'eventie/eventie',eventie );
224  } else if ( typeof exports === 'object' ) {
225    // CommonJS
226    module.exports = eventie;
227  } else {
228    // browser global
229    window.eventie = eventie;
230  }
231
232})( window );
233
234/*!
235 * EventEmitter v4.2.11 - git.io/ee
236 * Unlicense - http://unlicense.org/
237 * Oliver Caldwell - http://oli.me.uk/
238 * @preserve
239 */
240
241;(function () {
242  'use strict';
243
244  /**
245   * Class for managing events.
246   * Can be extended to provide event functionality in other classes.
247   *
248   * @class EventEmitter Manages event registering and emitting.
249   */
250  function EventEmitter() {}
251
252  // Shortcuts to improve speed and size
253  var proto = EventEmitter.prototype;
254  var exports = this;
255  var originalGlobalValue = exports.EventEmitter;
256
257  /**
258   * Finds the index of the listener for the event in its storage array.
259   *
260   * @param {Function[]} listeners Array of listeners to search through.
261   * @param {Function} listener Method to look for.
262   * @return {Number} Index of the specified listener, -1 if not found
263   * @api private
264   */
265  function indexOfListener(listeners, listener) {
266    var i = listeners.length;
267    while (i--) {
268      if (listeners[i].listener === listener) {
269        return i;
270      }
271    }
272
273    return -1;
274  }
275
276  /**
277   * Alias a method while keeping the context correct, to allow for overwriting of target method.
278   *
279   * @param {String} name The name of the target method.
280   * @return {Function} The aliased method
281   * @api private
282   */
283  function alias(name) {
284    return function aliasClosure() {
285      return this[name].apply(this, arguments);
286    };
287  }
288
289  /**
290   * Returns the listener array for the specified event.
291   * Will initialise the event object and listener arrays if required.
292   * 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: 16,384 bytes, lines 292-753
292ontaining bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
293   * Each property in the object response is an array of listener functions.
294   *
295   * @param {String|RegExp} evt Name of the event to return the listeners from.
296   * @return {Function[]|Object} All listener functions for the event.
297   */
298  proto.getListeners = function getListeners(evt) {
299    var events = this._getEvents();
300    var response;
301    var key;
302
303    // Return a concatenated array of all matching events if
304    // the selector is a regular expression.
305    if (evt instanceof RegExp) {
306      response = {};
307      for (key in events) {
308        if (events.hasOwnProperty(key) && evt.test(key)) {
309          response[key] = events[key];
310        }
311      }
312    }
313    else {
314      response = events[evt] || (events[evt] = []);
315    }
316
317    return response;
318  };
319
320  /**
321   * Takes a list of listener objects and flattens it into a list of listener functions.
322   *
323   * @param {Object[]} listeners Raw listener objects.
324   * @return {Function[]} Just the listener functions.
325   */
326  proto.flattenListeners = function flattenListeners(listeners) {
327    var flatListeners = [];
328    var i;
329
330    for (i = 0; i < listeners.length; i += 1) {
331      flatListeners.push(listeners[i].listener);
332    }
333
334    return flatListeners;
335  };
336
337  /**
338   * 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.
339   *
340   * @param {String|RegExp} evt Name of the event to return the listeners from.
341   * @return {Object} All listener functions for an event in an object.
342   */
343  proto.getListenersAsObject = function getListenersAsObject(evt) {
344    var listeners = this.getListeners(evt);
345    var response;
346
347    if (listeners instanceof Array) {
348      response = {};
349      response[evt] = listeners;
350    }
351
352    return response || listeners;
353  };
354
355  /**
356   * Adds a listener function to the specified event.
357   * The listener will not be added if it is a duplicate.
358   * If the listener returns true then it will be removed after it is called.
359   * If you pass a regular expression as the event name then the listener will be added to all events that match it.
360   *
361   * @param {String|RegExp} evt Name of the event to attach the listener to.
362   * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
363   * @return {Object} Current instance of EventEmitter for chaining.
364   */
365  proto.addListener = function addListener(evt, listener) {
366    var listeners = this.getListenersAsObject(evt);
367    var listenerIsWrapped = typeof listener === 'object';
368    var key;
369
370    for (key in listeners) {
371      if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
372        listeners[key].push(listenerIsWrapped ? listener : {
373          listener: listener,
374          once: false
375        });
376      }
377    }
378
379    return this;
380  };
381
382  /**
383   * Alias of addListener
384   */
385  proto.on = alias('addListener');
386
387  /**
388   * Semi-alias of addListener. It will add a listener that will be
389   * automatically removed after its first execution.
390   *
391   * @param {String|RegExp} evt Name of the event to attach the listener to.
392   * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
393   * @return {Object} Current instance of EventEmitter for chaining.
394   */
395  proto.addOnceListener = function addOnceListener(evt, listener) {
396    return this.addListener(evt, {
397      listener: listener,
398      once: true
399    });
400  };
401
402  /**
403   * Alias of addOnceListener.
404   */
405  proto.once = alias('addOnceListener');
406
407  /**
408   * 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.
409   * You need to tell it what event names should be matched by a regex.
410   *
411   * @param {String} evt Name of the event to create.
412   * @return {Object} Current instance of EventEmitter for chaining.
413   */
414  proto.defineEvent = function defineEvent(evt) {
415    this.getListeners(evt);
416    return this;
417  };
418
419  /**
420   * Uses defineEvent to define multiple events.
421   *
422   * @param {String[]} evts An array of event names to define.
423   * @return {Object} Current instance of EventEmitter for chaining.
424   */
425  proto.defineEvents = function defineEvents(evts) {
426    for (var i = 0; i < evts.length; i += 1) {
427      this.defineEvent(evts[i]);
428    }
429    return this;
430  };
431
432  /**
433   * Removes a listener function from the specified event.
434   * When passed a regular expression as the event name, it will remove the listener from all events that match it.
435   *
436   * @param {String|RegExp} evt Name of the event to remove the listener from.
437   * @param {Function} listener Method to remove from the event.
438   * @return {Object} Current instance of EventEmitter for chaining.
439   */
440  proto.removeListener = function removeListener(evt, listener) {
441    var listeners = this.getListenersAsObject(evt);
442    var index;
443    var key;
444
445    for (key in listeners) {
446      if (listeners.hasOwnProperty(key)) {
447        index = indexOfListener(listeners[key], listener);
448
449        if (index !== -1) {
450          listeners[key].splice(index, 1);
451        }
452      }
453    }
454
455    return this;
456  };
457
458  /**
459   * Alias of removeListener
460   */
461  proto.off = alias('removeListener');
462
463  /**
464   * Adds listeners in bulk using the manipulateListeners method.
465   * 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.
466   * You can also pass it a regular expression to add the array of listeners to all events that match it.
467   * Yeah, this function does quite a bit. That's probably a bad thing.
468   *
469   * @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.
470   * @param {Function[]} [listeners] An optional array of listener functions to add.
471   * @return {Object} Current instance of EventEmitter for chaining.
472   */
473  proto.addListeners = function addListeners(evt, listeners) {
474    // Pass through to manipulateListeners
475    return this.manipulateListeners(false, evt, listeners);
476  };
477
478  /**
479   * Removes listeners in bulk using the manipulateListeners method.
480   * 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.
481   * You can also pass it an event name and an array of listeners to be removed.
482   * You can also pass it a regular expression to remove the listeners from all events that match it.
483   *
484   * @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.
485   * @param {Function[]} [listeners] An optional array of listener functions to remove.
486   * @return {Object} Current instance of EventEmitter for chaining.
487   */
488  proto.removeListeners = function removeListeners(evt, listeners) {
489    // Pass through to manipulateListeners
490    return this.manipulateListeners(true, evt, listeners);
491  };
492
493  /**
494   * 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.
495   * The first argument will determine if the listeners are removed (true) or added (false).
496   * 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.
497   * You can also pass it an event name and an array of listeners to be added/removed.
498   * You can also pass it a regular expression to manipulate the listeners of all events that match it.
499   *
500   * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
501   * @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.
502   * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
503   * @return {Object} Current instance of EventEmitter for chaining.
504   */
505  proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
506    var i;
507    var value;
508    var single = remove ? this.removeListener : this.addListener;
509    var multiple = remove ? this.removeListeners : this.addListeners;
510
511    // If evt is an object then pass each of its properties to this method
512    if (typeof evt === 'object' && !(evt instanceof RegExp)) {
513      for (i in evt) {
514        if (evt.hasOwnProperty(i) && (value = evt[i])) {
515          // Pass the single listener straight through to the singular method
516          if (typeof value === 'function') {
517            single.call(this, i, value);
518          }
519          else {
520            // Otherwise pass back to the multiple function
521            multiple.call(this, i, value);
522          }
523        }
524      }
525    }
526    else {
527      // So evt must be a string
528      // And listeners must be an array of listeners
529      // Loop over it and pass each one to the multiple method
530      i = listeners.length;
531      while (i--) {
532        single.call(this, evt, listeners[i]);
533      }
534    }
535
536    return this;
537  };
538
539  /**
540   * Removes all listeners from a specified event.
541   * If you do not specify an event then all listeners will be removed.
542   * That means every event will be emptied.
543   * You can also pass a regex to remove all events that match it.
544   *
545   * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
546   * @return {Object} Current instance of EventEmitter for chaining.
547   */
548  proto.removeEvent = function removeEvent(evt) {
549    var type = typeof evt;
550    var events = this._getEvents();
551    var key;
552
553    // Remove different things depending on the state of evt
554    if (type === 'string') {
555      // Remove all listeners for the specified event
556      delete events[evt];
557    }
558    else if (evt instanceof RegExp) {
559      // Remove all events matching the regex.
560      for (key in events) {
561        if (events.hasOwnProperty(key) && evt.test(key)) {
562          delete events[key];
563        }
564      }
565    }
566    else {
567      // Remove all listeners in all events
568      delete this._events;
569    }
570
571    return this;
572  };
573
574  /**
575   * Alias of removeEvent.
576   *
577   * Added to mirror the node API.
578   */
579  proto.removeAllListeners = alias('removeEvent');
580
581  /**
582   * Emits an event of your choice.
583   * When emitted, every listener attached to that event will be executed.
584   * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
585   * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
586   * So they will not arrive within the array on the other side, they will be separate.
587   * You can also pass a regular expression to emit to all events that match it.
588   *
589   * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
590   * @param {Array} [args] Optional array of arguments to be passed to each listener.
591   * @return {Object} Current instance of EventEmitter for chaining.
592   */
593  proto.emitEvent = function emitEvent(evt, args) {
594    var listeners = this.getListenersAsObject(evt);
595    var listener;
596    var i;
597    var key;
598    var response;
599
600    for (key in listeners) {
601      if (listeners.hasOwnProperty(key)) {
602        i = listeners[key].length;
603
604        while (i--) {
605          // If the listener returns true then it shall be removed from the event
606          // The function is executed either with a basic call or an apply if there is an args array
607          listener = listeners[key][i];
608
609          if (listener.once === true) {
610            this.removeListener(evt, listener.listener);
611          }
612
613          response = listener.listener.apply(this, args || []);
614
615          if (response === this._getOnceReturnValue()) {
616            this.removeListener(evt, listener.listener);
617          }
618        }
619      }
620    }
621
622    return this;
623  };
624
625  /**
626   * Alias of emitEvent
627   */
628  proto.trigger = alias('emitEvent');
629
630  /**
631   * 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.
632   * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
633   *
634   * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
635   * @param {...*} Optional additional arguments to be passed to each listener.
636   * @return {Object} Current instance of EventEmitter for chaining.
637   */
638  proto.emit = function emit(evt) {
639    var args = Array.prototype.slice.call(arguments, 1);
640    return this.emitEvent(evt, args);
641  };
642
643  /**
644   * Sets the current value to check against when executing listeners. If a
645   * listeners return value matches the one set here then it will be removed
646   * after execution. This value defaults to true.
647   *
648   * @param {*} value The new value to check for when executing listeners.
649   * @return {Object} Current instance of EventEmitter for chaining.
650   */
651  proto.setOnceReturnValue = function setOnceReturnValue(value) {
652    this._onceReturnValue = value;
653    return this;
654  };
655
656  /**
657   * Fetches the current value to check against when executing listeners. If
658   * the listeners return value matches this one then it should be removed
659   * automatically. It will return true by default.
660   *
661   * @return {*|Boolean} The current value to check for or the default, true.
662   * @api private
663   */
664  proto._getOnceReturnValue = function _getOnceReturnValue() {
665    if (this.hasOwnProperty('_onceReturnValue')) {
666      return this._onceReturnValue;
667    }
668    else {
669      return true;
670    }
671  };
672
673  /**
674   * Fetches the events object and creates one if required.
675   *
676   * @return {Object} The events storage object.
677   * @api private
678   */
679  proto._getEvents = function _getEvents() {
680    return this._events || (this._events = {});
681  };
682
683  /**
684   * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
685   *
686   * @return {Function} Non conflicting EventEmitter class.
687   */
688  EventEmitter.noConflict = function noConflict() {
689    exports.EventEmitter = originalGlobalValue;
690    return EventEmitter;
691  };
692
693  // Expose the class either via AMD, CommonJS or the global object
694  if (typeof define === 'function' && define.amd) {
695    define('eventEmitter/EventEmitter',[],function () {
696      return EventEmitter;
697    });
698  }
699  else if (typeof module === 'object' && module.exports){
700    module.exports = EventEmitter;
701  }
702  else {
703    exports.EventEmitter = EventEmitter;
704  }
705}.call(this));
706
707/*!
708 * getStyleProperty v1.0.4
709 * original by kangax
710 * http://perfectionkills.com/feature-testing-css-properties/
711 * MIT license
712 */
713
714/*jshint browser: true, strict: true, undef: true */
715/*global define: false, exports: false, module: false */
716
717( function( window ) {
718
719
720
721  var prefixes = 'Webkit Moz ms Ms O'.split(' ');
722  var docElemStyle = document.documentElement.style;
723
724  function getStyleProperty( propName ) {
725    if ( !propName ) {
726      return;
727    }
728
729    // test standard property first
730    if ( typeof docElemStyle[ propName ] === 'string' ) {
731      return propName;
732    }
733
734    // capitalize
735    propName = propName.charAt(0).toUpperCase() + propName.slice(1);
736
737    // test vendor specific properties
738    var prefixed;
739    for ( var i=0, len = prefixes.length; i < len; i++ ) {
740      prefixed = prefixes[i] + propName;
741      if ( typeof docElemStyle[ prefixed ] === 'string' ) {
742        return prefixed;
743      }
744    }
745  }
746
747  // transport
748  if ( typeof define === 'function' && define.amd ) {
749    // AMD
750    define( 'get-style-property/get-style-property',[],function() {
751      return getStyleProperty;
752    });
753  } else if ( 
753typeof exports === 'object' ) {
754    // CommonJS for Component
755    module.exports = getStyleProperty;
756  } else {
757    // browser global
758    window.getStyleProperty = getStyleProperty;
759  }
760
761})( window );
762
763/*!
764 * getSize v1.2.2
765 * measure size of elements
766 * MIT license
767 */
768
769/*jshint browser: true, strict: true, undef: true, unused: true */
770/*global define: false, exports: false, require: false, module: false, console: false */
771
772( function( window, undefined ) {
773
774
775
776  // -------------------------- helpers -------------------------- //
777
778  // get a number from a string, not a percentage
779  function getStyleSize( value ) {
780    var num = parseFloat( value );
781    // not a percent like '100%', and a number
782    var isValid = value.indexOf('%') === -1 && !isNaN( num );
783    return isValid && num;
784  }
785
786  function noop() {}
787
788  var logError = typeof console === 'undefined' ? noop :
789      function( message ) {
790        console.error( message );
791      };
792
793  // -------------------------- measurements -------------------------- //
794
795  var measurements = [
796    'paddingLeft',
797    'paddingRight',
798    'paddingTop',
799    'paddingBottom',
800    'marginLeft',
801    'marginRight',
802    'marginTop',
803    'marginBottom',
804    'borderLeftWidth',
805    'borderRightWidth',
806    'borderTopWidth',
807    'borderBottomWidth'
808  ];
809
810  function getZeroSize() {
811    var size = {
812      width: 0,
813      height: 0,
814      innerWidth: 0,
815      innerHeight: 0,
816      outerWidth: 0,
817      outerHeight: 0
818    };
819    for ( var i=0, len = measurements.length; i < len; i++ ) {
820      var measurement = measurements[i];
821      size[ measurement ] = 0;
822    }
823    return size;
824  }
825
826
827
828  function defineGetSize( getStyleProperty ) {
829
830    // -------------------------- setup -------------------------- //
831
832    var isSetup = false;
833
834    var getStyle, boxSizingProp, isBoxSizeOuter;
835
836    /**
837     * setup vars and functions
838     * do it on initial getSize(), rather than on script load
839     * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397
840     */
841    function setup() {
842      // setup once
843      if ( isSetup ) {
844        return;
845      }
846      isSetup = true;
847
848      var getComputedStyle = window.getComputedStyle;
849      getStyle = ( function() {
850        var getStyleFn = getComputedStyle ?
851            function( elem ) {
852              return getComputedStyle( elem, null );
853            } :
854            function( elem ) {
855              return elem.currentStyle;
856            };
857
858        return function getStyle( elem ) {
859          var style = getStyleFn( elem );
860          if ( !style ) {
861            logError( 'Style returned ' + style +
862                '. Are you running this code in a hidden iframe on Firefox? ' +
863                'See http://bit.ly/getsizebug1' );
864          }
865          return style;
866        };
867      })();
868
869      // -------------------------- box sizing -------------------------- //
870
871      boxSizingProp = getStyleProperty('boxSizing');
872
873      /**
874       * WebKit measures the outer-width on style.width on border-box elems
875       * IE & Firefox measures the inner-width
876       */
877      if ( boxSizingProp ) {
878        var div = document.createElement('div');
879        div.style.width = '200px';
880        div.style.padding = '1px 2px 3px 4px';
881        div.style.borderStyle = 'solid';
882        div.style.borderWidth = '1px 2px 3px 4px';
883        div.style[ boxSizingProp ] = 'border-box';
884
885        var body = document.body || document.documentElement;
886        body.appendChild( div );
887        var style = getStyle( div );
888
889        isBoxSizeOuter = getStyleSize( style.width ) === 200;
890        body.removeChild( div );
891      }
892
893    }
894
895    // -------------------------- getSize -------------------------- //
896
897    function getSize( elem ) {
898      setup();
899
900      // use querySeletor if elem is string
901      if ( typeof elem === 'string' ) {
902        elem = document.querySelector( elem );
903      }
904
905      // do not proceed on non-objects
906      if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
907        return;
908      }
909
910      var style = getStyle( elem );
911
912      // if hidden, everything is 0
913      if ( style.display === 'none' ) {
914        return getZeroSize();
915      }
916
917      var size = {};
918      size.width = elem.offsetWidth;
919      size.height = elem.offsetHeight;
920
921      var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
922          style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
923
924      // get all measurements
925      for ( var i=0, len = measurements.length; i < len; i++ ) {
926        var measurement = measurements[i];
927        var value = style[ measurement ];
928        value = mungeNonPixel( elem, value );
929        var num = parseFloat( value );
930        // any 'auto', 'medium' value will be 0
931        size[ measurement ] = !isNaN( num ) ? num : 0;
932      }
933
934      var paddingWidth = size.paddingLeft + size.paddingRight;
935      var paddingHeight = size.paddingTop + size.paddingBottom;
936      var marginWidth = size.marginLeft + size.marginRight;
937      var marginHeight = size.marginTop + size.marginBottom;
938      var borderWidth = size.borderLeftWidth + size.borderRightWidth;
939      var borderHeight = size.borderTopWidth + size.borderBottomWidth;
940
941      var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
942
943      // overwrite width and height if we can get it from style
944      var styleWidth = getStyleSize( style.width );
945      if ( styleWidth !== false ) {
946        size.width = styleWidth +
947            // add padding and border unless it's already including it
948            ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
949      }
950
951      var styleHeight = getStyleSize( style.height );
952      if ( styleHeight !== false ) {
953        size.height = styleHeight +
954            // add padding and border unless it's already including it
955            ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
956      }
957
958      size.innerWidth = size.width - ( paddingWidth + borderWidth );
959      size.innerHeight = size.height - ( paddingHeight + borderHeight );
960
961      size.outerWidth = size.width + marginWidth;
962      size.outerHeight = size.height + marginHeight;
963
964      return size;
965    }
966
967    // IE8 returns percent values, not pixels
968    // taken from jQuery's curCSS
969    function mungeNonPixel( elem, value ) {
970      // IE8 and has percent value
971      if ( window.getComputedStyle || value.indexOf('%') === -1 ) {
972        return value;
973      }
974      var style = elem.style;
975      // Remember the original values
976      var left = style.left;
977      var rs = elem.runtimeStyle;
978      var rsLeft = rs && rs.left;
979
980      // Put in the new values to get a computed value out
981      if ( rsLeft ) {
982        rs.left = elem.currentStyle.left;
983      }
984      style.left = value;
985      value = style.pixelLeft;
986
987      // Revert the changed values
988      style.left = left;
989      if ( rsLeft ) {
990        rs.left = rsLeft;
991      }
992
993      return value;
994    }
995
996    return getSize;
997
998  }
999
1000  // transport
1001  if ( typeof define === 'function' && define.amd ) {
1002    // AMD for RequireJS
1003    define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );
1004  } else if ( typeof exports === 'object' ) {
1005    // CommonJS for Component
1006    module.exports = defineGetSize( require('desandro-get-style-property') );
1007  } else {
1008    // browser global
1009    window.getSize = defineGetSize( window.getStyleProperty );
1010  }
1011
1012})( window );
1013
1014/*!
1015 * docReady v1.0.4
1016 * Cross browser DOMContentLoaded event emitter
1017 * MIT license
1018 */
1019
1020/*jshint browser: true, strict: true, undef: true, unused: true*/
1021/*global define: false, require: false, module: false */
1022
1023( function( window ) {
1024
1025
1026
1027  var document = window.document;
1028  // collection of functions to be triggered on ready
1029  var queue = [];
1030
1031  function docReady( fn ) {
1032    // throw out non-functions
1033    if ( typeof fn !== 'function' ) {
1034      return;
1035    }
1036
1037    if ( docReady.isReady ) {
1038      // ready now, hit it
1039      fn();
1040    } else {
1041      // queue function when ready
1042      queue.push( fn );
1043    }
1044  }
1045
1046  docReady.isReady = false;
1047
1048  // triggered on various doc ready events
1049  function onReady( event ) {
1050    // bail if already triggered or IE8 document is not ready just yet
1051    var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete';
1052    if ( docReady.isReady || isIE8NotReady ) {
1053      return;
1054    }
1055
1056    trigger();
1057  }
1058
1059  function trigger() {
1060    docReady.isReady = true;
1061    // process queue
1062    for ( var i=0, len = queue.length; i < len; i++ ) {
1063      var fn = queue[i];
1064      fn();
1065    }
1066  }
1067
1068  function defineDocReady( eventie ) {
1069    // trigger ready if page is ready
1070    if ( document.readyState === 'complete' ) {
1071      trigger();
1072    } else {
1073      // listen for events
1074      eventie.bind( document, 'DOMContentLoaded', onReady );
1075      eventie.bind( document, 'readystatechange', onReady );
1076      eventie.bind( window, 'load', onReady );
1077    }
1078
1079    return docReady;
1080  }
1081
1082  // transport
1083  if ( typeof define === 'function' && define.amd ) {
1084    // AMD
1085    define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady );
1086  } else if ( typeof exports === 'object' ) {
1087    module.exports = defineDocReady( require('eventie') );
1088  } else {
1089    // browser global
1090    window.docReady = defineDocReady( window.eventie );
1091  }
1092
1093})( window );
1094
1095/**
1096 * matchesSelector v1.0.3
1097 * matchesSelector( element, '.selector' )
1098 * MIT license
1099 */
1100
1101/*jshint browser: true, strict: true, undef: true, unused: true */
1102/*global define: false, module: false */
1103
1104( function( ElemProto ) {
1105
1106  'use strict';
1107
1108  var matchesMethod = ( function() {
1109    // check for the standard method name first
1110    if ( ElemProto.matches ) {
1111      return 'matches';
1112    }
1113    // check un-prefixed
1114    if ( ElemProto.matchesSelector ) {
1115      return 'matchesSelector';
1116    }
1117    // check vendor prefixes
1118    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
1119
1120    for ( var i=0, len = prefixes.length; i < len; i++ ) {
1121      var prefix = prefixes[i];
1122      var method = prefix + 'MatchesSelector';
1123      if ( ElemProto[ method ] ) {
1124        return method;
1125      }
1126    }
1127  })();
1128
1129  // ----- match ----- //
1130
1131  function match( elem, selector ) {
1132    return elem[ matchesMethod ]( selector );
1133  }
1134
1135  // ----- appendToFragment ----- //
1136
1137  function checkParent( elem ) {
1138    // not needed if already has parent
1139    if ( elem.parentNode ) {
1140      return;
1141    }
1142    var fragment = document.createDocumentFragment();
1143    fragment.appendChild( elem );
1144  }
1145
1146  // ----- query ----- //
1147
1148  // fall back to using QSA
1149  // thx @jonathantneal https://gist.github.com/3062955
1150  function query( elem, selector ) {
1151    // append to fragment if no parent
1152    checkParent( elem );
1153
1154    // match elem with all selected elems of parent
1155    var elems = elem.parentNode.querySelectorAll( selector );
1156    for ( var i=0, len = elems.length; i < len; i++ ) {
1157      // return true if match
1158      if ( elems[i] === elem ) {
1159        return true;
1160      }
1161    }
1162    // otherwise return false
1163    return false;
1164  }
1165
1166  // ----- matchChild ----- //
1167
1168  function matchChild( elem, selector ) {
1169    checkParent( elem );
1170    return match( elem, selector );
1171  }
1172
1173  // ----- matchesSelector ----- //
1174
1175  var matchesSelector;
1176
1177  if ( matchesMethod ) {
1178    // IE9 supports matchesSelector, but doesn't work on orphaned elems
1179    // check for that
1180    var div = document.createElement('div');
1181    var supportsOrphans = match( div, 'div' );
1182    matchesSelector = supportsOrphans ? match : matchChild;
1183  } else {
1184    matchesSelector = query;
1185  }
1186
1187  // transport
1188  if ( typeof define === 'function' && define.amd ) {
1189    // AMD
1190    define( 'matches-selector/matches-selector',[],function() {
1191      return matchesSelector;
1192    });
1193  } else if ( typeof exports === 'object' ) {
1194    module.exports = matchesSelector;
1195  }
1196  else {
1197    // browser global
1198    window.matchesSelector = matchesSelector;
1199  }
1200
1201})( Element.prototype );
1202
1203/**
1204 * Fizzy UI utils v1.0.1
1205 * MIT license
1206 */
1207
1208/*jshint browser: true, undef: true, unused: true, strict: true */
1209
1210( function( window, factory ) {
1211  /*global define: false, module: false, require: false */
1212  'use strict';
1213  // universal module definition
1214
1215  if ( typeof define == 'function' && define.amd ) {
1216    // AMD
1217    define( 'fizzy-ui-utils/utils',[
1218      'doc-ready/doc-ready',
1219      'matches-selector/matches-selector'
1220    ], function( docReady, matchesSelector ) {
1221      return factory( window, docReady, matchesSelector );
1222    });
1223  } else if ( typeof exports == 'object' ) {
1224    // CommonJS
1225    module.exports = factory(
1226        window,
1227        require('doc-ready'),
1228        require('desandro-matches-selector')
1229    );
1230  } else {
1231    // browser global
1232    window.fizzyUIUtils = factory(
1233        window,
1234        window.docReady,
1235        window.matchesSelector
1236    );
1237  }
1238
1239}( window, function factory( window, docReady, matchesSelector ) {
1240
1241
1242
1243  var utils = {};
1244
1245  // ----- extend ----- //
1246
1247  // extends objects
1248  utils.extend = function( a, b ) {
1249    for ( var prop in b ) {
1250      a[ prop ] = b[ prop ];
1251    }
1252    return a;
1253  };
1254
1255  // ----- modulo ----- //
1256
1257  utils.modulo = function( num, div ) {
1258    return ( ( num % div ) + div ) % div;
1259  };
1260
1261  // ----- isArray ----- //
1262
1263  var objToString = Object.prototype.toString;
1264  utils.isArray = function( obj ) {
1265    return objToString.call( obj ) == '[object Array]';
1266  };
1267
1268  // ----- makeArray ----- //
1269
1270  // turn element or nodeList into an array
1271  utils.makeArray = function( obj ) {
1272    var ary = [];
1273    if ( utils.isArray( obj ) ) {
1274      // use object if already an array
1275      ary = obj;
1276    } else if ( obj && typeof obj.length == 'number' ) {
1277      // convert nodeList to array
1278      for ( var i=0, len = obj.length; i < len; i++ ) {
1279        ary.push( obj[i] );
1280      }
1281    } else {
1282      // array of single index
1283      ary.push( obj );
1284    }
1285    return ary;
1286  };
1287
1288  // ----- indexOf ----- //
1289
1290  // index of helper cause IE8
1291  utils.indexOf = Array.prototype.indexOf ? function( ary, obj ) {
1292    return ary.indexOf( obj );
1293  } : function( ary, obj ) {
1294    for ( var i=0, len = ary.length; i < len; i++ ) {
1295      if ( ary[i] === obj ) {
1296        return i;
1297      }
1298    }
1299    return -1;
1300  };
1301
1302  // ----- removeFrom ----- //
1303
1304  utils.removeFrom = function( ary, obj ) {
1305    var index = utils.indexOf( ary, obj );
1306    if ( index != -1 ) {
1307      ary.splice( index, 1 );
1308    }
1309  };
1310
1311  // ----- isElement ----- //
1312
1313  // http://stackoverflow.com/a/384380/182183
1314  utils.isElement = typeof HTMLElement == 'object' ?
1315      function isElementDOM2( obj ) {
1316        return obj instanceof HTMLElement;
1317      } :
1318      function isElementQuirky( obj ) {
1319        return obj && typeof obj == 'object' && obj !== null &&
1320            obj.nodeType == 1 && typeof obj.nodeName == 'string';
1321      };
1322
1323  // ----- setText ----- //
1324
1325  utils.setText = ( function() {
1326    var setTextProperty;
1327    function setText( elem, text ) {
1328      // only check setTextProperty once
1329      setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' );
1330      elem[ setTextProperty ] = text;
1331    }
1332    return setText;
1333  })();
1334
1335  // ----- getParent ----- //
1336
1337  utils.getParent = function( elem, selector ) {
1338    while ( elem != document.body ) {
1339      elem = elem.parentNode;
1340      if ( matchesSelector( elem, selector ) ) {
1341        return elem;
1342      }
1343    }
1344  };
1345
1346  // ----- getQueryElement ----- //
1347
1348  // use element as selector string
1349  utils.getQueryElement = function( elem ) {
1350    if ( typeof elem == 'string' ) {
1351      return document.querySelector( elem );
1352    }
1353    return elem;
1354  };
1355
1356  // ----- handleEvent ----- //
1357
1358  // enable .ontype to trigger from .addEventListener( elem, 'type' )
1359  utils.handleEvent = function( event ) {
1360    var method = 'on' + event.type;
1361    if ( this[ method ] ) {
1362      this[ method ]( event );
1363    }
1364  };
1365
1366  // ----- filterFindElements ----- //
1367
1368  utils.filterFindElements = function( elems, selector ) {
1369    // make array of elems
1370    elems = utils.makeArray( elems );
1371    var ffElems = [];
1372
1373    for ( var i=0, len = elems.length; i < len; i++ ) {
1374      var elem = elems[i];
1375      // check that elem is an actual element
1376      if ( !utils.isElement( elem ) ) {
1377        continue;
1378      }
1379      // filter & find items if we have a selector
1380      if ( selector ) {
1381        // filter siblings
1382        if ( matchesSelector( elem, selector ) ) {
1383          ffElems.push( elem );
1384        }
1385        // find children
1386        var childElems = elem.querySelectorAll( selector );
1387        // concat childElems to filterFound array
1388        for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
1389          ffElems.push( childElems[j] );
1390        }
1391      } else {
1392        ffElems.push( elem );
1393      }
1394    }
1395
1396    return ffElems;
1397  };
1398
1399  // ----- debounceMethod ----- //
1400
1401  utils.debounceMethod = function( _class, methodName, threshold ) {
1402    // original method
1403    var method = _class.prototype[ methodName ];
1404    var timeoutName = methodName + 'Timeout';
1405
1406    _class.prototype[ methodName ] = function() {
1407      var timeout = this[ timeoutName ];
1408      if ( timeout ) {
1409        clearTimeout( timeout );
1410      }
1411      var args = arguments;
1412
1413      var _this = this;
1414      this[ timeoutName ] = setTimeout( function() {
1415        method.apply( _this, args );
1416        delete _this[ timeoutName ];
1417      }, threshold || 100 );
1418    };
1419  };
1420
1421  // ----- htmlInit ----- //
1422
1423  // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1424  utils.toDashed = function( str ) {
1425    return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
1426      return $1 + '-' + $2;
1427    }).toLowerCase();
1428  };
1429
1430  var console = window.console;
1431  /**
1432   * allow user to initialize classes via .js-namespace class
1433   * htmlInit( Widget, 'widgetName' )
1434   * options are parsed from data-namespace-option attribute
1435   */
1436  utils.htmlInit = function( WidgetClass, namespace ) {
1437    docReady( function() {
1438      var dashedNamespace = utils.toDashed( namespace );
1439      var elems = document.querySelectorAll( '.js-' + dashedNamespace );
1440      var dataAttr = 'data-' + dashedNamespace + '-options';
1441
1442      for ( var i=0, len = elems.length; i < len; i++ ) {
1443        var elem = elems[i];
1444        var attr = elem.getAttribute( dataAttr );
1445        var options;
1446        try {
1447          options = attr && JSON.parse( attr );
1448        } catch ( error ) {
1449          // log error, do not initialize
1450          if ( console ) {
1451            console.error( 'Error parsing ' + dataAttr + ' on ' +
1452                elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +
1453                error );
1454          }
1455          continue;
1456        }
1457        // initialize
1458        var instance = new WidgetClass( elem, options );
1459        // make available via $().data('layoutname')
1460        var jQuery = window.jQuery;
1461        if ( jQuery ) {
1462          jQuery.data( elem, namespace, instance );
1463        }
1464      }
1465    });
1466  };
1467
1468  // -----  ----- //
1469
1470  return utils;
1471
1472}));
1473
1474/**
1475 * Outlayer Item
1476 */
1477
1478( function( window, factory ) {
1479  'use strict';
1480  // universal module definition
1481  if ( typeof define === 'function' && define.amd ) {
1482    // AMD
1483    define( 'outlayer/item',[
1484          'eventEmitter/EventEmitter',
1485          'get-size/get-size',
1486          'get-style-property/get-style-property',
1487          'fizzy-ui-utils/utils'
1488        ],
1489        function( EventEmitter, getSize, getStyleProperty, utils ) {
1490          return factory( window, EventEmitter, getSize, getStyleProperty, utils );
1491        }
1492    );
1493  } else if (typeof exports === 'object') {
1494    // CommonJS
1495    module.exports = factory(
1496        window,
1497        require('wolfy87-eventemitter'),
1498        require('get-size'),
1499        require('desandro-get-style-property'),
1500        require('fizzy-ui-utils')
1501    );
1502  } else {
1503    // browser global
1504    window.Outlayer = {};
1505    window.Outlayer.Item = factory(
1506        window,
1507        window.EventEmitter,
1508        window.getSize,
1509        window.getStyleProperty,
1510        window.fizzyUIUtils
1511    );
1512  }
1513
1514}( window, function factory( window, EventEmitter, getSize, getStyleProperty, utils ) {
1515  'use strict';
1516
1517  // ----- helpers ----- //
1518
1519  var getComputedStyle = window.getComputedStyle;
1520  var getStyle = getComputedStyle ?
1521      function( elem ) {
1522        return getComputedStyle( elem, null );
1523      } :
1524      function( elem ) {
1525        return elem.currentStyle;
1526      };
1527
1528
1529  function isEmptyObj( obj ) {
1530    for ( var prop in obj ) {
1531      return false;
1532    }
1533    prop = null;
1534    return true;
1535  }
1536
1537  // -------------------------- CSS3 support -------------------------- //
1538
1539  var transitionProperty = getStyleProperty('transition');
1540  var transformProperty = getStyleProperty('transform');
1541  var supportsCSS3 = transitionProperty && transformProperty;
1542  var is3d = !!getStyleProperty('perspective');
1543
1544  var transitionEndEvent = {
1545    WebkitTransition: 'webkitTransitionEnd',
1546    MozTransition: 'transitionend',
1547    OTransition: 'otransitionend',
1548    transition: 'transitionend'
1549  }[ transitionProperty ];
1550
1551  // properties that could have vendor prefix
1552  var prefixableProperties = [
1553    'transform',
1554    'transition',
1555    'transitionDuration',
1556    'transitionProperty'
1557  ];
1558
1559  // cache all vendor properties
1560  var vendorProperties = ( function() {
1561    var cache = {};
1562    for ( var i=0, len = prefixableProperties.length; i < len; i++ ) {
1563      var prop = prefixableProperties[i];
1564      var supportedProp = getStyleProperty( prop );
1565      if ( supportedProp && supportedProp !== prop ) {
1566        cache[ prop ] = supportedProp;
1567      }
1568    }
1569    return cache;
1570  })();
1571
1572  // -------------------------- Item -------------------------- //
1573
1574  function Item( element, layout ) {
1575    if ( !element ) {
1576      return;
1577    }
1578
1579    this.element = element;
1580    // parent layout class, i.e. Masonry, Isotope, or Packery
1581    this.layout = layout;
1582    this.position = {
1583      x: 0,
1584      y: 0
1585    };
1586
1587    this._create();
1588  }
1589
1590  // inherit EventEmitter
1591  utils.extend( Item.prototype, EventEmitter.prototype );
1592
1593  Item.prototype._create = function() {
1594    // transition objects
1595    this._transn = {
1596      ingProperties: {},
1597      clean: {},
1598      onEnd: {}
1599    };
1600
1601    this.css({
1602      position: 'absolute'
1603    });
1604  };
1605
1606  // trigger specified handler for event type
1607  Item.prototype.handleEvent = function( event ) {
1608    var method = 'on' + event.type;
1609    if ( this[ method ] ) {
1610      this[ method ]( event );
1611    }
1612  };
1613
1614  Item.prototype.getSize = function() {
1615    this.size = getSize( this.element );
1616  };
1617
1618  /**
1619   * apply CSS styles to element
1620   * @param {Object} style
1621   */
1622  Item.prototype.css = function( style ) {
1623    var elemStyle = this.element.style;
1624
1625    for ( var prop in style ) {
1626      // use vendor property if available
1627      var supportedProp = vendorProperties[ prop ] || prop;
1628      elemStyle[ supportedProp ] = style[ prop ];
1629    }
1630  };
1631
1632  // measure position, and sets it
1633  Item.prototype.getPosition = function() {
1634    var style = getStyle( this.element );
1635    var layoutOptions = this.layout.options;
1636    var isOriginLeft = layoutOptions.isOriginLeft;
1637    var isOriginTop = layoutOptions.isOriginTop;
1638    var xValue = style[ isOriginLeft ? 'left' : 'right' ];
1639    var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
1640    // convert percent to pixels
1641    var layoutSize = this.layout.size;
1642    var x = xValue.indexOf('%') != -1 ?
1643        ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
1644    var y = yValue.indexOf('%') != -1 ?
1645        ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );
1646
1647    // clean up 'auto' or other non-integer values
1648    x = isNaN( x ) ? 0 : x;
1649    y = isNaN( y ) ? 0 : y;
1650    // remove padding from measurement
1651    x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
1652    y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
1653
1654    this.position.x = x;
1655    this.position.y = y;
1656  };
1657
1658  // set settled position, apply padding
1659  Item.prototype.layoutPosition = function() {
1660    var layoutSize = this.layout.size;
1661    var layoutOptions = this.layout.options;
1662    var style = {};
1663
1664    // x
1665    var xPadding = layoutOptions.isOriginLeft ? 'paddingLeft' : 'paddingRight';
1666    var xProperty = layoutOptions.isOriginLeft ? 'left' : 'right';
1667    var xResetProperty = layoutOptions.isOriginLeft ? 'right' : 'left';
1668
1669    var x = this.position.x + layoutSize[ xPadding ];
1670    // set in percentage or pixels
1671    style[ xProperty ] = this.getXValue( x );
1672    // reset other property
1673    style[ xResetProperty ] = '';
1674
1675    // y
1676    var yPadding = layoutOptions.isOriginTop ? 'paddingTop' : 'paddingBottom';
1677    var yProperty = layoutOptions.isOriginTop ? 'top' : 'bottom';
1678    var yResetProperty = layoutOptions.isOriginTop ? 'bottom' : 'top';
1679
1680    var y = this.position.y + layoutSize[ yPadding ];
1681    // set in percentage or pixels
1682    style[ yProperty ] = this.getYValue( y );
1683    // reset other property
1684    style[ yResetProperty ] = '';
1685
1686    this.css( style );
1687    this.emitEvent( 'layout', [ this ] );
1688  };
1689
1690  Item.prototype.getXValue = function( x ) {
1691    var layoutOptions = this.layout.options;
1692    return layoutOptions.percentPosition && !layoutOptions.isHorizontal ?
1693        ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
1694  };
1695
1696  Item.prototype.getYValue = function( y ) {
1697    var layoutOptions = this.layout.options;
1698    return layoutOptions.percentPosition && layoutOptions.isHorizontal ?
1699        ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
1700  };
1701
1702
1703  Item.prototype._transitionTo = function( x, y ) {
1704    this.getPosition();
1705    // get current x & y from top/left
1706    var curX = this.position.x;
1707    var curY = this.position.y;
1708
1709    var compareX = parseInt( x, 10 );
1710    var compareY = parseInt( y, 10 );
1711    var didNotMove = compareX === this.position.x && compareY === this.position.y;
1712
1713    // save end position
1714    this.setPosition( x, y );
1715
1716    // if did not move and not transitioning, just go to layout
1717    if ( didNotMove && !this.isTransitioning ) {
1718      this.layoutPosition();
1719      return;
1720    }
1721
1722    var transX = x - curX;
1723    var transY = y - curY;
1724    var transitionStyle = {};
1725    transitionStyle.transform = this.getTranslate( transX, transY );
1726
1727    this.transition({
1728      to: transitionStyle,
1729      onTransitionEnd: {
1730        transform: this.layoutPosition
1731      },
1732      isCleaning: true
1733    });
1734  };
1735
1736  Item.prototype.getTranslate = function( x, y ) {
1737    // flip cooridinates if origin on right or bottom
1738    var layoutOptions = this.layout.options;
1739    x = layoutOptions.isOriginLeft ? x : -x;
1740    y = layoutOptions.isOriginTop ? y : -y;
1741
1742    if ( is3d ) {
1743      return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
1744    }
1745
1746    return 'translate(' + x + 'px, ' + y + 'px)';
1747  };
1748
1749  // non transition + transform support
1750  Item.prototype.goTo = function( x, y ) {
1751    this.setPosition( x, y );
1752    this.layoutPosition();
1753  };
1754
1755  // use transition and transforms if supported
1756  Item.prototype.moveTo = supportsCSS3 ?
1757      Item.prototype._transitionTo : Item.prototype.goTo;
1758
1759  Item.prototype.setPosition = function( x, y ) {
1760    this.position.x = parseInt( x, 10 );
1761    this.position.y = parseInt( y, 10 );
1762  };
1763
1764  // ----- transition ----- //
1765
1766  /**
1767   * @param {Object} style - CSS
1768   * @param {Function} onTransitionEnd
1769   */
1770
1771  // non transition, just trigger callback
1772  Item.prototype._nonTransition = function( args ) {
1773    this.css( args.to );
1774    if ( args.isCleaning ) {
1775      this._removeStyles( args.to );
1776    }
1777    for ( var prop in args.onTransitionEnd ) {
1778      args.onTransitionEnd[ prop ].call( this );
1779    }
1780  };
1781
1782  /**
1783   * proper transition
1784   * @param {Object} args - arguments
1785   *   @param {Object} to - style to transition to
1786   *   @param {Object} from - style to start transition from
1787   *   @param {Boolean} isCleaning - removes transition styles after transition
1788   *   @param {Function} onTransitionEnd - callback
1789   */
1790  Item.prototype._transition = function( args ) {
1791    // redirect to nonTransition if no transition duration
1792    if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1793      this._nonTransition( args );
1794      return;
1795    }
1796
1797    var _transition = this._transn;
1798    // keep track of onTransitionEnd callback by css property
1799    for ( var prop in args.onTransitionEnd ) {
1800      _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
1801    }
1802    // keep track of properties that are transitioning
1803    for ( prop in args.to ) {
1804      _transition.ingProperties[ prop ] = true;
1805      // keep track of properties to clean up when transition is done
1806      if ( args.isCleaning ) {
1807        _transition.clean[ prop ] = true;
1808      }
1809    }
1810
1811    // set from styles
1812    if ( args.from ) {
1813      this.css( args.from );
1814      // force redraw. http://blog.alexmaccaw.com/css-transitions
1815      var h = this.element.offsetHeight;
1816      // hack for JSHint to hush about unused var
1817      h = null;
1818    }
1819    // enable transition
1820    this.enableTransition( args.to );
1821    // set styles that are transitioning
1822    this.css( args.to );
1823
1824    this.isTransitioning = true;
1825
1826  };
1827
1828  // dash before all cap letters, including first for
1829  // WebkitTransform => -webkit-transform
1830  function toDashedAll( str ) {
1831    return str.replace( /([A-Z])/g, function( $1 ) {
1832      return '-' + $1.toLowerCase();
1833    });
1834  }
1835
1836  var transitionProps = 'opacity,' +
1837      toDashedAll( vendorProperties.transform || 'transform' );
1838
1839  Item.prototype.enableTransition = function(/* style */) {
1840    // HACK changing transitionProperty during a transition
1841    // will cause transition to jump
1842    if ( this.isTransitioning ) {
1843      return;
1844    }
1845
1846    // make `transition: foo, bar, baz` from style object
1847    // HACK un-comment this when enableTransition can work
1848    // while a transition is happening
1849    // var transitionValues = [];
1850    // for ( var prop in style ) {
1851    //   // dash-ify camelCased properties like WebkitTransition
vendor: 11,346 bytes, lines 1852-2283
1852    //   prop = vendorProperties[ prop ] || prop;
1853    //   transitionValues.push( toDashedAll( prop ) );
1854    // }
1855    // enable transition styles
1856    this.css({
1857      transitionProperty: transitionProps,
1858      transitionDuration: this.layout.options.transitionDuration
1859    });
1860    // listen for transition end event
1861    this.element.addEventListener( transitionEndEvent, this, false );
1862  };
1863
1864  Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ];
1865
1866  // ----- events ----- //
1867
1868  Item.prototype.onwebkitTransitionEnd = function( event ) {
1869    this.ontransitionend( event );
1870  };
1871
1872  Item.prototype.onotransitionend = function( event ) {
1873    this.ontransitionend( event );
1874  };
1875
1876  // properties that I munge to make my life easier
1877  var dashedVendorProperties = {
1878    '-webkit-transform': 'transform',
1879    '-moz-transform': 'transform',
1880    '-o-transform': 'transform'
1881  };
1882
1883  Item.prototype.ontransitionend = function( event ) {
1884    // disregard bubbled events from children
1885    if ( event.target !== this.element ) {
1886      return;
1887    }
1888    var _transition = this._transn;
1889    // get property name of transitioned property, convert to prefix-free
1890    var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
1891
1892    // remove property that has completed transitioning
1893    delete _transition.ingProperties[ propertyName ];
1894    // check if any properties are still transitioning
1895    if ( isEmptyObj( _transition.ingProperties ) ) {
1896      // all properties have completed transitioning
1897      this.disableTransition();
1898    }
1899    // clean style
1900    if ( propertyName in _transition.clean ) {
1901      // clean up style
1902      this.element.style[ event.propertyName ] = '';
1903      delete _transition.clean[ propertyName ];
1904    }
1905    // trigger onTransitionEnd callback
1906    if ( propertyName in _transition.onEnd ) {
1907      var onTransitionEnd = _transition.onEnd[ propertyName ];
1908      onTransitionEnd.call( this );
1909      delete _transition.onEnd[ propertyName ];
1910    }
1911
1912    this.emitEvent( 'transitionEnd', [ this ] );
1913  };
1914
1915  Item.prototype.disableTransition = function() {
1916    this.removeTransitionStyles();
1917    this.element.removeEventListener( transitionEndEvent, this, false );
1918    this.isTransitioning = false;
1919  };
1920
1921  /**
1922   * removes style property from element
1923   * @param {Object} style
1924   **/
1925  Item.prototype._removeStyles = function( style ) {
1926    // clean up transition styles
1927    var cleanStyle = {};
1928    for ( var prop in style ) {
1929      cleanStyle[ prop ] = '';
1930    }
1931    this.css( cleanStyle );
1932  };
1933
1934  var cleanTransitionStyle = {
1935    transitionProperty: '',
1936    transitionDuration: ''
1937  };
1938
1939  Item.prototype.removeTransitionStyles = function() {
1940    // remove transition
1941    this.css( cleanTransitionStyle );
1942  };
1943
1944  // ----- show/hide/remove ----- //
1945
1946  // remove element from DOM
1947  Item.prototype.removeElem = function() {
1948    this.element.parentNode.removeChild( this.element );
1949    // remove display: none
1950    this.css({ display: '' });
1951    this.emitEvent( 'remove', [ this ] );
1952  };
1953
1954  Item.prototype.remove = function() {
1955    // just remove element if no transition support or no transition
1956    if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1957      this.removeElem();
1958      return;
1959    }
1960
1961    // start transition
1962    var _this = this;
1963    this.once( 'transitionEnd', function() {
1964      _this.removeElem();
1965    });
1966    this.hide();
1967  };
1968
1969  Item.prototype.reveal = function() {
1970    delete this.isHidden;
1971    // remove display: none
1972    this.css({ display: '' });
1973
1974    var options = this.layout.options;
1975
1976    var onTransitionEnd = {};
1977    var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
1978    onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
1979
1980    this.transition({
1981      from: options.hiddenStyle,
1982      to: options.visibleStyle,
1983      isCleaning: true,
1984      onTransitionEnd: onTransitionEnd
1985    });
1986  };
1987
1988  Item.prototype.onRevealTransitionEnd = function() {
1989    // check if still visible
1990    // during transition, item may have been hidden
1991    if ( !this.isHidden ) {
1992      this.emitEvent('reveal');
1993    }
1994  };
1995
1996  /**
1997   * get style property use for hide/reveal transition end
1998   * @param {String} styleProperty - hiddenStyle/visibleStyle
1999   * @returns {String}
2000   */
2001  Item.prototype.getHideRevealTransitionEndProperty = function( styleProperty ) {
2002    var optionStyle = this.layout.options[ styleProperty ];
2003    // use opacity
2004    if ( optionStyle.opacity ) {
2005      return 'opacity';
2006    }
2007    // get first property
2008    for ( var prop in optionStyle ) {
2009      return prop;
2010    }
2011  };
2012
2013  Item.prototype.hide = function() {
2014    // set flag
2015    this.isHidden = true;
2016    // remove display: none
2017    this.css({ display: '' });
2018
2019    var options = this.layout.options;
2020
2021    var onTransitionEnd = {};
2022    var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
2023    onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
2024
2025    this.transition({
2026      from: options.visibleStyle,
2027      to: options.hiddenStyle,
2028      // keep hidden stuff hidden
2029      isCleaning: true,
2030      onTransitionEnd: onTransitionEnd
2031    });
2032  };
2033
2034  Item.prototype.onHideTransitionEnd = function() {
2035    // check if still hidden
2036    // during transition, item may have been un-hidden
2037    if ( this.isHidden ) {
2038      this.css({ display: 'none' });
2039      this.emitEvent('hide');
2040    }
2041  };
2042
2043  Item.prototype.destroy = function() {
2044    this.css({
2045      position: '',
2046      left: '',
2047      right: '',
2048      top: '',
2049      bottom: '',
2050      transition: '',
2051      transform: ''
2052    });
2053  };
2054
2055  return Item;
2056
2057}));
2058
2059/*!
2060 * Outlayer v1.4.2
2061 * the brains and guts of a layout library
2062 * MIT license
2063 */
2064
2065( function( window, factory ) {
2066  'use strict';
2067  // universal module definition
2068
2069  if ( typeof define == 'function' && define.amd ) {
2070    // AMD
2071    define( 'outlayer/outlayer',[
2072          'eventie/eventie',
2073          'eventEmitter/EventEmitter',
2074          'get-size/get-size',
2075          'fizzy-ui-utils/utils',
2076          './item'
2077        ],
2078        function( eventie, EventEmitter, getSize, utils, Item ) {
2079          return factory( window, eventie, EventEmitter, getSize, utils, Item);
2080        }
2081    );
2082  } else if ( typeof exports == 'object' ) {
2083    // CommonJS
2084    module.exports = factory(
2085        window,
2086        require('eventie'),
2087        require('wolfy87-eventemitter'),
2088        require('get-size'),
2089        require('fizzy-ui-utils'),
2090        require('./item')
2091    );
2092  } else {
2093    // browser global
2094    window.Outlayer = factory(
2095        window,
2096        window.eventie,
2097        window.EventEmitter,
2098        window.getSize,
2099        window.fizzyUIUtils,
2100        window.Outlayer.Item
2101    );
2102  }
2103
2104}( window, function factory( window, eventie, EventEmitter, getSize, utils, Item ) {
2105  'use strict';
2106
2107  // ----- vars ----- //
2108
2109  var console = window.console;
2110  var jQuery = window.jQuery;
2111  var noop = function() {};
2112
2113  // -------------------------- Outlayer -------------------------- //
2114
2115  // globally unique identifiers
2116  var GUID = 0;
2117  // internal store of all Outlayer intances
2118  var instances = {};
2119
2120
2121  /**
2122   * @param {Element, String} element
2123   * @param {Object} options
2124   * @constructor
2125   */
2126  function Outlayer( element, options ) {
2127    var queryElement = utils.getQueryElement( element );
2128    if ( !queryElement ) {
2129      if ( console ) {
2130        console.error( 'Bad element for ' + this.constructor.namespace +
2131            ': ' + ( queryElement || element ) );
2132      }
2133      return;
2134    }
2135    this.element = queryElement;
2136    // add jQuery
2137    if ( jQuery ) {
2138      this.$element = jQuery( this.element );
2139    }
2140
2141    // options
2142    this.options = utils.extend( {}, this.constructor.defaults );
2143    this.option( options );
2144
2145    // add id for Outlayer.getFromElement
2146    var id = ++GUID;
2147    this.element.outlayerGUID = id; // expando
2148    instances[ id ] = this; // associate via id
2149
2150    // kick it off
2151    this._create();
2152
2153    if ( this.options.isInitLayout ) {
2154      this.layout();
2155    }
2156  }
2157
2158  // settings are for internal use only
2159  Outlayer.namespace = 'outlayer';
2160  Outlayer.Item = Item;
2161
2162  // default options
2163  Outlayer.defaults = {
2164    containerStyle: {
2165      position: 'relative'
2166    },
2167    isInitLayout: true,
2168    isOriginLeft: true,
2169    isOriginTop: true,
2170    isResizeBound: true,
2171    isResizingContainer: true,
2172    // item options
2173    transitionDuration: '0.4s',
2174    hiddenStyle: {
2175      opacity: 0,
2176      transform: 'scale(0.001)'
2177    },
2178    visibleStyle: {
2179      opacity: 1,
2180      transform: 'scale(1)'
2181    }
2182  };
2183
2184  // inherit EventEmitter
2185  utils.extend( Outlayer.prototype, EventEmitter.prototype );
2186
2187  /**
2188   * set options
2189   * @param {Object} opts
2190   */
2191  Outlayer.prototype.option = function( opts ) {
2192    utils.extend( this.options, opts );
2193  };
2194
2195  Outlayer.prototype._create = function() {
2196    // get items from children
2197    this.reloadItems();
2198    // elements that affect layout, but are not laid out
2199    this.stamps = [];
2200    this.stamp( this.options.stamp );
2201    // set container style
2202    utils.extend( this.element.style, this.options.containerStyle );
2203
2204    // bind resize method
2205    if ( this.options.isResizeBound ) {
2206      this.bindResize();
2207    }
2208  };
2209
2210  // goes through all children again and gets bricks in proper order
2211  Outlayer.prototype.reloadItems = function() {
2212    // collection of item elements
2213    this.items = this._itemize( this.element.children );
2214  };
2215
2216
2217  /**
2218   * turn elements into Outlayer.Items to be used in layout
2219   * @param {Array or NodeList or HTMLElement} elems
2220   * @returns {Array} items - collection of new Outlayer Items
2221   */
2222  Outlayer.prototype._itemize = function( elems ) {
2223
2224    var itemElems = this._filterFindItemElements( elems );
2225    var Item = this.constructor.Item;
2226
2227    // create new Outlayer Items for collection
2228    var items = [];
2229    for ( var i=0, len = itemElems.length; i < len; i++ ) {
2230      var elem = itemElems[i];
2231      var item = new Item( elem, this );
2232      items.push( item );
2233    }
2234
2235    return items;
2236  };
2237
2238  /**
2239   * get item elements to be used in layout
2240   * @param {Array or NodeList or HTMLElement} elems
2241   * @returns {Array} items - item elements
2242   */
2243  Outlayer.prototype._filterFindItemElements = function( elems ) {
2244    return utils.filterFindElements( elems, this.options.itemSelector );
2245  };
2246
2247  /**
2248   * getter method for getting item elements
2249   * @returns {Array} elems - collection of item elements
2250   */
2251  Outlayer.prototype.getItemElements = function() {
2252    var elems = [];
2253    for ( var i=0, len = this.items.length; i < len; i++ ) {
2254      elems.push( this.items[i].element );
2255    }
2256    return elems;
2257  };
2258
2259  // ----- init & layout ----- //
2260
2261  /**
2262   * lays out all items
2263   */
2264  Outlayer.prototype.layout = function() {
2265    this._resetLayout();
2266    this._manageStamps();
2267
2268    // don't animate first layout
2269    var isInstant = this.options.isLayoutInstant !== undefined ?
2270        this.options.isLayoutInstant : !this._isLayoutInited;
2271    this.layoutItems( this.items, isInstant );
2272
2273    // flag for initalized
2274    this._isLayoutInited = true;
2275  };
2276
2277  // _init is alias for layout
2278  Outlayer.prototype._init = Outlayer.prototype.layout;
2279
2280  /**
2281   * logic before any new layout
2282   */
2283  Outlayer.prototype._resetLayout = function() {
vendor: 7,213 bytes, lines 2284-2560
2284    this.getSize();
2285  };
2286
2287
2288  Outlayer.prototype.getSize = function() {
2289    this.size = getSize( this.element );
2290  };
2291
2292  /**
2293   * get measurement from option, for columnWidth, rowHeight, gutter
2294   * if option is String -> get element from selector string, & get size of element
2295   * if option is Element -> get size of element
2296   * else use option as a number
2297   *
2298   * @param {String} measurement
2299   * @param {String} size - width or height
2300   * @private
2301   */
2302  Outlayer.prototype._getMeasurement = function( measurement, size ) {
2303    var option = this.options[ measurement ];
2304    var elem;
2305    if ( !option ) {
2306      // default to 0
2307      this[ measurement ] = 0;
2308    } else {
2309      // use option as an element
2310      if ( typeof option === 'string' ) {
2311        elem = this.element.querySelector( option );
2312      } else if ( utils.isElement( option ) ) {
2313        elem = option;
2314      }
2315      // use size of element, if element
2316      this[ measurement ] = elem ? getSize( elem )[ size ] : option;
2317    }
2318  };
2319
2320  /**
2321   * layout a collection of item elements
2322   * @api public
2323   */
2324  Outlayer.prototype.layoutItems = function( items, isInstant ) {
2325    items = this._getItemsForLayout( items );
2326
2327    this._layoutItems( items, isInstant );
2328
2329    this._postLayout();
2330  };
2331
2332  /**
2333   * get the items to be laid out
2334   * you may want to skip over some items
2335   * @param {Array} items
2336   * @returns {Array} items
2337   */
2338  Outlayer.prototype._getItemsForLayout = function( items ) {
2339    var layoutItems = [];
2340    for ( var i=0, len = items.length; i < len; i++ ) {
2341      var item = items[i];
2342      if ( !item.isIgnored ) {
2343        layoutItems.push( item );
2344      }
2345    }
2346    return layoutItems;
2347  };
2348
2349  /**
2350   * layout items
2351   * @param {Array} items
2352   * @param {Boolean} isInstant
2353   */
2354  Outlayer.prototype._layoutItems = function( items, isInstant ) {
2355    this._emitCompleteOnItems( 'layout', items );
2356
2357    if ( !items || !items.length ) {
2358      // no items, emit event with empty array
2359      return;
2360    }
2361
2362    var queue = [];
2363
2364    for ( var i=0, len = items.length; i < len; i++ ) {
2365      var item = items[i];
2366      // get x/y object from method
2367      var position = this._getItemLayoutPosition( item );
2368      // enqueue
2369      position.item = item;
2370      position.isInstant = isInstant || item.isLayoutInstant;
2371      queue.push( position );
2372    }
2373
2374    this._processLayoutQueue( queue );
2375  };
2376
2377  /**
2378   * get item layout position
2379   * @param {Outlayer.Item} item
2380   * @returns {Object} x and y position
2381   */
2382  Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) {
2383    return {
2384      x: 0,
2385      y: 0
2386    };
2387  };
2388
2389  /**
2390   * iterate over array and position each item
2391   * Reason being - separating this logic prevents 'layout invalidation'
2392   * thx @paul_irish
2393   * @param {Array} queue
2394   */
2395  Outlayer.prototype._processLayoutQueue = function( queue ) {
2396    for ( var i=0, len = queue.length; i < len; i++ ) {
2397      var obj = queue[i];
2398      this._positionItem( obj.item, obj.x, obj.y, obj.isInstant );
2399    }
2400  };
2401
2402  /**
2403   * Sets position of item in DOM
2404   * @param {Outlayer.Item} item
2405   * @param {Number} x - horizontal position
2406   * @param {Number} y - vertical position
2407   * @param {Boolean} isInstant - disables transitions
2408   */
2409  Outlayer.prototype._positionItem = function( item, x, y, isInstant ) {
2410    if ( isInstant ) {
2411      // if not transition, just set CSS
2412      item.goTo( x, y );
2413    } else {
2414      item.moveTo( x, y );
2415    }
2416  };
2417
2418  /**
2419   * Any logic you want to do after each layout,
2420   * i.e. size the container
2421   */
2422  Outlayer.prototype._postLayout = function() {
2423    this.resizeContainer();
2424  };
2425
2426  Outlayer.prototype.resizeContainer = function() {
2427    if ( !this.options.isResizingContainer ) {
2428      return;
2429    }
2430    var size = this._getContainerSize();
2431    if ( size ) {
2432      this._setContainerMeasure( size.width, true );
2433      this._setContainerMeasure( size.height, false );
2434    }
2435  };
2436
2437  /**
2438   * Sets width or height of container if returned
2439   * @returns {Object} size
2440   *   @param {Number} width
2441   *   @param {Number} height
2442   */
2443  Outlayer.prototype._getContainerSize = noop;
2444
2445  /**
2446   * @param {Number} measure - size of width or height
2447   * @param {Boolean} isWidth
2448   */
2449  Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) {
2450    if ( measure === undefined ) {
2451      return;
2452    }
2453
2454    var elemSize = this.size;
2455    // add padding and border width if border box
2456    if ( elemSize.isBorderBox ) {
2457      measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
2458          elemSize.borderLeftWidth + elemSize.borderRightWidth :
2459          elemSize.paddingBottom + elemSize.paddingTop +
2460          elemSize.borderTopWidth + elemSize.borderBottomWidth;
2461    }
2462
2463    measure = Math.max( measure, 0 );
2464    this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
2465  };
2466
2467  /**
2468   * emit eventComplete on a collection of items events
2469   * @param {String} eventName
2470   * @param {Array} items - Outlayer.Items
2471   */
2472  Outlayer.prototype._emitCompleteOnItems = function( eventName, items ) {
2473    var _this = this;
2474    function onComplete() {
2475      _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
2476    }
2477
2478    var count = items.length;
2479    if ( !items || !count ) {
2480      onComplete();
2481      return;
2482    }
2483
2484    var doneCount = 0;
2485    function tick() {
2486      doneCount++;
2487      if ( doneCount === count ) {
2488        onComplete();
2489      }
2490    }
2491
2492    // bind callback
2493    for ( var i=0, len = items.length; i < len; i++ ) {
2494      var item = items[i];
2495      item.once( eventName, tick );
2496    }
2497  };
2498
2499  /**
2500   * emits events via eventEmitter and jQuery events
2501   * @param {String} type - name of event
2502   * @param {Event} event - original event
2503   * @param {Array} args - extra arguments
2504   */
2505  Outlayer.prototype.dispatchEvent = function( type, event, args ) {
2506    // add original event to arguments
2507    var emitArgs = event ? [ event ].concat( args ) : args;
2508    this.emitEvent( type, emitArgs );
2509
2510    if ( jQuery ) {
2511      // set this.$element
2512      this.$element = this.$element || jQuery( this.element );
2513      if ( event ) {
2514        // create jQuery event
2515        var $event = jQuery.Event( event );
2516        $event.type = type;
2517        this.$element.trigger( $event, args );
2518      } else {
2519        // just trigger with type if no event available
2520        this.$element.trigger( type, args );
2521      }
2522    }
2523  };
2524
2525  // -------------------------- ignore & stamps -------------------------- //
2526
2527
2528  /**
2529   * keep item in collection, but do not lay it out
2530   * ignored items do not get skipped in layout
2531   * @param {Element} elem
2532   */
2533  Outlayer.prototype.ignore = function( elem ) {
2534    var item = this.getItem( elem );
2535    if ( item ) {
2536      item.isIgnored = true;
2537    }
2538  };
2539
2540  /**
2541   * return item to layout collection
2542   * @param {Element} elem
2543   */
2544  Outlayer.prototype.unignore = function( elem ) {
2545    var item = this.getItem( elem );
2546    if ( item ) {
2547      delete item.isIgnored;
2548    }
2549  };
2550
2551  /**
2552   * adds elements to stamps
2553   * @param {NodeList, Array, Element, or String} elems
2554   */
2555  Outlayer.prototype.stamp = function( elems ) {
2556    elems = this._find( elems );
2557    if ( !elems ) {
2558      return;
2559    }
2560
2561    this.stamps = this.stamps.concat( elems );
2562    // ignore
2563    for ( var i=0, len = elems.length; i < len; i++ ) {
2564      var elem = elems[i];
2565      this.ignore( elem );
2566    }
2567  };
2568
2569  /**
2570   * removes elements to stamps
2571   * @param {NodeList, Array, or Element} elems
2572   */
2573  Outlayer.prototype.unstamp = function( elems ) {
2574    elems = this._find( elems );
2575    if ( !elems ){
2576      return;
2577    }
2578
2579    for ( var i=0, len = elems.length; i < len; i++ ) {
2580      var elem = elems[i];
2581      // filter out removed stamp elements
2582      utils.removeFrom( this.stamps, elem );
2583      this.unignore( elem );
2584    }
2585
2586  };
2587
2588  /**
2589   * finds child elements
2590   * @param {NodeList, Array, Element, or String} elems
2591   * @returns {Array} elems
2592   */
2593  Outlayer.prototype._find = function( elems ) {
2594    if ( !elems ) {
2595      return;
2596    }
2597    // if string, use argument as selector string
2598    if ( typeof elems === 'string' ) {
2599      elems = this.element.querySelectorAll( elems );
2600    }
2601    elems = utils.makeArray( elems );
2602    return elems;
2603  };
2604
2605  Outlayer.prototype._manageStamps = function() {
2606    if ( !this.stamps || !this.stamps.length ) {
2607      return;
2608    }
2609
2610    this._getBoundingRect();
2611
2612    for ( var i=0, len = this.stamps.length; i < len; i++ ) {
2613      var stamp = this.stamps[i];
2614      this._manageStamp( stamp );
2615    }
2616  };
2617
2618  // update boundingLeft / Top
2619  Outlayer.prototype._getBoundingRect = function() {
2620    // get bounding rect for container element
2621    var boundingRect = this.element.getBoundingClientRect();
2622    var size = this.size;
2623    this._boundingRect = {
2624      left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
2625      top: boundingRect.top + size.paddingTop + size.borderTopWidth,
2626      right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
2627      bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
2628    };
2629  };
2630
2631  /**
2632   * @param {Element} stamp
2633   **/
2634  Outlayer.prototype._manageStamp = noop;
2635
2636  /**
2637   * get x/y position of element relative to container element
2638   * @param {Element} elem
2639   * @returns {Object} offset - has left, top, right, bottom
2640   */
2641  Outlayer.prototype._getElementOffset = function( elem ) {
2642    var boundingRect = elem.getBoundingClientRect();
2643    var thisRect = this._boundingRect;
2644    var size = getSize( elem );
2645    var offset = {
2646      left: boundingRect.left - thisRect.left - size.marginLeft,
2647      top: boundingRect.top - thisRect.top - size.marginTop,
2648      right: thisRect.right - boundingRect.right - size.marginRight,
2649      bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
2650    };
2651    return offset;
2652  };
2653
2654  // -------------------------- resize -------------------------- //
2655
2656  // enable event handlers for listeners
2657  // i.e. resize -> onresize
2658  Outlayer.prototype.handleEvent = function( event ) {
2659    var method = 'on' + event.type;
2660    if ( this[ method ] ) {
2661      this[ method ]( event );
2662    }
2663  };
2664
2665  /**
2666   * Bind layout to window resizing
2667   */
2668  Outlayer.prototype.bindResize = function() {
2669    // bind just one listener
2670    if ( this.isResizeBound ) {
2671      return;
2672    }
2673    eventie.bind( window, 'resize', this );
2674    this.isResizeBound = true;
2675  };
2676
2677  /**
2678   * Unbind layout to window resizing
2679   */
2680  Outlayer.prototype.unbindResize = function() {
2681    if ( this.isResizeBound ) {
2682      eventie.unbind( window, 'resize', this );
2683    }
2684    this.isResizeBound = false;
2685  };
2686
2687  // original debounce by John Hann
2688  // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
2689
2690  // this fires every resize
2691  Outlayer.prototype.onresize = function() {
2692    if ( this.resizeTimeout ) {
2693      clearTimeout( this.resizeTimeout );
2694    }
2695
2696    var _this = this;
2697    function delayed() {
2698      _this.resize();
2699      delete _this.resizeTimeout;
2700    }
2701
2702    this.resizeTimeout = setTimeout( delayed, 100 );
2703  };
2704
2705  // debounced, layout on resize
2706  Outlayer.prototype.resize = function() {
2707    // don't trigger if size did not change
2708    // or if resize was unbound. See #9
2709    if ( !this.isResizeBound || !this.needsResizeLayout() ) {
2710      return;
2711    }
2712
2713    this.layout();
2714  };
2715
2716  /**
2717   * check if layout is needed post layout
2718   * @returns Boolean
2719   */
2720  Outlayer.prototype.needsResizeLayout = function() {
2721    var size = getSize( this.element );
2722    // check that this.size and size are there
2723    // IE8 triggers resize on body size change, so they might not be
2724    var hasSizes = this.size && size;
2725    return hasSizes && size.innerWidth !== this.size.innerWidth;
2726  };
2727
2728  // -------------------------- methods -------------------------- //
2729
2730  /**
2731   * add items to Outlayer instance
2732   * @param {Array or NodeList or Element} elems
2733   * @returns {Array} items - Outlayer.Items
2734   **/
2735  Outlayer.prototype.addItems = function( elems ) {
2736    var items = this._itemize( elems );
2737    // add items to collection
2738    if ( items.length ) {
2739      this.items = this.items.concat( items );
2740    }
2741    return items;
2742  };
2743
2744  /**
2745   * Layout newly-appended item elements
2746   * @param {Array or NodeList or Element} elems
2747   */
2748  Outlayer.prototype.appended = function( elems ) {
2749    var items = this.addItems( elems );
2750    if ( !items.length ) {
2751      return;
2752    }
2753    // layout and reveal just the new items
2754    this.layoutItems( items, true );
2755    this.reveal( items );
2756  };
2757
2758  /**
2759   * Layout prepended elements
2760   * @param {Array or NodeList or Element} elems
2761   */
2762  Outlayer.prototype.prepended = function( elems ) {
2763    var items = this._itemize( elems );
2764    if ( !items.length ) {
2765      return;
2766    }
2767    // add items to beginning of collection
2768    var previousItems = this.items.slice(0);
2769    this.items = items.concat( previousItems );
2770    // start new layout
2771    this._resetLayout();
2772    this._manageStamps();
2773    // layout new stuff without transition
2774    this.layoutItems( items, true );
2775    this.reveal( items );
2776    // layout previous items
2777    this.layoutItems( previousItems );
2778  };
2779
2780  /**
2781   * reveal a collection of items
2782   * @param {Array of Outlayer.Items} items
2783   */
2784  Outlayer.prototype.reveal = function( items ) {
2785    this._emitCompleteOnItems( 'reveal', items );
2786
2787    var len = items && items.length;
2788    for ( var i=0; len && i < len; i++ ) {
2789      var item = items[i];
2790      item.reveal();
2791    }
2792  };
2793
2794  /**
2795   * hide a collection of items
2796   * @param {Array of Outlayer.Items} items
2797   */
2798  Outlayer.prototype.hide = function( items ) {
2799    this._emitCompleteOnItems( 'hide', items );
2800
2801    var len = items && items.length;
2802    for ( var i=0; len && i < len; i++ ) {
2803      var item = items[i];
2804      item.hide();
2805    }
2806  };
2807
2808  /**
2809   * reveal item elements
2810   * @param {Array}, {Element}, {NodeList} items
2811   */
2812  Outlayer.prototype.revealItemElements = function( elems ) {
2813    var items = this.getItems( elems );
2814    this.reveal( items );
2815  };
2816
2817  /**
2818   * hide item elements
2819   * @param {Array}, {Element}, {NodeList} items
2820   */
2821  Outlayer.prototype.hideItemElements = function( elems ) {
2822    var items = this.getItems( elems );
2823    this.hide( items );
2824  };
2825
2826  /**
2827   * get Outlayer.Item, given an Element
2828   * @param {Element} elem
2829   * @param {Function} callback
2830   * @returns {Outlayer.Item} item
2831   */
2832  Outlayer.prototype.getItem = function( elem ) {
2833    // loop through items to get the one that matches
2834    for ( var i=0, len = this.items.length; i < len; i++ ) {
2835      var item = this.items[i];
2836      if ( item.element === elem ) {
2837        // return item
2838        return item;
2839      }
2840    }
2841  };
2842
2843  /**
2844   * get collection of Outlayer.Items, given Elements
2845   * @param {Array} elems
2846   * @returns {Array} items - Outlayer.Items
2847   */
2848  Outlayer.prototype.getItems = function( elems ) {
2849    elems = utils.makeArray( elems );
2850    var items = [];
2851    for ( var i=0, len = elems.length; i < len; i++ ) {
2852      var elem = elems[i];
2853      var item = this.getItem( elem );
2854      if ( item ) {
2855        items.push( item );
2856      }
2857    }
2858
2859    return items;
2860  };
2861
2862  /**
2863   * remove element(s) from instance and DOM
2864   * @param {Array or NodeList or Element} elems
2865   */
2866  Outlayer.prototype.remove = function( elems ) {
2867    var removeItems = this.getItems( elems );
2868
2869    this._emitCompleteOnItems( 'remove', removeItems );
2870
2871    // bail if no items to remove
2872    if ( !removeItems || !removeItems.length ) {
2873      return;
2874    }
2875
2876    for ( var i=0, len = removeItems.length; i < len; i++ ) {
2877      var item = removeItems[i];
2878      item.remove();
2879      // remove item from collection
2880      utils.removeFrom( this.items, item );
2881    }
2882  };
2883
2884  // ----- destroy ----- //
2885
2886  // remove and disable Outlayer instance
2887  Outlayer.prototype.destroy = function() {
2888    // clean up dynamic styles
2889    var style = this.element.style;
2890    style.height = '';
2891    style.position = '';
2892    style.width = '';
2893    // destroy items
2894    for ( var i=0, len = this.items.length; i < len; i++ ) {
2895      var item = this.items[i];
2896      item.destroy();
2897    }
2898
2899    this.unbindResize();
2900
2901    var id = this.element.outlayerGUID;
2902    delete instances[ id ]; // remove reference to instance by id
2903    delete this.element.outlayerGUID;
2904    // remove data for jQuery
2905    if ( jQuery ) {
2906      jQuery.removeData( this.element, this.constructor.namespace );
2907    }
2908
2909  };
2910
2911  // -------------------------- data -------------------------- //
2912
2913  /**
2914   * get Outlayer instance from element
2915   * @param {Element} elem
2916   * @returns {Outlayer}
2917   */
2918  Outlayer.data = function( elem ) {
2919    elem = utils.getQueryElement( elem );
2920    var id = elem && elem.outlayerGUID;
2921    return id && instances[ id ];
2922  };
2923
2924
2925  // -------------------------- create Outlayer class -------------------------- //
2926
2927  /**
2928   * create a layout class
2929   * @param {String} namespace
2930   */
2931  Outlayer.create = function( namespace, options ) {
2932    // sub-class Outlayer
2933    function Layout() {
2934      Outlayer.apply( this, arguments );
2935    }
2936    // inherit Outlayer prototype, use Object.create if there
2937    if ( Object.create ) {
2938      Layout.prototype = Object.create( Outlayer.prototype );
2939    } else {
2940      utils.extend( Layout.prototype, Outlayer.prototype );
2941    }
2942    // set contructor, used for namespace and Item
2943    Layout.prototype.constructor = Layout;
2944
2945    Layout.defaults = utils.extend( {}, Outlayer.defaults );
2946    // apply new options
2947    utils.extend( Layout.defaults, options );
2948    // keep prototype.settings for backwards compatibility (Packery v1.2.0)
2949    Layout.prototype.settings = {};
2950
2951    Layout.namespace = namespace;
2952
2953    Layout.data = Outlayer.data;
2954
2955    // sub-class Item
2956    Layout.Item = function LayoutItem() {
2957      Item.apply( this, arguments );
2958    };
2959
2960    Layout.Item.prototype = new Item();
2961
2962    // -------------------------- declarative -------------------------- //
2963
2964    utils.htmlInit( Layout, namespace );
2965
2966    // -------------------------- jQuery bridge -------------------------- //
2967
2968    // make into jQuery plugin
2969    if ( jQuery && jQuery.bridget ) {
2970      jQuery.bridget( namespace, Layout );
2971    }
2972
2973    return Layout;
2974  };
2975
2976  // ----- fin ----- //
2977
2978  // back in global
2979  Outlayer.Item = Item;
2980
2981  return Outlayer;
2982
2983}));
2984
2985
2986/**
2987 * Isotope Item
2988 **/
2989
2990( function( window, factory ) {
2991  'use strict';
2992  // universal module definition
2993  if ( typeof define == 'function' && define.amd ) {
2994    // AMD
2995    define( 'isotope/js/item',[
2996          'outlayer/outlayer'
2997        ],
2998        factory );
2999  } else if ( typeof exports == 'object' ) {
3000    // CommonJS
3001    module.exports = factory(
3002        require('outlayer')
3003    );
3004  } else {
3005    // browser global
3006    window.Isotope = window.Isotope || {};
3007    window.Isotope.Item = factory(
3008        window.Outlayer
3009    );
3010  }
3011
3012}( window, function factory( Outlayer ) {
3013  'use strict';
3014
3015  // -------------------------- Item -------------------------- //
3016
3017  // sub-class Outlayer Item
3018  function Item() {
3019    Outlayer.Item.apply( this, arguments );
3020  }
3021
3022  Item.prototype = new Outlayer.Item();
3023
3024  Item.prototype._create = function() {
3025    // assign id, used for original-order sorting
3026    this.id = this.layout.itemGUID++;
3027    Outlayer.Item.prototype._create.call( this );
3028    this.sortData = {};
3029  };
3030
3031  Item.prototype.updateSortData = function() {
3032    if ( this.isIgnored ) {
3033      return;
3034    }
3035    // default sorters
3036    this.sortData.id = this.id;
3037    // for backward compatibility
3038    this.sortData['original-order'] = this.id;
3039    this.sortData.random = Math.random();
3040    // go thru getSortData obj and apply the sorters
3041    var getSortData = this.layout.options.getSortData;
3042    var sorters = this.layout._sorters;
3043    for ( var key in getSortData ) {
3044      var sorter = sorters[ key ];
3045      this.sortData[ key ] = sorter( this.element, this );
3046    }
3047  };
3048
3049  var _destroy = Item.prototype.destroy;
3050  Item.prototype.destroy = function() {
3051    // call super
3052    _destroy.apply( this, arguments );
3053    // reset display, #741
3054    this.css({
3055      display: ''
3056    });
3057  };
3058
3059  return Item;
3060
3061}));
3062
3063/**
3064 * Isotope LayoutMode
3065 */
3066
3067( function( window, factory ) {
3068  'use strict';
3069  // universal module definition
3070
3071  if ( typeof define == 'function' && define.amd ) {
3072    // AMD
3073    define( 'isotope/js/layout-mode',[
3074          'get-size/get-size',
3075          'outlayer/outlayer'
3076        ],
3077        factory );
3078  } else if ( typeof exports == 'object' ) {
3079    // CommonJS
3080    module.exports = factory(
3081        require('get-size'),
3082        require('outlayer')
3083    );
3084  } else {
3085    // browser global
3086    window.Isotope = window.Isotope || {};
3087    window.Isotope.LayoutMode = factory(
3088        window.getSize,
3089        window.Outlayer
3090    );
3091  }
3092
3093}( window, function factory( getSize, Outlayer ) {
3094  'use strict';
3095
3096  // layout mode class
3097  function LayoutMode( isotope ) {
3098    this.isotope = isotope;
3099    // link properties
3100    if ( isotope ) {
3101      this.options = isotope.options[ this.namespace ];
3102      this.element = isotope.element;
3103      this.items = isotope.filteredItems;
3104      this.size = isotope.size;
3105    }
3106  }
3107
3108  /**
3109   * some methods should just defer to default Outlayer method
3110   * and reference the Isotope instance as `this`
3111   **/
3112  ( function() {
3113    var facadeMethods = [
3114      '_resetLayout',
3115      '_getItemLayoutPosition',
3116      '_manageStamp',
3117      '_getContainerSize',
3118      '_getElementOffset',
3119      'needsResizeLayout'
3120    ];
3121
3122    for ( var i=0, len = facadeMethods.length; i < len; i++ ) {
3123      var methodName = facadeMethods[i];
3124      LayoutMode.prototype[ methodName ] = getOutlayerMethod( methodName );
3125    }
3126
3127    function getOutlayerMethod( methodName ) {
3128      return function() {
3129        return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
3130      };
3131    }
3132  })();
3133
3134  // -----  ----- //
3135
3136  // for horizontal layout modes, check vertical size
3137  LayoutMode.prototype.needsVerticalResizeLayout = function() {
vendor: 20,350 bytes, lines 3138-3873
3138    // don't trigger if size did not change
3139    var size = getSize( this.isotope.element );
3140    // check that this.size and size are there
3141    // IE8 triggers resize on body size change, so they might not be
3142    var hasSizes = this.isotope.size && size;
3143    return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
3144  };
3145
3146  // ----- measurements ----- //
3147
3148  LayoutMode.prototype._getMeasurement = function() {
3149    this.isotope._getMeasurement.apply( this, arguments );
3150  };
3151
3152  LayoutMode.prototype.getColumnWidth = function() {
3153    this.getSegmentSize( 'column', 'Width' );
3154  };
3155
3156  LayoutMode.prototype.getRowHeight = function() {
3157    this.getSegmentSize( 'row', 'Height' );
3158  };
3159
3160  /**
3161   * get columnWidth or rowHeight
3162   * segment: 'column' or 'row'
3163   * size 'Width' or 'Height'
3164   **/
3165  LayoutMode.prototype.getSegmentSize = function( segment, size ) {
3166    var segmentName = segment + size;
3167    var outerSize = 'outer' + size;
3168    // columnWidth / outerWidth // rowHeight / outerHeight
3169    this._getMeasurement( segmentName, outerSize );
3170    // got rowHeight or columnWidth, we can chill
3171    if ( this[ segmentName ] ) {
3172      return;
3173    }
3174    // fall back to item of first element
3175    var firstItemSize = this.getFirstItemSize();
3176    this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
3177        // or size of container
3178        this.isotope.size[ 'inner' + size ];
3179  };
3180
3181  LayoutMode.prototype.getFirstItemSize = function() {
3182    var firstItem = this.isotope.filteredItems[0];
3183    return firstItem && firstItem.element && getSize( firstItem.element );
3184  };
3185
3186  // ----- methods that should reference isotope ----- //
3187
3188  LayoutMode.prototype.layout = function() {
3189    this.isotope.layout.apply( this.isotope, arguments );
3190  };
3191
3192  LayoutMode.prototype.getSize = function() {
3193    this.isotope.getSize();
3194    this.size = this.isotope.size;
3195  };
3196
3197  // -------------------------- create -------------------------- //
3198
3199  LayoutMode.modes = {};
3200
3201  LayoutMode.create = function( namespace, options ) {
3202
3203    function Mode() {
3204      LayoutMode.apply( this, arguments );
3205    }
3206
3207    Mode.prototype = new LayoutMode();
3208
3209    // default options
3210    if ( options ) {
3211      Mode.options = options;
3212    }
3213
3214    Mode.prototype.namespace = namespace;
3215    // register in Isotope
3216    LayoutMode.modes[ namespace ] = Mode;
3217
3218    return Mode;
3219  };
3220
3221  return LayoutMode;
3222
3223}));
3224
3225/*!
3226 * Masonry v3.3.1
3227 * Cascading grid layout library
3228 * http://masonry.desandro.com
3229 * MIT License
3230 * by David DeSandro
3231 */
3232
3233( function( window, factory ) {
3234  'use strict';
3235  // universal module definition
3236  if ( typeof define === 'function' && define.amd ) {
3237    // AMD
3238    define( 'masonry/masonry',[
3239          'outlayer/outlayer',
3240          'get-size/get-size',
3241          'fizzy-ui-utils/utils'
3242        ],
3243        factory );
3244  } else if ( typeof exports === 'object' ) {
3245    // CommonJS
3246    module.exports = factory(
3247        require('outlayer'),
3248        require('get-size'),
3249        require('fizzy-ui-utils')
3250    );
3251  } else {
3252    // browser global
3253    window.Masonry = factory(
3254        window.Outlayer,
3255        window.getSize,
3256        window.fizzyUIUtils
3257    );
3258  }
3259
3260}( window, function factory( Outlayer, getSize, utils ) {
3261
3262
3263
3264  // -------------------------- masonryDefinition -------------------------- //
3265
3266  // create an Outlayer layout class
3267  var Masonry = Outlayer.create('masonry');
3268
3269  Masonry.prototype._resetLayout = function() {
3270    this.getSize();
3271    this._getMeasurement( 'columnWidth', 'outerWidth' );
3272    this._getMeasurement( 'gutter', 'outerWidth' );
3273    this.measureColumns();
3274
3275    // reset column Y
3276    var i = this.cols;
3277    this.colYs = [];
3278    while (i--) {
3279      this.colYs.push( 0 );
3280    }
3281
3282    this.maxY = 0;
3283  };
3284
3285  Masonry.prototype.measureColumns = function() {
3286    this.getContainerWidth();
3287    // if columnWidth is 0, default to outerWidth of first item
3288    if ( !this.columnWidth ) {
3289      var firstItem = this.items[0];
3290      var firstItemElem = firstItem && firstItem.element;
3291      // columnWidth fall back to item of first element
3292      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
3293          // if first elem has no width, default to size of container
3294          this.containerWidth;
3295    }
3296
3297    var columnWidth = this.columnWidth += this.gutter;
3298
3299    // calculate columns
3300    var containerWidth = this.containerWidth + this.gutter;
3301    var cols = containerWidth / columnWidth;
3302    // fix rounding errors, typically with gutters
3303    var excess = columnWidth - containerWidth % columnWidth;
3304    // if overshoot is less than a pixel, round up, otherwise floor it
3305    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
3306    cols = Math[ mathMethod ]( cols );
3307    this.cols = Math.max( cols, 1 );
3308  };
3309
3310  Masonry.prototype.getContainerWidth = function() {
3311    // container is parent if fit width
3312    var container = this.options.isFitWidth ? this.element.parentNode : this.element;
3313    // check that this.size and size are there
3314    // IE8 triggers resize on body size change, so they might not be
3315    var size = getSize( container );
3316    this.containerWidth = size && size.innerWidth;
3317  };
3318
3319  Masonry.prototype._getItemLayoutPosition = function( item ) {
3320    item.getSize();
3321    // how many columns does this brick span
3322    var remainder = item.size.outerWidth % this.columnWidth;
3323    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
3324    // round if off by 1 pixel, otherwise use ceil
3325    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
3326    colSpan = Math.min( colSpan, this.cols );
3327
3328    var colGroup = this._getColGroup( colSpan );
3329    // get the minimum Y value from the columns
3330    var minimumY = Math.min.apply( Math, colGroup );
3331    var shortColIndex = utils.indexOf( colGroup, minimumY );
3332
3333    // position the brick
3334    var position = {
3335      x: this.columnWidth * shortColIndex,
3336      y: minimumY
3337    };
3338
3339    // apply setHeight to necessary columns
3340    var setHeight = minimumY + item.size.outerHeight;
3341    var setSpan = this.cols + 1 - colGroup.length;
3342    for ( var i = 0; i < setSpan; i++ ) {
3343      this.colYs[ shortColIndex + i ] = setHeight;
3344    }
3345
3346    return position;
3347  };
3348
3349  /**
3350   * @param {Number} colSpan - number of columns the element spans
3351   * @returns {Array} colGroup
3352   */
3353  Masonry.prototype._getColGroup = function( colSpan ) {
3354    if ( colSpan < 2 ) {
3355      // if brick spans only one column, use all the column Ys
3356      return this.colYs;
3357    }
3358
3359    var colGroup = [];
3360    // how many different places could this brick fit horizontally
3361    var groupCount = this.cols + 1 - colSpan;
3362    // for each group potential horizontal position
3363    for ( var i = 0; i < groupCount; i++ ) {
3364      // make an array of colY values for that one group
3365      var groupColYs = this.colYs.slice( i, i + colSpan );
3366      // and get the max value of the array
3367      colGroup[i] = Math.max.apply( Math, groupColYs );
3368    }
3369    return colGroup;
3370  };
3371
3372  Masonry.prototype._manageStamp = function( stamp ) {
3373    var stampSize = getSize( stamp );
3374    var offset = this._getElementOffset( stamp );
3375    // get the columns that this stamp affects
3376    var firstX = this.options.isOriginLeft ? offset.left : offset.right;
3377    var lastX = firstX + stampSize.outerWidth;
3378    var firstCol = Math.floor( firstX / this.columnWidth );
3379    firstCol = Math.max( 0, firstCol );
3380    var lastCol = Math.floor( lastX / this.columnWidth );
3381    // lastCol should not go over if multiple of columnWidth #425
3382    lastCol -= lastX % this.columnWidth ? 0 : 1;
3383    lastCol = Math.min( this.cols - 1, lastCol );
3384    // set colYs to bottom of the stamp
3385    var stampMaxY = ( this.options.isOriginTop ? offset.top : offset.bottom ) +
3386        stampSize.outerHeight;
3387    for ( var i = firstCol; i <= lastCol; i++ ) {
3388      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
3389    }
3390  };
3391
3392  Masonry.prototype._getContainerSize = function() {
3393    this.maxY = Math.max.apply( Math, this.colYs );
3394    var size = {
3395      height: this.maxY
3396    };
3397
3398    if ( this.options.isFitWidth ) {
3399      size.width = this._getContainerFitWidth();
3400    }
3401
3402    return size;
3403  };
3404
3405  Masonry.prototype._getContainerFitWidth = function() {
3406    var unusedCols = 0;
3407    // count unused columns
3408    var i = this.cols;
3409    while ( --i ) {
3410      if ( this.colYs[i] !== 0 ) {
3411        break;
3412      }
3413      unusedCols++;
3414    }
3415    // fit container to columns that have been used
3416    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
3417  };
3418
3419  Masonry.prototype.needsResizeLayout = function() {
3420    var previousWidth = this.containerWidth;
3421    this.getContainerWidth();
3422    return previousWidth !== this.containerWidth;
3423  };
3424
3425  return Masonry;
3426
3427}));
3428
3429/*!
3430 * Masonry layout mode
3431 * sub-classes Masonry
3432 * http://masonry.desandro.com
3433 */
3434
3435( function( window, factory ) {
3436  'use strict';
3437  // universal module definition
3438  if ( typeof define == 'function' && define.amd ) {
3439    // AMD
3440    define( 'isotope/js/layout-modes/masonry',[
3441          '../layout-mode',
3442          'masonry/masonry'
3443        ],
3444        factory );
3445  } else if ( typeof exports == 'object' ) {
3446    // CommonJS
3447    module.exports = factory(
3448        require('../layout-mode'),
3449        require('masonry-layout')
3450    );
3451  } else {
3452    // browser global
3453    factory(
3454        window.Isotope.LayoutMode,
3455        window.Masonry
3456    );
3457  }
3458
3459}( window, function factory( LayoutMode, Masonry ) {
3460  'use strict';
3461
3462  // -------------------------- helpers -------------------------- //
3463
3464  // extend objects
3465  function extend( a, b ) {
3466    for ( var prop in b ) {
3467      a[ prop ] = b[ prop ];
3468    }
3469    return a;
3470  }
3471
3472  // -------------------------- masonryDefinition -------------------------- //
3473
3474  // create an Outlayer layout class
3475  var MasonryMode = LayoutMode.create('masonry');
3476
3477  // save on to these methods
3478  var _getElementOffset = MasonryMode.prototype._getElementOffset;
3479  var layout = MasonryMode.prototype.layout;
3480  var _getMeasurement = MasonryMode.prototype._getMeasurement;
3481
3482  // sub-class Masonry
3483  extend( MasonryMode.prototype, Masonry.prototype );
3484
3485  // set back, as it was overwritten by Masonry
3486  MasonryMode.prototype._getElementOffset = _getElementOffset;
3487  MasonryMode.prototype.layout = layout;
3488  MasonryMode.prototype._getMeasurement = _getMeasurement;
3489
3490  var measureColumns = MasonryMode.prototype.measureColumns;
3491  MasonryMode.prototype.measureColumns = function() {
3492    // set items, used if measuring first item
3493    this.items = this.isotope.filteredItems;
3494    measureColumns.call( this );
3495  };
3496
3497  // HACK copy over isOriginLeft/Top options
3498  var _manageStamp = MasonryMode.prototype._manageStamp;
3499  MasonryMode.prototype._manageStamp = function() {
3500    this.options.isOriginLeft = this.isotope.options.isOriginLeft;
3501    this.options.isOriginTop = this.isotope.options.isOriginTop;
3502    _manageStamp.apply( this, arguments );
3503  };
3504
3505  return MasonryMode;
3506
3507}));
3508
3509/**
3510 * fitRows layout mode
3511 */
3512
3513( function( window, factory ) {
3514  'use strict';
3515  // universal module definition
3516  if ( typeof define == 'function' && define.amd ) {
3517    // AMD
3518    define( 'isotope/js/layout-modes/fit-rows',[
3519          '../layout-mode'
3520        ],
3521        factory );
3522  } else if ( typeof exports == 'object' ) {
3523    // CommonJS
3524    module.exports = factory(
3525        require('../layout-mode')
3526    );
3527  } else {
3528    // browser global
3529    factory(
3530        window.Isotope.LayoutMode
3531    );
3532  }
3533
3534}( window, function factory( LayoutMode ) {
3535  'use strict';
3536
3537  var FitRows = LayoutMode.create('fitRows');
3538
3539  FitRows.prototype._resetLayout = function() {
3540    this.x = 0;
3541    this.y = 0;
3542    this.maxY = 0;
3543    this._getMeasurement( 'gutter', 'outerWidth' );
3544  };
3545
3546  FitRows.prototype._getItemLayoutPosition = function( item ) {
3547    item.getSize();
3548
3549    var itemWidth = item.size.outerWidth + this.gutter;
3550    // if this element cannot fit in the current row
3551    var containerWidth = this.isotope.size.innerWidth + this.gutter;
3552    if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
3553      this.x = 0;
3554      this.y = this.maxY;
3555    }
3556
3557    var position = {
3558      x: this.x,
3559      y: this.y
3560    };
3561
3562    this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
3563    this.x += itemWidth;
3564
3565    return position;
3566  };
3567
3568  FitRows.prototype._getContainerSize = function() {
3569    return { height: this.maxY };
3570  };
3571
3572  return FitRows;
3573
3574}));
3575
3576/**
3577 * vertical layout mode
3578 */
3579
3580( function( window, factory ) {
3581  'use strict';
3582  // universal module definition
3583  if ( typeof define == 'function' && define.amd ) {
3584    // AMD
3585    define( 'isotope/js/layout-modes/vertical',[
3586          '../layout-mode'
3587        ],
3588        factory );
3589  } else if ( typeof exports == 'object' ) {
3590    // CommonJS
3591    module.exports = factory(
3592        require('../layout-mode')
3593    );
3594  } else {
3595    // browser global
3596    factory(
3597        window.Isotope.LayoutMode
3598    );
3599  }
3600
3601}( window, function factory( LayoutMode ) {
3602  'use strict';
3603
3604  var Vertical = LayoutMode.create( 'vertical', {
3605    horizontalAlignment: 0
3606  });
3607
3608  Vertical.prototype._resetLayout = function() {
3609    this.y = 0;
3610  };
3611
3612  Vertical.prototype._getItemLayoutPosition = function( item ) {
3613    item.getSize();
3614    var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
3615        this.options.horizontalAlignment;
3616    var y = this.y;
3617    this.y += item.size.outerHeight;
3618    return { x: x, y: y };
3619  };
3620
3621  Vertical.prototype._getContainerSize = function() {
3622    return { height: this.y };
3623  };
3624
3625  return Vertical;
3626
3627}));
3628
3629/*!
3630 * Isotope v2.2.2
3631 *
3632 * Licensed GPLv3 for open source use
3633 * or Isotope Commercial License for commercial use
3634 *
3635 * http://isotope.metafizzy.co
3636 * Copyright 2015 Metafizzy
3637 */
3638
3639( function( window, factory ) {
3640  'use strict';
3641  // universal module definition
3642
3643  if ( typeof define == 'function' && define.amd ) {
3644    // AMD
3645    define( [
3646          'outlayer/outlayer',
3647          'get-size/get-size',
3648          'matches-selector/matches-selector',
3649          'fizzy-ui-utils/utils',
3650          'isotope/js/item',
3651          'isotope/js/layout-mode',
3652          // include default layout modes
3653          'isotope/js/layout-modes/masonry',
3654          'isotope/js/layout-modes/fit-rows',
3655          'isotope/js/layout-modes/vertical'
3656        ],
3657        function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
3658          return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
3659        });
3660  } else if ( typeof exports == 'object' ) {
3661    // CommonJS
3662    module.exports = factory(
3663        window,
3664        require('outlayer'),
3665        require('get-size'),
3666        require('desandro-matches-selector'),
3667        require('fizzy-ui-utils'),
3668        require('./item'),
3669        require('./layout-mode'),
3670        // include default layout modes
3671        require('./layout-modes/masonry'),
3672        require('./layout-modes/fit-rows'),
3673        require('./layout-modes/vertical')
3674    );
3675  } else {
3676    // browser global
3677    window.Isotope = factory(
3678        window,
3679        window.Outlayer,
3680        window.getSize,
3681        window.matchesSelector,
3682        window.fizzyUIUtils,
3683        window.Isotope.Item,
3684        window.Isotope.LayoutMode
3685    );
3686  }
3687
3688}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
3689    Item, LayoutMode ) {
3690
3691
3692
3693  // -------------------------- vars -------------------------- //
3694
3695  var jQuery = window.jQuery;
3696
3697  // -------------------------- helpers -------------------------- //
3698
3699  var trim = String.prototype.trim ?
3700      function( str ) {
3701        return str.trim();
3702      } :
3703      function( str ) {
3704        return str.replace( /^\s+|\s+$/g, '' );
3705      };
3706
3707  var docElem = document.documentElement;
3708
3709  var getText = docElem.textContent ?
3710      function( elem ) {
3711        return elem.textContent;
3712      } :
3713      function( elem ) {
3714        return elem.innerText;
3715      };
3716
3717  // -------------------------- isotopeDefinition -------------------------- //
3718
3719  // create an Outlayer layout class
3720  var Isotope = Outlayer.create( 'isotope', {
3721    layoutMode: "masonry",
3722    isJQueryFiltering: true,
3723    sortAscending: true
3724  });
3725
3726  Isotope.Item = Item;
3727  Isotope.LayoutMode = LayoutMode;
3728
3729  Isotope.prototype._create = function() {
3730    this.itemGUID = 0;
3731    // functions that sort items
3732    this._sorters = {};
3733    this._getSorters();
3734    // call super
3735    Outlayer.prototype._create.call( this );
3736
3737    // create layout modes
3738    this.modes = {};
3739    // start filteredItems with all items
3740    this.filteredItems = this.items;
3741    // keep of track of sortBys
3742    this.sortHistory = [ 'original-order' ];
3743    // create from registered layout modes
3744    for ( var name in LayoutMode.modes ) {
3745      this._initLayoutMode( name );
3746    }
3747  };
3748
3749  Isotope.prototype.reloadItems = function() {
3750    // reset item ID counter
3751    this.itemGUID = 0;
3752    // call super
3753    Outlayer.prototype.reloadItems.call( this );
3754  };
3755
3756  Isotope.prototype._itemize = function() {
3757    var items = Outlayer.prototype._itemize.apply( this, arguments );
3758    // assign ID for original-order
3759    for ( var i=0, len = items.length; i < len; i++ ) {
3760      var item = items[i];
3761      item.id = this.itemGUID++;
3762    }
3763    this._updateItemsSortData( items );
3764    return items;
3765  };
3766
3767
3768  // -------------------------- layout -------------------------- //
3769
3770  Isotope.prototype._initLayoutMode = function( name ) {
3771    var Mode = LayoutMode.modes[ name ];
3772    // set mode options
3773    // HACK extend initial options, back-fill in default options
3774    var initialOpts = this.options[ name ] || {};
3775    this.options[ name ] = Mode.options ?
3776        utils.extend( Mode.options, initialOpts ) : initialOpts;
3777    // init layout mode instance
3778    this.modes[ name ] = new Mode( this );
3779  };
3780
3781
3782  Isotope.prototype.layout = function() {
3783    // if first time doing layout, do all magic
3784    if ( !this._isLayoutInited && this.options.isInitLayout ) {
3785      this.arrange();
3786      return;
3787    }
3788    this._layout();
3789  };
3790
3791  // private method to be used in layout() & magic()
3792  Isotope.prototype._layout = function() {
3793    // don't animate first layout
3794    var isInstant = this._getIsInstant();
3795    // layout flow
3796    this._resetLayout();
3797    this._manageStamps();
3798    this.layoutItems( this.filteredItems, isInstant );
3799
3800    // flag for initalized
3801    this._isLayoutInited = true;
3802  };
3803
3804  // filter + sort + layout
3805  Isotope.prototype.arrange = function( opts ) {
3806    // set any options pass
3807    this.option( opts );
3808    this._getIsInstant();
3809    // filter, sort, and layout
3810
3811    // filter
3812    var filtered = this._filter( this.items );
3813    this.filteredItems = filtered.matches;
3814
3815    var _this = this;
3816    function hideReveal() {
3817      _this.reveal( filtered.needReveal );
3818      _this.hide( filtered.needHide );
3819    }
3820
3821    this._bindArrangeComplete();
3822
3823    if ( this._isInstant ) {
3824      this._noTransition( hideReveal );
3825    } else {
3826      hideReveal();
3827    }
3828
3829    this._sort();
3830    this._layout();
3831  };
3832  // alias to _init for main plugin method
3833  Isotope.prototype._init = Isotope.prototype.arrange;
3834
3835  // HACK
3836  // Don't animate/transition first layout
3837  // Or don't animate/transition other layouts
3838  Isotope.prototype._getIsInstant = function() {
3839    var isInstant = this.options.isLayoutInstant !== undefined ?
3840        this.options.isLayoutInstant : !this._isLayoutInited;
3841    this._isInstant = isInstant;
3842    return isInstant;
3843  };
3844
3845  // listen for layoutComplete, hideComplete and revealComplete
3846  // to trigger arrangeComplete
3847  Isotope.prototype._bindArrangeComplete = function() {
3848    // listen for 3 events to trigger arrangeComplete
3849    var isLayoutComplete, isHideComplete, isRevealComplete;
3850    var _this = this;
3851    function arrangeParallelCallback() {
3852      if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
3853        _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
3854      }
3855    }
3856    this.once( 'layoutComplete', function() {
3857      isLayoutComplete = true;
3858      arrangeParallelCallback();
3859    });
3860    this.once( 'hideComplete', function() {
3861      isHideComplete = true;
3862      arrangeParallelCallback();
3863    });
3864    this.once( 'revealComplete', function() {
3865      isRevealComplete = true;
3866      arrangeParallelCallback();
3867    });
3868  };
3869
3870  // -------------------------- filter -------------------------- //
3871
3872  Isotope.prototype._filter = function( items ) {
3873    var filter = this.options.filter;
vendor: 5,803 bytes, lines 3874-4069
3874    filter = filter || '*';
3875    var matches = [];
3876    var hiddenMatched = [];
3877    var visibleUnmatched = [];
3878
3879    var test = this._getFilterTest( filter );
3880
3881    // test each item
3882    for ( var i=0, len = items.length; i < len; i++ ) {
3883      var item = items[i];
3884      if ( item.isIgnored ) {
3885        continue;
3886      }
3887      // add item to either matched or unmatched group
3888      var isMatched = test( item );
3889      // item.isFilterMatched = isMatched;
3890      // add to matches if its a match
3891      if ( isMatched ) {
3892        matches.push( item );
3893      }
3894      // add to additional group if item needs to be hidden or revealed
3895      if ( isMatched && item.isHidden ) {
3896        hiddenMatched.push( item );
3897      } else if ( !isMatched && !item.isHidden ) {
3898        visibleUnmatched.push( item );
3899      }
3900    }
3901
3902    // return collections of items to be manipulated
3903    return {
3904      matches: matches,
3905      needReveal: hiddenMatched,
3906      needHide: visibleUnmatched
3907    };
3908  };
3909
3910  // get a jQuery, function, or a matchesSelector test given the filter
3911  Isotope.prototype._getFilterTest = function( filter ) {
3912    if ( jQuery && this.options.isJQueryFiltering ) {
3913      // use jQuery
3914      return function( item ) {
3915        return jQuery( item.element ).is( filter );
3916      };
3917    }
3918    if ( typeof filter == 'function' ) {
3919      // use filter as function
3920      return function( item ) {
3921        return filter( item.element );
3922      };
3923    }
3924    // default, use filter as selector string
3925    return function( item ) {
3926      return matchesSelector( item.element, filter );
3927    };
3928  };
3929
3930  // -------------------------- sorting -------------------------- //
3931
3932  /**
3933   * @params {Array} elems
3934   * @public
3935   */
3936  Isotope.prototype.updateSortData = function( elems ) {
3937    // get items
3938    var items;
3939    if ( elems ) {
3940      elems = utils.makeArray( elems );
3941      items = this.getItems( elems );
3942    } else {
3943      // update all items if no elems provided
3944      items = this.items;
3945    }
3946
3947    this._getSorters();
3948    this._updateItemsSortData( items );
3949  };
3950
3951  Isotope.prototype._getSorters = function() {
3952    var getSortData = this.options.getSortData;
3953    for ( var key in getSortData ) {
3954      var sorter = getSortData[ key ];
3955      this._sorters[ key ] = mungeSorter( sorter );
3956    }
3957  };
3958
3959  /**
3960   * @params {Array} items - of Isotope.Items
3961   * @private
3962   */
3963  Isotope.prototype._updateItemsSortData = function( items ) {
3964    // do not update if no items
3965    var len = items && items.length;
3966
3967    for ( var i=0; len && i < len; i++ ) {
3968      var item = items[i];
3969      item.updateSortData();
3970    }
3971  };
3972
3973  // ----- munge sorter ----- //
3974
3975  // encapsulate this, as we just need mungeSorter
3976  // other functions in here are just for munging
3977  var mungeSorter = ( function() {
3978    // add a magic layer to sorters for convienent shorthands
3979    // `.foo-bar` will use the text of .foo-bar querySelector
3980    // `[foo-bar]` will use attribute
3981    // you can also add parser
3982    // `.foo-bar parseInt` will parse that as a number
3983    function mungeSorter( sorter ) {
3984      // if not a string, return function or whatever it is
3985      if ( typeof sorter != 'string' ) {
3986        return sorter;
3987      }
3988      // parse the sorter string
3989      var args = trim( sorter ).split(' ');
3990      var query = args[0];
3991      // check if query looks like [an-attribute]
3992      var attrMatch = query.match( /^\[(.+)\]$/ );
3993      var attr = attrMatch && attrMatch[1];
3994      var getValue = getValueGetter( attr, query );
3995      // use second argument as a parser
3996      var parser = Isotope.sortDataParsers[ args[1] ];
3997      // parse the value, if there was a parser
3998      sorter = parser ? function( elem ) {
3999            return elem && parser( getValue( elem ) );
4000          } :
4001          // otherwise just return value
4002          function( elem ) {
4003            return elem && getValue( elem );
4004          };
4005
4006      return sorter;
4007    }
4008
4009    // get an attribute getter, or get text of the querySelector
4010    function getValueGetter( attr, query ) {
4011      var getValue;
4012      // if query looks like [foo-bar], get attribute
4013      if ( attr ) {
4014        getValue = function( elem ) {
4015          return elem.getAttribute( attr );
4016        };
4017      } else {
4018        // otherwise, assume its a querySelector, and get its text
4019        getValue = function( elem ) {
4020          var child = elem.querySelector( query );
4021          return child && getText( child );
4022        };
4023      }
4024      return getValue;
4025    }
4026
4027    return mungeSorter;
4028  })();
4029
4030  // parsers used in getSortData shortcut strings
4031  Isotope.sortDataParsers = {
4032    'parseInt': function( val ) {
4033      return parseInt( val, 10 );
4034    },
4035    'parseFloat': function( val ) {
4036      return parseFloat( val );
4037    }
4038  };
4039
4040  // ----- sort method ----- //
4041
4042  // sort filteredItem order
4043  Isotope.prototype._sort = function() {
4044    var sortByOpt = this.options.sortBy;
4045    if ( !sortByOpt ) {
4046      return;
4047    }
4048    // concat all sortBy and sortHistory
4049    var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
4050    // sort magic
4051    var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
4052    this.filteredItems.sort( itemSorter );
4053    // keep track of sortBy History
4054    if ( sortByOpt != this.sortHistory[0] ) {
4055      // add to front, oldest goes in last
4056      this.sortHistory.unshift( sortByOpt );
4057    }
4058  };
4059
4060  // returns a function used for sorting
4061  function getItemSorter( sortBys, sortAsc ) {
4062    return function sorter( itemA, itemB ) {
4063      // cycle through all sortKeys
4064      for ( var i = 0, len = sortBys.length; i < len; i++ ) {
4065        var sortBy = sortBys[i];
4066        var a = itemA.sortData[ sortBy ];
4067        var b = itemB.sortData[ sortBy ];
4068        if ( a > b || a < b ) {
4069          // if sortAsc is an object, use the value given the sortBy key
4070          var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
4071          var direction = isAscending ? 1 : -1;
4072          return ( a > b ? 1 : -1 ) * direction;
4073        }
4074      }
4075      return 0;
4076    };
4077  }
4078
4079  // -------------------------- methods -------------------------- //
4080
4081  // get layout mode
4082  Isotope.prototype._mode = function() {
4083    var layoutMode = this.options.layoutMode;
4084    var mode = this.modes[ layoutMode ];
4085    if ( !mode ) {
4086      // TODO console.error
4087      throw new Error( 'No layout mode: ' + layoutMode );
4088    }
4089    // HACK sync mode's options
4090    // any options set after init for layout mode need to be synced
4091    mode.options = this.options[ layoutMode ];
4092    return mode;
4093  };
4094
4095  Isotope.prototype._resetLayout = function() {
4096    // trigger original reset layout
4097    Outlayer.prototype._resetLayout.call( this );
4098    this._mode()._resetLayout();
4099  };
4100
4101  Isotope.prototype._getItemLayoutPosition = function( item  ) {
4102    return this._mode()._getItemLayoutPosition( item );
4103  };
4104
4105  Isotope.prototype._manageStamp = function( stamp ) {
4106    this._mode()._manageStamp( stamp );
4107  };
4108
4109  Isotope.prototype._getContainerSize = function() {
4110    return this._mode()._getContainerSize();
4111  };
4112
4113  Isotope.prototype.needsResizeLayout = function() {
4114    return this._mode().needsResizeLayout();
4115  };
4116
4117  // -------------------------- adding & removing -------------------------- //
4118
4119  // HEADS UP overwrites default Outlayer appended
4120  Isotope.prototype.appended = function( elems ) {
4121    var items = this.addItems( elems );
4122    if ( !items.length ) {
4123      return;
4124    }
4125    // filter, layout, reveal new items
4126    var filteredItems = this._filterRevealAdded( items );
4127    // add to filteredItems
4128    this.filteredItems = this.filteredItems.concat( filteredItems );
4129  };
4130
4131  // HEADS UP overwrites default Outlayer prepended
4132  Isotope.prototype.prepended = function( elems ) {
4133    var items = this._itemize( elems );
4134    if ( !items.length ) {
4135      return;
4136    }
4137    // start new layout
4138    this._resetLayout();
4139    this._manageStamps();
4140    // filter, layout, reveal new items
4141    var filteredItems = this._filterRevealAdded( items );
4142    // layout previous items
4143    this.layoutItems( this.filteredItems );
4144    // add to items and filteredItems
4145    this.filteredItems = filteredItems.concat( this.filteredItems );
4146    this.items = items.concat( this.items );
4147  };
4148
4149  Isotope.prototype._filterRevealAdded = function( items ) {
4150    var filtered = this._filter( items );
4151    this.hide( filtered.needHide );
4152    // reveal all new items
4153    this.reveal( filtered.matches );
4154    // layout new items, no transition
4155    this.layoutItems( filtered.matches, true );
4156    return filtered.matches;
4157  };
4158
4159  /**
4160   * Filter, sort, and layout newly-appended item elements
4161   * @param {Array or NodeList or Element} elems
4162   */
4163  Isotope.prototype.insert = function( elems ) {
4164    var items = this.addItems( elems );
4165    if ( !items.length ) {
4166      return;
4167    }
4168    // append item elements
4169    var i, item;
4170    var len = items.length;
4171    for ( i=0; i < len; i++ ) {
4172      item = items[i];
4173      this.element.appendChild( item.element );
4174    }
4175    // filter new stuff
4176    var filteredInsertItems = this._filter( items ).matches;
4177    // set flag
4178    for ( i=0; i < len; i++ ) {
4179      items[i].isLayoutInstant = true;
4180    }
4181    this.arrange();
4182    // reset flag
4183    for ( i=0; i < len; i++ ) {
4184      delete items[i].isLayoutInstant;
4185    }
4186    this.reveal( filteredInsertItems );
4187  };
4188
4189  var _remove = Isotope.prototype.remove;
4190  Isotope.prototype.remove = function( elems ) {
4191    elems = utils.makeArray( elems );
4192    var removeItems = this.getItems( elems );
4193    // do regular thing
4194    _remove.call( this, elems );
4195    // bail if no items to remove
4196    var len = removeItems && removeItems.length;
4197    if ( !len ) {
4198      return;
4199    }
4200    // remove elems from filteredItems
4201    for ( var i=0; i < len; i++ ) {
4202      var item = removeItems[i];
4203      // remove item from collection
4204      utils.removeFrom( this.filteredItems, item );
4205    }
4206  };
4207
4208  Isotope.prototype.shuffle = function() {
4209    // update random sortData
4210    for ( var i=0, len = this.items.length; i < len; i++ ) {
4211      var item = this.items[i];
4212      item.sortData.random = Math.random();
4213    }
4214    this.options.sortBy = 'random';
4215    this._sort();
4216    this._layout();
4217  };
4218
4219  /**
4220   * trigger fn without transition
4221   * kind of hacky to have this in the first place
4222   * @param {Function} fn
4223   * @returns ret
4224   * @private
4225   */
4226  Isotope.prototype._noTransition = function( fn ) {
4227    // save transitionDuration before disabling
4228    var transitionDuration = this.options.transitionDuration;
4229    // disable transition
4230    this.options.transitionDuration = 0;
4231    // do it
4232    var returnValue = fn.call( this );
4233    // re-enable transition for reveal
4234    this.options.transitionDuration = transitionDuration;
4235    return returnValue;
4236  };
4237
4238  // ----- helper methods ----- //
4239
4240  /**
4241   * getter method for getting filtered item elements
4242   * @returns {Array} elems - collection of item elements
4243   */
4244  Isotope.prototype.getFilteredItemElements = function() {
4245    var elems = [];
4246    for ( var i=0, len = this.filteredItems.length; i < len; i++ ) {
4247      elems.push( this.filteredItems[i].element );
4248    }
4249    return elems;
4250  };
4251
4252  // -----  ----- //
4253
4254  return Isotope;
4255
4256}));
4257
4258
4259/*!
4260 * Packery layout mode PACKAGED v1.1.1
4261 * sub-classes Packery
4262 * http://packery.metafizzy.co
4263 */
4264
4265!function (a) { function b(a) { return new RegExp("(^|\\s+)" + a + "(\\s+|$)") } function c(a, b) { var c = d(a, b) ? f : e; c(a, b) } var d, e, f; "classList" in document.documentElement ? (d = function (a, b) { return a.classList.contains(b) }, e = function (a, b) { a.classList.add(b) }, f = function (a, b) { a.classList.remove(b) }) : (d = function (a, c) { return b(c).test(a.className) }, e = function (a, b) { d(a, b) || (a.className = a.className + " " + b) }, f = function (a, c) { a.className = a.className.replace(b(c), " ") }); var g = { hasClass: d, addClass: e, removeClass: f, toggleClass: c, has: d, add: e, remove: f, toggle: c }; "function" == typeof define && define.amd ? define("classie/classie", g) : "object" == typeof exports ? module.exports = g : a.classie = g }(window), function (a) { function b() { function a(b) { for (var c in a.defaults) this[c] = a.defaults[c]; for (c in b) this[c] = b[c] } return c.Rect = a, a.defaults = { x: 0, y: 0, width: 0, height: 0 }, a.prototype.contains = function (a) { var b = a.width || 0, c = a.height || 0; return this.x <= a.x && this.y <= a.y && this.x + this.width >= a.x + b && this.y + this.height >= a.y + c }, a.prototype.overlaps = function (a) { var b = this.x + this.width, c = this.y + this.height, d = a.x + a.width, e = a.y + a.height; return this.x < d && b > a.x && this.y < e && c > a.y }, a.prototype.getMaximalFreeRects = function (b) { if (!this.overlaps(b)) return !1; var c, d = [], e = this.x + this.width, f = this.y + this.height, g = b.x + b.width, h = b.y + b.he
4265ight; return this.y < b.y && (c = new a({ x: this.x, y: this.y, width: this.width, height: b.y - this.y }), d.push(c)), e > g && (c = new a({ x: g, y: this.y, width: e - g, height: this.height }), d.push(c)), f > h && (c = new a({ x: this.x, y: h, width: this.width, height: f - h }), d.push(c)), this.x < b.x && (c = new a({ x: this.x, y: this.y, width: b.x - this.x, height: this.height }), d.push(c)), d }, a.prototype.canFit = function (a) { return this.width >= a.width && this.height >= a.height }, a } var c = a.Packery = function () { }; "function" == typeof define && define.amd ? define("packery/js/rect", b) : "object" == typeof exports ? module.exports = b() : (a.Packery = a.Packery || {}, a.Packery.Rect = b()) }(window), function (a) { function b(a) { function b(a, b, c) { this.width = a || 0, this.height = b || 0, this.sortDirection = c || "downwardLeftToRight", this.reset() } b.prototype.reset = function () { this.spaces = [], this.newSpaces = []; var b = new a({ x: 0, y: 0, width: this.width, height: this.height }); this.spaces.push(b), this.sorter = c[this.sortDirection] || c.downwardLeftToRight }, b.prototype.pack = function (a) { for (var b = 0, c = this.spaces.length; c > b; b++) { var d = this.spaces[b]; if (d.canFit(a)) { this.placeInSpace(a, d); break } } }, b.prototype.placeInSpace = function (a, b) { a.x = b.x, a.y = b.y, this.placed(a) }, b.prototype.placed = function (a) { for (var b = [], c = 0, d = this.spaces.length; d > c; c++) { var e = this.spaces[c], f = e.getMaximalFreeRects(a); f ? b.push.apply(b, f) : b.push(e) } this.spaces = b, this.mergeSortSpaces() }, b.prototype.mergeSortSpaces = function () { b.mergeRects(this.spaces), this.spaces.sort(this.sorter) }, b.prototype.addSpace = function (a) { this.spaces.push(a), this.mergeSortSpaces() }, b.mergeRects = function (a) { for (var b = 0, c = a.length; c > b; b++) { var d = a[b]; if (d) { var e = a.slice(0); e.splice(b, 1); for (var f = 0, g = 0, h = e.length; h > g; g++) { var i = e[g], j = b > g ? 0 : 1; d.contains(i) && (a.splice(g + j - f, 1), f++) } } } return a }; var c = { downwardLeftToRight: function (a, b) { return a.y - b.y || a.x - b.x }, rightwardTopToBottom: function (a, b) { return a.x - b.x || a.y - b.y } }; return b } if ("function" == typeof define && define.amd) define("packery/js/packer", ["./rect"], b); else if ("object" == typeof exports) module.exports = b(require("./rect")); else { var c = a.Packery = a.Packery || {}; c.Packer = b(c.Rect) } }(window), function (a) { function b(a, b, c) { var d = a("transform"), e = function () { b.Item.apply(this, arguments) }; e.prototype = new b.Item; var f = e.prototype._create; return e.prototype._create = function () { f.call(this), this.rect = new c, this.placeRect = new c }, e.prototype.dragStart = function () { this.getPosition(), this.removeTransitionStyles(), this.isTransitioning && d && (this.element.style[d] = "none"), this.getSize(), this.isPlacing = !0, this.needsPositioning = !1, this.positionPlaceRect(this.position.x, this.position.y), this.isTransitioning = !1, this.didDrag = !1 }, e.prototype.dragMove = function (a, b) { this.didDrag = !0; var c = this.layout.size; a -= c.paddingLeft, b -= c.paddingTop, this.positionPlaceRect(a, b) }, e.prototype.dragStop = function () { this.getPosition(); var a = this.position.x !== this.placeRect.x, b = this.position.y !== this.placeRect.y; this.needsPositioning = a || b, this.didDrag = !1 }, e.prototype.positionPlaceRect = function (a, b, c) { this.placeRect.x = this.getPlaceRectCoord(a, !0), this.placeRect.y = this.getPlaceRectCoord(b, !1, c) }, e.prototype.getPlaceRectCoord = function (a, b, c) { var d = b ? "Width" : "Height", e = this.size["outer" + d], f = this.layout[b ? "columnWidth" : "rowHeight"], g = this.layout.size["inner" + d]; b || (g = Math.max(g, this.layout.maxY), this.layout.rowHeight || (g -= this.layout.gutter)); var h; if (f) { f += this.layout.gutter, g += b ? this.layout.gutter : 0, a = Math.round(a / f); var i; i = this.layout.options.isHorizontal ? b ? "ceil" : "floor" : b ? "floor" : "ceil"; var j = Math[i](g / f); j -= Math.ceil(e / f), h = j } else h = g - e; return a = c ? a : Math.min(a, h), a *= f || 1, Math.max(0, a) }, e.prototype.copyPlaceRectPosition = function () { this.rect.x = this.placeRect.x, this.rect.y = this.placeRect.y }, e.prototype.removeElem = function () { this.element.parentNode.removeChild(this.element), this.layout.packer.addSpace(this.rect), this.emitEvent("remove", [this]) }, e } "function" == typeof define && define.amd ? define("packery/js/item", ["get-style-property/get-style-property", "outlayer/outlayer", "./rect"], b) : "object" == typeof exports ? module.exports = b(require("desandro-get-style-property"), require("outlayer"), require("./rect")) : a.Packery.Item = b(a.getStyleProperty, a.Outlayer, a.Packery.Rect) }(window), function (a) { function b(a, b, c, d, e, f) { function g(a, b) { return a.position.y - b.position.y || a.position.x - b.position.x } function h(a, b) { return a.position.x - b.position.x || a.position.y - b.position.y } d.prototype.canFit = function (a) { return this.width >= a.width - 1 && this.height >= a.height - 1 }; var i = c.create("packery"); return i.Item = f, i.prototype._create = function () { c.prototype._create.call(this), this.packer = new e, this.stamp(this.options.stamped); var a = this; this.handleDraggabilly = { dragStart: function (b) { a.itemDragStart(b.element) }, dragMove: function (b) { a.itemDragMove(b.element, b.position.x, b.position.y) }, dragEnd: function (b) { a.itemDragEnd(b.element) } }, this.handleUIDraggable = { start: function (b) { a.itemDragStart(b.currentTarget) }, drag: function (b, c) { a.itemDragMove(b.currentTarget, c.position.left, c.position.top) }, stop: function (b) { a.itemDragEnd(b.currentTarget) } } }
4265, i.prototype._resetLayout = function () { this.getSize(), this._getMeasurements(); var a = this.packer; this.options.isHorizontal ? (a.width = Number.POSITIVE_INFINITY, a.height = this.size.innerHeight + this.gutter, a.sortDirection = "rightwardTopToBottom") : (a.width = this.size.innerWidth + this.gutter, a.height = Number.POSITIVE_INFINITY, a.sortDirection = "downwardLeftToRight"), a.reset(), this.maxY = 0, this.maxX = 0 }, i.prototype._getMeasurements = function () { this._getMeasurement("columnWidth", "width"), this._getMeasurement("rowHeight", "height"), this._getMeasurement("gutter", "width") }, i.prototype._getItemLayoutPosition = function (a) { return this._packItem(a), a.rect }, i.prototype._packItem = function (a) { this._setRectSize(a.element, a.rect), this.packer.pack(a.rect), this._setMaxXY(a.rect) }, i.prototype._setMaxXY = function (a) { this.maxX = Math.max(a.x + a.width, this.maxX), this.maxY = Math.max(a.y + a.height, this.maxY) }, i.prototype._setRectSize = function (a, c) { var d = b(a), e = d.outerWidth, f = d.outerHeight; (e || f) && (e = this._applyGridGutter(e, this.columnWidth), f = this._applyGridGutter(f, this.rowHeight)), c.width = Math.min(e, this.packer.width), c.height = Math.min(f, this.packer.height) }, i.prototype._applyGridGutter = function (a, b) { if (!b) return a + this.gutter; b += this.gutter; var c = a % b, d = c && 1 > c ? "round" : "ceil"; return a = Math[d](a / b) * b }, i.prototype._getContainerSize = function () { return this.options.isHorizontal ? { width: this.maxX - this.gutter } : { height: this.maxY - this.gutter } }, i.prototype._manageStamp = function (a) { var b, c = this.getItem(a); if (c && c.isPlacing) b = c.placeRect; else { var e = this._getElementOffset(a); b = new d({ x: this.options.isOriginLeft ? e.left : e.right, y: this.options.isOriginTop ? e.top : e.bottom }) } this._setRectSize(a, b), this.packer.placed(b), this._setMaxXY(b) }, i.prototype.sortItemsByPosition = function () { var a = this.options.isHorizontal ? h : g; this.items.sort(a) }, i.prototype.fit = function (a, b, c) { var d = this.getItem(a); d && (this._getMeasurements(), this.stamp(d.element), d.getSize(), d.isPlacing = !0, b = void 0 === b ? d.rect.x : b, c = void 0 === c ? d.rect.y : c, d.positionPlaceRect(b, c, !0), this._bindFitEvents(d), d.moveTo(d.placeRect.x, d.placeRect.y), this.layout(), this.unstamp(d.element), this.sortItemsByPosition(), d.isPlacing = !1, d.copyPlaceRectPosition()) }, i.prototype._bindFitEvents = function (a) { function b() { d++ , 2 === d && c.emitEvent("fitComplete", [c, a]) } var c = this, d = 0; a.on("layout", function () { return b(), !0 }), this.on("layoutComplete", function () { return b(), !0 }) }, i.prototype.resize = function () { var a = b(this.element), c = this.size && a, d = this.options.isHorizontal ? "innerHeight" : "innerWidth"; c && a[d] === this.size[d] || this.layout() }, i.prototype.itemDragStart = function (a) { this.stamp(a); var b = this.getItem(a); b && b.dragStart() }, i.prototype.itemDragMove = function (a, b, c) { function d() { f.layout(), delete f.dragTimeout } var e = this.getItem(a); e && e.dragMove(b, c); var f = this; this.clearDragTimeout(), this.dragTimeout = setTimeout(d, 40) }, i.prototype.clearDragTimeout = function () { this.dragTimeout && clearTimeout(this.dragTimeout) }, i.prototype.itemDragEnd = function (b) { var c, d = this.getItem(b); if (d && (c = d.didDrag, d.dragStop()), !d || !c && !d.needsPositioning) return void this.unstamp(b); a.add(d.element, "is-positioning-post-drag"); var e = this._getDragEndLayoutComplete(b, d); d.needsPositioning ? (d.on("layout", e), d.moveTo(d.placeRect.x, d.placeRect.y)) : d && d.copyPlaceRectPosition(), this.clearDragTimeout(), this.on("layoutComplete", e), this.layout() }, i.prototype._getDragEndLayoutComplete = function (b, c) { var d = c && c.needsPositioning, e = 0, f = d ? 2 : 1, g = this; return function () { return e++ , e !== f ? !0 : (c && (a.remove(c.element, "is-positioning-post-drag"), c.isPlacing = !1, c.copyPlaceRectPosition()), g.unstamp(b), g.sortItemsByPosition(), d && g.emitEvent("dragItemPositioned", [g, c]), !0) } }, i.prototype.bindDraggabillyEvents = function (a) { a.on("dragStart", this.handleDraggabilly.dragStart), a.on("dragMove", this.handleDraggabilly.dragMove), a.on("dragEnd", this.handleDraggabilly.dragEnd) }, i.prototype.bindUIDraggableEvents = function (a) { a.on("dragstart", this.handleUIDraggable.start).on("drag", this.handleUIDraggable.drag).on("dragstop", this.handleUIDraggable.stop) }, i.Rect = d, i.Packer = e, i } "function" == typeof define && define.amd ? define("packery/js/packery", ["classie/classie", "get-size/get-size", "outlayer/outlayer", "./rect", "./packer", "./item"], b) : "object" == typeof exports ? module.exports = b(require("desandro-classie"), require("get-size"), require("outlayer"), require("./rect"), require("./packer"), require("./item")) : a.Packery = b(a.classie, a.getSize, a.Outlayer, a.Packery.Rect, a.Packery.Packer, a.Packery.Item) }(window), function (a) { function b(a, b) { for (var c in b) a[c] = b[c]; return a } function c(a, c, d) { var e = a.create("packery"), f = e.prototype._getElementOffset, g = e.prototype._getMeasurement; b(e.prototype, c.prototype), e.prototype._getElementOffset = f, e.prototype._getMeasurement = g; var h = e.prototype._resetLayout; e.prototype._resetLayout = function () { this.packer = this.packer || new c.Packer, h.apply(this, arguments) }; var i = e.prototype._getItemLayoutPosition; e.prototype._getItemLayoutPosition = function (a) { return a.rect = a.rect || new c.Rect, i.call(this, a) }; var j = e.prototype._manageStamp; return e.prototype._manageStamp = function () { this.options.isOriginLeft = this.isotope.options.isOriginLeft, this.options.isOriginTop = this.isotope.options.isOriginTop, j.apply(this, arguments) }, e.prototype.needsResizeLayout = function () { var a = d(this.element), b = this.size && a, c = this.options.isHorizontal ? "innerHe
4265ight" : "innerWidth"; return b && a[c] !== this.size[c] }, e } "function" == typeof define && define.amd ? define(["isotope/js/layout-mode", "packery/js/packery", "get-size/get-size"], c) : "object" == typeof exports ? module.exports = c(require("isotope-layout/js/layout-mode"), require("packery"), require("get-size")) : c(a.Isotope.LayoutMode, a.Packery, a.getSize) }(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.