PageSourceSearch

http://www.educationindex2.com/wp-content/plugins/qc-simple-link-d…/assets/js/packery.pkgd.js?ver=5.3.25

js educationindex2.com collected 2026-09-27 02:36:02 UTC 84,773 bytes, 3,410 lines download raw bytes

vendor: 6,082 bytes, lines 1-255
1/*!
2 * Packery PACKAGED v2.1.1
3 * Gapless, draggable grid layouts
4 *
5 * Licensed GPLv3 for open source use
6 * or Packery Commercial License for commercial use
7 *
8 * http://packery.metafizzy.co
9 * Copyright 2016 Metafizzy
10 */
11
12/**
13 * Bridget makes jQuery widgets
14 * v2.0.0
15 * MIT license
16 */
17
18/* jshint browser: true, strict: true, undef: true, unused: true */
19
20( function( window, factory ) {
21  'use strict';
22  /* globals define: false, module: false, require: false */
23
24  if ( typeof define == 'function' && define.amd ) {
25    // AMD
26    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
27      factory( window, jQuery );
28    });
29  } else if ( typeof module == 'object' && module.exports ) {
30    // CommonJS
31    module.exports = factory(
32      window,
33      require('jquery')
34    );
35  } else {
36    // browser global
37    window.jQueryBridget = factory(
38      window,
39      window.jQuery
40    );
41  }
42
43}( window, function factory( window, jQuery ) {
44'use strict';
45
46// ----- utils ----- //
47
48var arraySlice = Array.prototype.slice;
49
50// helper function for logging errors
51// $.error breaks jQuery chaining
52var console = window.console;
53var logError = typeof console == 'undefined' ? function() {} :
54  function( message ) {
55    console.error( message );
56  };
57
58// ----- jQueryBridget ----- //
59
60function jQueryBridget( namespace, PluginClass, $ ) {
61  $ = $ || jQuery || window.jQuery;
62  if ( !$ ) {
63    return;
64  }
65
66  // add option method -> $().plugin('option', {...})
67  if ( !PluginClass.prototype.option ) {
68    // option setter
69    PluginClass.prototype.option = function( opts ) {
70      // bail out if not an object
71      if ( !$.isPlainObject( opts ) ){
72        return;
73      }
74      this.options = $.extend( true, this.options, opts );
75    };
76  }
77
78  // make jQuery plugin
79  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
80    if ( typeof arg0 == 'string' ) {
81      // method call $().plugin( 'methodName', { options } )
82      // shift arguments by 1
83      var args = arraySlice.call( arguments, 1 );
84      return methodCall( this, arg0, args );
85    }
86    // just $().plugin({ options })
87    plainCall( this, arg0 );
88    return this;
89  };
90
91  // $().plugin('methodName')
92  function methodCall( $elems, methodName, args ) {
93    var returnValue;
94    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
95
96    $elems.each( function( i, elem ) {
97      // get instance
98      var instance = $.data( elem, namespace );
99      if ( !instance ) {
100        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
101          pluginMethodStr );
102        return;
103      }
104
105      var method = instance[ methodName ];
106      if ( !method || methodName.charAt(0) == '_' ) {
107        logError( pluginMethodStr + ' is not a valid method' );
108        return;
109      }
110
111      // apply method, get return value
112      var value = method.apply( instance, args );
113      // set return value if value is returned, use only first value
114      returnValue = returnValue === undefined ? value : returnValue;
115    });
116
117    return returnValue !== undefined ? returnValue : $elems;
118  }
119
120  function plainCall( $elems, options ) {
121    $elems.each( function( i, elem ) {
122      var instance = $.data( elem, namespace );
123      if ( instance ) {
124        // set options & init
125        instance.option( options );
126        instance._init();
127      } else {
128        // initialize new instance
129        instance = new PluginClass( elem, options );
130        $.data( elem, namespace, instance );
131      }
132    });
133  }
134
135  updateJQuery( $ );
136
137}
138
139// ----- updateJQuery ----- //
140
141// set $.bridget for v1 backwards compatibility
142function updateJQuery( $ ) {
143  if ( !$ || ( $ && $.bridget ) ) {
144    return;
145  }
146  $.bridget = jQueryBridget;
147}
148
149updateJQuery( jQuery || window.jQuery );
150
151// -----  ----- //
152
153return jQueryBridget;
154
155}));
156
157/*!
158 * getSize v2.0.2
159 * measure size of elements
160 * MIT license
161 */
162
163/*jshint browser: true, strict: true, undef: true, unused: true */
164/*global define: false, module: false, console: false */
165
166( function( window, factory ) {
167  'use strict';
168
169  if ( typeof define == 'function' && define.amd ) {
170    // AMD
171    define( 'get-size/get-size',[],function() {
172      return factory();
173    });
174  } else if ( typeof module == 'object' && module.exports ) {
175    // CommonJS
176    module.exports = factory();
177  } else {
178    // browser global
179    window.getSize = factory();
180  }
181
182})( window, function factory() {
183'use strict';
184
185// -------------------------- helpers -------------------------- //
186
187// get a number from a string, not a percentage
188function getStyleSize( value ) {
189  var num = parseFloat( value );
190  // not a percent like '100%', and a number
191  var isValid = value.indexOf('%') == -1 && !isNaN( num );
192  return isValid && num;
193}
194
195function noop() {}
196
197var logError = typeof console == 'undefined' ? noop :
198  function( message ) {
199    console.error( message );
200  };
201
202// -------------------------- measurements -------------------------- //
203
204var measurements = [
205  'paddingLeft',
206  'paddingRight',
207  'paddingTop',
208  'paddingBottom',
209  'marginLeft',
210  'marginRight',
211  'marginTop',
212  'marginBottom',
213  'borderLeftWidth',
214  'borderRightWidth',
215  'borderTopWidth',
216  'borderBottomWidth'
217];
218
219var measurementsLength = measurements.length;
220
221function getZeroSize() {
222  var size = {
223    width: 0,
224    height: 0,
225    innerWidth: 0,
226    innerHeight: 0,
227    outerWidth: 0,
228    outerHeight: 0
229  };
230  for ( var i=0; i < measurementsLength; i++ ) {
231    var measurement = measurements[i];
232    size[ measurement ] = 0;
233  }
234  return size;
235}
236
237// -------------------------- getStyle -------------------------- //
238
239/**
240 * getStyle, get style of element, check for Firefox bug
241 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
242 */
243function getStyle( elem ) {
244  var style = getComputedStyle( elem );
245  if ( !style ) {
246    logError( 'Style returned ' + style +
247      '. Are you running this code in a hidden iframe on Firefox? ' +
248      'See http://bit.ly/getsizebug1' );
249  }
250  return style;
251}
252
253// -------------------------- setup -------------------------- //
254
255var isSetup = false;
vendor: 5,967 bytes, lines 256-490
256
257var isBoxSizeOuter;
258
259/**
260 * setup
261 * check isBoxSizerOuter
262 * do on first getSize() rather than on page load for Firefox bug
263 */
264function setup() {
265  // setup once
266  if ( isSetup ) {
267    return;
268  }
269  isSetup = true;
270
271  // -------------------------- box sizing -------------------------- //
272
273  /**
274   * WebKit measures the outer-width on style.width on border-box elems
275   * IE & Firefox<29 measures the inner-width
276   */
277  var div = document.createElement('div');
278  div.style.width = '200px';
279  div.style.padding = '1px 2px 3px 4px';
280  div.style.borderStyle = 'solid';
281  div.style.borderWidth = '1px 2px 3px 4px';
282  div.style.boxSizing = 'border-box';
283
284  var body = document.body || document.documentElement;
285  body.appendChild( div );
286  var style = getStyle( div );
287
288  getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;
289  body.removeChild( div );
290
291}
292
293// -------------------------- getSize -------------------------- //
294
295function getSize( elem ) {
296  setup();
297
298  // use querySeletor if elem is string
299  if ( typeof elem == 'string' ) {
300    elem = document.querySelector( elem );
301  }
302
303  // do not proceed on non-objects
304  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
305    return;
306  }
307
308  var style = getStyle( elem );
309
310  // if hidden, everything is 0
311  if ( style.display == 'none' ) {
312    return getZeroSize();
313  }
314
315  var size = {};
316  size.width = elem.offsetWidth;
317  size.height = elem.offsetHeight;
318
319  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
320
321  // get all measurements
322  for ( var i=0; i < measurementsLength; i++ ) {
323    var measurement = measurements[i];
324    var value = style[ measurement ];
325    var num = parseFloat( value );
326    // any 'auto', 'medium' value will be 0
327    size[ measurement ] = !isNaN( num ) ? num : 0;
328  }
329
330  var paddingWidth = size.paddingLeft + size.paddingRight;
331  var paddingHeight = size.paddingTop + size.paddingBottom;
332  var marginWidth = size.marginLeft + size.marginRight;
333  var marginHeight = size.marginTop + size.marginBottom;
334  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
335  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
336
337  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
338
339  // overwrite width and height if we can get it from style
340  var styleWidth = getStyleSize( style.width );
341  if ( styleWidth !== false ) {
342    size.width = styleWidth +
343      // add padding and border unless it's already including it
344      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
345  }
346
347  var styleHeight = getStyleSize( style.height );
348  if ( styleHeight !== false ) {
349    size.height = styleHeight +
350      // add padding and border unless it's already including it
351      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
352  }
353
354  size.innerWidth = size.width - ( paddingWidth + borderWidth );
355  size.innerHeight = size.height - ( paddingHeight + borderHeight );
356
357  size.outerWidth = size.width + marginWidth;
358  size.outerHeight = size.height + marginHeight;
359
360  return size;
361}
362
363return getSize;
364
365});
366
367/**
368 * EvEmitter v1.0.2
369 * Lil' event emitter
370 * MIT License
371 */
372
373/* jshint unused: true, undef: true, strict: true */
374
375( function( global, factory ) {
376  // universal module definition
377  /* jshint strict: false */ /* globals define, module */
378  if ( typeof define == 'function' && define.amd ) {
379    // AMD - RequireJS
380    define( 'ev-emitter/ev-emitter',factory );
381  } else if ( typeof module == 'object' && module.exports ) {
382    // CommonJS - Browserify, Webpack
383    module.exports = factory();
384  } else {
385    // Browser globals
386    global.EvEmitter = factory();
387  }
388
389}( this, function() {
390
391
392
393function EvEmitter() {}
394
395var proto = EvEmitter.prototype;
396
397proto.on = function( eventName, listener ) {
398  if ( !eventName || !listener ) {
399    return;
400  }
401  // set events hash
402  var events = this._events = this._events || {};
403  // set listeners array
404  var listeners = events[ eventName ] = events[ eventName ] || [];
405  // only add once
406  if ( listeners.indexOf( listener ) == -1 ) {
407    listeners.push( listener );
408  }
409
410  return this;
411};
412
413proto.once = function( eventName, listener ) {
414  if ( !eventName || !listener ) {
415    return;
416  }
417  // add event
418  this.on( eventName, listener );
419  // set once flag
420  // set onceEvents hash
421  var onceEvents = this._onceEvents = this._onceEvents || {};
422  // set onceListeners object
423  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
424  // set flag
425  onceListeners[ listener ] = true;
426
427  return this;
428};
429
430proto.off = function( eventName, listener ) {
431  var listeners = this._events && this._events[ eventName ];
432  if ( !listeners || !listeners.length ) {
433    return;
434  }
435  var index = listeners.indexOf( listener );
436  if ( index != -1 ) {
437    listeners.splice( index, 1 );
438  }
439
440  return this;
441};
442
443proto.emitEvent = function( eventName, args ) {
444  var listeners = this._events && this._events[ eventName ];
445  if ( !listeners || !listeners.length ) {
446    return;
447  }
448  var i = 0;
449  var listener = listeners[i];
450  args = args || [];
451  // once stuff
452  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
453
454  while ( listener ) {
455    var isOnce = onceListeners && onceListeners[ listener ];
456    if ( isOnce ) {
457      // remove listener
458      // remove before trigger to prevent recursion
459      this.off( eventName, listener );
460      // unset once flag
461      delete onceListeners[ listener ];
462    }
463    // trigger listener
464    listener.apply( this, args );
465    // get next listener
466    i += isOnce ? 0 : 1;
467    listener = listeners[i];
468  }
469
470  return this;
471};
472
473return EvEmitter;
474
475}));
476
477/**
478 * matchesSelector v2.0.1
479 * matchesSelector( element, '.selector' )
480 * MIT license
481 */
482
483/*jshint browser: true, strict: true, undef: true, unused: true */
484
485( function( window, factory ) {
486  /*global define: false, module: false */
487  'use strict';
488  // universal module definition
489  if ( typeof define == 'function' && define.amd ) {
490    // AMD
vendor: 16,003 bytes, lines 491-1106
491    define( 'desandro-matches-selector/matches-selector',factory );
492  } else if ( typeof module == 'object' && module.exports ) {
493    // CommonJS
494    module.exports = factory();
495  } else {
496    // browser global
497    window.matchesSelector = factory();
498  }
499
500}( window, function factory() {
501  'use strict';
502
503  var matchesMethod = ( function() {
504    var ElemProto = Element.prototype;
505    // check for the standard method name first
506    if ( ElemProto.matches ) {
507      return 'matches';
508    }
509    // check un-prefixed
510    if ( ElemProto.matchesSelector ) {
511      return 'matchesSelector';
512    }
513    // check vendor prefixes
514    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
515
516    for ( var i=0; i < prefixes.length; i++ ) {
517      var prefix = prefixes[i];
518      var method = prefix + 'MatchesSelector';
519      if ( ElemProto[ method ] ) {
520        return method;
521      }
522    }
523  })();
524
525  return function matchesSelector( elem, selector ) {
526    return elem[ matchesMethod ]( selector );
527  };
528
529}));
530
531/**
532 * Fizzy UI utils v2.0.1
533 * MIT license
534 */
535
536/*jshint browser: true, undef: true, unused: true, strict: true */
537
538( function( window, factory ) {
539  // universal module definition
540  /*jshint strict: false */ /*globals define, module, require */
541
542  if ( typeof define == 'function' && define.amd ) {
543    // AMD
544    define( 'fizzy-ui-utils/utils',[
545      'desandro-matches-selector/matches-selector'
546    ], function( matchesSelector ) {
547      return factory( window, matchesSelector );
548    });
549  } else if ( typeof module == 'object' && module.exports ) {
550    // CommonJS
551    module.exports = factory(
552      window,
553      require('desandro-matches-selector')
554    );
555  } else {
556    // browser global
557    window.fizzyUIUtils = factory(
558      window,
559      window.matchesSelector
560    );
561  }
562
563}( window, function factory( window, matchesSelector ) {
564
565
566
567var utils = {};
568
569// ----- extend ----- //
570
571// extends objects
572utils.extend = function( a, b ) {
573  for ( var prop in b ) {
574    a[ prop ] = b[ prop ];
575  }
576  return a;
577};
578
579// ----- modulo ----- //
580
581utils.modulo = function( num, div ) {
582  return ( ( num % div ) + div ) % div;
583};
584
585// ----- makeArray ----- //
586
587// turn element or nodeList into an array
588utils.makeArray = function( obj ) {
589  var ary = [];
590  if ( Array.isArray( obj ) ) {
591    // use object if already an array
592    ary = obj;
593  } else if ( obj && typeof obj.length == 'number' ) {
594    // convert nodeList to array
595    for ( var i=0; i < obj.length; i++ ) {
596      ary.push( obj[i] );
597    }
598  } else {
599    // array of single index
600    ary.push( obj );
601  }
602  return ary;
603};
604
605// ----- removeFrom ----- //
606
607utils.removeFrom = function( ary, obj ) {
608  var index = ary.indexOf( obj );
609  if ( index != -1 ) {
610    ary.splice( index, 1 );
611  }
612};
613
614// ----- getParent ----- //
615
616utils.getParent = function( elem, selector ) {
617  while ( elem != document.body ) {
618    elem = elem.parentNode;
619    if ( matchesSelector( elem, selector ) ) {
620      return elem;
621    }
622  }
623};
624
625// ----- getQueryElement ----- //
626
627// use element as selector string
628utils.getQueryElement = function( elem ) {
629  if ( typeof elem == 'string' ) {
630    return document.querySelector( elem );
631  }
632  return elem;
633};
634
635// ----- handleEvent ----- //
636
637// enable .ontype to trigger from .addEventListener( elem, 'type' )
638utils.handleEvent = function( event ) {
639  var method = 'on' + event.type;
640  if ( this[ method ] ) {
641    this[ method ]( event );
642  }
643};
644
645// ----- filterFindElements ----- //
646
647utils.filterFindElements = function( elems, selector ) {
648  // make array of elems
649  elems = utils.makeArray( elems );
650  var ffElems = [];
651
652  elems.forEach( function( elem ) {
653    // check that elem is an actual element
654    if ( !( elem instanceof HTMLElement ) ) {
655      return;
656    }
657    // add elem if no selector
658    if ( !selector ) {
659      ffElems.push( elem );
660      return;
661    }
662    // filter & find items if we have a selector
663    // filter
664    if ( matchesSelector( elem, selector ) ) {
665      ffElems.push( elem );
666    }
667    // find children
668    var childElems = elem.querySelectorAll( selector );
669    // concat childElems to filterFound array
670    for ( var i=0; i < childElems.length; i++ ) {
671      ffElems.push( childElems[i] );
672    }
673  });
674
675  return ffElems;
676};
677
678// ----- debounceMethod ----- //
679
680utils.debounceMethod = function( _class, methodName, threshold ) {
681  // original method
682  var method = _class.prototype[ methodName ];
683  var timeoutName = methodName + 'Timeout';
684
685  _class.prototype[ methodName ] = function() {
686    var timeout = this[ timeoutName ];
687    if ( timeout ) {
688      clearTimeout( timeout );
689    }
690    var args = arguments;
691
692    var _this = this;
693    this[ timeoutName ] = setTimeout( function() {
694      method.apply( _this, args );
695      delete _this[ timeoutName ];
696    }, threshold || 100 );
697  };
698};
699
700// ----- docReady ----- //
701
702utils.docReady = function( callback ) {
703  if ( document.readyState == 'complete' ) {
704    callback();
705  } else {
706    document.addEventListener( 'DOMContentLoaded', callback );
707  }
708};
709
710// ----- htmlInit ----- //
711
712// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
713utils.toDashed = function( str ) {
714  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
715    return $1 + '-' + $2;
716  }).toLowerCase();
717};
718
719var console = window.console;
720/**
721 * allow user to initialize classes via [data-namespace] or .js-namespace class
722 * htmlInit( Widget, 'widgetName' )
723 * options are parsed from data-namespace-options
724 */
725utils.htmlInit = function( WidgetClass, namespace ) {
726  utils.docReady( function() {
727    var dashedNamespace = utils.toDashed( namespace );
728    var dataAttr = 'data-' + dashedNamespace;
729    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
730    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
731    var elems = utils.makeArray( dataAttrElems )
732      .concat( utils.makeArray( jsDashElems ) );
733    var dataOptionsAttr = dataAttr + '-options';
734    var jQuery = window.jQuery;
735
736    elems.forEach( function( elem ) {
737      var attr = elem.getAttribute( dataAttr ) ||
738        elem.getAttribute( dataOptionsAttr );
739      var options;
740      try {
741        options = attr && JSON.parse( attr );
742      } catch ( error ) {
743        // log error, do not initialize
744        if ( console ) {
745          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
746          ': ' + error );
747        }
748        return;
749      }
750      // initialize
751      var instance = new WidgetClass( elem, options );
752      // make available via $().data('layoutname')
753      if ( jQuery ) {
754        jQuery.data( elem, namespace, instance );
755      }
756    });
757
758  });
759};
760
761// -----  ----- //
762
763return utils;
764
765}));
766
767/**
768 * Outlayer Item
769 */
770
771( function( window, factory ) {
772  // universal module definition
773  /* jshint strict: false */ /* globals define, module, require */
774  if ( typeof define == 'function' && define.amd ) {
775    // AMD - RequireJS
776    define( 'outlayer/item',[
777        'ev-emitter/ev-emitter',
778        'get-size/get-size'
779      ],
780      factory
781    );
782  } else if ( typeof module == 'object' && module.exports ) {
783    // CommonJS - Browserify, Webpack
784    module.exports = factory(
785      require('ev-emitter'),
786      require('get-size')
787    );
788  } else {
789    // browser global
790    window.Outlayer = {};
791    window.Outlayer.Item = factory(
792      window.EvEmitter,
793      window.getSize
794    );
795  }
796
797}( window, function factory( EvEmitter, getSize ) {
798'use strict';
799
800// ----- helpers ----- //
801
802function isEmptyObj( obj ) {
803  for ( var prop in obj ) {
804    return false;
805  }
806  prop = null;
807  return true;
808}
809
810// -------------------------- CSS3 support -------------------------- //
811
812
813var docElemStyle = document.documentElement.style;
814
815var transitionProperty = typeof docElemStyle.transition == 'string' ?
816  'transition' : 'WebkitTransition';
817var transformProperty = typeof docElemStyle.transform == 'string' ?
818  'transform' : 'WebkitTransform';
819
820var transitionEndEvent = {
821  WebkitTransition: 'webkitTransitionEnd',
822  transition: 'transitionend'
823}[ transitionProperty ];
824
825// cache all vendor properties that could have vendor prefix
826var vendorProperties = {
827  transform: transformProperty,
828  transition: transitionProperty,
829  transitionDuration: transitionProperty + 'Duration',
830  transitionProperty: transitionProperty + 'Property',
831  transitionDelay: transitionProperty + 'Delay'
832};
833
834// -------------------------- Item -------------------------- //
835
836function Item( element, layout ) {
837  if ( !element ) {
838    return;
839  }
840
841  this.element = element;
842  // parent layout class, i.e. Masonry, Isotope, or Packery
843  this.layout = layout;
844  this.position = {
845    x: 0,
846    y: 0
847  };
848
849  this._create();
850}
851
852// inherit EvEmitter
853var proto = Item.prototype = Object.create( EvEmitter.prototype );
854proto.constructor = Item;
855
856proto._create = function() {
857  // transition objects
858  this._transn = {
859    ingProperties: {},
860    clean: {},
861    onEnd: {}
862  };
863
864  this.css({
865    position: 'absolute'
866  });
867};
868
869// trigger specified handler for event type
870proto.handleEvent = function( event ) {
871  var method = 'on' + event.type;
872  if ( this[ method ] ) {
873    this[ method ]( event );
874  }
875};
876
877proto.getSize = function() {
878  this.size = getSize( this.element );
879};
880
881/**
882 * apply CSS styles to element
883 * @param {Object} style
884 */
885proto.css = function( style ) {
886  var elemStyle = this.element.style;
887
888  for ( var prop in style ) {
889    // use vendor property if available
890    var supportedProp = vendorProperties[ prop ] || prop;
891    elemStyle[ supportedProp ] = style[ prop ];
892  }
893};
894
895 // measure position, and sets it
896proto.getPosition = function() {
897  var style = getComputedStyle( this.element );
898  var isOriginLeft = this.layout._getOption('originLeft');
899  var isOriginTop = this.layout._getOption('originTop');
900  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
901  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
902  // convert percent to pixels
903  var layoutSize = this.layout.size;
904  var x = xValue.indexOf('%') != -1 ?
905    ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
906  var y = yValue.indexOf('%') != -1 ?
907    ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );
908
909  // clean up 'auto' or other non-integer values
910  x = isNaN( x ) ? 0 : x;
911  y = isNaN( y ) ? 0 : y;
912  // remove padding from measurement
913  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
914  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
915
916  this.position.x = x;
917  this.position.y = y;
918};
919
920// set settled position, apply padding
921proto.layoutPosition = function() {
922  var layoutSize = this.layout.size;
923  var style = {};
924  var isOriginLeft = this.layout._getOption('originLeft');
925  var isOriginTop = this.layout._getOption('originTop');
926
927  // x
928  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
929  var xProperty = isOriginLeft ? 'left' : 'right';
930  var xResetProperty = isOriginLeft ? 'right' : 'left';
931
932  var x = this.position.x + layoutSize[ xPadding ];
933  // set in percentage or pixels
934  style[ xProperty ] = this.getXValue( x );
935  // reset other property
936  style[ xResetProperty ] = '';
937
938  // y
939  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
940  var yProperty = isOriginTop ? 'top' : 'bottom';
941  var yResetProperty = isOriginTop ? 'bottom' : 'top';
942
943  var y = this.position.y + layoutSize[ yPadding ];
944  // set in percentage or pixels
945  style[ yProperty ] = this.getYValue( y );
946  // reset other property
947  style[ yResetProperty ] = '';
948
949  this.css( style );
950  this.emitEvent( 'layout', [ this ] );
951};
952
953proto.getXValue = function( x ) {
954  var isHorizontal = this.layout._getOption('horizontal');
955  return this.layout.options.percentPosition && !isHorizontal ?
956    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
957};
958
959proto.getYValue = function( y ) {
960  var isHorizontal = this.layout._getOption('horizontal');
961  return this.layout.options.percentPosition && isHorizontal ?
962    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
963};
964
965proto._transitionTo = function( x, y ) {
966  this.getPosition();
967  // get current x & y from top/left
968  var curX = this.position.x;
969  var curY = this.position.y;
970
971  var compareX = parseInt( x, 10 );
972  var compareY = parseInt( y, 10 );
973  var didNotMove = compareX === this.position.x && compareY === this.position.y;
974
975  // save end position
976  this.setPosition( x, y );
977
978  // if did not move and not transitioning, just go to layout
979  if ( didNotMove && !this.isTransitioning ) {
980    this.layoutPosition();
981    return;
982  }
983
984  var transX = x - curX;
985  var transY = y - curY;
986  var transitionStyle = {};
987  transitionStyle.transform = this.getTranslate( transX, transY );
988
989  this.transition({
990    to: transitionStyle,
991    onTransitionEnd: {
992      transform: this.layoutPosition
993    },
994    isCleaning: true
995  });
996};
997
998proto.getTranslate = function( x, y ) {
999  // flip cooridinates if origin on right or bottom
1000  var isOriginLeft = this.layout._getOption('originLeft');
1001  var isOriginTop = this.layout._getOption('originTop');
1002  x = isOriginLeft ? x : -x;
1003  y = isOriginTop ? y : -y;
1004  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
1005};
1006
1007// non transition + transform support
1008proto.goTo = function( x, y ) {
1009  this.setPosition( x, y );
1010  this.layoutPosition();
1011};
1012
1013proto.moveTo = proto._transitionTo;
1014
1015proto.setPosition = function( x, y ) {
1016  this.position.x = parseInt( x, 10 );
1017  this.position.y = parseInt( y, 10 );
1018};
1019
1020// ----- transition ----- //
1021
1022/**
1023 * @param {Object} style - CSS
1024 * @param {Function} onTransitionEnd
1025 */
1026
1027// non transition, just trigger callback
1028proto._nonTransition = function( args ) {
1029  this.css( args.to );
1030  if ( args.isCleaning ) {
1031    this._removeStyles( args.to );
1032  }
1033  for ( var prop in args.onTransitionEnd ) {
1034    args.onTransitionEnd[ prop ].call( this );
1035  }
1036};
1037
1038/**
1039 * proper transition
1040 * @param {Object} args - arguments
1041 *   @param {Object} to - style to transition to
1042 *   @param {Object} from - style to start transition from
1043 *   @param {Boolean} isCleaning - removes transition styles after transition
1044 *   @param {Function} onTransitionEnd - callback
1045 */
1046proto.transition = function( args ) {
1047  // redirect to nonTransition if no transition duration
1048  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1049    this._nonTransition( args );
1050    return;
1051  }
1052
1053  var _transition = this._transn;
1054  // keep track of onTransitionEnd callback by css property
1055  for ( var prop in args.onTransitionEnd ) {
1056    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
1057  }
1058  // keep track of properties that are transitioning
1059  for ( prop in args.to ) {
1060    _transition.ingProperties[ prop ] = true;
1061    // keep track of properties to clean up when transition is done
1062    if ( args.isCleaning ) {
1063      _transition.clean[ prop ] = true;
1064    }
1065  }
1066
1067  // set from styles
1068  if ( args.from ) {
1069    this.css( args.from );
1070    // force redraw. http://blog.alexmaccaw.com/css-transitions
1071    var h = this.element.offsetHeight;
1072    // hack for JSHint to hush about unused var
1073    h = null;
1074  }
1075  // enable transition
1076  this.enableTransition( args.to );
1077  // set styles that are transitioning
1078  this.css( args.to );
1079
1080  this.isTransitioning = true;
1081
1082};
1083
1084// dash before all cap letters, including first for
1085// WebkitTransform => -webkit-transform
1086function toDashedAll( str ) {
1087  return str.replace( /([A-Z])/g, function( $1 ) {
1088    return '-' + $1.toLowerCase();
1089  });
1090}
1091
1092var transitionProps = 'opacity,' + toDashedAll( transformProperty );
1093
1094proto.enableTransition = function(/* style */) {
1095  // HACK changing transitionProperty during a transition
1096  // will cause transition to jump
1097  if ( this.isTransitioning ) {
1098    return;
1099  }
1100
1101  // make `transition: foo, bar, baz` from style object
1102  // HACK un-comment this when enableTransition can work
1103  // while a transition is happening
1104  // var transitionValues = [];
1105  // for ( var prop in style ) {
1106  //   // dash-ify camelCased properties like WebkitTransition
vendor: 5,416 bytes, lines 1107-1322
1107  //   prop = vendorProperties[ prop ] || prop;
1108  //   transitionValues.push( toDashedAll( prop ) );
1109  // }
1110  // munge number to millisecond, to match stagger
1111  var duration = this.layout.options.transitionDuration;
1112  duration = typeof duration == 'number' ? duration + 'ms' : duration;
1113  // enable transition styles
1114  this.css({
1115    transitionProperty: transitionProps,
1116    transitionDuration: duration,
1117    transitionDelay: this.staggerDelay || 0
1118  });
1119  // listen for transition end event
1120  this.element.addEventListener( transitionEndEvent, this, false );
1121};
1122
1123// ----- events ----- //
1124
1125proto.onwebkitTransitionEnd = function( event ) {
1126  this.ontransitionend( event );
1127};
1128
1129proto.onotransitionend = function( event ) {
1130  this.ontransitionend( event );
1131};
1132
1133// properties that I munge to make my life easier
1134var dashedVendorProperties = {
1135  '-webkit-transform': 'transform'
1136};
1137
1138proto.ontransitionend = function( event ) {
1139  // disregard bubbled events from children
1140  if ( event.target !== this.element ) {
1141    return;
1142  }
1143  var _transition = this._transn;
1144  // get property name of transitioned property, convert to prefix-free
1145  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
1146
1147  // remove property that has completed transitioning
1148  delete _transition.ingProperties[ propertyName ];
1149  // check if any properties are still transitioning
1150  if ( isEmptyObj( _transition.ingProperties ) ) {
1151    // all properties have completed transitioning
1152    this.disableTransition();
1153  }
1154  // clean style
1155  if ( propertyName in _transition.clean ) {
1156    // clean up style
1157    this.element.style[ event.propertyName ] = '';
1158    delete _transition.clean[ propertyName ];
1159  }
1160  // trigger onTransitionEnd callback
1161  if ( propertyName in _transition.onEnd ) {
1162    var onTransitionEnd = _transition.onEnd[ propertyName ];
1163    onTransitionEnd.call( this );
1164    delete _transition.onEnd[ propertyName ];
1165  }
1166
1167  this.emitEvent( 'transitionEnd', [ this ] );
1168};
1169
1170proto.disableTransition = function() {
1171  this.removeTransitionStyles();
1172  this.element.removeEventListener( transitionEndEvent, this, false );
1173  this.isTransitioning = false;
1174};
1175
1176/**
1177 * removes style property from element
1178 * @param {Object} style
1179**/
1180proto._removeStyles = function( style ) {
1181  // clean up transition styles
1182  var cleanStyle = {};
1183  for ( var prop in style ) {
1184    cleanStyle[ prop ] = '';
1185  }
1186  this.css( cleanStyle );
1187};
1188
1189var cleanTransitionStyle = {
1190  transitionProperty: '',
1191  transitionDuration: '',
1192  transitionDelay: ''
1193};
1194
1195proto.removeTransitionStyles = function() {
1196  // remove transition
1197  this.css( cleanTransitionStyle );
1198};
1199
1200// ----- stagger ----- //
1201
1202proto.stagger = function( delay ) {
1203  delay = isNaN( delay ) ? 0 : delay;
1204  this.staggerDelay = delay + 'ms';
1205};
1206
1207// ----- show/hide/remove ----- //
1208
1209// remove element from DOM
1210proto.removeElem = function() {
1211  this.element.parentNode.removeChild( this.element );
1212  // remove display: none
1213  this.css({ display: '' });
1214  this.emitEvent( 'remove', [ this ] );
1215};
1216
1217proto.remove = function() {
1218  // just remove element if no transition support or no transition
1219  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1220    this.removeElem();
1221    return;
1222  }
1223
1224  // start transition
1225  this.once( 'transitionEnd', function() {
1226    this.removeElem();
1227  });
1228  this.hide();
1229};
1230
1231proto.reveal = function() {
1232  delete this.isHidden;
1233  // remove display: none
1234  this.css({ display: '' });
1235
1236  var options = this.layout.options;
1237
1238  var onTransitionEnd = {};
1239  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
1240  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
1241
1242  this.transition({
1243    from: options.hiddenStyle,
1244    to: options.visibleStyle,
1245    isCleaning: true,
1246    onTransitionEnd: onTransitionEnd
1247  });
1248};
1249
1250proto.onRevealTransitionEnd = function() {
1251  // check if still visible
1252  // during transition, item may have been hidden
1253  if ( !this.isHidden ) {
1254    this.emitEvent('reveal');
1255  }
1256};
1257
1258/**
1259 * get style property use for hide/reveal transition end
1260 * @param {String} styleProperty - hiddenStyle/visibleStyle
1261 * @returns {String}
1262 */
1263proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
1264  var optionStyle = this.layout.options[ styleProperty ];
1265  // use opacity
1266  if ( optionStyle.opacity ) {
1267    return 'opacity';
1268  }
1269  // get first property
1270  for ( var prop in optionStyle ) {
1271    return prop;
1272  }
1273};
1274
1275proto.hide = function() {
1276  // set flag
1277  this.isHidden = true;
1278  // remove display: none
1279  this.css({ display: '' });
1280
1281  var options = this.layout.options;
1282
1283  var onTransitionEnd = {};
1284  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
1285  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
1286
1287  this.transition({
1288    from: options.visibleStyle,
1289    to: options.hiddenStyle,
1290    // keep hidden stuff hidden
1291    isCleaning: true,
1292    onTransitionEnd: onTransitionEnd
1293  });
1294};
1295
1296proto.onHideTransitionEnd = function() {
1297  // check if still hidden
1298  // during transition, item may have been un-hidden
1299  if ( this.isHidden ) {
1300    this.css({ display: 'none' });
1301    this.emitEvent('hide');
1302  }
1303};
1304
1305proto.destroy = function() {
1306  this.css({
1307    position: '',
1308    left: '',
1309    right: '',
1310    top: '',
1311    bottom: '',
1312    transition: '',
1313    transform: ''
1314  });
1315};
1316
1317return Item;
1318
1319}));
1320
1321/*!
1322 * Outlayer v2.1.0
vendor: 32,302 bytes, lines 1322-2701
1322
1323 * the brains and guts of a layout library
1324 * MIT license
1325 */
1326
1327( function( window, factory ) {
1328  'use strict';
1329  // universal module definition
1330  /* jshint strict: false */ /* globals define, module, require */
1331  if ( typeof define == 'function' && define.amd ) {
1332    // AMD - RequireJS
1333    define( 'outlayer/outlayer',[
1334        'ev-emitter/ev-emitter',
1335        'get-size/get-size',
1336        'fizzy-ui-utils/utils',
1337        './item'
1338      ],
1339      function( EvEmitter, getSize, utils, Item ) {
1340        return factory( window, EvEmitter, getSize, utils, Item);
1341      }
1342    );
1343  } else if ( typeof module == 'object' && module.exports ) {
1344    // CommonJS - Browserify, Webpack
1345    module.exports = factory(
1346      window,
1347      require('ev-emitter'),
1348      require('get-size'),
1349      require('fizzy-ui-utils'),
1350      require('./item')
1351    );
1352  } else {
1353    // browser global
1354    window.Outlayer = factory(
1355      window,
1356      window.EvEmitter,
1357      window.getSize,
1358      window.fizzyUIUtils,
1359      window.Outlayer.Item
1360    );
1361  }
1362
1363}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
1364'use strict';
1365
1366// ----- vars ----- //
1367
1368var console = window.console;
1369var jQuery = window.jQuery;
1370var noop = function() {};
1371
1372// -------------------------- Outlayer -------------------------- //
1373
1374// globally unique identifiers
1375var GUID = 0;
1376// internal store of all Outlayer intances
1377var instances = {};
1378
1379
1380/**
1381 * @param {Element, String} element
1382 * @param {Object} options
1383 * @constructor
1384 */
1385function Outlayer( element, options ) {
1386  var queryElement = utils.getQueryElement( element );
1387  if ( !queryElement ) {
1388    if ( console ) {
1389      console.error( 'Bad element for ' + this.constructor.namespace +
1390        ': ' + ( queryElement || element ) );
1391    }
1392    return;
1393  }
1394  this.element = queryElement;
1395  // add jQuery
1396  if ( jQuery ) {
1397    this.$element = jQuery( this.element );
1398  }
1399
1400  // options
1401  this.options = utils.extend( {}, this.constructor.defaults );
1402  this.option( options );
1403
1404  // add id for Outlayer.getFromElement
1405  var id = ++GUID;
1406  this.element.outlayerGUID = id; // expando
1407  instances[ id ] = this; // associate via id
1408
1409  // kick it off
1410  this._create();
1411
1412  var isInitLayout = this._getOption('initLayout');
1413  if ( isInitLayout ) {
1414    this.layout();
1415  }
1416}
1417
1418// settings are for internal use only
1419Outlayer.namespace = 'outlayer';
1420Outlayer.Item = Item;
1421
1422// default options
1423Outlayer.defaults = {
1424  containerStyle: {
1425    position: 'relative'
1426  },
1427  initLayout: true,
1428  originLeft: true,
1429  originTop: true,
1430  resize: true,
1431  resizeContainer: true,
1432  // item options
1433  transitionDuration: '0.4s',
1434  hiddenStyle: {
1435    opacity: 0,
1436    transform: 'scale(0.001)'
1437  },
1438  visibleStyle: {
1439    opacity: 1,
1440    transform: 'scale(1)'
1441  }
1442};
1443
1444var proto = Outlayer.prototype;
1445// inherit EvEmitter
1446utils.extend( proto, EvEmitter.prototype );
1447
1448/**
1449 * set options
1450 * @param {Object} opts
1451 */
1452proto.option = function( opts ) {
1453  utils.extend( this.options, opts );
1454};
1455
1456/**
1457 * get backwards compatible option value, check old name
1458 */
1459proto._getOption = function( option ) {
1460  var oldOption = this.constructor.compatOptions[ option ];
1461  return oldOption && this.options[ oldOption ] !== undefined ?
1462    this.options[ oldOption ] : this.options[ option ];
1463};
1464
1465Outlayer.compatOptions = {
1466  // currentName: oldName
1467  initLayout: 'isInitLayout',
1468  horizontal: 'isHorizontal',
1469  layoutInstant: 'isLayoutInstant',
1470  originLeft: 'isOriginLeft',
1471  originTop: 'isOriginTop',
1472  resize: 'isResizeBound',
1473  resizeContainer: 'isResizingContainer'
1474};
1475
1476proto._create = function() {
1477  // get items from children
1478  this.reloadItems();
1479  // elements that affect layout, but are not laid out
1480  this.stamps = [];
1481  this.stamp( this.options.stamp );
1482  // set container style
1483  utils.extend( this.element.style, this.options.containerStyle );
1484
1485  // bind resize method
1486  var canBindResize = this._getOption('resize');
1487  if ( canBindResize ) {
1488    this.bindResize();
1489  }
1490};
1491
1492// goes through all children again and gets bricks in proper order
1493proto.reloadItems = function() {
1494  // collection of item elements
1495  this.items = this._itemize( this.element.children );
1496};
1497
1498
1499/**
1500 * turn elements into Outlayer.Items to be used in layout
1501 * @param {Array or NodeList or HTMLElement} elems
1502 * @returns {Array} items - collection of new Outlayer Items
1503 */
1504proto._itemize = function( elems ) {
1505
1506  var itemElems = this._filterFindItemElements( elems );
1507  var Item = this.constructor.Item;
1508
1509  // create new Outlayer Items for collection
1510  var items = [];
1511  for ( var i=0; i < itemElems.length; i++ ) {
1512    var elem = itemElems[i];
1513    var item = new Item( elem, this );
1514    items.push( item );
1515  }
1516
1517  return items;
1518};
1519
1520/**
1521 * get item elements to be used in layout
1522 * @param {Array or NodeList or HTMLElement} elems
1523 * @returns {Array} items - item elements
1524 */
1525proto._filterFindItemElements = function( elems ) {
1526  return utils.filterFindElements( elems, this.options.itemSelector );
1527};
1528
1529/**
1530 * getter method for getting item elements
1531 * @returns {Array} elems - collection of item elements
1532 */
1533proto.getItemElements = function() {
1534  return this.items.map( function( item ) {
1535    return item.element;
1536  });
1537};
1538
1539// ----- init & layout ----- //
1540
1541/**
1542 * lays out all items
1543 */
1544proto.layout = function() {
1545  this._resetLayout();
1546  this._manageStamps();
1547
1548  // don't animate first layout
1549  var layoutInstant = this._getOption('layoutInstant');
1550  var isInstant = layoutInstant !== undefined ?
1551    layoutInstant : !this._isLayoutInited;
1552  this.layoutItems( this.items, isInstant );
1553
1554  // flag for initalized
1555  this._isLayoutInited = true;
1556};
1557
1558// _init is alias for layout
1559proto._init = proto.layout;
1560
1561/**
1562 * logic before any new layout
1563 */
1564proto._resetLayout = function() {
1565  this.getSize();
1566};
1567
1568
1569proto.getSize = function() {
1570  this.size = getSize( this.element );
1571};
1572
1573/**
1574 * get measurement from option, for columnWidth, rowHeight, gutter
1575 * if option is String -> get element from selector string, & get size of element
1576 * if option is Element -> get size of element
1577 * else use option as a number
1578 *
1579 * @param {String} measurement
1580 * @param {String} size - width or height
1581 * @private
1582 */
1583proto._getMeasurement = function( measurement, size ) {
1584  var option = this.options[ measurement ];
1585  var elem;
1586  if ( !option ) {
1587    // default to 0
1588    this[ measurement ] = 0;
1589  } else {
1590    // use option as an element
1591    if ( typeof option == 'string' ) {
1592      elem = this.element.querySelector( option );
1593    } else if ( option instanceof HTMLElement ) {
1594      elem = option;
1595    }
1596    // use size of element, if element
1597    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
1598  }
1599};
1600
1601/**
1602 * layout a collection of item elements
1603 * @api public
1604 */
1605proto.layoutItems = function( items, isInstant ) {
1606  items = this._getItemsForLayout( items );
1607
1608  this._layoutItems( items, isInstant );
1609
1610  this._postLayout();
1611};
1612
1613/**
1614 * get the items to be laid out
1615 * you may want to skip over some items
1616 * @param {Array} items
1617 * @returns {Array} items
1618 */
1619proto._getItemsForLayout = function( items ) {
1620  return items.filter( function( item ) {
1621    return !item.isIgnored;
1622  });
1623};
1624
1625/**
1626 * layout items
1627 * @param {Array} items
1628 * @param {Boolean} isInstant
1629 */
1630proto._layoutItems = function( items, isInstant ) {
1631  this._emitCompleteOnItems( 'layout', items );
1632
1633  if ( !items || !items.length ) {
1634    // no items, emit event with empty array
1635    return;
1636  }
1637
1638  var queue = [];
1639
1640  items.forEach( function( item ) {
1641    // get x/y object from method
1642    var position = this._getItemLayoutPosition( item );
1643    // enqueue
1644    position.item = item;
1645    position.isInstant = isInstant || item.isLayoutInstant;
1646    queue.push( position );
1647  }, this );
1648
1649  this._processLayoutQueue( queue );
1650};
1651
1652/**
1653 * get item layout position
1654 * @param {Outlayer.Item} item
1655 * @returns {Object} x and y position
1656 */
1657proto._getItemLayoutPosition = function( /* item */ ) {
1658  return {
1659    x: 0,
1660    y: 0
1661  };
1662};
1663
1664/**
1665 * iterate over array and position each item
1666 * Reason being - separating this logic prevents 'layout invalidation'
1667 * thx @paul_irish
1668 * @param {Array} queue
1669 */
1670proto._processLayoutQueue = function( queue ) {
1671  this.updateStagger();
1672  queue.forEach( function( obj, i ) {
1673    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
1674  }, this );
1675};
1676
1677// set stagger from option in milliseconds number
1678proto.updateStagger = function() {
1679  var stagger = this.options.stagger;
1680  if ( stagger === null || stagger === undefined ) {
1681    this.stagger = 0;
1682    return;
1683  }
1684  this.stagger = getMilliseconds( stagger );
1685  return this.stagger;
1686};
1687
1688/**
1689 * Sets position of item in DOM
1690 * @param {Outlayer.Item} item
1691 * @param {Number} x - horizontal position
1692 * @param {Number} y - vertical position
1693 * @param {Boolean} isInstant - disables transitions
1694 */
1695proto._positionItem = function( item, x, y, isInstant, i ) {
1696  if ( isInstant ) {
1697    // if not transition, just set CSS
1698    item.goTo( x, y );
1699  } else {
1700    item.stagger( i * this.stagger );
1701    item.moveTo( x, y );
1702  }
1703};
1704
1705/**
1706 * Any logic you want to do after each layout,
1707 * i.e. size the container
1708 */
1709proto._postLayout = function() {
1710  this.resizeContainer();
1711};
1712
1713proto.resizeContainer = function() {
1714  var isResizingContainer = this._getOption('resizeContainer');
1715  if ( !isResizingContainer ) {
1716    return;
1717  }
1718  var size = this._getContainerSize();
1719  if ( size ) {
1720    this._setContainerMeasure( size.width, true );
1721    this._setContainerMeasure( size.height, false );
1722  }
1723};
1724
1725/**
1726 * Sets width or height of container if returned
1727 * @returns {Object} size
1728 *   @param {Number} width
1729 *   @param {Number} height
1730 */
1731proto._getContainerSize = noop;
1732
1733/**
1734 * @param {Number} measure - size of width or height
1735 * @param {Boolean} isWidth
1736 */
1737proto._setContainerMeasure = function( measure, isWidth ) {
1738  if ( measure === undefined ) {
1739    return;
1740  }
1741
1742  var elemSize = this.size;
1743  // add padding and border width if border box
1744  if ( elemSize.isBorderBox ) {
1745    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
1746      elemSize.borderLeftWidth + elemSize.borderRightWidth :
1747      elemSize.paddingBottom + elemSize.paddingTop +
1748      elemSize.borderTopWidth + elemSize.borderBottomWidth;
1749  }
1750
1751  measure = Math.max( measure, 0 );
1752  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
1753};
1754
1755/**
1756 * emit eventComplete on a collection of items events
1757 * @param {String} eventName
1758 * @param {Array} items - Outlayer.Items
1759 */
1760proto._emitCompleteOnItems = function( eventName, items ) {
1761  var _this = this;
1762  function onComplete() {
1763    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
1764  }
1765
1766  var count = items.length;
1767  if ( !items || !count ) {
1768    onComplete();
1769    return;
1770  }
1771
1772  var doneCount = 0;
1773  function tick() {
1774    doneCount++;
1775    if ( doneCount == count ) {
1776      onComplete();
1777    }
1778  }
1779
1780  // bind callback
1781  items.forEach( function( item ) {
1782    item.once( eventName, tick );
1783  });
1784};
1785
1786/**
1787 * emits events via EvEmitter and jQuery events
1788 * @param {String} type - name of event
1789 * @param {Event} event - original event
1790 * @param {Array} args - extra arguments
1791 */
1792proto.dispatchEvent = function( type, event, args ) {
1793  // add original event to arguments
1794  var emitArgs = event ? [ event ].concat( args ) : args;
1795  this.emitEvent( type, emitArgs );
1796
1797  if ( jQuery ) {
1798    // set this.$element
1799    this.$element = this.$element || jQuery( this.element );
1800    if ( event ) {
1801      // create jQuery event
1802      var $event = jQuery.Event( event );
1803      $event.type = type;
1804      this.$element.trigger( $event, args );
1805    } else {
1806      // just trigger with type if no event available
1807      this.$element.trigger( type, args );
1808    }
1809  }
1810};
1811
1812// -------------------------- ignore & stamps -------------------------- //
1813
1814
1815/**
1816 * keep item in collection, but do not lay it out
1817 * ignored items do not get skipped in layout
1818 * @param {Element} elem
1819 */
1820proto.ignore = function( elem ) {
1821  var item = this.getItem( elem );
1822  if ( item ) {
1823    item.isIgnored = true;
1824  }
1825};
1826
1827/**
1828 * return item to layout collection
1829 * @param {Element} elem
1830 */
1831proto.unignore = function( elem ) {
1832  var item = this.getItem( elem );
1833  if ( item ) {
1834    delete item.isIgnored;
1835  }
1836};
1837
1838/**
1839 * adds elements to stamps
1840 * @param {NodeList, Array, Element, or String} elems
1841 */
1842proto.stamp = function( elems ) {
1843  elems = this._find( elems );
1844  if ( !elems ) {
1845    return;
1846  }
1847
1848  this.stamps = this.stamps.concat( elems );
1849  // ignore
1850  elems.forEach( this.ignore, this );
1851};
1852
1853/**
1854 * removes elements to stamps
1855 * @param {NodeList, Array, or Element} elems
1856 */
1857proto.unstamp = function( elems ) {
1858  elems = this._find( elems );
1859  if ( !elems ){
1860    return;
1861  }
1862
1863  elems.forEach( function( elem ) {
1864    // filter out removed stamp elements
1865    utils.removeFrom( this.stamps, elem );
1866    this.unignore( elem );
1867  }, this );
1868};
1869
1870/**
1871 * finds child elements
1872 * @param {NodeList, Array, Element, or String} elems
1873 * @returns {Array} elems
1874 */
1875proto._find = function( elems ) {
1876  if ( !elems ) {
1877    return;
1878  }
1879  // if string, use argument as selector string
1880  if ( typeof elems == 'string' ) {
1881    elems = this.element.querySelectorAll( elems );
1882  }
1883  elems = utils.makeArray( elems );
1884  return elems;
1885};
1886
1887proto._manageStamps = function() {
1888  if ( !this.stamps || !this.stamps.length ) {
1889    return;
1890  }
1891
1892  this._getBoundingRect();
1893
1894  this.stamps.forEach( this._manageStamp, this );
1895};
1896
1897// update boundingLeft / Top
1898proto._getBoundingRect = function() {
1899  // get bounding rect for container element
1900  var boundingRect = this.element.getBoundingClientRect();
1901  var size = this.size;
1902  this._boundingRect = {
1903    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
1904    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
1905    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
1906    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
1907  };
1908};
1909
1910/**
1911 * @param {Element} stamp
1912**/
1913proto._manageStamp = noop;
1914
1915/**
1916 * get x/y position of element relative to container element
1917 * @param {Element} elem
1918 * @returns {Object} offset - has left, top, right, bottom
1919 */
1920proto._getElementOffset = function( elem ) {
1921  var boundingRect = elem.getBoundingClientRect();
1922  var thisRect = this._boundingRect;
1923  var size = getSize( elem );
1924  var offset = {
1925    left: boundingRect.left - thisRect.left - size.marginLeft,
1926    top: boundingRect.top - thisRect.top - size.marginTop,
1927    right: thisRect.right - boundingRect.right - size.marginRight,
1928    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
1929  };
1930  return offset;
1931};
1932
1933// -------------------------- resize -------------------------- //
1934
1935// enable event handlers for listeners
1936// i.e. resize -> onresize
1937proto.handleEvent = utils.handleEvent;
1938
1939/**
1940 * Bind layout to window resizing
1941 */
1942proto.bindResize = function() {
1943  window.addEventListener( 'resize', this );
1944  this.isResizeBound = true;
1945};
1946
1947/**
1948 * Unbind layout to window resizing
1949 */
1950proto.unbindResize = function() {
1951  window.removeEventListener( 'resize', this );
1952  this.isResizeBound = false;
1953};
1954
1955proto.onresize = function() {
1956  this.resize();
1957};
1958
1959utils.debounceMethod( Outlayer, 'onresize', 100 );
1960
1961proto.resize = function() {
1962  // don't trigger if size did not change
1963  // or if resize was unbound. See #9
1964  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
1965    return;
1966  }
1967
1968  this.layout();
1969};
1970
1971/**
1972 * check if layout is needed post layout
1973 * @returns Boolean
1974 */
1975proto.needsResizeLayout = function() {
1976  var size = getSize( this.element );
1977  // check that this.size and size are there
1978  // IE8 triggers resize on body size change, so they might not be
1979  var hasSizes = this.size && size;
1980  return hasSizes && size.innerWidth !== this.size.innerWidth;
1981};
1982
1983// -------------------------- methods -------------------------- //
1984
1985/**
1986 * add items to Outlayer instance
1987 * @param {Array or NodeList or Element} elems
1988 * @returns {Array} items - Outlayer.Items
1989**/
1990proto.addItems = function( elems ) {
1991  var items = this._itemize( elems );
1992  // add items to collection
1993  if ( items.length ) {
1994    this.items = this.items.concat( items );
1995  }
1996  return items;
1997};
1998
1999/**
2000 * Layout newly-appended item elements
2001 * @param {Array or NodeList or Element} elems
2002 */
2003proto.appended = function( elems ) {
2004  var items = this.addItems( elems );
2005  if ( !items.length ) {
2006    return;
2007  }
2008  // layout and reveal just the new items
2009  this.layoutItems( items, true );
2010  this.reveal( items );
2011};
2012
2013/**
2014 * Layout prepended elements
2015 * @param {Array or NodeList or Element} elems
2016 */
2017proto.prepended = function( elems ) {
2018  var items = this._itemize( elems );
2019  if ( !items.length ) {
2020    return;
2021  }
2022  // add items to beginning of collection
2023  var previousItems = this.items.slice(0);
2024  this.items = items.concat( previousItems );
2025  // start new layout
2026  this._resetLayout();
2027  this._manageStamps();
2028  // layout new stuff without transition
2029  this.layoutItems( items, true );
2030  this.reveal( items );
2031  // layout previous items
2032  this.layoutItems( previousItems );
2033};
2034
2035/**
2036 * reveal a collection of items
2037 * @param {Array of Outlayer.Items} items
2038 */
2039proto.reveal = function( items ) {
2040  this._emitCompleteOnItems( 'reveal', items );
2041  if ( !items || !items.length ) {
2042    return;
2043  }
2044  var stagger = this.updateStagger();
2045  items.forEach( function( item, i ) {
2046    item.stagger( i * stagger );
2047    item.reveal();
2048  });
2049};
2050
2051/**
2052 * hide a collection of items
2053 * @param {Array of Outlayer.Items} items
2054 */
2055proto.hide = function( items ) {
2056  this._emitCompleteOnItems( 'hide', items );
2057  if ( !items || !items.length ) {
2058    return;
2059  }
2060  var stagger = this.updateStagger();
2061  items.forEach( function( item, i ) {
2062    item.stagger( i * stagger );
2063    item.hide();
2064  });
2065};
2066
2067/**
2068 * reveal item elements
2069 * @param {Array}, {Element}, {NodeList} items
2070 */
2071proto.revealItemElements = function( elems ) {
2072  var items = this.getItems( elems );
2073  this.reveal( items );
2074};
2075
2076/**
2077 * hide item elements
2078 * @param {Array}, {Element}, {NodeList} items
2079 */
2080proto.hideItemElements = function( elems ) {
2081  var items = this.getItems( elems );
2082  this.hide( items );
2083};
2084
2085/**
2086 * get Outlayer.Item, given an Element
2087 * @param {Element} elem
2088 * @param {Function} callback
2089 * @returns {Outlayer.Item} item
2090 */
2091proto.getItem = function( elem ) {
2092  // loop through items to get the one that matches
2093  for ( var i=0; i < this.items.length; i++ ) {
2094    var item = this.items[i];
2095    if ( item.element == elem ) {
2096      // return item
2097      return item;
2098    }
2099  }
2100};
2101
2102/**
2103 * get collection of Outlayer.Items, given Elements
2104 * @param {Array} elems
2105 * @returns {Array} items - Outlayer.Items
2106 */
2107proto.getItems = function( elems ) {
2108  elems = utils.makeArray( elems );
2109  var items = [];
2110  elems.forEach( function( elem ) {
2111    var item = this.getItem( elem );
2112    if ( item ) {
2113      items.push( item );
2114    }
2115  }, this );
2116
2117  return items;
2118};
2119
2120/**
2121 * remove element(s) from instance and DOM
2122 * @param {Array or NodeList or Element} elems
2123 */
2124proto.remove = function( elems ) {
2125  var removeItems = this.getItems( elems );
2126
2127  this._emitCompleteOnItems( 'remove', removeItems );
2128
2129  // bail if no items to remove
2130  if ( !removeItems || !removeItems.length ) {
2131    return;
2132  }
2133
2134  removeItems.forEach( function( item ) {
2135    item.remove();
2136    // remove item from collection
2137    utils.removeFrom( this.items, item );
2138  }, this );
2139};
2140
2141// ----- destroy ----- //
2142
2143// remove and disable Outlayer instance
2144proto.destroy = function() {
2145  // clean up dynamic styles
2146  var style = this.element.style;
2147  style.height = '';
2148  style.position = '';
2149  style.width = '';
2150  // destroy items
2151  this.items.forEach( function( item ) {
2152    item.destroy();
2153  });
2154
2155  this.unbindResize();
2156
2157  var id = this.element.outlayerGUID;
2158  delete instances[ id ]; // remove reference to instance by id
2159  delete this.element.outlayerGUID;
2160  // remove data for jQuery
2161  if ( jQuery ) {
2162    jQuery.removeData( this.element, this.constructor.namespace );
2163  }
2164
2165};
2166
2167// -------------------------- data -------------------------- //
2168
2169/**
2170 * get Outlayer instance from element
2171 * @param {Element} elem
2172 * @returns {Outlayer}
2173 */
2174Outlayer.data = function( elem ) {
2175  elem = utils.getQueryElement( elem );
2176  var id = elem && elem.outlayerGUID;
2177  return id && instances[ id ];
2178};
2179
2180
2181// -------------------------- create Outlayer class -------------------------- //
2182
2183/**
2184 * create a layout class
2185 * @param {String} namespace
2186 */
2187Outlayer.create = function( namespace, options ) {
2188  // sub-class Outlayer
2189  var Layout = subclass( Outlayer );
2190  // apply new options and compatOptions
2191  Layout.defaults = utils.extend( {}, Outlayer.defaults );
2192  utils.extend( Layout.defaults, options );
2193  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );
2194
2195  Layout.namespace = namespace;
2196
2197  Layout.data = Outlayer.data;
2198
2199  // sub-class Item
2200  Layout.Item = subclass( Item );
2201
2202  // -------------------------- declarative -------------------------- //
2203
2204  utils.htmlInit( Layout, namespace );
2205
2206  // -------------------------- jQuery bridge -------------------------- //
2207
2208  // make into jQuery plugin
2209  if ( jQuery && jQuery.bridget ) {
2210    jQuery.bridget( namespace, Layout );
2211  }
2212
2213  return Layout;
2214};
2215
2216function subclass( Parent ) {
2217  function SubClass() {
2218    Parent.apply( this, arguments );
2219  }
2220
2221  SubClass.prototype = Object.create( Parent.prototype );
2222  SubClass.prototype.constructor = SubClass;
2223
2224  return SubClass;
2225}
2226
2227// ----- helpers ----- //
2228
2229// how many milliseconds are in each unit
2230var msUnits = {
2231  ms: 1,
2232  s: 1000
2233};
2234
2235// munge time-like parameter into millisecond number
2236// '0.4s' -> 40
2237function getMilliseconds( time ) {
2238  if ( typeof time == 'number' ) {
2239    return time;
2240  }
2241  var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
2242  var num = matches && matches[1];
2243  var unit = matches && matches[2];
2244  if ( !num.length ) {
2245    return 0;
2246  }
2247  num = parseFloat( num );
2248  var mult = msUnits[ unit ] || 1;
2249  return num * mult;
2250}
2251
2252// ----- fin ----- //
2253
2254// back in global
2255Outlayer.Item = Item;
2256
2257return Outlayer;
2258
2259}));
2260
2261/**
2262 * Rect
2263 * low-level utility class for basic geometry
2264 */
2265
2266( function( window, factory ) {
2267  // universal module definition
2268  /* jshint strict: false */ /* globals define, module */
2269  if ( typeof define == 'function' && define.amd ) {
2270    // AMD
2271    define( 'packery/js/rect',factory );
2272  } else if ( typeof module == 'object' && module.exports ) {
2273    // CommonJS
2274    module.exports = factory();
2275  } else {
2276    // browser global
2277    window.Packery = window.Packery || {};
2278    window.Packery.Rect = factory();
2279  }
2280
2281}( window, function factory() {
2282'use strict';
2283
2284// -------------------------- Rect -------------------------- //
2285
2286function Rect( props ) {
2287  // extend properties from defaults
2288  for ( var prop in Rect.defaults ) {
2289    this[ prop ] = Rect.defaults[ prop ];
2290  }
2291
2292  for ( prop in props ) {
2293    this[ prop ] = props[ prop ];
2294  }
2295
2296}
2297
2298Rect.defaults = {
2299  x: 0,
2300  y: 0,
2301  width: 0,
2302  height: 0
2303};
2304
2305var proto = Rect.prototype;
2306
2307/**
2308 * Determines whether or not this rectangle wholly encloses another rectangle or point.
2309 * @param {Rect} rect
2310 * @returns {Boolean}
2311**/
2312proto.contains = function( rect ) {
2313  // points don't have width or height
2314  var otherWidth = rect.width || 0;
2315  var otherHeight = rect.height || 0;
2316  return this.x <= rect.x &&
2317    this.y <= rect.y &&
2318    this.x + this.width >= rect.x + otherWidth &&
2319    this.y + this.height >= rect.y + otherHeight;
2320};
2321
2322/**
2323 * Determines whether or not the rectangle intersects with another.
2324 * @param {Rect} rect
2325 * @returns {Boolean}
2326**/
2327proto.overlaps = function( rect ) {
2328  var thisRight = this.x + this.width;
2329  var thisBottom = this.y + this.height;
2330  var rectRight = rect.x + rect.width;
2331  var rectBottom = rect.y + rect.height;
2332
2333  // http://stackoverflow.com/a/306332
2334  return this.x < rectRight &&
2335    thisRight > rect.x &&
2336    this.y < rectBottom &&
2337    thisBottom > rect.y;
2338};
2339
2340/**
2341 * @param {Rect} rect - the overlapping rect
2342 * @returns {Array} freeRects - rects representing the area around the rect
2343**/
2344proto.getMaximalFreeRects = function( rect ) {
2345
2346  // if no intersection, return false
2347  if ( !this.overlaps( rect ) ) {
2348    return false;
2349  }
2350
2351  var freeRects = [];
2352  var freeRect;
2353
2354  var thisRight = this.x + this.width;
2355  var thisBottom = this.y + this.height;
2356  var rectRight = rect.x + rect.width;
2357  var rectBottom = rect.y + rect.height;
2358
2359  // top
2360  if ( this.y < rect.y ) {
2361    freeRect = new Rect({
2362      x: this.x,
2363      y: this.y,
2364      width: this.width,
2365      height: rect.y - this.y
2366    });
2367    freeRects.push( freeRect );
2368  }
2369
2370  // right
2371  if ( thisRight > rectRight ) {
2372    freeRect = new Rect({
2373      x: rectRight,
2374      y: this.y,
2375      width: thisRight - rectRight,
2376      height: this.height
2377    });
2378    freeRects.push( freeRect );
2379  }
2380
2381  // bottom
2382  if ( thisBottom > rectBottom ) {
2383    freeRect = new Rect({
2384      x: this.x,
2385      y: rectBottom,
2386      width: this.width,
2387      height: thisBottom - rectBottom
2388    });
2389    freeRects.push( freeRect );
2390  }
2391
2392  // left
2393  if ( this.x < rect.x ) {
2394    freeRect = new Rect({
2395      x: this.x,
2396      y: this.y,
2397      width: rect.x - this.x,
2398      height: this.height
2399    });
2400    freeRects.push( freeRect );
2401  }
2402
2403  return freeRects;
2404};
2405
2406proto.canFit = function( rect ) {
2407  return this.width >= rect.width && this.height >= rect.height;
2408};
2409
2410return Rect;
2411
2412}));
2413
2414/**
2415 * Packer
2416 * bin-packing algorithm
2417 */
2418
2419( function( window, factory ) {
2420  // universal module definition
2421  /* jshint strict: false */ /* globals define, module, require */
2422  if ( typeof define == 'function' && define.amd ) {
2423    // AMD
2424    define( 'packery/js/packer',[ './rect' ], factory );
2425  } else if ( typeof module == 'object' && module.exports ) {
2426    // CommonJS
2427    module.exports = factory(
2428      require('./rect')
2429    );
2430  } else {
2431    // browser global
2432    var Packery = window.Packery = window.Packery || {};
2433    Packery.Packer = factory( Packery.Rect );
2434  }
2435
2436}( window, function factory( Rect ) {
2437'use strict';
2438
2439// -------------------------- Packer -------------------------- //
2440
2441/**
2442 * @param {Number} width
2443 * @param {Number} height
2444 * @param {String} sortDirection
2445 *   topLeft for vertical, leftTop for horizontal
2446 */
2447function Packer( width, height, sortDirection ) {
2448  this.width = width || 0;
2449  this.height = height || 0;
2450  this.sortDirection = sortDirection || 'downwardLeftToRight';
2451
2452  this.reset();
2453}
2454
2455var proto = Packer.prototype;
2456
2457proto.reset = function() {
2458  this.spaces = [];
2459
2460  var initialSpace = new Rect({
2461    x: 0,
2462    y: 0,
2463    width: this.width,
2464    height: this.height
2465  });
2466
2467  this.spaces.push( initialSpace );
2468  // set sorter
2469  this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight;
2470};
2471
2472// change x and y of rect to fit with in Packer's available spaces
2473proto.pack = function( rect ) {
2474  for ( var i=0; i < this.spaces.length; i++ ) {
2475    var space = this.spaces[i];
2476    if ( space.canFit( rect ) ) {
2477      this.placeInSpace( rect, space );
2478      break;
2479    }
2480  }
2481};
2482
2483proto.columnPack = function( rect ) {
2484  for ( var i=0; i < this.spaces.length; i++ ) {
2485    var space = this.spaces[i];
2486    var canFitInSpaceColumn = space.x <= rect.x &&
2487      space.x + space.width >= rect.x + rect.width &&
2488      space.height >= rect.height - 0.01; // fudge number for rounding error
2489    if ( canFitInSpaceColumn ) {
2490      rect.y = space.y;
2491      this.placed( rect );
2492      break;
2493    }
2494  }
2495};
2496
2497proto.rowPack = function( rect ) {
2498  for ( var i=0; i < this.spaces.length; i++ ) {
2499    var space = this.spaces[i];
2500    var canFitInSpaceRow = space.y <= rect.y &&
2501      space.y + space.height >= rect.y + rect.height &&
2502      space.width >= rect.width - 0.01; // fudge number for rounding error
2503    if ( canFitInSpaceRow ) {
2504      rect.x = space.x;
2505      this.placed( rect );
2506      break;
2507    }
2508  }
2509};
2510
2511proto.placeInSpace = function( rect, space ) {
2512  // place rect in space
2513  rect.x = space.x;
2514  rect.y = space.y;
2515
2516  this.placed( rect );
2517};
2518
2519// update spaces with placed rect
2520proto.placed = function( rect ) {
2521  // update spaces
2522  var revisedSpaces = [];
2523  for ( var i=0; i < this.spaces.length; i++ ) {
2524    var space = this.spaces[i];
2525    var newSpaces = space.getMaximalFreeRects( rect );
2526    // add either the original space or the new spaces to the revised spaces
2527    if ( newSpaces ) {
2528      revisedSpaces.push.apply( revisedSpaces, newSpaces );
2529    } else {
2530      revisedSpaces.push( space );
2531    }
2532  }
2533
2534  this.spaces = revisedSpaces;
2535
2536  this.mergeSortSpaces();
2537};
2538
2539proto.mergeSortSpaces = function() {
2540  // remove redundant spaces
2541  Packer.mergeRects( this.spaces );
2542  this.spaces.sort( this.sorter );
2543};
2544
2545// add a space back
2546proto.addSpace = function( rect ) {
2547  this.spaces.push( rect );
2548  this.mergeSortSpaces();
2549};
2550
2551// -------------------------- utility functions -------------------------- //
2552
2553/**
2554 * Remove redundant rectangle from array of rectangles
2555 * @param {Array} rects: an array of Rects
2556 * @returns {Array} rects: an array of Rects
2557**/
2558Packer.mergeRects = function( rects ) {
2559  var i = 0;
2560  var rect = rects[i];
2561
2562  rectLoop:
2563  while ( rect ) {
2564    var j = 0;
2565    var compareRect = rects[ i + j ];
2566
2567    while ( compareRect ) {
2568      if  ( compareRect == rect ) {
2569        j++; // next
2570      } else if ( compareRect.contains( rect ) ) {
2571        // remove rect
2572        rects.splice( i, 1 );
2573        rect = rects[i]; // set next rect
2574        continue rectLoop; // bail on compareLoop
2575      } else if ( rect.contains( compareRect ) ) {
2576        // remove compareRect
2577        rects.splice( i + j, 1 );
2578      } else {
2579        j++;
2580      }
2581      compareRect = rects[ i + j ]; // set next compareRect
2582    }
2583    i++;
2584    rect = rects[i];
2585  }
2586
2587  return rects;
2588};
2589
2590
2591// -------------------------- sorters -------------------------- //
2592
2593// functions for sorting rects in order
2594var sorters = {
2595  // top down, then left to right
2596  downwardLeftToRight: function( a, b ) {
2597    return a.y - b.y || a.x - b.x;
2598  },
2599  // left to right, then top down
2600  rightwardTopToBottom: function( a, b ) {
2601    return a.x - b.x || a.y - b.y;
2602  }
2603};
2604
2605
2606// --------------------------  -------------------------- //
2607
2608return Packer;
2609
2610}));
2611
2612/**
2613 * Packery Item Element
2614**/
2615
2616( function( window, factory ) {
2617  // universal module definition
2618  /* jshint strict: false */ /* globals define, module, require */
2619  if ( typeof define == 'function' && define.amd ) {
2620    // AMD
2621    define( 'packery/js/item',[
2622        'outlayer/outlayer',
2623        './rect'
2624      ],
2625      factory );
2626  } else if ( typeof module == 'object' && module.exports ) {
2627    // CommonJS
2628    module.exports = factory(
2629      require('outlayer'),
2630      require('./rect')
2631    );
2632  } else {
2633    // browser global
2634    window.Packery.Item = factory(
2635      window.Outlayer,
2636      window.Packery.Rect
2637    );
2638  }
2639
2640}( window, function factory( Outlayer, Rect ) {
2641'use strict';
2642
2643// -------------------------- Item -------------------------- //
2644
2645var docElemStyle = document.documentElement.style;
2646
2647var transformProperty = typeof docElemStyle.transform == 'string' ?
2648  'transform' : 'WebkitTransform';
2649
2650// sub-class Item
2651var Item = function PackeryItem() {
2652  Outlayer.Item.apply( this, arguments );
2653};
2654
2655var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
2656
2657var __create = proto._create;
2658proto._create = function() {
2659  // call default _create logic
2660  __create.call( this );
2661  this.rect = new Rect();
2662};
2663
2664var _moveTo = proto.moveTo;
2665proto.moveTo = function( x, y ) {
2666  // don't shift 1px while dragging
2667  var dx = Math.abs( this.position.x - x );
2668  var dy = Math.abs( this.position.y - y );
2669
2670  var canHackGoTo = this.layout.dragItemCount && !this.isPlacing &&
2671    !this.isTransitioning && dx < 1 && dy < 1;
2672  if ( canHackGoTo ) {
2673    this.goTo( x, y );
2674    return;
2675  }
2676  _moveTo.apply( this, arguments );
2677};
2678
2679// -------------------------- placing -------------------------- //
2680
2681proto.enablePlacing = function() {
2682  this.removeTransitionStyles();
2683  // remove transform property from transition
2684  if ( this.isTransitioning && transformProperty ) {
2685    this.element.style[ transformProperty ] = 'none';
2686  }
2687  this.isTransitioning = false;
2688  this.getSize();
2689  this.layout._setRectSize( this.element, this.rect );
2690  this.isPlacing = true;
2691};
2692
2693proto.disablePlacing = function() {
2694  this.isPlacing = false;
2695};
2696
2697// -----  ----- //
2698
2699// remove element from DOM
2700proto.removeElem = function() {
2701  
vendor: 2,266 bytes, lines 2701-2788
2701this.element.parentNode.removeChild( this.element );
2702  // add space back to packer
2703  this.layout.packer.addSpace( this.rect );
2704  this.emitEvent( 'remove', [ this ] );
2705};
2706
2707// ----- dropPlaceholder ----- //
2708
2709proto.showDropPlaceholder = function() {
2710  var dropPlaceholder = this.dropPlaceholder;
2711  if ( !dropPlaceholder ) {
2712    // create dropPlaceholder
2713    dropPlaceholder = this.dropPlaceholder = document.createElement('div');
2714    dropPlaceholder.className = 'packery-drop-placeholder';
2715    dropPlaceholder.style.position = 'absolute';
2716  }
2717
2718  dropPlaceholder.style.width = this.size.width + 'px';
2719  dropPlaceholder.style.height = this.size.height + 'px';
2720  this.positionDropPlaceholder();
2721  this.layout.element.appendChild( dropPlaceholder );
2722};
2723
2724proto.positionDropPlaceholder = function() {
2725  this.dropPlaceholder.style[ transformProperty ] = 'translate(' +
2726    this.rect.x + 'px, ' + this.rect.y + 'px)';
2727};
2728
2729proto.hideDropPlaceholder = function() {
2730  // only remove once, #333
2731  var parent = this.dropPlaceholder.parentNode;
2732  if ( parent ) {
2733    parent.removeChild( this.dropPlaceholder );
2734  }
2735};
2736
2737// -----  ----- //
2738
2739return Item;
2740
2741}));
2742
2743/*!
2744 * Packery v2.1.1
2745 * Gapless, draggable grid layouts
2746 *
2747 * Licensed GPLv3 for open source use
2748 * or Packery Commercial License for commercial use
2749 *
2750 * http://packery.metafizzy.co
2751 * Copyright 2016 Metafizzy
2752 */
2753
2754( function( window, factory ) {
2755  // universal module definition
2756  /* jshint strict: false */ /* globals define, module, require */
2757  if ( typeof define == 'function' && define.amd ) {
2758    // AMD
2759    define( [
2760        'get-size/get-size',
2761        'outlayer/outlayer',
2762        'packery/js/rect',
2763        'packery/js/packer',
2764        'packery/js/item'
2765      ],
2766      factory );
2767  } else if ( typeof module == 'object' && module.exports ) {
2768    // CommonJS
2769    module.exports = factory(
2770      require('get-size'),
2771      require('outlayer'),
2772      require('./rect'),
2773      require('./packer'),
2774      require('./item')
2775    );
2776  } else {
2777    // browser global
2778    window.Packery = factory(
2779      window.getSize,
2780      window.Outlayer,
2781      window.Packery.Rect,
2782      window.Packery.Packer,
2783      window.Packery.Item
2784    );
2785  }
2786
2787}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) {
2788'use strict';
vendor: 11,082 bytes, lines 2788-3204
2788
2789
2790// ----- Rect ----- //
2791
2792// allow for pixel rounding errors IE8-IE11 & Firefox; #227
2793Rect.prototype.canFit = function( rect ) {
2794  return this.width >= rect.width - 1 && this.height >= rect.height - 1;
2795};
2796
2797// -------------------------- Packery -------------------------- //
2798
2799// create an Outlayer layout class
2800var Packery = Outlayer.create('packery');
2801Packery.Item = Item;
2802
2803var proto = Packery.prototype;
2804
2805proto._create = function() {
2806  // call super
2807  Outlayer.prototype._create.call( this );
2808
2809  // initial properties
2810  this.packer = new Packer();
2811  // packer for drop targets
2812  this.shiftPacker = new Packer();
2813  this.isEnabled = true;
2814
2815  this.dragItemCount = 0;
2816
2817  // create drag handlers
2818  var _this = this;
2819  this.handleDraggabilly = {
2820    dragStart: function() {
2821      _this.itemDragStart( this.element );
2822    },
2823    dragMove: function() {
2824      _this.itemDragMove( this.element, this.position.x, this.position.y );
2825    },
2826    dragEnd: function() {
2827      _this.itemDragEnd( this.element );
2828    }
2829  };
2830
2831  this.handleUIDraggable = {
2832    start: function handleUIDraggableStart( event, ui ) {
2833      // HTML5 may trigger dragstart, dismiss HTML5 dragging
2834      if ( !ui ) {
2835        return;
2836      }
2837      _this.itemDragStart( event.currentTarget );
2838    },
2839    drag: function handleUIDraggableDrag( event, ui ) {
2840      if ( !ui ) {
2841        return;
2842      }
2843      _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top );
2844    },
2845    stop: function handleUIDraggableStop( event, ui ) {
2846      if ( !ui ) {
2847        return;
2848      }
2849      _this.itemDragEnd( event.currentTarget );
2850    }
2851  };
2852
2853};
2854
2855
2856// ----- init & layout ----- //
2857
2858/**
2859 * logic before any new layout
2860 */
2861proto._resetLayout = function() {
2862  this.getSize();
2863
2864  this._getMeasurements();
2865
2866  // reset packer
2867  var width, height, sortDirection;
2868  // packer settings, if horizontal or vertical
2869  if ( this._getOption('horizontal') ) {
2870    width = Infinity;
2871    height = this.size.innerHeight + this.gutter;
2872    sortDirection = 'rightwardTopToBottom';
2873  } else {
2874    width = this.size.innerWidth + this.gutter;
2875    height = Infinity;
2876    sortDirection = 'downwardLeftToRight';
2877  }
2878
2879  this.packer.width = this.shiftPacker.width = width;
2880  this.packer.height = this.shiftPacker.height = height;
2881  this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection;
2882
2883  this.packer.reset();
2884
2885  // layout
2886  this.maxY = 0;
2887  this.maxX = 0;
2888};
2889
2890/**
2891 * update columnWidth, rowHeight, & gutter
2892 * @private
2893 */
2894proto._getMeasurements = function() {
2895  this._getMeasurement( 'columnWidth', 'width' );
2896  this._getMeasurement( 'rowHeight', 'height' );
2897  this._getMeasurement( 'gutter', 'width' );
2898};
2899
2900proto._getItemLayoutPosition = function( item ) {
2901  this._setRectSize( item.element, item.rect );
2902  if ( this.isShifting || this.dragItemCount > 0 ) {
2903    var packMethod = this._getPackMethod();
2904    this.packer[ packMethod ]( item.rect );
2905  } else {
2906    this.packer.pack( item.rect );
2907  }
2908
2909  this._setMaxXY( item.rect );
2910  return item.rect;
2911};
2912
2913proto.shiftLayout = function() {
2914  this.isShifting = true;
2915  this.layout();
2916  delete this.isShifting;
2917};
2918
2919proto._getPackMethod = function() {
2920  return this._getOption('horizontal') ? 'rowPack' : 'columnPack';
2921};
2922
2923
2924/**
2925 * set max X and Y value, for size of container
2926 * @param {Packery.Rect} rect
2927 * @private
2928 */
2929proto._setMaxXY = function( rect ) {
2930  this.maxX = Math.max( rect.x + rect.width, this.maxX );
2931  this.maxY = Math.max( rect.y + rect.height, this.maxY );
2932};
2933
2934/**
2935 * set the width and height of a rect, applying columnWidth and rowHeight
2936 * @param {Element} elem
2937 * @param {Packery.Rect} rect
2938 */
2939proto._setRectSize = function( elem, rect ) {
2940  var size = getSize( elem );
2941  var w = size.outerWidth;
2942  var h = size.outerHeight;
2943  // size for columnWidth and rowHeight, if available
2944  // only check if size is non-zero, #177
2945  if ( w || h ) {
2946    w = this._applyGridGutter( w, this.columnWidth );
2947    h = this._applyGridGutter( h, this.rowHeight );
2948  }
2949  // rect must fit in packer
2950  rect.width = Math.min( w, this.packer.width );
2951  rect.height = Math.min( h, this.packer.height );
2952};
2953
2954/**
2955 * fits item to columnWidth/rowHeight and adds gutter
2956 * @param {Number} measurement - item width or height
2957 * @param {Number} gridSize - columnWidth or rowHeight
2958 * @returns measurement
2959 */
2960proto._applyGridGutter = function( measurement, gridSize ) {
2961  // just add gutter if no gridSize
2962  if ( !gridSize ) {
2963    return measurement + this.gutter;
2964  }
2965  gridSize += this.gutter;
2966  // fit item to columnWidth/rowHeight
2967  var remainder = measurement % gridSize;
2968  var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
2969  measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize;
2970  return measurement;
2971};
2972
2973proto._getContainerSize = function() {
2974  if ( this._getOption('horizontal') ) {
2975    return {
2976      width: this.maxX - this.gutter
2977    };
2978  } else {
2979    return {
2980      height: this.maxY - this.gutter
2981    };
2982  }
2983};
2984
2985
2986// -------------------------- stamp -------------------------- //
2987
2988/**
2989 * makes space for element
2990 * @param {Element} elem
2991 */
2992proto._manageStamp = function( elem ) {
2993
2994  var item = this.getItem( elem );
2995  var rect;
2996  if ( item && item.isPlacing ) {
2997    rect = item.rect;
2998  } else {
2999    var offset = this._getElementOffset( elem );
3000    rect = new Rect({
3001      x: this._getOption('originLeft') ? offset.left : offset.right,
3002      y: this._getOption('originTop') ? offset.top : offset.bottom
3003    });
3004  }
3005
3006  this._setRectSize( elem, rect );
3007  // save its space in the packer
3008  this.packer.placed( rect );
3009  this._setMaxXY( rect );
3010};
3011
3012// -------------------------- methods -------------------------- //
3013
3014function verticalSorter( a, b ) {
3015  return a.position.y - b.position.y || a.position.x - b.position.x;
3016}
3017
3018function horizontalSorter( a, b ) {
3019  return a.position.x - b.position.x || a.position.y - b.position.y;
3020}
3021
3022proto.sortItemsByPosition = function() {
3023  var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter;
3024  this.items.sort( sorter );
3025};
3026
3027/**
3028 * Fit item element in its current position
3029 * Packery will position elements around it
3030 * useful for expanding elements
3031 *
3032 * @param {Element} elem
3033 * @param {Number} x - horizontal destination position, optional
3034 * @param {Number} y - vertical destination position, optional
3035 */
3036proto.fit = function( elem, x, y ) {
3037  var item = this.getItem( elem );
3038  if ( !item ) {
3039    return;
3040  }
3041
3042  // stamp item to get it out of layout
3043  this.stamp( item.element );
3044  // set placing flag
3045  item.enablePlacing();
3046  this.updateShiftTargets( item );
3047  // fall back to current position for fitting
3048  x = x === undefined ? item.rect.x: x;
3049  y = y === undefined ? item.rect.y: y;
3050  // position it best at its destination
3051  this.shift( item, x, y );
3052  this._bindFitEvents( item );
3053  item.moveTo( item.rect.x, item.rect.y );
3054  // layout everything else
3055  this.shiftLayout();
3056  // return back to regularly scheduled programming
3057  this.unstamp( item.element );
3058  this.sortItemsByPosition();
3059  item.disablePlacing();
3060};
3061
3062/**
3063 * emit event when item is fit and other items are laid out
3064 * @param {Packery.Item} item
3065 * @private
3066 */
3067proto._bindFitEvents = function( item ) {
3068  var _this = this;
3069  var ticks = 0;
3070  function onLayout() {
3071    ticks++;
3072    if ( ticks != 2 ) {
3073      return;
3074    }
3075    _this.dispatchEvent( 'fitComplete', null, [ item ] );
3076  }
3077  // when item is laid out
3078  item.once( 'layout', onLayout );
3079  // when all items are laid out
3080  this.once( 'layoutComplete', onLayout );
3081};
3082
3083// -------------------------- resize -------------------------- //
3084
3085// debounced, layout on resize
3086proto.resize = function() {
3087  // don't trigger if size did not change
3088  // or if resize was unbound. See #285, outlayer#9
3089  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
3090    return;
3091  }
3092
3093  if ( this.options.shiftPercentResize ) {
3094    this.resizeShiftPercentLayout();
3095  } else {
3096    this.layout();
3097  }
3098};
3099
3100/**
3101 * check if layout is needed post layout
3102 * @returns Boolean
3103 */
3104proto.needsResizeLayout = function() {
3105  var size = getSize( this.element );
3106  var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth';
3107  return size[ innerSize ] != this.size[ innerSize ];
3108};
3109
3110proto.resizeShiftPercentLayout = function() {
3111  var items = this._getItemsForLayout( this.items );
3112
3113  var isHorizontal = this._getOption('horizontal');
3114  var coord = isHorizontal ? 'y' : 'x';
3115  var measure = isHorizontal ? 'height' : 'width';
3116  var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
3117  var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth';
3118
3119  // proportional re-align items
3120  var previousSegment = this[ segmentName ];
3121  previousSegment = previousSegment && previousSegment + this.gutter;
3122
3123  if ( previousSegment ) {
3124    this._getMeasurements();
3125    var currentSegment = this[ segmentName ] + this.gutter;
3126    items.forEach( function( item ) {
3127      var seg = Math.round( item.rect[ coord ] / previousSegment );
3128      item.rect[ coord ] = seg * currentSegment;
3129    });
3130  } else {
3131    var currentSize = getSize( this.element )[ innerSize ] + this.gutter;
3132    var previousSize = this.packer[ measure ];
3133    items.forEach( function( item ) {
3134      item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize;
3135    });
3136  }
3137
3138  this.shiftLayout();
3139};
3140
3141// -------------------------- drag -------------------------- //
3142
3143/**
3144 * handle an item drag start event
3145 * @param {Element} elem
3146 */
3147proto.itemDragStart = function( elem ) {
3148  if ( !this.isEnabled ) {
3149    return;
3150  }
3151  this.stamp( elem );
3152  // this.ignore( elem );
3153  var item = this.getItem( elem );
3154  if ( !item ) {
3155    return;
3156  }
3157
3158  item.enablePlacing();
3159  item.showDropPlaceholder();
3160  this.dragItemCount++;
3161  this.updateShiftTargets( item );
3162};
3163
3164proto.updateShiftTargets = function( dropItem ) {
3165  this.shiftPacker.reset();
3166
3167  // pack stamps
3168  this._getBoundingRect();
3169  var isOriginLeft = this._getOption('originLeft');
3170  var isOriginTop = this._getOption('originTop');
3171  this.stamps.forEach( function( stamp ) {
3172    // ignore dragged item
3173    var item = this.getItem( stamp );
3174    if ( item && item.isPlacing ) {
3175      return;
3176    }
3177    var offset = this._getElementOffset( stamp );
3178    var rect = new Rect({
3179      x: isOriginLeft ? offset.left : offset.right,
3180      y: isOriginTop ? offset.top : offset.bottom
3181    });
3182    this._setRectSize( stamp, rect );
3183    // save its space in the packer
3184    this.shiftPacker.placed( rect );
3185  }, this );
3186
3187  // reset shiftTargets
3188  var isHorizontal = this._getOption('horizontal');
3189  var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
3190  var measure = isHorizontal ? 'height' : 'width';
3191
3192  this.shiftTargetKeys = [];
3193  this.shiftTargets = [];
3194  var boundsSize;
3195  var segment = this[ segmentName ];
3196  segment = segment && segment + this.gutter;
3197
3198  if ( segment ) {
3199    var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment );
3200    var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment );
3201    boundsSize = ( segs - segmentSpan ) * segment;
3202    // add targets on top
3203    for ( var i=0; i < segs; i++ ) {
3204      
3204var initialX = isHorizontal ? 0 : i * segment;
3205      var initialY = isHorizontal ? i * segment : 0;
3206      this._addShiftTarget( initialX, initialY
vendor: 5,509 bytes, lines 3206-3410
3206, boundsSize );
3207    }
3208  } else {
3209    boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ];
3210    this._addShiftTarget( 0, 0, boundsSize );
3211  }
3212
3213  // pack each item to measure where shiftTargets are
3214  var items = this._getItemsForLayout( this.items );
3215  var packMethod = this._getPackMethod();
3216  items.forEach( function( item ) {
3217    var rect = item.rect;
3218    this._setRectSize( item.element, rect );
3219    this.shiftPacker[ packMethod ]( rect );
3220
3221    // add top left corner
3222    this._addShiftTarget( rect.x, rect.y, boundsSize );
3223    // add bottom left / top right corner
3224    var cornerX = isHorizontal ? rect.x + rect.width : rect.x;
3225    var cornerY = isHorizontal ? rect.y : rect.y + rect.height;
3226    this._addShiftTarget( cornerX, cornerY, boundsSize );
3227
3228    if ( segment ) {
3229      // add targets for each column on bottom / row on right
3230      var segSpan = Math.round( rect[ measure ] / segment );
3231      for ( var i=1; i < segSpan; i++ ) {
3232        var segX = isHorizontal ? cornerX : rect.x + segment * i;
3233        var segY = isHorizontal ? rect.y + segment * i : cornerY;
3234        this._addShiftTarget( segX, segY, boundsSize );
3235      }
3236    }
3237  }, this );
3238
3239};
3240
3241proto._addShiftTarget = function( x, y, boundsSize ) {
3242  var checkCoord = this._getOption('horizontal') ? y : x;
3243  if ( checkCoord !== 0 && checkCoord > boundsSize ) {
3244    return;
3245  }
3246  // create string for a key, easier to keep track of what targets
3247  var key = x + ',' + y;
3248  var hasKey = this.shiftTargetKeys.indexOf( key ) != -1;
3249  if ( hasKey ) {
3250    return;
3251  }
3252  this.shiftTargetKeys.push( key );
3253  this.shiftTargets.push({ x: x, y: y });
3254};
3255
3256// -------------------------- drop -------------------------- //
3257
3258proto.shift = function( item, x, y ) {
3259  var shiftPosition;
3260  var minDistance = Infinity;
3261  var position = { x: x, y: y };
3262  this.shiftTargets.forEach( function( target ) {
3263    var distance = getDistance( target, position );
3264    if ( distance < minDistance ) {
3265      shiftPosition = target;
3266      minDistance = distance;
3267    }
3268  });
3269  item.rect.x = shiftPosition.x;
3270  item.rect.y = shiftPosition.y;
3271};
3272
3273function getDistance( a, b ) {
3274  var dx = b.x - a.x;
3275  var dy = b.y - a.y;
3276  return Math.sqrt( dx * dx + dy * dy );
3277}
3278
3279// -------------------------- drag move -------------------------- //
3280
3281var DRAG_THROTTLE_TIME = 120;
3282
3283/**
3284 * handle an item drag move event
3285 * @param {Element} elem
3286 * @param {Number} x - horizontal change in position
3287 * @param {Number} y - vertical change in position
3288 */
3289proto.itemDragMove = function( elem, x, y ) {
3290  var item = this.isEnabled && this.getItem( elem );
3291  if ( !item ) {
3292    return;
3293  }
3294
3295  x -= this.size.paddingLeft;
3296  y -= this.size.paddingTop;
3297
3298  var _this = this;
3299  function onDrag() {
3300    _this.shift( item, x, y );
3301    item.positionDropPlaceholder();
3302    _this.layout();
3303  }
3304
3305  // throttle
3306  var now = new Date();
3307  if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) {
3308    clearTimeout( this.dragTimeout );
3309    this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME );
3310  } else {
3311    onDrag();
3312    this._itemDragTime = now;
3313  }
3314};
3315
3316// -------------------------- drag end -------------------------- //
3317
3318/**
3319 * handle an item drag end event
3320 * @param {Element} elem
3321 */
3322proto.itemDragEnd = function( elem ) {
3323  var item = this.isEnabled && this.getItem( elem );
3324  if ( !item ) {
3325    return;
3326  }
3327
3328  clearTimeout( this.dragTimeout );
3329  item.element.classList.add('is-positioning-post-drag');
3330
3331  var completeCount = 0;
3332  var _this = this;
3333  function onDragEndLayoutComplete() {
3334    completeCount++;
3335    if ( completeCount != 2 ) {
3336      return;
3337    }
3338    // reset drag item
3339    item.element.classList.remove('is-positioning-post-drag');
3340    item.hideDropPlaceholder();
3341    _this.dispatchEvent( 'dragItemPositioned', null, [ item ] );
3342  }
3343
3344  item.once( 'layout', onDragEndLayoutComplete );
3345  this.once( 'layoutComplete', onDragEndLayoutComplete );
3346  item.moveTo( item.rect.x, item.rect.y );
3347  this.layout();
3348  this.dragItemCount = Math.max( 0, this.dragItemCount - 1 );
3349  this.sortItemsByPosition();
3350  item.disablePlacing();
3351  this.unstamp( item.element );
3352};
3353
3354/**
3355 * binds Draggabilly events
3356 * @param {Draggabilly} draggie
3357 */
3358proto.bindDraggabillyEvents = function( draggie ) {
3359  this._bindDraggabillyEvents( draggie, 'on' );
3360};
3361
3362proto.unbindDraggabillyEvents = function( draggie ) {
3363  this._bindDraggabillyEvents( draggie, 'off' );
3364};
3365
3366proto._bindDraggabillyEvents = function( draggie, method ) {
3367  var handlers = this.handleDraggabilly;
3368  draggie[ method ]( 'dragStart', handlers.dragStart );
3369  draggie[ method ]( 'dragMove', handlers.dragMove );
3370  draggie[ method ]( 'dragEnd', handlers.dragEnd );
3371};
3372
3373/**
3374 * binds jQuery UI Draggable events
3375 * @param {jQuery} $elems
3376 */
3377proto.bindUIDraggableEvents = function( $elems ) {
3378  this._bindUIDraggableEvents( $elems, 'on' );
3379};
3380
3381proto.unbindUIDraggableEvents = function( $elems ) {
3382  this._bindUIDraggableEvents( $elems, 'off' );
3383};
3384
3385proto._bindUIDraggableEvents = function( $elems, method ) {
3386  var handlers = this.handleUIDraggable;
3387  $elems
3388    [ method ]( 'dragstart', handlers.start )
3389    [ method ]( 'drag', handlers.drag )
3390    [ method ]( 'dragstop', handlers.stop );
3391};
3392
3393// ----- destroy ----- //
3394
3395var _destroy = proto.destroy;
3396proto.destroy = function() {
3397  _destroy.apply( this, arguments );
3398  // disable flag; prevent drag events from triggering. #72
3399  this.isEnabled = false;
3400};
3401
3402// -----  ----- //
3403
3404Packery.Rect = Rect;
3405Packery.Packer = Packer;
3406
3407return Packery;
3408
3409}));
3410

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.