text: /*!
   * imagesLoaded v3.0.2
   * JavaScript is all like "You images are done yet or what?"
   */
  
  (function(window) {
  
      'use strict';
  
      var $ = window.jQuery;
      var console = window.console;
      var hasConsole = typeof console !== 'undefined';
  
      // -------------------------- helpers -------------------------- //
  
      // extend objects
      function extend(a, b) {
          for (var prop in b) {
              a[prop] = b[prop];
          }
          return a;
      }
  
      var objToString = Object.prototype.toString;
  
      function isArray(obj) {
          return objToString.call(obj) === '[object Array]';
      }
  
      // turn element or nodeList into an array
      function makeArray(obj) {
          var ary = [];
          if (isArray(obj)) {
              // use object if already an array
              ary = obj;
          } else if (typeof obj.length === 'number') {
              // convert nodeList to array
              for (var i = 0, len = obj.length; i < len; i++) {
                  ary.push(obj[i]);
              }
          } else {
              // array of single index
              ary.push(obj);
          }
          return ary;
      }
  
      // --------------------------  -------------------------- //
  
      function defineImagesLoaded(EventEmitter, eventie) {
  
          /**
           * @param {Array, Element, NodeList, String} elem
           * @param {Object or Function} options - if function, use as callback
           * @param {Function} onAlways - callback function
           */
          function ImagesLoaded(elem, options, onAlways) {
              // coerce ImagesLoaded() without new, to be new ImagesLoaded()
              if (!(this instanceof ImagesLoaded)) {
                  return new ImagesLoaded(elem, options);
              }
              // use elem as selector string
              if (typeof elem === 'string') {
                  elem = document.querySelectorAll(elem);
              }
  
              this.elements = makeArray(elem);
              this.options = extend({}, this.options);
  
              if (typeof options === 'function') {
                  onAlways = options;
              } else {
                  extend(this.options, options);
              }
  
              if (onAlways) {
                  this.on('always', onAlways);
              }
  
              this.getImages();
  
              if ($) {
                  // add jQuery Deferred object
                  this.jqDeferred = new $.Deferred();
              }
  
              // HACK check async to allow time to bind listeners
              var _this = this;
              setTimeout(function() {
                  _this.check();
              });
          }
  
          ImagesLoaded.prototype = new EventEmitter();
  
          ImagesLoaded.prototype.options = {};
  
          ImagesLoaded.prototype.getImages = function() {
              this.images = [];
  
              // filter & find items if we have an item selector
              for (var i = 0, len = this.elements.length; i < len; i++) {
                  var elem = this.elements[i];
                  // filter siblings
                  if (elem.nodeName === 'IMG') {
                      this.addImage(elem);
                  }
                  // find children
                  var childElems = elem.querySelectorAll('img');
                  // concat childElems to filterFound array
                  for (var j = 0, jLen = childElems.length; j < jLen; j++) {
                      var img = childElems[j];
                      this.addImage(img);
                  }
              }
          };
  
          /**
           * @param {Image} img
           */
          ImagesLoaded.prototype.addImage = function(img) {
              var loadingImage = new LoadingImage(img);
              this.images.push(loadingImage);
          };
  
          ImagesLoaded.prototype.check = function() {
              var _this = this;
              var checkedCount = 0;
              var length = this.images.length;
              this.hasAnyBroken = false;
              // complete if no images
              if (!length) {
                  this.complete();
                  return;
              }
  
              function onConfirm(image, message) {
                  if (_this.options.debug && hasConsole) {
                      console.log('confirm', image, message);
                  }
  
                  _this.progress(image);
                  checkedCount++;
                  if (checkedCount === length) {
                      _this.complete();
                  }
                  return true; // bind once
              }
  
              for (var i = 0; i < length; i++) {
                  var loadingImage = this.images[i];
                  loadingImage.on('confirm', onConfirm);
                  loadingImage.check();
              }
          };
  
          ImagesLoaded.prototype.progress = function(image) {
              this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
              this.emit('progress', this, image);
              if (this.jqDeferred) {
                  this.jqDeferred.notify(this, image);
              }
          };
  
          ImagesLoaded.prototype.complete = function() {
              var eventName = this.hasAnyBroken ? 'fail' : 'done';
              this.isComplete = true;
              this.emit(eventName, this);
              this.emit('always', this);
              if (this.jqDeferred) {
                  var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
                  this.jqDeferred[jqMethod](this);
              }
          };
  
          // -------------------------- jquery -------------------------- //
  
          if ($) {
              $.fn.imagesLoaded = function(options, callback) {
                  var instance = new ImagesLoaded(this, options, callback);
                  return instance.jqDeferred.promise($(this));
              };
          }
  
  
          // --------------------------  -------------------------- //
  
          var cache = {};
  
          function LoadingImage(img) {
              this.img = img;
          }
  
          LoadingImage.prototype = new EventEmitter();
  
          LoadingImage.prototype.check = function() {
              // first check cached any previous images that have same src
              var cached = cache[this.img.src];
              if (cached) {
                  this.useCached(cached);
                  return;
              }
              // add this to cache
              cache[this.img.src] = this;
  
              // If complete is true and browser supports natural sizes,
              // try to check for image status manually.
              if (this.img.complete && this.img.naturalWidth !== undefined) {
                  // report based on naturalWidth
                  this.confirm(this.img.naturalWidth !== 0, 'naturalWidth');
                  return;
              }
  
              // If none of the checks above matched, simulate loading on detached element.
              var proxyImage = this.proxyImage = new Image();
              eventie.bind(proxyImage, 'load', this);
              eventie.bind(proxyImage, 'error', this);
              proxyImage.src = this.img.src;
          };
  
          LoadingImage.prototype.useCached = function(cached) {
              if (cached.isConfirmed) {
                  this.confirm(cached.isLoaded, 'cached was confirmed');
              } else {
                  var _this = this;
                  cached.on('confirm', function(image) {
                      _this.confirm(image.isLoaded, 'cache emitted confirmed');
                      return true; // bind once
                  });
              }
          };
  
          LoadingImage.prototype.confirm = function(isLoaded, message) {
              this.isConfirmed = true;
              this.isLoaded = isLoaded;
              this.emit('confirm', this, message);
          };
  
          // trigger specified handler for event type
          LoadingImage.prototype.handleEvent = function(event) {
              var method = 'on' + event.type;
              if (this[method]) {
                  this[method](event);
              }
          };
  
          LoadingImage.prototype.onload = function() {
              this.confirm(true, 'onload');
              this.unbindProxyEvents();
          };
  
          LoadingImage.prototype.onerror = function() {
              this.confirm(false, 'onerror');
              this.unbindProxyEvents();
          };
  
          LoadingImage.prototype.unbindProxyEvents = function() {
              eventie.unbind(this.proxyImage, 'load', this);
              eventie.unbind(this.proxyImage, 'error', this);
          };
  
          // -----  ----- //
  
          return ImagesLoaded;
      }
  
      // -------------------------- transport -------------------------- //
  
      if (typeof define === 'function' && define.amd) {
          // AMD
          define([
                  'eventEmitter',
                  'eventie'
              ],
              defineImagesLoaded);
      } else {
          // browser global
          window.imagesLoaded = defineImagesLoaded(
              window.EventEmitter,
              window.eventie
          );
      }
  
  })(window);