PageSourceSearch

https://zan.kz/lib/owlSlider/src/js/owl.carousel.js

js zan.kz collected 2026-10-02 02:30:12 UTC 45,093 bytes, 1,692 lines download raw bytes

vendor: 6,254 bytes, lines 1-325
1/**
2 * Owl carousel
3 * @version 2.1.6
4 * @author Bartosz Wojciechowski
5 * @author David Deutsch
6 * @license The MIT License (MIT)
7 * @todo Lazy Load Icon
8 * @todo prevent animationend bubling
9 * @todo itemsScaleUp
10 * @todo Test Zepto
11 * @todo stagePadding calculate wrong active classes
12 */
13;(function($, window, document, undefined) {
14
15	/**
16	 * Creates a carousel.
17	 * @class The Owl Carousel.
18	 * @public
19	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
20	 * @param {Object} [options] - The options
21	 */
22	function Owl(element, options) {
23
24		/**
25		 * Current settings for the carousel.
26		 * @public
27		 */
28		this.settings = null;
29
30		/**
31		 * Current options set by the caller including defaults.
32		 * @public
33		 */
34		this.options = $.extend({}, Owl.Defaults, options);
35
36		/**
37		 * Plugin element.
38		 * @public
39		 */
40		this.$element = $(element);
41
42		/**
43		 * Proxied event handlers.
44		 * @protected
45		 */
46		this._handlers = {};
47
48		/**
49		 * References to the running plugins of this carousel.
50		 * @protected
51		 */
52		this._plugins = {};
53
54		/**
55		 * Currently suppressed events to prevent them from beeing retriggered.
56		 * @protected
57		 */
58		this._supress = {};
59
60		/**
61		 * Absolute current position.
62		 * @protected
63		 */
64		this._current = null;
65
66		/**
67		 * Animation speed in milliseconds.
68		 * @protected
69		 */
70		this._speed = null;
71
72		/**
73		 * Coordinates of all items in pixel.
74		 * @todo The name of this member is missleading.
75		 * @protected
76		 */
77		this._coordinates = [];
78
79		/**
80		 * Current breakpoint.
81		 * @todo Real media queries would be nice.
82		 * @protected
83		 */
84		this._breakpoint = null;
85
86		/**
87		 * Current width of the plugin element.
88		 */
89		this._width = null;
90
91		/**
92		 * All real items.
93		 * @protected
94		 */
95		this._items = [];
96
97		/**
98		 * All cloned items.
99		 * @protected
100		 */
101		this._clones = [];
102
103		/**
104		 * Merge values of all items.
105		 * @todo Maybe this could be part of a plugin.
106		 * @protected
107		 */
108		this._mergers = [];
109
110		/**
111		 * Widths of all items.
112		 */
113		this._widths = [];
114
115		/**
116		 * Invalidated parts within the update process.
117		 * @protected
118		 */
119		this._invalidated = {};
120
121		/**
122		 * Ordered list of workers for the update process.
123		 * @protected
124		 */
125		this._pipe = [];
126
127		/**
128		 * Current state information for the drag operation.
129		 * @todo #261
130		 * @protected
131		 */
132		this._drag = {
133			time: null,
134			target: null,
135			pointer: null,
136			stage: {
137				start: null,
138				current: null
139			},
140			direction: null
141		};
142
143		/**
144		 * Current state information and their tags.
145		 * @type {Object}
146		 * @protected
147		 */
148		this._states = {
149			current: {},
150			tags: {
151				'initializing': [ 'busy' ],
152				'animating': [ 'busy' ],
153				'dragging': [ 'interacting' ]
154			}
155		};
156
157		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
158			this._handlers[handler] = $.proxy(this[handler], this);
159		}, this));
160
161		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
162			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
163				= new plugin(this);
164		}, this));
165
166		$.each(Owl.Workers, $.proxy(function(priority, worker) {
167			this._pipe.push({
168				'filter': worker.filter,
169				'run': $.proxy(worker.run, this)
170			});
171		}, this));
172
173		this.setup();
174		this.initialize();
175	}
176
177	/**
178	 * Default options for the carousel.
179	 * @public
180	 */
181	Owl.Defaults = {
182		items: 3,
183		loop: false,
184		center: false,
185		rewind: false,
186
187		mouseDrag: true,
188		touchDrag: true,
189		pullDrag: true,
190		freeDrag: false,
191
192		margin: 0,
193		stagePadding: 0,
194
195		merge: false,
196		mergeFit: true,
197		autoWidth: false,
198
199		startPosition: 0,
200		rtl: false,
201
202		smartSpeed: 250,
203		fluidSpeed: false,
204		dragEndSpeed: false,
205
206		responsive: {},
207		responsiveRefreshRate: 200,
208		responsiveBaseElement: window,
209
210		fallbackEasing: 'swing',
211
212		info: false,
213
214		nestedItemSelector: false,
215		itemElement: 'div',
216		stageElement: 'div',
217
218		refreshClass: 'owl-refresh',
219		loadedClass: 'owl-loaded',
220		loadingClass: 'owl-loading',
221		rtlClass: 'owl-rtl',
222		responsiveClass: 'owl-responsive',
223		dragClass: 'owl-drag',
224		itemClass: 'owl-item',
225		stageClass: 'owl-stage',
226		stageOuterClass: 'owl-stage-outer',
227		grabClass: 'owl-grab'
228	};
229
230	/**
231	 * Enumeration for width.
232	 * @public
233	 * @readonly
234	 * @enum {String}
235	 */
236	Owl.Width = {
237		Default: 'default',
238		Inner: 'inner',
239		Outer: 'outer'
240	};
241
242	/**
243	 * Enumeration for types.
244	 * @public
245	 * @readonly
246	 * @enum {String}
247	 */
248	Owl.Type = {
249		Event: 'event',
250		State: 'state'
251	};
252
253	/**
254	 * Contains all registered plugins.
255	 * @public
256	 */
257	Owl.Plugins = {};
258
259	/**
260	 * List of workers involved in the update process.
261	 */
262	Owl.Workers = [ {
263		filter: [ 'width', 'settings' ],
264		run: function() {
265			this._width = this.$element.width();
266		}
267	}, {
268		filter: [ 'width', 'items', 'settings' ],
269		run: function(cache) {
270			cache.current = this._items && this._items[this.relative(this._current)];
271		}
272	}, {
273		filter: [ 'items', 'settings' ],
274		run: function() {
275			this.$stage.children('.cloned').remove();
276		}
277	}, {
278		filter: [ 'width', 'items', 'settings' ],
279		run: function(cache) {
280			var margin = this.settings.margin || '',
281				grid = !this.settings.autoWidth,
282				rtl = this.settings.rtl,
283				css = {
284					'width': 'auto',
285					'margin-left': rtl ? margin : '',
286					'margin-right': rtl ? '' : margin
287				};
288
289			!grid && this.$stage.children().css(css);
290
291			cache.css = css;
292		}
293	}, {
294		filter: [ 'width', 'items', 'settings' ],
295		run: function(cache) {
296			var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
297				merge = null,
298				iterator = this._items.length,
299				grid = !this.settings.autoWidth,
300				widths = [];
301
302			cache.items = {
303				merge: false,
304				width: width
305			};
306
307			while (iterator--) {
308				merge = this._mergers[iterator];
309				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
310
311				cache.items.merge = merge > 1 || cache.items.merge;
312
313				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
314			}
315
316			this._widths = widths;
317		}
318	}, {
319		filter: [ 'items', 'settings' ],
320		run: function() {
321			var clones = [],
322				items = this._items,
323				settings = this.settings,
324				// TODO: Should be computed from number of min width items in stage
325				view = Math.max(settings.items * 2, 4),
vendor: 684 bytes, lines 326-344
326				size = Math.ceil(items.length / 2) * 2,
327				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
328				append = '',
329				prepend = '';
330
331			repeat /= 2;
332
333			while (repeat--) {
334				// Switch to only using appended clones
335				clones.push(this.normalize(clones.length / 2, true));
336				append = append + items[clones[clones.length - 1]][0].outerHTML;
337				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
338				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
339			}
340
341			this._clones = clones;
342
343			$(append).addClass('cloned').appendTo(this.$stage);
344			$(prepend).addClass('cloned').prependTo(this.$stage);
vendor: 31,179 bytes, lines 344-1452
344
345		}
346	}, {
347		filter: [ 'width', 'items', 'settings' ],
348		run: function() {
349			var rtl = this.settings.rtl ? 1 : -1,
350				size = this._clones.length + this._items.length,
351				iterator = -1,
352				previous = 0,
353				current = 0,
354				coordinates = [];
355
356			while (++iterator < size) {
357				previous = coordinates[iterator - 1] || 0;
358				current = this._widths[this.relative(iterator)] + this.settings.margin;
359				coordinates.push(previous + current * rtl);
360			}
361
362			this._coordinates = coordinates;
363		}
364	}, {
365		filter: [ 'width', 'items', 'settings' ],
366		run: function() {
367			var padding = this.settings.stagePadding,
368				coordinates = this._coordinates,
369				css = {
370					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
371					'padding-left': padding || '',
372					'padding-right': padding || ''
373				};
374
375			this.$stage.css(css);
376		}
377	}, {
378		filter: [ 'width', 'items', 'settings' ],
379		run: function(cache) {
380			var iterator = this._coordinates.length,
381				grid = !this.settings.autoWidth,
382				items = this.$stage.children();
383
384			if (grid && cache.items.merge) {
385				while (iterator--) {
386					cache.css.width = this._widths[this.relative(iterator)];
387					items.eq(iterator).css(cache.css);
388				}
389			} else if (grid) {
390				cache.css.width = cache.items.width;
391				items.css(cache.css);
392			}
393		}
394	}, {
395		filter: [ 'items' ],
396		run: function() {
397			this._coordinates.length < 1 && this.$stage.removeAttr('style');
398		}
399	}, {
400		filter: [ 'width', 'items', 'settings' ],
401		run: function(cache) {
402			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
403			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
404			this.reset(cache.current);
405		}
406	}, {
407		filter: [ 'position' ],
408		run: function() {
409			this.animate(this.coordinates(this._current));
410		}
411	}, {
412		filter: [ 'width', 'position', 'items', 'settings' ],
413		run: function() {
414			var rtl = this.settings.rtl ? 1 : -1,
415				padding = this.settings.stagePadding * 2,
416				begin = this.coordinates(this.current()) + padding,
417				end = begin + this.width() * rtl,
418				inner, outer, matches = [], i, n;
419
420			for (i = 0, n = this._coordinates.length; i < n; i++) {
421				inner = this._coordinates[i - 1] || 0;
422				outer = Math.abs(this._coordinates[i]) + padding * rtl;
423
424				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
425					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
426					matches.push(i);
427				}
428			}
429
430			this.$stage.children('.active').removeClass('active');
431			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
432
433			if (this.settings.center) {
434				this.$stage.children('.center').removeClass('center');
435				this.$stage.children().eq(this.current()).addClass('center');
436			}
437		}
438	} ];
439
440	/**
441	 * Initializes the carousel.
442	 * @protected
443	 */
444	Owl.prototype.initialize = function() {
445		this.enter('initializing');
446		this.trigger('initialize');
447
448		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
449
450		if (this.settings.autoWidth && !this.is('pre-loading')) {
451			var imgs, nestedSelector, width;
452			imgs = this.$element.find('img');
453			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
454			width = this.$element.children(nestedSelector).width();
455
456			if (imgs.length && width <= 0) {
457				this.preloadAutoWidthImages(imgs);
458			}
459		}
460
461		this.$element.addClass(this.options.loadingClass);
462
463		// create stage
464		this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
465			.wrap('<div class="' + this.settings.stageOuterClass + '"/>');
466
467		// append stage
468		this.$element.append(this.$stage.parent());
469
470		// append content
471		this.replace(this.$element.children().not(this.$stage.parent()));
472
473		// check visibility
474		if (this.$element.is(':visible')) {
475			// update view
476			this.refresh();
477		} else {
478			// invalidate width
479			this.invalidate('width');
480		}
481
482		this.$element
483			.removeClass(this.options.loadingClass)
484			.addClass(this.options.loadedClass);
485
486		// register event handlers
487		this.registerEventHandlers();
488
489		this.leave('initializing');
490		this.trigger('initialized');
491	};
492
493	/**
494	 * Setups the current settings.
495	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
496	 * @todo Support for media queries by using `matchMedia` would be nice.
497	 * @public
498	 */
499	Owl.prototype.setup = function() {
500		var viewport = this.viewport(),
501			overwrites = this.options.responsive,
502			match = -1,
503			settings = null;
504
505		if (!overwrites) {
506			settings = $.extend({}, this.options);
507		} else {
508			$.each(overwrites, function(breakpoint) {
509				if (breakpoint <= viewport && breakpoint > match) {
510					match = Number(breakpoint);
511				}
512			});
513
514			settings = $.extend({}, this.options, overwrites[match]);
515			if (typeof settings.stagePadding === 'function') {
516				settings.stagePadding = settings.stagePadding();
517			}
518			delete settings.responsive;
519
520			// responsive class
521			if (settings.responsiveClass) {
522				this.$element.attr('class',
523					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
524				);
525			}
526		}
527
528		this.trigger('change', { property: { name: 'settings', value: settings } });
529		this._breakpoint = match;
530		this.settings = settings;
531		this.invalidate('settings');
532		this.trigger('changed', { property: { name: 'settings', value: this.settings } });
533	};
534
535	/**
536	 * Updates option logic if necessery.
537	 * @protected
538	 */
539	Owl.prototype.optionsLogic = function() {
540		if (this.settings.autoWidth) {
541			this.settings.stagePadding = false;
542			this.settings.merge = false;
543		}
544	};
545
546	/**
547	 * Prepares an item before add.
548	 * @todo Rename event parameter `content` to `item`.
549	 * @protected
550	 * @returns {jQuery|HTMLElement} - The item container.
551	 */
552	Owl.prototype.prepare = function(item) {
553		var event = this.trigger('prepare', { content: item });
554
555		if (!event.data) {
556			event.data = $('<' + this.settings.itemElement + '/>')
557				.addClass(this.options.itemClass).append(item)
558		}
559
560		this.trigger('prepared', { content: event.data });
561
562		return event.data;
563	};
564
565	/**
566	 * Updates the view.
567	 * @public
568	 */
569	Owl.prototype.update = function() {
570		var i = 0,
571			n = this._pipe.length,
572			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
573			cache = {};
574
575		while (i < n) {
576			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
577				this._pipe[i].run(cache);
578			}
579			i++;
580		}
581
582		this._invalidated = {};
583
584		!this.is('valid') && this.enter('valid');
585	};
586
587	/**
588	 * Gets the width of the view.
589	 * @public
590	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
591	 * @returns {Number} - The width of the view in pixel.
592	 */
593	Owl.prototype.width = function(dimension) {
594		dimension = dimension || Owl.Width.Default;
595		switch (dimension) {
596			case Owl.Width.Inner:
597			case Owl.Width.Outer:
598				return this._width;
599			default:
600				return this._width - this.settings.stagePadding * 2 + this.settings.margin;
601		}
602	};
603
604	/**
605	 * Refreshes the carousel primarily for adaptive purposes.
606	 * @public
607	 */
608	Owl.prototype.refresh = function() {
609		this.enter('refreshing');
610		this.trigger('refresh');
611
612		this.setup();
613
614		this.optionsLogic();
615
616		this.$element.addClass(this.options.refreshClass);
617
618		this.update();
619
620		this.$element.removeClass(this.options.refreshClass);
621
622		this.leave('refreshing');
623		this.trigger('refreshed');
624	};
625
626	/**
627	 * Checks window `resize` event.
628	 * @protected
629	 */
630	Owl.prototype.onThrottledResize = function() {
631		window.clearTimeout(this.resizeTimer);
632		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
633	};
634
635	/**
636	 * Checks window `resize` event.
637	 * @protected
638	 */
639	Owl.prototype.onResize = function() {
640		if (!this._items.length) {
641			return false;
642		}
643
644		if (this._width === this.$element.width()) {
645			return false;
646		}
647
648		if (!this.$element.is(':visible')) {
649			return false;
650		}
651
652		this.enter('resizing');
653
654		if (this.trigger('resize').isDefaultPrevented()) {
655			this.leave('resizing');
656			return false;
657		}
658
659		this.invalidate('width');
660
661		this.refresh();
662
663		this.leave('resizing');
664		this.trigger('resized');
665	};
666
667	/**
668	 * Registers event handlers.
669	 * @todo Check `msPointerEnabled`
670	 * @todo #261
671	 * @protected
672	 */
673	Owl.prototype.registerEventHandlers = function() {
674		if ($.support.transition) {
675			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
676		}
677
678		if (this.settings.responsive !== false) {
679			this.on(window, 'resize', this._handlers.onThrottledResize);
680		}
681
682		if (this.settings.mouseDrag) {
683			this.$element.addClass(this.options.dragClass);
684			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
685			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
686		}
687
688		if (this.settings.touchDrag){
689			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
690			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
691		}
692	};
693
694	/**
695	 * Handles `touchstart` and `mousedown` events.
696	 * @todo Horizontal swipe threshold as option
697	 * @todo #261
698	 * @protected
699	 * @param {Event} event - The event arguments.
700	 */
701	Owl.prototype.onDragStart = function(event) {
702		var stage = null;
703
704		if (event.which === 3) {
705			return;
706		}
707
708		if ($.support.transform) {
709			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
710			stage = {
711				x: stage[stage.length === 16 ? 12 : 4],
712				y: stage[stage.length === 16 ? 13 : 5]
713			};
714		} else {
715			stage = this.$stage.position();
716			stage = {
717				x: this.settings.rtl ?
718					stage.left + this.$stage.width() - this.width() + this.settings.margin :
719					stage.left,
720				y: stage.top
721			};
722		}
723
724		if (this.is('animating')) {
725			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
726			this.invalidate('position');
727		}
728
729		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
730
731		this.speed(0);
732
733		this._drag.time = new Date().getTime();
734		this._drag.target = $(event.target);
735		this._drag.stage.start = stage;
736		this._drag.stage.current = stage;
737		this._drag.pointer = this.pointer(event);
738
739		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
740
741		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
742			var delta = this.difference(this._drag.pointer, this.pointer(event));
743
744			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
745
746			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
747				return;
748			}
749
750			event.preventDefault();
751
752			this.enter('dragging');
753			this.trigger('drag');
754		}, this));
755	};
756
757	/**
758	 * Handles the `touchmove` and `mousemove` events.
759	 * @todo #261
760	 * @protected
761	 * @param {Event} event - The event arguments.
762	 */
763	Owl.prototype.onDragMove = function(event) {
764		var minimum = null,
765			maximum = null,
766			pull = null,
767			delta = this.difference(this._drag.pointer, this.pointer(event)),
768			stage = this.difference(this._drag.stage.start, delta);
769
770		if (!this.is('dragging')) {
771			return;
772		}
773
774		event.preventDefault();
775
776		if (this.settings.loop) {
777			minimum = this.coordinates(this.minimum());
778			maximum = this.coordinates(this.maximum() + 1) - minimum;
779			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
780		} else {
781			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
782			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
783			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
784			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
785		}
786
787		this._drag.stage.current = stage;
788
789		this.animate(stage.x);
790	};
791
792	/**
793	 * Handles the `touchend` and `mouseup` events.
794	 * @todo #261
795	 * @todo Threshold for click event
796	 * @protected
797	 * @param {Event} event - The event arguments.
798	 */
799	Owl.prototype.onDragEnd = function(event) {
800		var delta = this.difference(this._drag.pointer, this.pointer(event)),
801			stage = this._drag.stage.current,
802			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
803
804		$(document).off('.owl.core');
805
806		this.$element.removeClass(this.options.grabClass);
807
808		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
809			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
810			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
811			this.invalidate('position');
812			this.update();
813
814			this._drag.direction = direction;
815
816			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
817				this._drag.target.one('click.owl.core', function() { return false; });
818			}
819		}
820
821		if (!this.is('dragging')) {
822			return;
823		}
824
825		this.leave('dragging');
826		this.trigger('dragged');
827	};
828
829	/**
830	 * Gets absolute position of the closest item for a coordinate.
831	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
832	 * @protected
833	 * @param {Number} coordinate - The coordinate in pixel.
834	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
835	 * @return {Number} - The absolute position of the closest item.
836	 */
837	Owl.prototype.closest = function(coordinate, direction) {
838		var position = -1,
839			pull = 30,
840			width = this.width(),
841			coordinates = this.coordinates();
842
843		if (!this.settings.freeDrag) {
844			// check closest item
845			$.each(coordinates, $.proxy(function(index, value) {
846				// on a left pull, check on current index
847				if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {
848					position = index;
849				// on a right pull, check on previous index
850				// to do so, subtract width from value and set position = index + 1
851				} else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {
852					position = index + 1;
853				} else if (this.op(coordinate, '<', value)
854					&& this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
855					position = direction === 'left' ? index + 1 : index;
856				}
857				return position === -1;
858			}, this));
859		}
860
861		if (!this.settings.loop) {
862			// non loop boundries
863			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
864				position = coordinate = this.minimum();
865			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
866				position = coordinate = this.maximum();
867			}
868		}
869
870		return position;
871	};
872
873	/**
874	 * Animates the stage.
875	 * @todo #270
876	 * @public
877	 * @param {Number} coordinate - The coordinate in pixels.
878	 */
879	Owl.prototype.animate = function(coordinate) {
880		var animate = this.speed() > 0;
881
882		this.is('animating') && this.onTransitionEnd();
883
884		if (animate) {
885			this.enter('animating');
886			this.trigger('translate');
887		}
888
889		if ($.support.transform3d && $.support.transition) {
890			this.$stage.css({
891				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
892				transition: (this.speed() / 1000) + 's'
893			});
894		} else if (animate) {
895			this.$stage.animate({
896				left: coordinate + 'px'
897			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
898		} else {
899			this.$stage.css({
900				left: coordinate + 'px'
901			});
902		}
903	};
904
905	/**
906	 * Checks whether the carousel is in a specific state or not.
907	 * @param {String} state - The state to check.
908	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
909	 */
910	Owl.prototype.is = function(state) {
911		return this._states.current[state] && this._states.current[state] > 0;
912	};
913
914	/**
915	 * Sets the absolute position of the current item.
916	 * @public
917	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
918	 * @returns {Number} - The absolute position of the current item.
919	 */
920	Owl.prototype.current = function(position) {
921		if (position === undefined) {
922			return this._current;
923		}
924
925		if (this._items.length === 0) {
926			return undefined;
927		}
928
929		position = this.normalize(position);
930
931		if (this._current !== position) {
932			var event = this.trigger('change', { property: { name: 'position', value: position } });
933
934			if (event.data !== undefined) {
935				position = this.normalize(event.data);
936			}
937
938			this._current = position;
939
940			this.invalidate('position');
941
942			this.trigger('changed', { property: { name: 'position', value: this._current } });
943		}
944
945		return this._current;
946	};
947
948	/**
949	 * Invalidates the given part of the update routine.
950	 * @param {String} [part] - The part to invalidate.
951	 * @returns {Array.<String>} - The invalidated parts.
952	 */
953	Owl.prototype.invalidate = function(part) {
954		if ($.type(part) === 'string') {
955			this._invalidated[part] = true;
956			this.is('valid') && this.leave('valid');
957		}
958		return $.map(this._invalidated, function(v, i) { return i });
959	};
960
961	/**
962	 * Resets the absolute position of the current item.
963	 * @public
964	 * @param {Number} position - The absolute position of the new item.
965	 */
966	Owl.prototype.reset = function(position) {
967		position = this.normalize(position);
968
969		if (position === undefined) {
970			return;
971		}
972
973		this._speed = 0;
974		this._current = position;
975
976		this.suppress([ 'translate', 'translated' ]);
977
978		this.animate(this.coordinates(position));
979
980		this.release([ 'translate', 'translated' ]);
981	};
982
983	/**
984	 * Normalizes an absolute or a relative position of an item.
985	 * @public
986	 * @param {Number} position - The absolute or relative position to normalize.
987	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
988	 * @returns {Number} - The normalized position.
989	 */
990	Owl.prototype.normalize = function(position, relative) {
991		var n = this._items.length,
992			m = relative ? 0 : this._clones.length;
993
994		if (!this.isNumeric(position) || n < 1) {
995			position = undefined;
996		} else if (position < 0 || position >= n + m) {
997			position = ((position - m / 2) % n + n) % n + m / 2;
998		}
999
1000		return position;
1001	};
1002
1003	/**
1004	 * Converts an absolute position of an item into a relative one.
1005	 * @public
1006	 * @param {Number} position - The absolute position to convert.
1007	 * @returns {Number} - The converted position.
1008	 */
1009	Owl.prototype.relative = function(position) {
1010		position -= this._clones.length / 2;
1011		return this.normalize(position, true);
1012	};
1013
1014	/**
1015	 * Gets the maximum position for the current item.
1016	 * @public
1017	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1018	 * @returns {Number}
1019	 */
1020	Owl.prototype.maximum = function(relative) {
1021		var settings = this.settings,
1022			maximum = this._coordinates.length,
1023			iterator,
1024			reciprocalItemsWidth,
1025			elementWidth;
1026
1027		if (settings.loop) {
1028			maximum = this._clones.length / 2 + this._items.length - 1;
1029		} else if (settings.autoWidth || settings.merge) {
1030			iterator = this._items.length;
1031			reciprocalItemsWidth = this._items[--iterator].width();
1032			elementWidth = this.$element.width();
1033			while (iterator--) {
1034				reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin;
1035				if (reciprocalItemsWidth > elementWidth) {
1036					break;
1037				}
1038			}
1039			maximum = iterator + 1;
1040		} else if (settings.center) {
1041			maximum = this._items.length - 1;
1042		} else {
1043			maximum = this._items.length - settings.items;
1044		}
1045
1046		if (relative) {
1047			maximum -= this._clones.length / 2;
1048		}
1049
1050		return Math.max(maximum, 0);
1051	};
1052
1053	/**
1054	 * Gets the minimum position for the current item.
1055	 * @public
1056	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1057	 * @returns {Number}
1058	 */
1059	Owl.prototype.minimum = function(relative) {
1060		return relative ? 0 : this._clones.length / 2;
1061	};
1062
1063	/**
1064	 * Gets an item at the specified relative position.
1065	 * @public
1066	 * @param {Number} [position] - The relative position of the item.
1067	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1068	 */
1069	Owl.prototype.items = function(position) {
1070		if (position === undefined) {
1071			return this._items.slice();
1072		}
1073
1074		position = this.normalize(position, true);
1075		return this._items[position];
1076	};
1077
1078	/**
1079	 * Gets an item at the specified relative position.
1080	 * @public
1081	 * @param {Number} [position] - The relative position of the item.
1082	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1083	 */
1084	Owl.prototype.mergers = function(position) {
1085		if (position === undefined) {
1086			return this._mergers.slice();
1087		}
1088
1089		position = this.normalize(position, true);
1090		return this._mergers[position];
1091	};
1092
1093	/**
1094	 * Gets the absolute positions of clones for an item.
1095	 * @public
1096	 * @param {Number} [position] - The relative position of the item.
1097	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
1098	 */
1099	Owl.prototype.clones = function(position) {
1100		var odd = this._clones.length / 2,
1101			even = odd + this._items.length,
1102			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
1103
1104		if (position === undefined) {
1105			return $.map(this._clones, function(v, i) { return map(i) });
1106		}
1107
1108		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
1109	};
1110
1111	/**
1112	 * Sets the current animation speed.
1113	 * @public
1114	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
1115	 * @returns {Number} - The current animation speed in milliseconds.
1116	 */
1117	Owl.prototype.speed = function(speed) {
1118		if (speed !== undefined) {
1119			this._speed = speed;
1120		}
1121
1122		return this._speed;
1123	};
1124
1125	/**
1126	 * Gets the coordinate of an item.
1127	 * @todo The name of this method is missleanding.
1128	 * @public
1129	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
1130	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
1131	 */
1132	Owl.prototype.coordinates = function(position) {
1133		var multiplier = 1,
1134			newPosition = position - 1,
1135			coordinate;
1136
1137		if (position === undefined) {
1138			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
1139				return this.coordinates(index);
1140			}, this));
1141		}
1142
1143		if (this.settings.center) {
1144			if (this.settings.rtl) {
1145				multiplier = -1;
1146				newPosition = position + 1;
1147			}
1148
1149			coordinate = this._coordinates[position];
1150			coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;
1151		} else {
1152			coordinate = this._coordinates[newPosition] || 0;
1153		}
1154
1155		coordinate = Math.ceil(coordinate);
1156
1157		return coordinate;
1158	};
1159
1160	/**
1161	 * Calculates the speed for a translation.
1162	 * @protected
1163	 * @param {Number} from - The absolute position of the start item.
1164	 * @param {Number} to - The absolute position of the target item.
1165	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
1166	 * @returns {Number} - The time in milliseconds for the translation.
1167	 */
1168	Owl.prototype.duration = function(from, to, factor) {
1169		if (factor === 0) {
1170			return 0;
1171		}
1172
1173		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
1174	};
1175
1176	/**
1177	 * Slides to the specified item.
1178	 * @public
1179	 * @param {Number} position - The position of the item.
1180	 * @param {Number} [speed] - The time in milliseconds for the transition.
1181	 */
1182	Owl.prototype.to = function(position, speed) {
1183		var current = this.current(),
1184			revert = null,
1185			distance = position - this.relative(current),
1186			direction = (distance > 0) - (distance < 0),
1187			items = this._items.length,
1188			minimum = this.minimum(),
1189			maximum = this.maximum();
1190
1191		if (this.settings.loop) {
1192			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
1193				distance += direction * -1 * items;
1194			}
1195
1196			position = current + distance;
1197			revert = ((position - minimum) % items + items) % items + minimum;
1198
1199			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
1200				current = revert - distance;
1201				position = revert;
1202				this.reset(current);
1203			}
1204		} else if (this.settings.rewind) {
1205			maximum += 1;
1206			position = (position % maximum + maximum) % maximum;
1207		} else {
1208			position = Math.max(minimum, Math.min(maximum, position));
1209		}
1210
1211		this.speed(this.duration(current, position, speed));
1212		this.current(position);
1213
1214		if (this.$element.is(':visible')) {
1215			this.update();
1216		}
1217	};
1218
1219	/**
1220	 * Slides to the next item.
1221	 * @public
1222	 * @param {Number} [speed] - The time in milliseconds for the transition.
1223	 */
1224	Owl.prototype.next = function(speed) {
1225		speed = speed || false;
1226		this.to(this.relative(this.current()) + 1, speed);
1227	};
1228
1229	/**
1230	 * Slides to the previous item.
1231	 * @public
1232	 * @param {Number} [speed] - The time in milliseconds for the transition.
1233	 */
1234	Owl.prototype.prev = function(speed) {
1235		speed = speed || false;
1236		this.to(this.relative(this.current()) - 1, speed);
1237	};
1238
1239	/**
1240	 * Handles the end of an animation.
1241	 * @protected
1242	 * @param {Event} event - The event arguments.
1243	 */
1244	Owl.prototype.onTransitionEnd = function(event) {
1245
1246		// if css2 animation then event object is undefined
1247		if (event !== undefined) {
1248			event.stopPropagation();
1249
1250			// Catch only owl-stage transitionEnd event
1251			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
1252				return false;
1253			}
1254		}
1255
1256		this.leave('animating');
1257		this.trigger('translated');
1258	};
1259
1260	/**
1261	 * Gets viewport width.
1262	 * @protected
1263	 * @return {Number} - The width in pixel.
1264	 */
1265	Owl.prototype.viewport = function() {
1266		var width;
1267		if (this.options.responsiveBaseElement !== window) {
1268			width = $(this.options.responsiveBaseElement).width();
1269		} else if (window.innerWidth) {
1270			width = window.innerWidth;
1271		} else if (document.documentElement && document.documentElement.clientWidth) {
1272			width = document.documentElement.clientWidth;
1273		} else {
1274			console.warn('Can not detect viewport width.');
1275		}
1276		return width;
1277	};
1278
1279	/**
1280	 * Replaces the current content.
1281	 * @public
1282	 * @param {HTMLElement|jQuery|String} content - The new content.
1283	 */
1284	Owl.prototype.replace = function(content) {
1285		this.$stage.empty();
1286		this._items = [];
1287
1288		if (content) {
1289			content = (content instanceof jQuery) ? content : $(content);
1290		}
1291
1292		if (this.settings.nestedItemSelector) {
1293			content = content.find('.' + this.settings.nestedItemSelector);
1294		}
1295
1296		content.filter(function() {
1297			return this.nodeType === 1;
1298		}).each($.proxy(function(index, item) {
1299			item = this.prepare(item);
1300			this.$stage.append(item);
1301			this._items.push(item);
1302			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1303		}, this));
1304
1305		this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
1306
1307		this.invalidate('items');
1308	};
1309
1310	/**
1311	 * Adds an item.
1312	 * @todo Use `item` instead of `content` for the event arguments.
1313	 * @public
1314	 * @param {HTMLElement|jQuery|String} content - The item content to add.
1315	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
1316	 */
1317	Owl.prototype.add = function(content, position) {
1318		var current = this.relative(this._current);
1319
1320		position = position === undefined ? this._items.length : this.normalize(position, true);
1321		content = content instanceof jQuery ? content : $(content);
1322
1323		this.trigger('add', { content: content, position: position });
1324
1325		content = this.prepare(content);
1326
1327		if (this._items.length === 0 || position === this._items.length) {
1328			this._items.length === 0 && this.$stage.append(content);
1329			this._items.length !== 0 && this._items[position - 1].after(content);
1330			this._items.push(content);
1331			this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1332		} else {
1333			this._items[position].before(content);
1334			this._items.splice(position, 0, content);
1335			this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1336		}
1337
1338		this._items[current] && this.reset(this._items[current].index());
1339
1340		this.invalidate('items');
1341
1342		this.trigger('added', { content: content, position: position });
1343	};
1344
1345	/**
1346	 * Removes an item by its position.
1347	 * @todo Use `item` instead of `content` for the event arguments.
1348	 * @public
1349	 * @param {Number} position - The relative position of the item to remove.
1350	 */
1351	Owl.prototype.remove = function(position) {
1352		position = this.normalize(position, true);
1353
1354		if (position === undefined) {
1355			return;
1356		}
1357
1358		this.trigger('remove', { content: this._items[position], position: position });
1359
1360		this._items[position].remove();
1361		this._items.splice(position, 1);
1362		this._mergers.splice(position, 1);
1363
1364		this.invalidate('items');
1365
1366		this.trigger('removed', { content: null, position: position });
1367	};
1368
1369	/**
1370	 * Preloads images with auto width.
1371	 * @todo Replace by a more generic approach
1372	 * @protected
1373	 */
1374	Owl.prototype.preloadAutoWidthImages = function(images) {
1375		images.each($.proxy(function(i, element) {
1376			this.enter('pre-loading');
1377			element = $(element);
1378			$(new Image()).one('load', $.proxy(function(e) {
1379				element.attr('src', e.target.src);
1380				element.css('opacity', 1);
1381				this.leave('pre-loading');
1382				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
1383			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
1384		}, this));
1385	};
1386
1387	/**
1388	 * Destroys the carousel.
1389	 * @public
1390	 */
1391	Owl.prototype.destroy = function() {
1392
1393		this.$element.off('.owl.core');
1394		this.$stage.off('.owl.core');
1395		$(document).off('.owl.core');
1396
1397		if (this.settings.responsive !== false) {
1398			window.clearTimeout(this.resizeTimer);
1399			this.off(window, 'resize', this._handlers.onThrottledResize);
1400		}
1401
1402		for (var i in this._plugins) {
1403			this._plugins[i].destroy();
1404		}
1405
1406		this.$stage.children('.cloned').remove();
1407
1408		this.$stage.unwrap();
1409		this.$stage.children().contents().unwrap();
1410		this.$stage.children().unwrap();
1411
1412		this.$element
1413			.removeClass(this.options.refreshClass)
1414			.removeClass(this.options.loadingClass)
1415			.removeClass(this.options.loadedClass)
1416			.removeClass(this.options.rtlClass)
1417			.removeClass(this.options.dragClass)
1418			.removeClass(this.options.grabClass)
1419			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
1420			.removeData('owl.carousel');
1421	};
1422
1423	/**
1424	 * Operators to calculate right-to-left and left-to-right.
1425	 * @protected
1426	 * @param {Number} [a] - The left side operand.
1427	 * @param {String} [o] - The operator.
1428	 * @param {Number} [b] - The right side operand.
1429	 */
1430	Owl.prototype.op = function(a, o, b) {
1431		var rtl = this.settings.rtl;
1432		switch (o) {
1433			case '<':
1434				return rtl ? a > b : a < b;
1435			case '>':
1436				return rtl ? a < b : a > b;
1437			case '>=':
1438				return rtl ? a <= b : a >= b;
1439			case '<=':
1440				return rtl ? a >= b : a <= b;
1441			default:
1442				break;
1443		}
1444	};
1445
1446	/**
1447	 * Attaches to an internal event.
1448	 * @protected
1449	 * @param {HTMLElement} element - The event source.
1450	 * @param {String} event - The event name.
1451	 * @param {Function} listener - The event handler to attach.
1452	 * @param {Boolean} capture - Wether the event should be handled at the capturing p
vendor: 6,976 bytes, lines 1452-1692
1452hase or not.
1453	 */
1454	Owl.prototype.on = function(element, event, listener, capture) {
1455		if (element.addEventListener) {
1456			element.addEventListener(event, listener, capture);
1457		} else if (element.attachEvent) {
1458			element.attachEvent('on' + event, listener);
1459		}
1460	};
1461
1462	/**
1463	 * Detaches from an internal event.
1464	 * @protected
1465	 * @param {HTMLElement} element - The event source.
1466	 * @param {String} event - The event name.
1467	 * @param {Function} listener - The attached event handler to detach.
1468	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
1469	 */
1470	Owl.prototype.off = function(element, event, listener, capture) {
1471		if (element.removeEventListener) {
1472			element.removeEventListener(event, listener, capture);
1473		} else if (element.detachEvent) {
1474			element.detachEvent('on' + event, listener);
1475		}
1476	};
1477
1478	/**
1479	 * Triggers a public event.
1480	 * @todo Remove `status`, `relatedTarget` should be used instead.
1481	 * @protected
1482	 * @param {String} name - The event name.
1483	 * @param {*} [data=null] - The event data.
1484	 * @param {String} [namespace=carousel] - The event namespace.
1485	 * @param {String} [state] - The state which is associated with the event.
1486	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
1487	 * @returns {Event} - The event arguments.
1488	 */
1489	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
1490		var status = {
1491			item: { count: this._items.length, index: this.current() }
1492		}, handler = $.camelCase(
1493			$.grep([ 'on', name, namespace ], function(v) { return v })
1494				.join('-').toLowerCase()
1495		), event = $.Event(
1496			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
1497			$.extend({ relatedTarget: this }, status, data)
1498		);
1499
1500		if (!this._supress[name]) {
1501			$.each(this._plugins, function(name, plugin) {
1502				if (plugin.onTrigger) {
1503					plugin.onTrigger(event);
1504				}
1505			});
1506
1507			this.register({ type: Owl.Type.Event, name: name });
1508			this.$element.trigger(event);
1509
1510			if (this.settings && typeof this.settings[handler] === 'function') {
1511				this.settings[handler].call(this, event);
1512			}
1513		}
1514
1515		return event;
1516	};
1517
1518	/**
1519	 * Enters a state.
1520	 * @param name - The state name.
1521	 */
1522	Owl.prototype.enter = function(name) {
1523		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1524			if (this._states.current[name] === undefined) {
1525				this._states.current[name] = 0;
1526			}
1527
1528			this._states.current[name]++;
1529		}, this));
1530	};
1531
1532	/**
1533	 * Leaves a state.
1534	 * @param name - The state name.
1535	 */
1536	Owl.prototype.leave = function(name) {
1537		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1538			this._states.current[name]--;
1539		}, this));
1540	};
1541
1542	/**
1543	 * Registers an event or state.
1544	 * @public
1545	 * @param {Object} object - The event or state to register.
1546	 */
1547	Owl.prototype.register = function(object) {
1548		if (object.type === Owl.Type.Event) {
1549			if (!$.event.special[object.name]) {
1550				$.event.special[object.name] = {};
1551			}
1552
1553			if (!$.event.special[object.name].owl) {
1554				var _default = $.event.special[object.name]._default;
1555				$.event.special[object.name]._default = function(e) {
1556					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
1557						return _default.apply(this, arguments);
1558					}
1559					return e.namespace && e.namespace.indexOf('owl') > -1;
1560				};
1561				$.event.special[object.name].owl = true;
1562			}
1563		} else if (object.type === Owl.Type.State) {
1564			if (!this._states.tags[object.name]) {
1565				this._states.tags[object.name] = object.tags;
1566			} else {
1567				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
1568			}
1569
1570			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
1571				return $.inArray(tag, this._states.tags[object.name]) === i;
1572			}, this));
1573		}
1574	};
1575
1576	/**
1577	 * Suppresses events.
1578	 * @protected
1579	 * @param {Array.<String>} events - The events to suppress.
1580	 */
1581	Owl.prototype.suppress = function(events) {
1582		$.each(events, $.proxy(function(index, event) {
1583			this._supress[event] = true;
1584		}, this));
1585	};
1586
1587	/**
1588	 * Releases suppressed events.
1589	 * @protected
1590	 * @param {Array.<String>} events - The events to release.
1591	 */
1592	Owl.prototype.release = function(events) {
1593		$.each(events, $.proxy(function(index, event) {
1594			delete this._supress[event];
1595		}, this));
1596	};
1597
1598	/**
1599	 * Gets unified pointer coordinates from event.
1600	 * @todo #261
1601	 * @protected
1602	 * @param {Event} - The `mousedown` or `touchstart` event.
1603	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
1604	 */
1605	Owl.prototype.pointer = function(event) {
1606		var result = { x: null, y: null };
1607
1608		event = event.originalEvent || event || window.event;
1609
1610		event = event.touches && event.touches.length ?
1611			event.touches[0] : event.changedTouches && event.changedTouches.length ?
1612				event.changedTouches[0] : event;
1613
1614		if (event.pageX) {
1615			result.x = event.pageX;
1616			result.y = event.pageY;
1617		} else {
1618			result.x = event.clientX;
1619			result.y = event.clientY;
1620		}
1621
1622		return result;
1623	};
1624
1625	/**
1626	 * Determines if the input is a Number or something that can be coerced to a Number
1627	 * @protected
1628	 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested
1629	 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number
1630	 */
1631	Owl.prototype.isNumeric = function(number) {
1632		return !isNaN(parseFloat(number));
1633	};
1634
1635	/**
1636	 * Gets the difference of two vectors.
1637	 * @todo #261
1638	 * @protected
1639	 * @param {Object} - The first vector.
1640	 * @param {Object} - The second vector.
1641	 * @returns {Object} - The difference.
1642	 */
1643	Owl.prototype.difference = function(first, second) {
1644		return {
1645			x: first.x - second.x,
1646			y: first.y - second.y
1647		};
1648	};
1649
1650	/**
1651	 * The jQuery Plugin for the Owl Carousel
1652	 * @todo Navigation plugin `next` and `prev`
1653	 * @public
1654	 */
1655	$.fn.owlCarousel = function(option) {
1656		var args = Array.prototype.slice.call(arguments, 1);
1657
1658		return this.each(function() {
1659			var $this = $(this),
1660				data = $this.data('owl.carousel');
1661
1662			if (!data) {
1663				data = new Owl(this, typeof option == 'object' && option);
1664				$this.data('owl.carousel', data);
1665
1666				$.each([
1667					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
1668				], function(i, event) {
1669					data.register({ type: Owl.Type.Event, name: event });
1670					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
1671						if (e.namespace && e.relatedTarget !== this) {
1672							this.suppress([ event ]);
1673							data[event].apply(this, [].slice.call(arguments, 1));
1674							this.release([ event ]);
1675						}
1676					}, data));
1677				});
1678			}
1679
1680			if (typeof option == 'string' && option.charAt(0) !== '_') {
1681				data[option].apply(data, args);
1682			}
1683		});
1684	};
1685
1686	/**
1687	 * The constructor for the jQuery Plugin
1688	 * @public
1689	 */
1690	$.fn.owlCarousel.Constructor = Owl;
1691
1692})(window.Zepto || window.jQuery, window, document);

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.