PageSourceSearch

https://sirenia.no/wp-content/themes/twotone/assets/js/vendor/imagesloaded.js?ver=3.1.8

js sirenia.no collected 2026-10-02 12:25:54 UTC 26,344 bytes, 887 lines download raw bytes

1/*!
2 * imagesLoaded PACKAGED v3.1.8
3 * JavaScript is all like "You images are done yet or what?"
4 * MIT License
5 */
6
7/*!
8 * EventEmitter v4.2.6 - git.io/ee
9 * Oliver Caldwell
10 * MIT license
11 * @preserve
12 */
13
14( function () {
15
16	/**
17	 * Class for managing events.
18	 * Can be extended to provide event functionality in other classes.
19	 *
20	 * @class EventEmitter Manages event registering and emitting.
21	 */
22	function EventEmitter() {}
23
24	// Shortcuts to improve speed and size
25	var proto = EventEmitter.prototype;
26	var exports = this;
27	var originalGlobalValue = exports.EventEmitter;
28
29	/**
30	 * Finds the index of the listener for the event in it's storage array.
31	 *
32	 * @param {Function[]} listeners Array of listeners to search through.
33	 * @param {Function} listener Method to look for.
34	 * @return {Number} Index of the specified listener, -1 if not found
35	 * @api private
36	 */
37	function indexOfListener( listeners, listener ) {
38		var i = listeners.length;
39		while ( i-- ) {
40			if ( listeners[i].listener === listener ) {
41				return i;
42			}
43		}
44
45		return -1;
46	}
47
48	/**
49	 * Alias a method while keeping the context correct, to allow for overwriting of target method.
50	 *
51	 * @param {String} name The name of the target method.
52	 * @return {Function} The aliased method
53	 * @api private
54	 */
55	function alias( name ) {
56		return function aliasClosure() {
57			return this[ name ].apply( this, arguments );
58		};
59	}
60
61	/**
62	 * Returns the listener array for the specified event.
63	 * Will initialise the event object and listener arrays if required.
64	 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object c
vendor: 10,956 bytes, lines 64-357
64ontaining bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
65	 * Each property in the object response is an array of listener functions.
66	 *
67	 * @param {String|RegExp} evt Name of the event to return the listeners from.
68	 * @return {Function[]|Object} All listener functions for the event.
69	 */
70	proto.getListeners = function getListeners( evt ) {
71		var events = this._getEvents();
72		var response;
73		var key;
74
75		// Return a concatenated array of all matching events if
76		// the selector is a regular expression.
77		if ( typeof evt === 'object' ) {
78			response = {};
79			for ( key in events ) {
80				if ( events.hasOwnProperty( key ) && evt.test( key ) ) {
81					response[ key ] = events[ key ];
82				}
83			}
84		}
85		else {
86			response = events[ evt ] || ( events[ evt ] = [] );
87		}
88
89		return response;
90	};
91
92	/**
93	 * Takes a list of listener objects and flattens it into a list of listener functions.
94	 *
95	 * @param {Object[]} listeners Raw listener objects.
96	 * @return {Function[]} Just the listener functions.
97	 */
98	proto.flattenListeners = function flattenListeners( listeners ) {
99		var flatListeners = [];
100		var i;
101
102		for ( i = 0; i < listeners.length; i += 1 ) {
103			flatListeners.push( listeners[i].listener );
104		}
105
106		return flatListeners;
107	};
108
109	/**
110	 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
111	 *
112	 * @param {String|RegExp} evt Name of the event to return the listeners from.
113	 * @return {Object} All listener functions for an event in an object.
114	 */
115	proto.getListenersAsObject = function getListenersAsObject( evt ) {
116		var listeners = this.getListeners( evt );
117		var response;
118
119		if ( listeners instanceof Array ) {
120			response = {};
121			response[ evt ] = listeners;
122		}
123
124		return response || listeners;
125	};
126
127	/**
128	 * Adds a listener function to the specified event.
129	 * The listener will not be added if it is a duplicate.
130	 * If the listener returns true then it will be removed after it is called.
131	 * If you pass a regular expression as the event name then the listener will be added to all events that match it.
132	 *
133	 * @param {String|RegExp} evt Name of the event to attach the listener to.
134	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
135	 * @return {Object} Current instance of EventEmitter for chaining.
136	 */
137	proto.addListener = function addListener( evt, listener ) {
138		var listeners = this.getListenersAsObject( evt );
139		var listenerIsWrapped = typeof listener === 'object';
140		var key;
141
142		for ( key in listeners ) {
143			if ( listeners.hasOwnProperty( key ) && indexOfListener( listeners[ key ], listener ) === -1 ) {
144				listeners[ key ].push( listenerIsWrapped ? listener : {
145					listener: listener,
146					once: false
147				} );
148			}
149		}
150
151		return this;
152	};
153
154	/**
155	 * Alias of addListener
156	 */
157	proto.on = alias( 'addListener' );
158
159	/**
160	 * Semi-alias of addListener. It will add a listener that will be
161	 * automatically removed after it's first execution.
162	 *
163	 * @param {String|RegExp} evt Name of the event to attach the listener to.
164	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
165	 * @return {Object} Current instance of EventEmitter for chaining.
166	 */
167	proto.addOnceListener = function addOnceListener( evt, listener ) {
168		return this.addListener( evt, {
169			listener: listener,
170			once: true
171		} );
172	};
173
174	/**
175	 * Alias of addOnceListener.
176	 */
177	proto.once = alias( 'addOnceListener' );
178
179	/**
180	 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
181	 * You need to tell it what event names should be matched by a regex.
182	 *
183	 * @param {String} evt Name of the event to create.
184	 * @return {Object} Current instance of EventEmitter for chaining.
185	 */
186	proto.defineEvent = function defineEvent( evt ) {
187		this.getListeners( evt );
188		return this;
189	};
190
191	/**
192	 * Uses defineEvent to define multiple events.
193	 *
194	 * @param {String[]} evts An array of event names to define.
195	 * @return {Object} Current instance of EventEmitter for chaining.
196	 */
197	proto.defineEvents = function defineEvents( evts ) {
198		for ( var i = 0; i < evts.length; i += 1 ) {
199			this.defineEvent( evts[i] );
200		}
201		return this;
202	};
203
204	/**
205	 * Removes a listener function from the specified event.
206	 * When passed a regular expression as the event name, it will remove the listener from all events that match it.
207	 *
208	 * @param {String|RegExp} evt Name of the event to remove the listener from.
209	 * @param {Function} listener Method to remove from the event.
210	 * @return {Object} Current instance of EventEmitter for chaining.
211	 */
212	proto.removeListener = function removeListener( evt, listener ) {
213		var listeners = this.getListenersAsObject( evt );
214		var index;
215		var key;
216
217		for ( key in listeners ) {
218			if ( listeners.hasOwnProperty( key ) ) {
219				index = indexOfListener( listeners[ key ], listener );
220
221				if ( index !== -1 ) {
222					listeners[ key ].splice( index, 1 );
223				}
224			}
225		}
226
227		return this;
228	};
229
230	/**
231	 * Alias of removeListener
232	 */
233	proto.off = alias( 'removeListener' );
234
235	/**
236	 * Adds listeners in bulk using the manipulateListeners method.
237	 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
238	 * You can also pass it a regular expression to add the array of listeners to all events that match it.
239	 * Yeah, this function does quite a bit. That's probably a bad thing.
240	 *
241	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
242	 * @param {Function[]} [listeners] An optional array of listener functions to add.
243	 * @return {Object} Current instance of EventEmitter for chaining.
244	 */
245	proto.addListeners = function addListeners( evt, listeners ) {
246		// Pass through to manipulateListeners
247		return this.manipulateListeners( false, evt, listeners );
248	};
249
250	/**
251	 * Removes listeners in bulk using the manipulateListeners method.
252	 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
253	 * You can also pass it an event name and an array of listeners to be removed.
254	 * You can also pass it a regular expression to remove the listeners from all events that match it.
255	 *
256	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
257	 * @param {Function[]} [listeners] An optional array of listener functions to remove.
258	 * @return {Object} Current instance of EventEmitter for chaining.
259	 */
260	proto.removeListeners = function removeListeners( evt, listeners ) {
261		// Pass through to manipulateListeners
262		return this.manipulateListeners( true, evt, listeners );
263	};
264
265	/**
266	 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
267	 * The first argument will determine if the listeners are removed (true) or added (false).
268	 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
269	 * You can also pass it an event name and an array of listeners to be added/removed.
270	 * You can also pass it a regular expression to manipulate the listeners of all events that match it.
271	 *
272	 * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
273	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
274	 * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
275	 * @return {Object} Current instance of EventEmitter for chaining.
276	 */
277	proto.manipulateListeners = function manipulateListeners( remove, evt, listeners ) {
278		var i;
279		var value;
280		var single = remove ? this.removeListener : this.addListener;
281		var multiple = remove ? this.removeListeners : this.addListeners;
282
283		// If evt is an object then pass each of it's properties to this method
284		if ( typeof evt === 'object' && !( evt instanceof RegExp ) ) {
285			for ( i in evt ) {
286				if ( evt.hasOwnProperty(i) && ( value = evt[i] ) ) {
287					// Pass the single listener straight through to the singular method
288					if ( typeof value === 'function' ) {
289						single.call( this, i, value );
290					}
291					else {
292						// Otherwise pass back to the multiple function
293						multiple.call( this, i, value );
294					}
295				}
296			}
297		}
298		else {
299			// So evt must be a string
300			// And listeners must be an array of listeners
301			// Loop over it and pass each one to the multiple method
302			i = listeners.length;
303			while (i--) {
304				single.call( this, evt, listeners[i] );
305			}
306		}
307
308		return this;
309	};
310
311	/**
312	 * Removes all listeners from a specified event.
313	 * If you do not specify an event then all listeners will be removed.
314	 * That means every event will be emptied.
315	 * You can also pass a regex to remove all events that match it.
316	 *
317	 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
318	 * @return {Object} Current instance of EventEmitter for chaining.
319	 */
320	proto.removeEvent = function removeEvent( evt ) {
321		var type = typeof evt;
322		var events = this._getEvents();
323		var key;
324
325		// Remove different things depending on the state of evt
326		if ( type === 'string' ) {
327			// Remove all listeners for the specified event
328			delete events[ evt ];
329		}
330		else if ( type === 'object' ) {
331			// Remove all events matching the regex.
332			for ( key in events ) {
333				if ( events.hasOwnProperty( key ) && evt.test( key ) ) {
334					delete events[ key ];
335				}
336			}
337		}
338		else {
339			// Remove all listeners in all events
340			delete this._events;
341		}
342
343		return this;
344	};
345
346	/**
347	 * Alias of removeEvent.
348	 *
349	 * Added to mirror the node API.
350	 */
351	proto.removeAllListeners = alias( 'removeEvent' );
352
353	/**
354	 * Emits an event of your choice.
355	 * When emitted, every listener attached to that event will be executed.
356	 * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
357	 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
358	 * So they will not arrive within the array on the other side, they will be separate.
359	 * You can also pass a regular expression to emit to all events that match it.
360	 *
361	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
362	 * @param {Array} [args] Optional array of arguments to be passed to each listener.
363	 * @return {Object} Current instance of EventEmitter for chaining.
364	 */
365	proto.emitEvent = function emitEvent( evt, args ) {
366		var listeners = this.getListenersAsObject( evt );
367		var listener;
368		var i;
369		var key;
370		var response;
371
372		for ( key in listeners ) {
373			if ( listeners.hasOwnProperty( key ) ) {
374				i = listeners[ key ].length;
375
376				while (i--) {
377					// If the listener returns true then it shall be removed from the event
378					// The function is executed either with a basic call or an apply if there is an args array
379					listener = listeners[ key ][i];
380
381					if ( listener.once === true ) {
382						this.removeListener( evt, listener.listener );
383					}
384
385					response = listener.listener.apply( this, args || [] );
386
387					if ( response === this._getOnceReturnValue() ) {
388						this.removeListener( evt, listener.listener );
389					}
390				}
391			}
392		}
393
394		return this;
395	};
396
397	/**
398	 * Alias of emitEvent
399	 */
400	proto.trigger = alias( 'emitEvent' );
401
402	/**
403	 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
404	 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
405	 *
406	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
407	 * @param {...*} Optional additional arguments to be passed to each listener.
408	 * @return {Object} Current instance of EventEmitter for chaining.
409	 */
410	proto.emit = function emit( evt ) {
411		var args = Array.prototype.slice.call( arguments, 1 );
412		return this.emitEvent( evt, args );
413	};
414
415	/**
416	 * Sets the current value to check against when executing listeners. If a
417	 * listeners return value matches the one set here then it will be removed
418	 * after execution. This value defaults to true.
419	 *
420	 * @param {*} value The new value to check for when executing listeners.
421	 * @return {Object} Current instance of EventEmitter for chaining.
422	 */
423	proto.setOnceReturnValue = function setOnceReturnValue( value ) {
424		this._onceReturnValue = value;
425		return this;
426	};
427
428	/**
429	 * Fetches the current value to check against when executing listeners. If
430	 * the listeners return value matches this one then it should be removed
431	 * automatically. It will return true by default.
432	 *
433	 * @return {*|Boolean} The current value to check for or the default, true.
434	 * @api private
435	 */
436	proto._getOnceReturnValue = function _getOnceReturnValue() {
437		if ( this.hasOwnProperty( '_onceReturnValue' ) ) {
438			return this._onceReturnValue;
439		}
440		else {
441			return true;
442		}
443	};
444
445	/**
446	 * Fetches the events object and creates one if required.
447	 *
448	 * @return {Object} The events storage object.
449	 * @api private
450	 */
451	proto._getEvents = function _getEvents() {
452		return this._events || ( this._events = {} );
453	};
454
455	/**
456	 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
457	 *
458	 * @return {Function} Non conflicting EventEmitter class.
459	 */
460	EventEmitter.noConflict = function noConflict() {
461		exports.EventEmitter = originalGlobalValue;
462		return EventEmitter;
463	};
464
465	// Expose the class either via AMD, CommonJS or the global object
466	if ( typeof define === 'function' && define.amd ) {
467		define( 'eventEmitter/EventEmitter', [], function () {
468			return EventEmitter;
469		} );
470	}
471	else if ( typeof module === 'object' && module.exports ) {
472		module.exports = EventEmitter;
473	}
474	else {
475		this.EventEmitter = EventEmitter;
476	}
477}.call( this ) );
478
479/*!
480 * eventie v1.0.4
481 * event binding helper
482 *   eventie.bind( elem, 'click', myFn )
483 *   eventie.unbind( elem, 'click', myFn )
484 */
485
486/*jshint browser: true, undef: true, unused: true */
487/*global define: false */
488
489( function( window ) {
490
491	var docElem = document.documentElement;
492
493	var bind = function() {};
494
495	function getIEEvent( obj ) {
496		var event = window.event;
497		// add event.target
498		event.target = event.target || event.srcElement || obj;
499		return event;
500	}
501
502	if ( docElem.addEventListener ) {
503		bind = function( obj, type, fn ) {
504			obj.addEventListener( type, fn, false );
505		};
506	} else if ( docElem.attachEvent ) {
507		bind = function( obj, type, fn ) {
508			obj[ type + fn ] = fn.handleEvent ?
509			function() {
510				var event = getIEEvent( obj );
511				fn.handleEvent.call( fn, event );
512			} :
513			function() {
514				var event = getIEEvent( obj );
515				fn.call( obj, event );
516			};
517			obj.attachEvent( "on" + type, obj[ type + fn ] );
518		};
519	}
520
521	var unbind = function() {};
522
523	if ( docElem.removeEventListener ) {
524		unbind = function( obj, type, fn ) {
525			obj.removeEventListener( type, fn, false );
526		};
527	} else if ( docElem.detachEvent ) {
528		unbind = function( obj, type, fn ) {
529			obj.detachEvent( "on" + type, obj[ type + fn ] );
530			try {
531				delete obj[ type + fn ];
532			} catch ( err ) {
533				// can't delete window object properties
534				obj[ type + fn ] = undefined;
535			}
536		};
537	}
538
539	var eventie = {
540		bind: bind,
541		unbind: unbind
542	};
543
544	// transport
545	if ( typeof define === 'function' && define.amd ) {
546		// AMD
547		define( 'eventie/eventie',eventie );
548	} else {
549		// browser global
550		window.eventie = eventie;
551	}
552
553} )( this );
554
555/*!
556 * imagesLoaded v3.1.8
557 * JavaScript is all like "You images are done yet or what?"
558 * MIT License
559 */
560
561( function( window, factory ) {
562  // universal module definition
563
564	/*global define: false, module: false, require: false */
565
566	if ( typeof define === 'function' && define.amd ) {
567		// AMD
568		define( [
569		'eventEmitter/EventEmitter',
570		'eventie/eventie'
571		], function( EventEmitter, eventie ) {
572			return factory( window, EventEmitter, eventie );
573		});
574	} else if ( typeof exports === 'object' ) {
575		// CommonJS
576		module.exports = factory(
577			window,
578			require('wolfy87-eventemitter'),
579			require('eventie')
580		);
581	} else {
582		// browser global
583		window.imagesLoaded = factory(
584			window,
585			window.EventEmitter,
586			window.eventie
587		);
588	}
589
590})( window,
591
592	// --------------------------  factory -------------------------- //
593
594	function factory( window, EventEmitter, eventie ) {
595
596	var $ = window.jQuery;
597	var console = window.console;
598	var hasConsole = typeof console !== 'undefined';
599
600	// -------------------------- helpers -------------------------- //
601
602	// extend objects
603	function extend( a, b ) {
604		for ( var prop in b ) {
605			a[ prop ] = b[ prop ];
606		}
607		return a;
608	}
609
610	var objToString = Object.prototype.toString;
611	function isArray( obj ) {
612		return objToString.call( obj ) === '[object Array]';
613	}
614
615	// turn element or nodeList into an array
616	function makeArray( obj ) {
617		var ary = [];
618		if ( isArray( obj ) ) {
619			// use object if already an array
620			ary = obj;
621		} else if ( typeof obj.length === 'number' ) {
622			// convert nodeList to array
623			for ( var i=0, len = obj.length; i < len; i++ ) {
624				ary.push( obj[i] );
625			}
626		} else {
627			// array of single index
628			ary.push( obj );
629		}
630		return ary;
631	}
632
633	// -------------------------- imagesLoaded -------------------------- //
634
635	/**
636	 * @param {Array, Element, NodeList, String} elem
637	 * @param {Object or Function} options - if function, use as callback
638	 * @param {Function} onAlways - callback function
639	 */
640	function ImagesLoaded( elem, options, onAlways ) {
641		// coerce ImagesLoaded() without new, to be new ImagesLoaded()
642		if ( !( this instanceof ImagesLoaded ) ) {
643			return new ImagesLoaded( elem, options );
644		}
645		// use elem as selector string
646		if ( typeof elem === 'string' ) {
647			elem = document.querySelectorAll( elem );
648		}
649
650		this.elements = makeArray( elem );
651		this.options = extend( {}, this.options );
652
653		if ( typeof options === 'function' ) {
654			onAlways = options;
655		} else {
656			extend( this.options, options );
657		}
658
659		if ( onAlways ) {
660			this.on( 'always', onAlways );
661		}
662
663		this.getImages();
664
665		if ( $ ) {
666			// add jQuery Deferred object
667			this.jqDeferred = new $.Deferred();
668		}
669
670		// HACK check async to allow time to bind listeners
671		var _this = this;
672		setTimeout( function() {
673			_this.check();
674		});
675	}
676
677	ImagesLoaded.prototype = new EventEmitter();
678
679	ImagesLoaded.prototype.options = {};
680
681	ImagesLoaded.prototype.getImages = function() {
682		this.images = [];
683
684		// filter & find items if we have an item selector
685		for ( var i=0, len = this.elements.length; i < len; i++ ) {
686			var elem = this.elements[i];
687			// filter siblings
688			if ( elem.nodeName === 'IMG' ) {
689				this.addImage( elem );
690			}
691			// find children
692			// no non-element nodes, #143
693			var nodeType = elem.nodeType;
694			if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) {
695				continue;
696			}
697			var childElems = elem.querySelectorAll('img');
698			// concat childElems to filterFound array
699			for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
700				var img = childElems[j];
701				this.addImage( img );
702			}
703		}
704	};
705
706	/**
707	 * @param {Image} img
708	 */
709	ImagesLoaded.prototype.addImage = function( img ) {
710		var loadingImage = new LoadingImage( img );
711		this.images.push( loadingImage );
712	};
713
714	ImagesLoaded.prototype.check = function() {
715		var _this = this;
716		var checkedCount = 0;
717		var length = this.images.length;
718		this.hasAnyBroken = false;
719		// complete if no images
720		if ( !length ) {
721			this.complete();
722			return;
723		}
724
725		function onConfirm( image, message ) {
726			if ( _this.options.debug && hasConsole ) {
727				console.log( 'confirm', image, message );
728			}
729
730			_this.progress( image );
731			checkedCount++;
732			if ( checkedCount === length ) {
733				_this.complete();
734			}
735			return true; // bind once
736		}
737
738		for ( var i=0; i < length; i++ ) {
739			var loadingImage = this.images[i];
740			loadingImage.on( 'confirm', onConfirm );
741			loadingImage.check();
742		}
743	};
744
745	ImagesLoaded.prototype.progress = function( image ) {
746		this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
747		// HACK - Chrome triggers event before object properties have changed. #83
748		var _this = this;
749		setTimeout( function() {
750			_this.emit( 'progress', _this, image );
751			if ( _this.jqDeferred && _this.jqDeferred.notify ) {
752				_this.jqDeferred.notify( _this, image );
753			}
754		} );
755	};
756
757	ImagesLoaded.prototype.complete = function() {
758		var eventName = this.hasAnyBroken ? 'fail' : 'done';
759		this.isComplete = true;
760		var _this = this;
761		// HACK - another setTimeout so that confirm happens after progress
762		setTimeout( function() {
763			_this.emit( eventName, _this );
764			_this.emit( 'always', _this );
765			if ( _this.jqDeferred ) {
766				var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve';
767				_this.jqDeferred[ jqMethod ]( _this );
768			}
769		} );
770	};
771
772	// -------------------------- jquery -------------------------- //
773
774	if ( $ ) {
775		$.fn.imagesLoaded = function( options, callback ) {
776			var instance = new ImagesLoaded( this, options, callback );
777			return instance.jqDeferred.promise( $(this) );
778		};
779	}
780
781
782	// --------------------------  -------------------------- //
783
784	function LoadingImage( img ) {
785		this.img = img;
786	}
787
788	LoadingImage.prototype = new EventEmitter();
789
790	LoadingImage.prototype.check = function() {
791		// first check cached any previous images that have same src
792		var resource = cache[ this.img.src ] || new Resource( this.img.src );
793		if ( resource.isConfirmed ) {
794			this.confirm( resource.isLoaded, 'cached was confirmed' );
795			return;
796		}
797
798		// If complete is true and browser supports natural sizes,
799		// try to check for image status manually.
800		if ( this.img.complete && this.img.naturalWidth !== undefined ) {
801			// report based on naturalWidth
802			this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
803			return;
804		}
805
806		// If none of the checks above matched, simulate loading on detached element.
807		var _this = this;
808		resource.on( 'confirm', function( resrc, message ) {
809			_this.confirm( resrc.isLoaded, message );
810			return true;
811		} );
812
813		resource.check();
814	};
815
816	LoadingImage.prototype.confirm = function( isLoaded, message ) {
817		this.isLoaded = isLoaded;
818		this.emit( 'confirm', this, message );
819	};
820
821	// -------------------------- Resource -------------------------- //
822
823	// Resource checks each src, only once
824	// separate class from LoadingImage to prevent memory leaks. See #115
825
826	var cache = {};
827
828	function Resource( src ) {
829		this.src = src;
830		// add to cache
831		cache[ src ] = this;
832	}
833
834	Resource.prototype = new EventEmitter();
835
836	Resource.prototype.check = function() {
837		// only trigger checking once
838		if ( this.isChecked ) {
839			return;
840		}
841		// simulate loading on detached element
842		var proxyImage = new Image();
843		eventie.bind( proxyImage, 'load', this );
844		eventie.bind( proxyImage, 'error', this );
845		proxyImage.src = this.src;
846		// set flag
847		this.isChecked = true;
848	};
849
850	// ----- events ----- //
851
852	// trigger specified handler for event type
853	Resource.prototype.handleEvent = function( event ) {
854		var method = 'on' + event.type;
855		if ( this[ method ] ) {
856			this[ method ]( event );
857		}
858	};
859
860	Resource.prototype.onload = function( event ) {
861		this.confirm( true, 'onload' );
862		this.unbindProxyEvents( event );
863	};
864
865	Resource.prototype.onerror = function( event ) {
866		this.confirm( false, 'onerror' );
867		this.unbindProxyEvents( event );
868	};
869
870	// ----- confirm ----- //
871
872	Resource.prototype.confirm = function( isLoaded, message ) {
873		this.isConfirmed = true;
874		this.isLoaded = isLoaded;
875		this.emit( 'confirm', this, message );
876	};
877
878	Resource.prototype.unbindProxyEvents = function( event ) {
879		eventie.unbind( event.target, 'load', this );
880		eventie.unbind( event.target, 'error', this );
881	};
882
883	// -----  ----- //
884
885	return ImagesLoaded;
886
887} );

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.