text: // Production steps of ECMA-262, Edition 6, 22.1.2.1
  if (!Array.from) {
    Array.from = (function () {
      var toStr = Object.prototype.toString;
      var isCallable = function (fn) {
        return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
      };
      var toInteger = function (value) {
        var number = Number(value);
        if (isNaN(number)) { return 0; }
        if (number === 0 || !isFinite(number)) { return number; }
        return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
      };
      var maxSafeInteger = Math.pow(2, 53) - 1;
      var toLength = function (value) {
        var len = toInteger(value);
        return Math.min(Math.max(len, 0), maxSafeInteger);
      };
  
      return function from(arrayLike/*, mapFn, thisArg */) {
        var C = this;
        var items = Object(arrayLike);
  
        if (arrayLike == null) {
          throw new TypeError('Array.from requires an array-like object - not null or undefined');
        }
  
        var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
        var T;
        if (typeof mapFn !== 'undefined') {
          if (!isCallable(mapFn)) {
            throw new TypeError('Array.from: when provided, the second argument must be a function');
          }
  
          if (arguments.length > 2) {
            T = arguments[2];
          }
        }
  
        var len = toLength(items.length);
        var A = isCallable(C) ? Object(new C(len)) : new Array(len);
        var k = 0;
        var kValue;
        while (k < len) {
          kValue = items[k];
          if (mapFn) {
            A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
          } else {
            A[k] = kValue;
          }
          k += 1;
        }
        A.length = len;
        return A;
      };
    }());
  }
  // Production steps of ECMA-262, Edition 5, 15.4.4.18
  // Reference: http://es5.github.io/#x15.4.4.18
  if (!Array.prototype.forEach) {
  
    Array.prototype.forEach = function(callback/*, thisArg*/) {
  
      var T, k;
  
      if (this == null) {
        throw new TypeError('this is null or not defined');
      }
  
      var O = Object(this);
      var len = O.length >>> 0;
      if (typeof callback !== 'function') {
        throw new TypeError(callback + ' is not a function');
      }
  
      if (arguments.length > 1) {
        T = arguments[1];
      }
  
      k = 0;
  
      while (k < len) {
  
        var kValue;
  
        if (k in O) {
          kValue = O[k];
          callback.call(T, kValue, k, O);
        }
        k++;
      }
    };
  }
  
  function createImageLoader(settings) {
    var loadImageByUrl = function(target) {
      target.addEventListener("load", function() {
        target.style.opacity = 1;
      });
      target.setAttribute("src", target.getAttribute("data-src"));
    };
  
    var imageList = Array.from(document.querySelectorAll('img[loader=ready]'));
    imageList.forEach(function(element, index) {
      element.style.opacity = 0;
      element.style.transition = "opacity 0.5s ease-in-out";
      loadImageByUrl(element);
    });
    var lazyloader = createLazyloader();
    lazyloader();
  
    function throttle(fn, delay, atleast) {
      var timeout   = null,
          startTime = new Date();
      return function() {
        var curTime = new Date();
        clearTimeout(timeout);
        if (curTime - startTime >= atleast) {
            fn();
            startTime = curTime;
        } else {
            timeout = setTimeout(fn, delay);
        }
      }
    }
    function getOffset(el) {
      var box = el.getBoundingClientRect();
      return {
        top: box.top + window.pageYOffset - document.documentElement.clientTop,
        left: box.left + window.pageXOffset - document.documentElement.clientLeft
      };
    }
    function createLazyloader() {
      var lazyImageList = Array.from(document.querySelectorAll('img[loader=lazy]'));
      lazyImageList.forEach(function(element, index) {
        element.style.opacity = 0;
        element.style.transition = "opacity 0.5s ease-in-out";
      });
  
      return function() {
        var seeHeight = window.innerHeight;
        var scrollTop =
          (document.documentElement && document.documentElement.scrollTop) ||
          (document.body && document.body.scrollTop);
  
        lazyImageList = lazyImageList.filter(function(element, index) {
          var offsetTop = getOffset(element).top
          var hasVisible = offsetTop < seeHeight + scrollTop;
          if (hasVisible) {
            loadImageByUrl(element);
          }
  
          return !hasVisible;
        });
      }
    }
  
    if (window.addEventListener) {
      window.addEventListener('scroll', throttle(lazyloader, 500, 500), false);
    } else if (window.attachEvent) {
      window.attachEvent('onscroll', throttle(lazyloader, 500, 500));
    }
  }
  