(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors * Released under MIT license * Based on Underscore.js 1.8.3 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** Used as references for various `Number` constants. */ var NAN = 0 / 0; /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString = objectProto.toString; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min; /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = function() { return root.Date.now(); }; /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time; // Start the timer for the trailing edge. timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result = wait - timeSinceLastCall; return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } // Restart the timer. timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { // Handle invocations in a tight loop. timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return !!value && typeof value == 'object'; } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && objectToString.call(value) == symbolTag); } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } module.exports = debounce; }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],2:[function(require,module,exports){ var util = require('./util.js'), targetWidths = require('./targetWidths.js'), autoSize = require('./autoSize'); var ImgixTag = (function () { function ImgixTag(el, opts) { this.el = el; this.settings = opts || {}; if (!this.el) { console.warn('ImgixTag must be passed a DOM element.'); return; } this.window = this.settings.window ? this.settings.window : null; if (this.el.hasAttribute('ix-initialized') && !this.settings.force) { return; } this.ixPathVal = el.getAttribute(this.settings.pathInputAttribute); this.ixParamsVal = el.getAttribute(this.settings.paramsInputAttribute); this.ixSrcVal = el.getAttribute(this.settings.srcInputAttribute); this.ixHostVal = el.getAttribute(this.settings.hostInputAttribute) || this.settings.host; if (this.ixPathVal && !this.ixHostVal) { console.warn( 'You must set a value for `imgix.config.host` or specify an `ix-host` attribute to use `ix-path` and `ix-params`.' ); return; } if (typeof this.ixPathVal === 'string' && this.ixPathVal.length == 0) { console.warn('`ix-path` cannot accept a value of empty string ""'); return; } if (typeof this.ixSrcVal === 'string' && this.ixSrcVal.length == 0) { console.warn('`ix-src` cannot accept a value of empty string ""'); return; } this.baseParams = this._extractBaseParams(); this.baseUrl = this._buildBaseUrl(); this.baseUrlWithoutQuery = this.baseUrl.split('?')[0]; //manual override to use sizes, srcset, and src when lazyloading if(util.isString(this.el.className)){ if (this.el.className.includes("nolazyload")){ this.settings.sizesAttribute = "sizes"; this.settings.srcsetAttribute = "srcset"; this.settings.srcAttribute = "src"; } } if (util.isString(this.settings.sizesAttribute)) { this.el.setAttribute(this.settings.sizesAttribute, this.sizes()); } if (util.isString(this.settings.srcsetAttribute)) { this.el.setAttribute(this.settings.srcsetAttribute, this.srcset()); } if ( util.isString(this.settings.srcAttribute) && this.el.nodeName == 'IMG' ) { this.el.setAttribute(this.settings.srcAttribute, this.src()); } this.el.setAttribute('ix-initialized', 'ix-initialized'); } ImgixTag.prototype._extractBaseParams = function () { var params = {}; if ( this.settings.defaultParams && typeof this.settings.defaultParams === 'object' && this.settings.defaultParams !== null ) { params = Object.assign({}, this.settings.defaultParams); } if (this.ixPathVal) { params = Object.assign({}, params, JSON.parse(this.ixParamsVal) || {}); // Encode any passed Base64 variant params for (var key in params) { if (key.substr(-2) === '64') { params[key] = util.encode64(params[key]); } } } else { // If the user used `ix-src`, we have to extract the base params // from that string URL. var lastQuestion = this.ixSrcVal.lastIndexOf('?'); if (lastQuestion > -1) { var paramString = this.ixSrcVal.substr(lastQuestion + 1), splitParams = paramString.split('&'); for (var i = 0, splitParam; i < splitParams.length; i++) { splitParam = splitParams[i].split('='); params[splitParam[0]] = splitParam[1]; } } } if (this.settings.includeLibraryParam) { params.ixlib = 'imgixjs-' + imgix.VERSION; } return params; }; ImgixTag.prototype._buildBaseUrl = function () { if (this.ixSrcVal) { return this.ixSrcVal; } var path = this.ixPathVal, protocol = this.settings.useHttps ? 'https' : 'http', url = protocol + '://' + this.ixHostVal, hostEndsWithSlash = this.ixHostVal.substr(-1) === '/', pathStartsWithSlash = path[0] === '/'; // Make sure we don't end up with 2 or 0 slashes between // the host and path portions of the generated URL if (hostEndsWithSlash && pathStartsWithSlash) { url += path.substr(1); } else if (!hostEndsWithSlash && !pathStartsWithSlash) { url += '/' + path; } else { url += path; } url += '?'; var params = [], param; for (var key in this.baseParams) { param = this.baseParams[key]; if (param == null) { continue; } params.push(encodeURIComponent(key) + '=' + encodeURIComponent(param)); } url += params.join('&'); return url; }; ImgixTag.prototype._buildSrcsetPair = function (targetWidth) { var clonedParams = util.shallowClone(this.baseParams); clonedParams.w = targetWidth; var url = this.baseUrlWithoutQuery + '?', val, params = []; for (var key in clonedParams) { val = clonedParams[key]; params.push(key + '=' + val); } url += params.join('&'); return url + ' ' + targetWidth + 'w'; }; ImgixTag.prototype.src = function () { return this.baseUrl; }; // Returns a comma-separated list of `url widthDescriptor` pairs, // scaled appropriately to the same aspect ratio as the base image // as appropriate. ImgixTag.prototype.srcset = function () { var pairs = []; for (var i = 0; i < targetWidths.length; i++) { pairs.push(this._buildSrcsetPair(targetWidths[i])); } return pairs.join(', '); }; ImgixTag.prototype.sizes = function () { var existingSizes = this.el.getAttribute('sizes'); var ixSizes = this.el.getAttribute('ix-sizes'); const el = this.el; const _window = this.window; /** * * The conditionals bellow decide when to override the value for `sizes` for * the given element. * * - If `sizes` set, we leave the value as is even if `ix-sizes` is `auto` * - If `sizes` not set and `ix-sizes` not auto, set `sizes` to `ix-sizes` * - If `sizes` not set and `ix-sizes` is auto, set `sizes` automatically * - If `sizes` and `ix-sizes` not set, set `sizes` to browser default */ if (existingSizes == null && ixSizes !== 'auto') { return ixSizes ? ixSizes : '100vw'; } else if (existingSizes == null && ixSizes === 'auto') { return autoSize.updateOnResize({ el, existingSizes, ixSizes, _window }); } else { return existingSizes ? existingSizes : '100vw'; } }; return ImgixTag; })(); module.exports = ImgixTag; },{"./autoSize":3,"./targetWidths.js":6,"./util.js":7}],3:[function(require,module,exports){ const util = require('./util'); const WIDTH_MIN_SIZE = 40; const DEBOUNCE_TIMEOUT = 200; /** * Function that returns an element width that's equal to or greater than * WIDTH_MIN_SIZE. * * If the element width is less than the minimum, it will recursively * look for first parent element with width greater than WIDTH_MIN_SIZE. * * As a fallback, if the resulting width is still less than minimum, width * is set to WIDTH_MIN_SIZE. * * We do this to avoid failing to resize when window expands and avoid * setting sizes to 0 when el.offsetWidth == 0. */ const getWidth = function ({ parent, width }) { if (width < WIDTH_MIN_SIZE) { width = WIDTH_MIN_SIZE; // TODO: add check and test for parent == null let parentWidth = parent.offsetWidth; let parentNode = parent.parentNode; // get the fist parent that has a size over the minimum while (parentNode && parentWidth < width) { parentWidth = parentNode.offsetWidth; // set for next loop parentNode = parentNode.parentNode; } if (parentWidth > width) { width = parentWidth; } } return width; }; // Based off of: https://stackoverflow.com/questions/1977871/check-if-an-image-is-loaded-no-errors-with-jquery // Determines if the `img` element was rendered on the page const imageLoaded = ({ el }) => { // During the onload event, browser identifies any images that // weren’t downloaded as not complete. Some Gecko-based browsers // report this incorrectly. More here: https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-complete if (!el.complete) { console.warn( 'Imgix.js: attempted to set sizes attribute on element with complete evaluating to false' ); return false; } // naturalWidth and naturalHeight give the intrinsic (natural), // density-corrected size of the image. If img failed to load, // both of these will be zero. More here: https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-naturalheight if (el.naturalWidth === 0) { console.warn( 'Imgix.js: attempted to set sizes attribute on element with no naturalWidth' ); return false; } // Otherwise, assume it’s ok. return true; }; // Returns true if img has sizes attr and the img has loaded. const imgCanBeSized = ({ el, existingSizes, ixSizes, elHasAttributes }) => { if (!existingSizes && !ixSizes) { console.warn( 'Imgix.js: attempted to set sizes attribute on element without existing sizes attribute value' ); return false; } if (!elHasAttributes) { console.warn( 'Imgix.js: attempted to set sizes attribute on element with no attributes' ); return false; } return imageLoaded({ el }); }; const getCurrentSize = ({ el, existingSizes, ixSizes, elHasAttributes, _window, }) => { // TODO: instead of sizes="557px" do sizes="(max-width: currentBrowserWidth + 100) 557px, 100vw" // browserWidth = 1000px, image width = 500px // sizes="(max-width: currentBrowserWidth + 100) 557px, (imageWidth / browserWidth * 100)vw" --> 50vw // If image loaded calc size, otherwise leave as existing let currentSize = imgCanBeSized({ el, existingSizes, ixSizes, elHasAttributes, _window, }) ? getWidth({ el, parent: el.parentNode, width: el.offsetWidth, }) + 'px' : existingSizes; return currentSize; }; const resizeElement = ({ el, existingSizes, ixSizes, _window, elHasAttributes, }) => { // Run our resize function callback that calcs current size // and updates the elements `sizes` to match. const currentSize = getCurrentSize({ el, existingSizes, ixSizes, elHasAttributes, _window, }); // Only update element attributes if changed if (currentSize !== existingSizes) { _window.requestAnimationFrame(() => { el.setAttribute('sizes', currentSize); }); } }; // Function that makes throttled rAF calls to avoid multiple calls in the same frame const updateOnResize = ({ el, existingSizes, ixSizes, _window }) => { // debounce fn const elHasAttributes = el.hasAttributes(); const requestIdleCallback = util.rICShim(_window); const runDebounce = util.debounce(() => { requestIdleCallback(() => resizeElement({ el, existingSizes, ixSizes, _window, elHasAttributes }) ); }, DEBOUNCE_TIMEOUT); // Listen for resize _window.addEventListener('resize', runDebounce, false); // Return the current size return ( getWidth({ el, parent: el.parentNode, width: el.offsetWidth, }) + 'px' ); }; const autoSize = { getElementWidth: getWidth, imgCanBeSized, updateOnResize, }; module.exports = autoSize; },{"./util":7}],4:[function(require,module,exports){ module.exports = { // URL assembly host: null, useHttps: true, includeLibraryParam: true, defaultParams: {}, // Output element attributes srcAttribute: 'src', srcsetAttribute: 'srcset', sizesAttribute: 'sizes', // Input element attributes srcInputAttribute: 'ix-src', pathInputAttribute: 'ix-path', paramsInputAttribute: 'ix-params', hostInputAttribute: 'ix-host', window: typeof window !== 'undefined' ? window : null, }; },{}],5:[function(require,module,exports){ (function (global){(function (){ var ImgixTag = require('./ImgixTag.js'), util = require('./util.js'), defaultConfig = require('./defaultConfig'); var VERSION = '4.0.0'; global.imgix = { init: function (opts) { var settings = util.shallowClone(this.config); util.extend(settings, opts || {}); var elementQuery = [ 'img[' + settings.srcInputAttribute + ']', 'source[' + settings.srcInputAttribute + ']', 'img[' + settings.pathInputAttribute + ']', 'source[' + settings.pathInputAttribute + ']', ].join(','); var allImgandSourceTags = document.querySelectorAll(elementQuery); for (var i = 0, el; i < allImgandSourceTags.length; i++) { new ImgixTag(allImgandSourceTags[i], settings); } }, config: defaultConfig, VERSION: VERSION, }; util.domReady(function () { util.objectEach(defaultConfig, function (defaultValue, key) { var metaTagValue = util.getMetaTagValue(key); if (typeof metaTagValue !== 'undefined') { var defaultConfigType = typeof defaultConfig[key]; // Only allow boolean values for boolean configs if (defaultConfigType === 'boolean') { global.imgix.config[key] = !!metaTagValue; } else if (defaultConfigType === 'object' && defaultConfig[key] != null) { global.imgix.config[key] = JSON.parse(metaTagValue) || {}; } else { global.imgix.config[key] = metaTagValue; } } }); if (util.getMetaTagValue('autoInit') !== false) { global.imgix.init(); } }); }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./ImgixTag.js":2,"./defaultConfig":4,"./util.js":7}],6:[function(require,module,exports){ function targetWidths() { var resolutions = []; var prev = 100; var INCREMENT_PERCENTAGE = 8; var MAX_SIZE = 8192; function ensureEven(n) { return 2 * Math.round(n / 2); } while (prev <= MAX_SIZE) { resolutions.push(ensureEven(prev)); prev *= 1 + (INCREMENT_PERCENTAGE / 100) * 2; } return resolutions; } module.exports = targetWidths(); },{}],7:[function(require,module,exports){ const _debounce = require('lodash.debounce'); module.exports = { compact: function (arr) { var compactedArr = []; for (var i = 0; i < arr.length; i++) { arr[i] && compactedArr.push(arr[i]); } return compactedArr; }, shallowClone: function (obj) { var clone = {}; for (var key in obj) { clone[key] = obj[key]; } return clone; }, extend: function (dest, source) { for (var key in source) { dest[key] = source[key]; } return dest; }, uniq: function (arr) { var n = {}, r = [], i; for (i = 0; i < arr.length; i++) { if (!n[arr[i]]) { n[arr[i]] = true; r.push(arr[i]); } } return r; }, objectEach: function (obj, iterator) { for (var key in obj) { if (obj.hasOwnProperty(key)) { iterator(obj[key], key); } } }, isString: function (value) { return typeof value === 'string'; }, encode64: function (str) { var encodedUtf8Str = unescape(encodeURIComponent(str)), b64Str = btoa(encodedUtf8Str), urlSafeB64Str = b64Str.replace(/\+/g, '-'); urlSafeB64Str = urlSafeB64Str .replace(/\//g, '_') .replace(/\//g, '_') .replace(/\=+$/, ''); return urlSafeB64Str; }, decode64: function (urlSafeB64Str) { var b64Str = urlSafeB64Str.replace(/-/g, '+').replace(/_/g, '/'), encodedUtf8Str = atob(b64Str), str = decodeURIComponent(escape(encodedUtf8Str)); return str; }, domReady: function (cb) { if (document.readyState === 'complete') { setTimeout(cb, 0); } else if (document.addEventListener) { document.addEventListener('DOMContentLoaded', cb, false); } else { document.attachEvent('onreadystatechange', function () { if (document.readyState === 'complete') { cb(); } }); } }, getMetaTagValue: function (propertyName) { var metaTag = document.querySelector( 'meta[property="ix:' + propertyName + '"]' ), metaTagContent; if (!metaTag) { return; } metaTagContent = metaTag.getAttribute('content'); if (metaTagContent === 'true') { return true; } else if (metaTagContent === 'false') { return false; } else if (metaTagContent === '' || metaTagContent === 'null') { return null; } else { return metaTagContent; } }, debounce: _debounce, rICShim: function (_window) { // from: https://developers.google.com/web/updates/2015/08/using-requestidlecallback#checking_for_requestidlecallback return ( _window.requestIdleCallback || function (cb) { var start = Date.now(); return setTimeout(function () { cb({ didTimeout: false, timeRemaining: function () { return Math.max(0, 50 - (Date.now() - start)); }, }); }, 1); } ); }, }; },{"lodash.debounce":1}]},{},[5]);