PageSourceSearch

https://www.theblistblog.com/wp-content/plugins/portfolio-wp/js/owl-carousel/owl.carousel.js?ver=7.0.6

js theblistblog.com collected 2026-09-26 16:53:13 UTC 89,535 bytes, 3,432 lines download raw bytes

vendor: 22,759 bytes, lines 1-931
1
2;(function($, window, document, undefined) {
3
4	/**
5	 * Creates a carousel.
6	 * @class The Owl Carousel.
7	 * @public
8	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
9	 * @param {Object} [options] - The options
10	 */
11	function Owl(element, options) {
12
13		/**
14		 * Current settings for the carousel.
15		 * @public
16		 */
17		this.settings = null;
18
19		/**
20		 * Current options set by the caller including defaults.
21		 * @public
22		 */
23		this.options = $.extend({}, Owl.Defaults, options);
24
25		/**
26		 * Plugin element.
27		 * @public
28		 */
29		this.$element = $(element);
30
31		/**
32		 * Proxied event handlers.
33		 * @protected
34		 */
35		this._handlers = {};
36
37		/**
38		 * References to the running plugins of this carousel.
39		 * @protected
40		 */
41		this._plugins = {};
42
43		/**
44		 * Currently suppressed events to prevent them from being retriggered.
45		 * @protected
46		 */
47		this._supress = {};
48
49		/**
50		 * Absolute current position.
51		 * @protected
52		 */
53		this._current = null;
54
55		/**
56		 * Animation speed in milliseconds.
57		 * @protected
58		 */
59		this._speed = null;
60
61		/**
62		 * Coordinates of all items in pixel.
63		 * @todo The name of this member is missleading.
64		 * @protected
65		 */
66		this._coordinates = [];
67
68		/**
69		 * Current breakpoint.
70		 * @todo Real media queries would be nice.
71		 * @protected
72		 */
73		this._breakpoint = null;
74
75		/**
76		 * Current width of the plugin element.
77		 */
78		this._width = null;
79
80		/**
81		 * All real items.
82		 * @protected
83		 */
84		this._items = [];
85
86		/**
87		 * All cloned items.
88		 * @protected
89		 */
90		this._clones = [];
91
92		/**
93		 * Merge values of all items.
94		 * @todo Maybe this could be part of a plugin.
95		 * @protected
96		 */
97		this._mergers = [];
98
99		/**
100		 * Widths of all items.
101		 */
102		this._widths = [];
103
104		/**
105		 * Invalidated parts within the update process.
106		 * @protected
107		 */
108		this._invalidated = {};
109
110		/**
111		 * Ordered list of workers for the update process.
112		 * @protected
113		 */
114		this._pipe = [];
115
116		/**
117		 * Current state information for the drag operation.
118		 * @todo #261
119		 * @protected
120		 */
121		this._drag = {
122			time: null,
123			target: null,
124			pointer: null,
125			stage: {
126				start: null,
127				current: null
128			},
129			direction: null
130		};
131
132		/**
133		 * Current state information and their tags.
134		 * @type {Object}
135		 * @protected
136		 */
137		this._states = {
138			current: {},
139			tags: {
140				'initializing': [ 'busy' ],
141				'animating': [ 'busy' ],
142				'dragging': [ 'interacting' ]
143			}
144		};
145
146		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
147			this._handlers[handler] = $.proxy(this[handler], this);
148		}, this));
149
150		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
151			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
152				= new plugin(this);
153		}, this));
154
155		$.each(Owl.Workers, $.proxy(function(priority, worker) {
156			this._pipe.push({
157				'filter': worker.filter,
158				'run': $.proxy(worker.run, this)
159			});
160		}, this));
161
162		this.setup();
163		this.initialize();
164	}
165
166	/**
167	 * Default options for the carousel.
168	 * @public
169	 */
170	Owl.Defaults = {
171		items: 3,
172		loop: false,
173		center: false,
174		rewind: false,
175		checkVisibility: true,
176
177		mouseDrag: true,
178		touchDrag: true,
179		pullDrag: true,
180		freeDrag: false,
181
182		margin: 0,
183		stagePadding: 0,
184
185		merge: false,
186		mergeFit: true,
187		autoWidth: false,
188
189		startPosition: 0,
190		rtl: false,
191
192		smartSpeed: 250,
193		fluidSpeed: false,
194		dragEndSpeed: false,
195
196		responsive: {},
197		responsiveRefreshRate: 200,
198		responsiveBaseElement: window,
199
200		fallbackEasing: 'swing',
201		slideTransition: '',
202
203		info: false,
204
205		nestedItemSelector: false,
206		itemElement: 'div',
207		stageElement: 'div',
208
209		refreshClass: 'owl-refresh',
210		loadedClass: 'owl-loaded',
211		loadingClass: 'owl-loading',
212		rtlClass: 'owl-rtl',
213		responsiveClass: 'owl-responsive',
214		dragClass: 'owl-drag',
215		itemClass: 'owl-item',
216		stageClass: 'owl-stage',
217		stageOuterClass: 'owl-stage-outer',
218		grabClass: 'owl-grab'
219	};
220
221	/**
222	 * Enumeration for width.
223	 * @public
224	 * @readonly
225	 * @enum {String}
226	 */
227	Owl.Width = {
228		Default: 'default',
229		Inner: 'inner',
230		Outer: 'outer'
231	};
232
233	/**
234	 * Enumeration for types.
235	 * @public
236	 * @readonly
237	 * @enum {String}
238	 */
239	Owl.Type = {
240		Event: 'event',
241		State: 'state'
242	};
243
244	/**
245	 * Contains all registered plugins.
246	 * @public
247	 */
248	Owl.Plugins = {};
249
250	/**
251	 * List of workers involved in the update process.
252	 */
253	Owl.Workers = [ {
254		filter: [ 'width', 'settings' ],
255		run: function() {
256			this._width = this.$element.width();
257		}
258	}, {
259		filter: [ 'width', 'items', 'settings' ],
260		run: function(cache) {
261			cache.current = this._items && this._items[this.relative(this._current)];
262		}
263	}, {
264		filter: [ 'items', 'settings' ],
265		run: function() {
266			this.$stage.children('.cloned').remove();
267		}
268	}, {
269		filter: [ 'width', 'items', 'settings' ],
270		run: function(cache) {
271			var margin = this.settings.margin || '',
272				grid = !this.settings.autoWidth,
273				rtl = this.settings.rtl,
274				css = {
275					'width': 'auto',
276					'margin-left': rtl ? margin : '',
277					'margin-right': rtl ? '' : margin
278				};
279
280			!grid && this.$stage.children().css(css);
281
282			cache.css = css;
283		}
284	}, {
285		filter: [ 'width', 'items', 'settings' ],
286		run: function(cache) {
287			var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
288				merge = null,
289				iterator = this._items.length,
290				grid = !this.settings.autoWidth,
291				widths = [];
292
293			cache.items = {
294				merge: false,
295				width: width
296			};
297
298			while (iterator--) {
299				merge = this._mergers[iterator];
300				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
301
302				cache.items.merge = merge > 1 || cache.items.merge;
303
304				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
305			}
306
307			this._widths = widths;
308		}
309	}, {
310		filter: [ 'items', 'settings' ],
311		run: function() {
312			var clones = [],
313				items = this._items,
314				settings = this.settings,
315				// TODO: Should be computed from number of min width items in stage
316				view = Math.max(settings.items * 2, 4),
317				size = Math.ceil(items.length / 2) * 2,
318				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
319				append = '',
320				prepend = '';
321
322			repeat /= 2;
323
324			while (repeat > 0) {
325				// Switch to only using appended clones
326				clones.push(this.normalize(clones.length / 2, true));
327				append = append + items[clones[clones.length - 1]][0].outerHTML;
328				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
329				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
330				repeat -= 1;
331			}
332
333			this._clones = clones;
334
335			$(append).addClass('cloned').appendTo(this.$stage);
336			$(prepend).addClass('cloned').prependTo(this.$stage);
337		}
338	}, {
339		filter: [ 'width', 'items', 'settings' ],
340		run: function() {
341			var rtl = this.settings.rtl ? 1 : -1,
342				size = this._clones.length + this._items.length,
343				iterator = -1,
344				previous = 0,
345				current = 0,
346				coordinates = [];
347
348			while (++iterator < size) {
349				previous = coordinates[iterator - 1] || 0;
350				current = this._widths[this.relative(iterator)] + this.settings.margin;
351				coordinates.push(previous + current * rtl);
352			}
353
354			this._coordinates = coordinates;
355		}
356	}, {
357		filter: [ 'width', 'items', 'settings' ],
358		run: function() {
359			var padding = this.settings.stagePadding,
360				coordinates = this._coordinates,
361				css = {
362					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
363					'padding-left': padding || '',
364					'padding-right': padding || ''
365				};
366
367			this.$stage.css(css);
368		}
369	}, {
370		filter: [ 'width', 'items', 'settings' ],
371		run: function(cache) {
372			var iterator = this._coordinates.length,
373				grid = !this.settings.autoWidth,
374				items = this.$stage.children();
375
376			if (grid && cache.items.merge) {
377				while (iterator--) {
378					cache.css.width = this._widths[this.relative(iterator)];
379					items.eq(iterator).css(cache.css);
380				}
381			} else if (grid) {
382				cache.css.width = cache.items.width;
383				items.css(cache.css);
384			}
385		}
386	}, {
387		filter: [ 'items' ],
388		run: function() {
389			this._coordinates.length < 1 && this.$stage.removeAttr('style');
390		}
391	}, {
392		filter: [ 'width', 'items', 'settings' ],
393		run: function(cache) {
394			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
395			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
396			this.reset(cache.current);
397		}
398	}, {
399		filter: [ 'position' ],
400		run: function() {
401			this.animate(this.coordinates(this._current));
402		}
403	}, {
404		filter: [ 'width', 'position', 'items', 'settings' ],
405		run: function() {
406			var rtl = this.settings.rtl ? 1 : -1,
407				padding = this.settings.stagePadding * 2,
408				begin = this.coordinates(this.current()) + padding,
409				end = begin + this.width() * rtl,
410				inner, outer, matches = [], i, n;
411
412			for (i = 0, n = this._coordinates.length; i < n; i++) {
413				inner = this._coordinates[i - 1] || 0;
414				outer = Math.abs(this._coordinates[i]) + padding * rtl;
415
416				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
417					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
418					matches.push(i);
419				}
420			}
421
422			this.$stage.children('.active').removeClass('active');
423			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
424
425			this.$stage.children('.center').removeClass('center');
426			if (this.settings.center) {
427				this.$stage.children().eq(this.current()).addClass('center');
428			}
429		}
430	} ];
431
432	/**
433	 * Create the stage DOM element
434	 */
435	Owl.prototype.initializeStage = function() {
436		this.$stage = this.$element.find('.' + this.settings.stageClass);
437
438		// if the stage is already in the DOM, grab it and skip stage initialization
439		if (this.$stage.length) {
440			return;
441		}
442
443		this.$element.addClass(this.options.loadingClass);
444
445		// create stage
446		this.$stage = $('<' + this.settings.stageElement + '>', {
447			"class": this.settings.stageClass
448		}).wrap( $( '<div/>', {
449			"class": this.settings.stageOuterClass
450		}));
451
452		// append stage
453		this.$element.append(this.$stage.parent());
454	};
455
456	/**
457	 * Create item DOM elements
458	 */
459	Owl.prototype.initializeItems = function() {
460		var $items = this.$element.find('.owl-item');
461
462		// if the items are already in the DOM, grab them and skip item initialization
463		if ($items.length) {
464			this._items = $items.get().map(function(item) {
465				return $(item);
466			});
467
468			this._mergers = this._items.map(function() {
469				return 1;
470			});
471
472			this.refresh();
473
474			return;
475		}
476
477		// append content
478		this.replace(this.$element.children().not(this.$stage.parent()));
479
480		// check visibility
481		if (this.isVisible()) {
482			// update view
483			this.refresh();
484		} else {
485			// invalidate width
486			this.invalidate('width');
487		}
488
489		this.$element
490			.removeClass(this.options.loadingClass)
491			.addClass(this.options.loadedClass);
492	};
493
494	/**
495	 * Initializes the carousel.
496	 * @protected
497	 */
498	Owl.prototype.initialize = function() {
499		this.enter('initializing');
500		this.trigger('initialize');
501
502		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
503
504		if (this.settings.autoWidth && !this.is('pre-loading')) {
505			var imgs, nestedSelector, width;
506			imgs = this.$element.find('img');
507			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
508			width = this.$element.children(nestedSelector).width();
509
510			if (imgs.length && width <= 0) {
511				this.preloadAutoWidthImages(imgs);
512			}
513		}
514
515		this.initializeStage();
516		this.initializeItems();
517
518		// register event handlers
519		this.registerEventHandlers();
520
521		this.leave('initializing');
522		this.trigger('initialized');
523	};
524
525	/**
526	 * @returns {Boolean} visibility of $element
527	 *                    if you know the carousel will always be visible you can set `checkVisibility` to `false` to
528	 *                    prevent the expensive browser layout forced reflow the $element.is(':visible') does
529	 */
530	Owl.prototype.isVisible = function() {
531		return this.settings.checkVisibility
532			? this.$element.is(':visible')
533			: true;
534	};
535
536	/**
537	 * Setups the current settings.
538	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
539	 * @todo Support for media queries by using `matchMedia` would be nice.
540	 * @public
541	 */
542	Owl.prototype.setup = function() {
543		var viewport = this.viewport(),
544			overwrites = this.options.responsive,
545			match = -1,
546			settings = null;
547
548		if (!overwrites) {
549			settings = $.extend({}, this.options);
550		} else {
551			$.each(overwrites, function(breakpoint) {
552				if (breakpoint <= viewport && breakpoint > match) {
553					match = Number(breakpoint);
554				}
555			});
556
557			settings = $.extend({}, this.options, overwrites[match]);
558			if (typeof settings.stagePadding === 'function') {
559				settings.stagePadding = settings.stagePadding();
560			}
561			delete settings.responsive;
562
563			// responsive class
564			if (settings.responsiveClass) {
565				this.$element.attr('class',
566					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
567				);
568			}
569		}
570
571		this.trigger('change', { property: { name: 'settings', value: settings } });
572		this._breakpoint = match;
573		this.settings = settings;
574		this.invalidate('settings');
575		this.trigger('changed', { property: { name: 'settings', value: this.settings } });
576	};
577
578	/**
579	 * Updates option logic if necessery.
580	 * @protected
581	 */
582	Owl.prototype.optionsLogic = function() {
583		if (this.settings.autoWidth) {
584			this.settings.stagePadding = false;
585			this.settings.merge = false;
586		}
587	};
588
589	/**
590	 * Prepares an item before add.
591	 * @todo Rename event parameter `content` to `item`.
592	 * @protected
593	 * @returns {jQuery|HTMLElement} - The item container.
594	 */
595	Owl.prototype.prepare = function(item) {
596		var event = this.trigger('prepare', { content: item });
597
598		if (!event.data) {
599			event.data = $('<' + this.settings.itemElement + '/>')
600				.addClass(this.options.itemClass).append(item)
601		}
602
603		this.trigger('prepared', { content: event.data });
604
605		return event.data;
606	};
607
608	/**
609	 * Updates the view.
610	 * @public
611	 */
612	Owl.prototype.update = function() {
613		var i = 0,
614			n = this._pipe.length,
615			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
616			cache = {};
617
618		while (i < n) {
619			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
620				this._pipe[i].run(cache);
621			}
622			i++;
623		}
624
625		this._invalidated = {};
626
627		!this.is('valid') && this.enter('valid');
628	};
629
630	/**
631	 * Gets the width of the view.
632	 * @public
633	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
634	 * @returns {Number} - The width of the view in pixel.
635	 */
636	Owl.prototype.width = function(dimension) {
637		dimension = dimension || Owl.Width.Default;
638		switch (dimension) {
639			case Owl.Width.Inner:
640			case Owl.Width.Outer:
641				return this._width;
642			default:
643				return this._width - this.settings.stagePadding * 2 + this.settings.margin;
644		}
645	};
646
647	/**
648	 * Refreshes the carousel primarily for adaptive purposes.
649	 * @public
650	 */
651	Owl.prototype.refresh = function() {
652		this.enter('refreshing');
653		this.trigger('refresh');
654
655		this.setup();
656
657		this.optionsLogic();
658
659		this.$element.addClass(this.options.refreshClass);
660
661		this.update();
662
663		this.$element.removeClass(this.options.refreshClass);
664
665		this.leave('refreshing');
666		this.trigger('refreshed');
667	};
668
669	/**
670	 * Checks window `resize` event.
671	 * @protected
672	 */
673	Owl.prototype.onThrottledResize = function() {
674		window.clearTimeout(this.resizeTimer);
675		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
676	};
677
678	/**
679	 * Checks window `resize` event.
680	 * @protected
681	 */
682	Owl.prototype.onResize = function() {
683		if (!this._items.length) {
684			return false;
685		}
686
687		if (this._width === this.$element.width()) {
688			return false;
689		}
690
691		if (!this.isVisible()) {
692			return false;
693		}
694
695		this.enter('resizing');
696
697		if (this.trigger('resize').isDefaultPrevented()) {
698			this.leave('resizing');
699			return false;
700		}
701
702		this.invalidate('width');
703
704		this.refresh();
705
706		this.leave('resizing');
707		this.trigger('resized');
708	};
709
710	/**
711	 * Registers event handlers.
712	 * @todo Check `msPointerEnabled`
713	 * @todo #261
714	 * @protected
715	 */
716	Owl.prototype.registerEventHandlers = function() {
717		if ($.support.transition) {
718			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
719		}
720
721		if (this.settings.responsive !== false) {
722			this.on(window, 'resize', this._handlers.onThrottledResize);
723		}
724
725		if (this.settings.mouseDrag) {
726			this.$element.addClass(this.options.dragClass);
727			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
728			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
729		}
730
731		if (this.settings.touchDrag){
732			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
733			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
734		}
735	};
736
737	/**
738	 * Handles `touchstart` and `mousedown` events.
739	 * @todo Horizontal swipe threshold as option
740	 * @todo #261
741	 * @protected
742	 * @param {Event} event - The event arguments.
743	 */
744	Owl.prototype.onDragStart = function(event) {
745		var stage = null;
746
747		if (event.which === 3) {
748			return;
749		}
750
751		if ($.support.transform) {
752			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
753			stage = {
754				x: stage[stage.length === 16 ? 12 : 4],
755				y: stage[stage.length === 16 ? 13 : 5]
756			};
757		} else {
758			stage = this.$stage.position();
759			stage = {
760				x: this.settings.rtl ?
761					stage.left + this.$stage.width() - this.width() + this.settings.margin :
762					stage.left,
763				y: stage.top
764			};
765		}
766
767		if (this.is('animating')) {
768			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
769			this.invalidate('position');
770		}
771
772		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
773
774		this.speed(0);
775
776		this._drag.time = new Date().getTime();
777		this._drag.target = $(event.target);
778		this._drag.stage.start = stage;
779		this._drag.stage.current = stage;
780		this._drag.pointer = this.pointer(event);
781
782		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
783
784		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
785			var delta = this.difference(this._drag.pointer, this.pointer(event));
786
787			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
788
789			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
790				return;
791			}
792
793			event.preventDefault();
794
795			this.enter('dragging');
796			this.trigger('drag');
797		}, this));
798	};
799
800	/**
801	 * Handles the `touchmove` and `mousemove` events.
802	 * @todo #261
803	 * @protected
804	 * @param {Event} event - The event arguments.
805	 */
806	Owl.prototype.onDragMove = function(event) {
807		var minimum = null,
808			maximum = null,
809			pull = null,
810			delta = this.difference(this._drag.pointer, this.pointer(event)),
811			stage = this.difference(this._drag.stage.start, delta);
812
813		if (!this.is('dragging')) {
814			return;
815		}
816
817		event.preventDefault();
818
819		if (this.settings.loop) {
820			minimum = this.coordinates(this.minimum());
821			maximum = this.coordinates(this.maximum() + 1) - minimum;
822			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
823		} else {
824			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
825			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
826			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
827			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
828		}
829
830		this._drag.stage.current = stage;
831
832		this.animate(stage.x);
833	};
834
835	/**
836	 * Handles the `touchend` and `mouseup` events.
837	 * @todo #261
838	 * @todo Threshold for click event
839	 * @protected
840	 * @param {Event} event - The event arguments.
841	 */
842	Owl.prototype.onDragEnd = function(event) {
843		var delta = this.difference(this._drag.pointer, this.pointer(event)),
844			stage = this._drag.stage.current,
845			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
846
847		$(document).off('.owl.core');
848
849		this.$element.removeClass(this.options.grabClass);
850
851		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
852			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
853			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
854			this.invalidate('position');
855			this.update();
856
857			this._drag.direction = direction;
858
859			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
860				this._drag.target.one('click.owl.core', function() { return false; });
861			}
862		}
863
864		if (!this.is('dragging')) {
865			return;
866		}
867
868		this.leave('dragging');
869		this.trigger('dragged');
870	};
871
872	/**
873	 * Gets absolute position of the closest item for a coordinate.
874	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
875	 * @protected
876	 * @param {Number} coordinate - The coordinate in pixel.
877	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
878	 * @return {Number} - The absolute position of the closest item.
879	 */
880	Owl.prototype.closest = function(coordinate, direction) {
881		var position = -1,
882			pull = 30,
883			width = this.width(),
884			coordinates = this.coordinates();
885
886		if (!this.settings.freeDrag) {
887			// check closest item
888			$.each(coordinates, $.proxy(function(index, value) {
889				// on a left pull, check on current index
890				if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {
891					position = index;
892				// on a right pull, check on previous index
893				// to do so, subtract width from value and set position = index + 1
894				} else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {
895					position = index + 1;
896				} else if (this.op(coordinate, '<', value)
897					&& this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) {
898					position = direction === 'left' ? index + 1 : index;
899				}
900				return position === -1;
901			}, this));
902		}
903
904		if (!this.settings.loop) {
905			// non loop boundries
906			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
907				position = coordinate = this.minimum();
908			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
909				position = coordinate = this.maximum();
910			}
911		}
912
913		return position;
914	};
915
916	/**
917	 * Animates the stage.
918	 * @todo #270
919	 * @public
920	 * @param {Number} coordinate - The coordinate in pixels.
921	 */
922	Owl.prototype.animate = function(coordinate) {
923		var animate = this.speed() > 0;
924
925		this.is('animating') && this.onTransitionEnd();
926
927		if (animate) {
928			this.enter('animating');
929			this.trigger('translate');
930		}
931
vendor: 10,524 bytes, lines 932-1299
932		if ($.support.transform3d && $.support.transition) {
933			this.$stage.css({
934				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
935				transition: (this.speed() / 1000) + 's' + (
936					this.settings.slideTransition ? ' ' + this.settings.slideTransition : ''
937				)
938			});
939		} else if (animate) {
940			this.$stage.animate({
941				left: coordinate + 'px'
942			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
943		} else {
944			this.$stage.css({
945				left: coordinate + 'px'
946			});
947		}
948	};
949
950	/**
951	 * Checks whether the carousel is in a specific state or not.
952	 * @param {String} state - The state to check.
953	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
954	 */
955	Owl.prototype.is = function(state) {
956		return this._states.current[state] && this._states.current[state] > 0;
957	};
958
959	/**
960	 * Sets the absolute position of the current item.
961	 * @public
962	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
963	 * @returns {Number} - The absolute position of the current item.
964	 */
965	Owl.prototype.current = function(position) {
966		if (position === undefined) {
967			return this._current;
968		}
969
970		if (this._items.length === 0) {
971			return undefined;
972		}
973
974		position = this.normalize(position);
975
976		if (this._current !== position) {
977			var event = this.trigger('change', { property: { name: 'position', value: position } });
978
979			if (event.data !== undefined) {
980				position = this.normalize(event.data);
981			}
982
983			this._current = position;
984
985			this.invalidate('position');
986
987			this.trigger('changed', { property: { name: 'position', value: this._current } });
988		}
989
990		return this._current;
991	};
992
993	/**
994	 * Invalidates the given part of the update routine.
995	 * @param {String} [part] - The part to invalidate.
996	 * @returns {Array.<String>} - The invalidated parts.
997	 */
998	Owl.prototype.invalidate = function(part) {
999		if ($.type(part) === 'string') {
1000			this._invalidated[part] = true;
1001			this.is('valid') && this.leave('valid');
1002		}
1003		return $.map(this._invalidated, function(v, i) { return i });
1004	};
1005
1006	/**
1007	 * Resets the absolute position of the current item.
1008	 * @public
1009	 * @param {Number} position - The absolute position of the new item.
1010	 */
1011	Owl.prototype.reset = function(position) {
1012		position = this.normalize(position);
1013
1014		if (position === undefined) {
1015			return;
1016		}
1017
1018		this._speed = 0;
1019		this._current = position;
1020
1021		this.suppress([ 'translate', 'translated' ]);
1022
1023		this.animate(this.coordinates(position));
1024
1025		this.release([ 'translate', 'translated' ]);
1026	};
1027
1028	/**
1029	 * Normalizes an absolute or a relative position of an item.
1030	 * @public
1031	 * @param {Number} position - The absolute or relative position to normalize.
1032	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
1033	 * @returns {Number} - The normalized position.
1034	 */
1035	Owl.prototype.normalize = function(position, relative) {
1036		var n = this._items.length,
1037			m = relative ? 0 : this._clones.length;
1038
1039		if (!this.isNumeric(position) || n < 1) {
1040			position = undefined;
1041		} else if (position < 0 || position >= n + m) {
1042			position = ((position - m / 2) % n + n) % n + m / 2;
1043		}
1044
1045		return position;
1046	};
1047
1048	/**
1049	 * Converts an absolute position of an item into a relative one.
1050	 * @public
1051	 * @param {Number} position - The absolute position to convert.
1052	 * @returns {Number} - The converted position.
1053	 */
1054	Owl.prototype.relative = function(position) {
1055		position -= this._clones.length / 2;
1056		return this.normalize(position, true);
1057	};
1058
1059	/**
1060	 * Gets the maximum position for the current item.
1061	 * @public
1062	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1063	 * @returns {Number}
1064	 */
1065	Owl.prototype.maximum = function(relative) {
1066		var settings = this.settings,
1067			maximum = this._coordinates.length,
1068			iterator,
1069			reciprocalItemsWidth,
1070			elementWidth;
1071
1072		if (settings.loop) {
1073			maximum = this._clones.length / 2 + this._items.length - 1;
1074		} else if (settings.autoWidth || settings.merge) {
1075			iterator = this._items.length;
1076			if (iterator) {
1077				reciprocalItemsWidth = this._items[--iterator].width();
1078				elementWidth = this.$element.width();
1079				while (iterator--) {
1080					reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin;
1081					if (reciprocalItemsWidth > elementWidth) {
1082						break;
1083					}
1084				}
1085			}
1086			maximum = iterator + 1;
1087		} else if (settings.center) {
1088			maximum = this._items.length - 1;
1089		} else {
1090			maximum = this._items.length - settings.items;
1091		}
1092
1093		if (relative) {
1094			maximum -= this._clones.length / 2;
1095		}
1096
1097		return Math.max(maximum, 0);
1098	};
1099
1100	/**
1101	 * Gets the minimum position for the current item.
1102	 * @public
1103	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1104	 * @returns {Number}
1105	 */
1106	Owl.prototype.minimum = function(relative) {
1107		return relative ? 0 : this._clones.length / 2;
1108	};
1109
1110	/**
1111	 * Gets an item at the specified relative position.
1112	 * @public
1113	 * @param {Number} [position] - The relative position of the item.
1114	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1115	 */
1116	Owl.prototype.items = function(position) {
1117		if (position === undefined) {
1118			return this._items.slice();
1119		}
1120
1121		position = this.normalize(position, true);
1122		return this._items[position];
1123	};
1124
1125	/**
1126	 * Gets an item at the specified relative position.
1127	 * @public
1128	 * @param {Number} [position] - The relative position of the item.
1129	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1130	 */
1131	Owl.prototype.mergers = function(position) {
1132		if (position === undefined) {
1133			return this._mergers.slice();
1134		}
1135
1136		position = this.normalize(position, true);
1137		return this._mergers[position];
1138	};
1139
1140	/**
1141	 * Gets the absolute positions of clones for an item.
1142	 * @public
1143	 * @param {Number} [position] - The relative position of the item.
1144	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
1145	 */
1146	Owl.prototype.clones = function(position) {
1147		var odd = this._clones.length / 2,
1148			even = odd + this._items.length,
1149			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
1150
1151		if (position === undefined) {
1152			return $.map(this._clones, function(v, i) { return map(i) });
1153		}
1154
1155		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
1156	};
1157
1158	/**
1159	 * Sets the current animation speed.
1160	 * @public
1161	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
1162	 * @returns {Number} - The current animation speed in milliseconds.
1163	 */
1164	Owl.prototype.speed = function(speed) {
1165		if (speed !== undefined) {
1166			this._speed = speed;
1167		}
1168
1169		return this._speed;
1170	};
1171
1172	/**
1173	 * Gets the coordinate of an item.
1174	 * @todo The name of this method is missleanding.
1175	 * @public
1176	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
1177	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
1178	 */
1179	Owl.prototype.coordinates = function(position) {
1180		var multiplier = 1,
1181			newPosition = position - 1,
1182			coordinate;
1183
1184		if (position === undefined) {
1185			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
1186				return this.coordinates(index);
1187			}, this));
1188		}
1189
1190		if (this.settings.center) {
1191			if (this.settings.rtl) {
1192				multiplier = -1;
1193				newPosition = position + 1;
1194			}
1195
1196			coordinate = this._coordinates[position];
1197			coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;
1198		} else {
1199			coordinate = this._coordinates[newPosition] || 0;
1200		}
1201
1202		coordinate = Math.ceil(coordinate);
1203
1204		return coordinate;
1205	};
1206
1207	/**
1208	 * Calculates the speed for a translation.
1209	 * @protected
1210	 * @param {Number} from - The absolute position of the start item.
1211	 * @param {Number} to - The absolute position of the target item.
1212	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
1213	 * @returns {Number} - The time in milliseconds for the translation.
1214	 */
1215	Owl.prototype.duration = function(from, to, factor) {
1216		if (factor === 0) {
1217			return 0;
1218		}
1219
1220		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
1221	};
1222
1223	/**
1224	 * Slides to the specified item.
1225	 * @public
1226	 * @param {Number} position - The position of the item.
1227	 * @param {Number} [speed] - The time in milliseconds for the transition.
1228	 */
1229	Owl.prototype.to = function(position, speed) {
1230		var current = this.current(),
1231			revert = null,
1232			distance = position - this.relative(current),
1233			direction = (distance > 0) - (distance < 0),
1234			items = this._items.length,
1235			minimum = this.minimum(),
1236			maximum = this.maximum();
1237
1238		if (this.settings.loop) {
1239			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
1240				distance += direction * -1 * items;
1241			}
1242
1243			position = current + distance;
1244			revert = ((position - minimum) % items + items) % items + minimum;
1245
1246			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
1247				current = revert - distance;
1248				position = revert;
1249				this.reset(current);
1250			}
1251		} else if (this.settings.rewind) {
1252			maximum += 1;
1253			position = (position % maximum + maximum) % maximum;
1254		} else {
1255			position = Math.max(minimum, Math.min(maximum, position));
1256		}
1257
1258		this.speed(this.duration(current, position, speed));
1259		this.current(position);
1260
1261		if (this.isVisible()) {
1262			this.update();
1263		}
1264	};
1265
1266	/**
1267	 * Slides to the next item.
1268	 * @public
1269	 * @param {Number} [speed] - The time in milliseconds for the transition.
1270	 */
1271	Owl.prototype.next = function(speed) {
1272		speed = speed || false;
1273		this.to(this.relative(this.current()) + 1, speed);
1274	};
1275
1276	/**
1277	 * Slides to the previous item.
1278	 * @public
1279	 * @param {Number} [speed] - The time in milliseconds for the transition.
1280	 */
1281	Owl.prototype.prev = function(speed) {
1282		speed = speed || false;
1283		this.to(this.relative(this.current()) - 1, speed);
1284	};
1285
1286	/**
1287	 * Handles the end of an animation.
1288	 * @protected
1289	 * @param {Event} event - The event arguments.
1290	 */
1291	Owl.prototype.onTransitionEnd = function(event) {
1292
1293		// if css2 animation then event object is undefined
1294		if (event !== undefined) {
1295			event.stopPropagation();
1296
1297			// Catch only owl-stage transitionEnd event
1298			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
1299				return false;
vendor: 22,957 bytes, lines 1300-2148
1300			}
1301		}
1302
1303		this.leave('animating');
1304		this.trigger('translated');
1305	};
1306
1307	/**
1308	 * Gets viewport width.
1309	 * @protected
1310	 * @return {Number} - The width in pixel.
1311	 */
1312	Owl.prototype.viewport = function() {
1313		var width;
1314		if (this.options.responsiveBaseElement !== window) {
1315			width = $(this.options.responsiveBaseElement).width();
1316		} else if (window.innerWidth) {
1317			width = window.innerWidth;
1318		} else if (document.documentElement && document.documentElement.clientWidth) {
1319			width = document.documentElement.clientWidth;
1320		} else {
1321			console.warn('Can not detect viewport width.');
1322		}
1323		return width;
1324	};
1325
1326	/**
1327	 * Replaces the current content.
1328	 * @public
1329	 * @param {HTMLElement|jQuery|String} content - The new content.
1330	 */
1331	Owl.prototype.replace = function(content) {
1332		this.$stage.empty();
1333		this._items = [];
1334
1335		if (content) {
1336			content = (content instanceof jQuery) ? content : $(content);
1337		}
1338
1339		if (this.settings.nestedItemSelector) {
1340			content = content.find('.' + this.settings.nestedItemSelector);
1341		}
1342
1343		content.filter(function() {
1344			return this.nodeType === 1;
1345		}).each($.proxy(function(index, item) {
1346			item = this.prepare(item);
1347			this.$stage.append(item);
1348			this._items.push(item);
1349			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1350		}, this));
1351
1352		this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
1353
1354		this.invalidate('items');
1355	};
1356
1357	/**
1358	 * Adds an item.
1359	 * @todo Use `item` instead of `content` for the event arguments.
1360	 * @public
1361	 * @param {HTMLElement|jQuery|String} content - The item content to add.
1362	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
1363	 */
1364	Owl.prototype.add = function(content, position) {
1365		var current = this.relative(this._current);
1366
1367		position = position === undefined ? this._items.length : this.normalize(position, true);
1368		content = content instanceof jQuery ? content : $(content);
1369
1370		this.trigger('add', { content: content, position: position });
1371
1372		content = this.prepare(content);
1373
1374		if (this._items.length === 0 || position === this._items.length) {
1375			this._items.length === 0 && this.$stage.append(content);
1376			this._items.length !== 0 && this._items[position - 1].after(content);
1377			this._items.push(content);
1378			this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1379		} else {
1380			this._items[position].before(content);
1381			this._items.splice(position, 0, content);
1382			this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1383		}
1384
1385		this._items[current] && this.reset(this._items[current].index());
1386
1387		this.invalidate('items');
1388
1389		this.trigger('added', { content: content, position: position });
1390	};
1391
1392	/**
1393	 * Removes an item by its position.
1394	 * @todo Use `item` instead of `content` for the event arguments.
1395	 * @public
1396	 * @param {Number} position - The relative position of the item to remove.
1397	 */
1398	Owl.prototype.remove = function(position) {
1399		position = this.normalize(position, true);
1400
1401		if (position === undefined) {
1402			return;
1403		}
1404
1405		this.trigger('remove', { content: this._items[position], position: position });
1406
1407		this._items[position].remove();
1408		this._items.splice(position, 1);
1409		this._mergers.splice(position, 1);
1410
1411		this.invalidate('items');
1412
1413		this.trigger('removed', { content: null, position: position });
1414	};
1415
1416	/**
1417	 * Preloads images with auto width.
1418	 * @todo Replace by a more generic approach
1419	 * @protected
1420	 */
1421	Owl.prototype.preloadAutoWidthImages = function(images) {
1422		images.each($.proxy(function(i, element) {
1423			this.enter('pre-loading');
1424			element = $(element);
1425			$(new Image()).one('load', $.proxy(function(e) {
1426				element.attr('src', e.target.src);
1427				element.css('opacity', 1);
1428				this.leave('pre-loading');
1429				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
1430			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
1431		}, this));
1432	};
1433
1434	/**
1435	 * Destroys the carousel.
1436	 * @public
1437	 */
1438	Owl.prototype.destroy = function() {
1439
1440		this.$element.off('.owl.core');
1441		this.$stage.off('.owl.core');
1442		$(document).off('.owl.core');
1443
1444		if (this.settings.responsive !== false) {
1445			window.clearTimeout(this.resizeTimer);
1446			this.off(window, 'resize', this._handlers.onThrottledResize);
1447		}
1448
1449		for (var i in this._plugins) {
1450			this._plugins[i].destroy();
1451		}
1452
1453		this.$stage.children('.cloned').remove();
1454
1455		this.$stage.unwrap();
1456		this.$stage.children().contents().unwrap();
1457		this.$stage.children().unwrap();
1458		this.$stage.remove();
1459		this.$element
1460			.removeClass(this.options.refreshClass)
1461			.removeClass(this.options.loadingClass)
1462			.removeClass(this.options.loadedClass)
1463			.removeClass(this.options.rtlClass)
1464			.removeClass(this.options.dragClass)
1465			.removeClass(this.options.grabClass)
1466			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
1467			.removeData('owl.carousel');
1468	};
1469
1470	/**
1471	 * Operators to calculate right-to-left and left-to-right.
1472	 * @protected
1473	 * @param {Number} [a] - The left side operand.
1474	 * @param {String} [o] - The operator.
1475	 * @param {Number} [b] - The right side operand.
1476	 */
1477	Owl.prototype.op = function(a, o, b) {
1478		var rtl = this.settings.rtl;
1479		switch (o) {
1480			case '<':
1481				return rtl ? a > b : a < b;
1482			case '>':
1483				return rtl ? a < b : a > b;
1484			case '>=':
1485				return rtl ? a <= b : a >= b;
1486			case '<=':
1487				return rtl ? a >= b : a <= b;
1488			default:
1489				break;
1490		}
1491	};
1492
1493	/**
1494	 * Attaches to an internal event.
1495	 * @protected
1496	 * @param {HTMLElement} element - The event source.
1497	 * @param {String} event - The event name.
1498	 * @param {Function} listener - The event handler to attach.
1499	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
1500	 */
1501	Owl.prototype.on = function(element, event, listener, capture) {
1502		if (element.addEventListener) {
1503			element.addEventListener(event, listener, capture);
1504		} else if (element.attachEvent) {
1505			element.attachEvent('on' + event, listener);
1506		}
1507	};
1508
1509	/**
1510	 * Detaches from an internal event.
1511	 * @protected
1512	 * @param {HTMLElement} element - The event source.
1513	 * @param {String} event - The event name.
1514	 * @param {Function} listener - The attached event handler to detach.
1515	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
1516	 */
1517	Owl.prototype.off = function(element, event, listener, capture) {
1518		if (element.removeEventListener) {
1519			element.removeEventListener(event, listener, capture);
1520		} else if (element.detachEvent) {
1521			element.detachEvent('on' + event, listener);
1522		}
1523	};
1524
1525	/**
1526	 * Triggers a public event.
1527	 * @todo Remove `status`, `relatedTarget` should be used instead.
1528	 * @protected
1529	 * @param {String} name - The event name.
1530	 * @param {*} [data=null] - The event data.
1531	 * @param {String} [namespace=carousel] - The event namespace.
1532	 * @param {String} [state] - The state which is associated with the event.
1533	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
1534	 * @returns {Event} - The event arguments.
1535	 */
1536	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
1537		var status = {
1538			item: { count: this._items.length, index: this.current() }
1539		}, handler = $.camelCase(
1540			$.grep([ 'on', name, namespace ], function(v) { return v })
1541				.join('-').toLowerCase()
1542		), event = $.Event(
1543			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
1544			$.extend({ relatedTarget: this }, status, data)
1545		);
1546
1547		if (!this._supress[name]) {
1548			$.each(this._plugins, function(name, plugin) {
1549				if (plugin.onTrigger) {
1550					plugin.onTrigger(event);
1551				}
1552			});
1553
1554			this.register({ type: Owl.Type.Event, name: name });
1555			this.$element.trigger(event);
1556
1557			if (this.settings && typeof this.settings[handler] === 'function') {
1558				this.settings[handler].call(this, event);
1559			}
1560		}
1561
1562		return event;
1563	};
1564
1565	/**
1566	 * Enters a state.
1567	 * @param name - The state name.
1568	 */
1569	Owl.prototype.enter = function(name) {
1570		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1571			if (this._states.current[name] === undefined) {
1572				this._states.current[name] = 0;
1573			}
1574
1575			this._states.current[name]++;
1576		}, this));
1577	};
1578
1579	/**
1580	 * Leaves a state.
1581	 * @param name - The state name.
1582	 */
1583	Owl.prototype.leave = function(name) {
1584		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1585			this._states.current[name]--;
1586		}, this));
1587	};
1588
1589	/**
1590	 * Registers an event or state.
1591	 * @public
1592	 * @param {Object} object - The event or state to register.
1593	 */
1594	Owl.prototype.register = function(object) {
1595		if (object.type === Owl.Type.Event) {
1596			if (!$.event.special[object.name]) {
1597				$.event.special[object.name] = {};
1598			}
1599
1600			if (!$.event.special[object.name].owl) {
1601				var _default = $.event.special[object.name]._default;
1602				$.event.special[object.name]._default = function(e) {
1603					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
1604						return _default.apply(this, arguments);
1605					}
1606					return e.namespace && e.namespace.indexOf('owl') > -1;
1607				};
1608				$.event.special[object.name].owl = true;
1609			}
1610		} else if (object.type === Owl.Type.State) {
1611			if (!this._states.tags[object.name]) {
1612				this._states.tags[object.name] = object.tags;
1613			} else {
1614				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
1615			}
1616
1617			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
1618				return $.inArray(tag, this._states.tags[object.name]) === i;
1619			}, this));
1620		}
1621	};
1622
1623	/**
1624	 * Suppresses events.
1625	 * @protected
1626	 * @param {Array.<String>} events - The events to suppress.
1627	 */
1628	Owl.prototype.suppress = function(events) {
1629		$.each(events, $.proxy(function(index, event) {
1630			this._supress[event] = true;
1631		}, this));
1632	};
1633
1634	/**
1635	 * Releases suppressed events.
1636	 * @protected
1637	 * @param {Array.<String>} events - The events to release.
1638	 */
1639	Owl.prototype.release = function(events) {
1640		$.each(events, $.proxy(function(index, event) {
1641			delete this._supress[event];
1642		}, this));
1643	};
1644
1645	/**
1646	 * Gets unified pointer coordinates from event.
1647	 * @todo #261
1648	 * @protected
1649	 * @param {Event} - The `mousedown` or `touchstart` event.
1650	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
1651	 */
1652	Owl.prototype.pointer = function(event) {
1653		var result = { x: null, y: null };
1654
1655		event = event.originalEvent || event || window.event;
1656
1657		event = event.touches && event.touches.length ?
1658			event.touches[0] : event.changedTouches && event.changedTouches.length ?
1659				event.changedTouches[0] : event;
1660
1661		if (event.pageX) {
1662			result.x = event.pageX;
1663			result.y = event.pageY;
1664		} else {
1665			result.x = event.clientX;
1666			result.y = event.clientY;
1667		}
1668
1669		return result;
1670	};
1671
1672	/**
1673	 * Determines if the input is a Number or something that can be coerced to a Number
1674	 * @protected
1675	 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested
1676	 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number
1677	 */
1678	Owl.prototype.isNumeric = function(number) {
1679		return !isNaN(parseFloat(number));
1680	};
1681
1682	/**
1683	 * Gets the difference of two vectors.
1684	 * @todo #261
1685	 * @protected
1686	 * @param {Object} - The first vector.
1687	 * @param {Object} - The second vector.
1688	 * @returns {Object} - The difference.
1689	 */
1690	Owl.prototype.difference = function(first, second) {
1691		return {
1692			x: first.x - second.x,
1693			y: first.y - second.y
1694		};
1695	};
1696
1697	/**
1698	 * The jQuery Plugin for the Owl Carousel
1699	 * @todo Navigation plugin `next` and `prev`
1700	 * @public
1701	 */
1702	$.fn.owlCarousel = function(option) {
1703		var args = Array.prototype.slice.call(arguments, 1);
1704
1705		return this.each(function() {
1706			var $this = $(this),
1707				data = $this.data('owl.carousel');
1708
1709			if (!data) {
1710				data = new Owl(this, typeof option == 'object' && option);
1711				$this.data('owl.carousel', data);
1712
1713				$.each([
1714					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
1715				], function(i, event) {
1716					data.register({ type: Owl.Type.Event, name: event });
1717					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
1718						if (e.namespace && e.relatedTarget !== this) {
1719							this.suppress([ event ]);
1720							data[event].apply(this, [].slice.call(arguments, 1));
1721							this.release([ event ]);
1722						}
1723					}, data));
1724				});
1725			}
1726
1727			if (typeof option == 'string' && option.charAt(0) !== '_') {
1728				data[option].apply(data, args);
1729			}
1730		});
1731	};
1732
1733	/**
1734	 * The constructor for the jQuery Plugin
1735	 * @public
1736	 */
1737	$.fn.owlCarousel.Constructor = Owl;
1738
1739})(window.Zepto || window.jQuery, window, document);
1740
1741/**
1742 * AutoRefresh Plugin
1743 * @version 2.3.4
1744 * @author Artus Kolanowski
1745 * @author David Deutsch
1746 * @license The MIT License (MIT)
1747 */
1748;(function($, window, document, undefined) {
1749
1750	/**
1751	 * Creates the auto refresh plugin.
1752	 * @class The Auto Refresh Plugin
1753	 * @param {Owl} carousel - The Owl Carousel
1754	 */
1755	var AutoRefresh = function(carousel) {
1756		/**
1757		 * Reference to the core.
1758		 * @protected
1759		 * @type {Owl}
1760		 */
1761		this._core = carousel;
1762
1763		/**
1764		 * Refresh interval.
1765		 * @protected
1766		 * @type {number}
1767		 */
1768		this._interval = null;
1769
1770		/**
1771		 * Whether the element is currently visible or not.
1772		 * @protected
1773		 * @type {Boolean}
1774		 */
1775		this._visible = null;
1776
1777		/**
1778		 * All event handlers.
1779		 * @protected
1780		 * @type {Object}
1781		 */
1782		this._handlers = {
1783			'initialized.owl.carousel': $.proxy(function(e) {
1784				if (e.namespace && this._core.settings.autoRefresh) {
1785					this.watch();
1786				}
1787			}, this)
1788		};
1789
1790		// set default options
1791		this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
1792
1793		// register event handlers
1794		this._core.$element.on(this._handlers);
1795	};
1796
1797	/**
1798	 * Default options.
1799	 * @public
1800	 */
1801	AutoRefresh.Defaults = {
1802		autoRefresh: true,
1803		autoRefreshInterval: 500
1804	};
1805
1806	/**
1807	 * Watches the element.
1808	 */
1809	AutoRefresh.prototype.watch = function() {
1810		if (this._interval) {
1811			return;
1812		}
1813
1814		this._visible = this._core.isVisible();
1815		this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
1816	};
1817
1818	/**
1819	 * Refreshes the element.
1820	 */
1821	AutoRefresh.prototype.refresh = function() {
1822		if (this._core.isVisible() === this._visible) {
1823			return;
1824		}
1825
1826		this._visible = !this._visible;
1827
1828		this._core.$element.toggleClass('owl-hidden', !this._visible);
1829
1830		this._visible && (this._core.invalidate('width') && this._core.refresh());
1831	};
1832
1833	/**
1834	 * Destroys the plugin.
1835	 */
1836	AutoRefresh.prototype.destroy = function() {
1837		var handler, property;
1838
1839		window.clearInterval(this._interval);
1840
1841		for (handler in this._handlers) {
1842			this._core.$element.off(handler, this._handlers[handler]);
1843		}
1844		for (property in Object.getOwnPropertyNames(this)) {
1845			typeof this[property] != 'function' && (this[property] = null);
1846		}
1847	};
1848
1849	$.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
1850
1851})(window.Zepto || window.jQuery, window, document);
1852
1853/**
1854 * Lazy Plugin
1855 * @version 2.3.4
1856 * @author Bartosz Wojciechowski
1857 * @author David Deutsch
1858 * @license The MIT License (MIT)
1859 */
1860;(function($, window, document, undefined) {
1861
1862	/**
1863	 * Creates the lazy plugin.
1864	 * @class The Lazy Plugin
1865	 * @param {Owl} carousel - The Owl Carousel
1866	 */
1867	var Lazy = function(carousel) {
1868
1869		/**
1870		 * Reference to the core.
1871		 * @protected
1872		 * @type {Owl}
1873		 */
1874		this._core = carousel;
1875
1876		/**
1877		 * Already loaded items.
1878		 * @protected
1879		 * @type {Array.<jQuery>}
1880		 */
1881		this._loaded = [];
1882
1883		/**
1884		 * Event handlers.
1885		 * @protected
1886		 * @type {Object}
1887		 */
1888		this._handlers = {
1889			'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) {
1890				if (!e.namespace) {
1891					return;
1892				}
1893
1894				if (!this._core.settings || !this._core.settings.lazyLoad) {
1895					return;
1896				}
1897
1898				if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
1899					var settings = this._core.settings,
1900						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
1901						i = ((settings.center && n * -1) || 0),
1902						position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i,
1903						clones = this._core.clones().length,
1904						load = $.proxy(function(i, v) { this.load(v) }, this);
1905					//TODO: Need documentation for this new option
1906					if (settings.lazyLoadEager > 0) {
1907						n += settings.lazyLoadEager;
1908						// If the carousel is looping also preload images that are to the "left"
1909						if (settings.loop) {
1910              position -= settings.lazyLoadEager;
1911              n++;
1912            }
1913					}
1914
1915					while (i++ < n) {
1916						this.load(clones / 2 + this._core.relative(position));
1917						clones && $.each(this._core.clones(this._core.relative(position)), load);
1918						position++;
1919					}
1920				}
1921			}, this)
1922		};
1923
1924		// set the default options
1925		this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
1926
1927		// register event handler
1928		this._core.$element.on(this._handlers);
1929	};
1930
1931	/**
1932	 * Default options.
1933	 * @public
1934	 */
1935	Lazy.Defaults = {
1936		lazyLoad: false,
1937		lazyLoadEager: 0
1938	};
1939
1940	/**
1941	 * Loads all resources of an item at the specified position.
1942	 * @param {Number} position - The absolute position of the item.
1943	 * @protected
1944	 */
1945	Lazy.prototype.load = function(position) {
1946		var $item = this._core.$stage.children().eq(position),
1947			$elements = $item && $item.find('.owl-lazy');
1948
1949		if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
1950			return;
1951		}
1952
1953		$elements.each($.proxy(function(index, element) {
1954			var $element = $(element), image,
1955                url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src') || $element.attr('data-srcset');
1956
1957			this._core.trigger('load', { element: $element, url: url }, 'lazy');
1958
1959			if ($element.is('img')) {
1960				$element.one('load.owl.lazy', $.proxy(function() {
1961					$element.css('opacity', 1);
1962					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1963				}, this)).attr('src', url);
1964            } else if ($element.is('source')) {
1965                $element.one('load.owl.lazy', $.proxy(function() {
1966                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1967                }, this)).attr('srcset', url);
1968			} else {
1969				image = new Image();
1970				image.onload = $.proxy(function() {
1971					$element.css({
1972						'background-image': 'url("' + url + '")',
1973						'opacity': '1'
1974					});
1975					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1976				}, this);
1977				image.src = url;
1978			}
1979		}, this));
1980
1981		this._loaded.push($item.get(0));
1982	};
1983
1984	/**
1985	 * Destroys the plugin.
1986	 * @public
1987	 */
1988	Lazy.prototype.destroy = function() {
1989		var handler, property;
1990
1991		for (handler in this.handlers) {
1992			this._core.$element.off(handler, this.handlers[handler]);
1993		}
1994		for (property in Object.getOwnPropertyNames(this)) {
1995			typeof this[property] != 'function' && (this[property] = null);
1996		}
1997	};
1998
1999	$.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
2000
2001})(window.Zepto || window.jQuery, window, document);
2002
2003/**
2004 * AutoHeight Plugin
2005 * @version 2.3.4
2006 * @author Bartosz Wojciechowski
2007 * @author David Deutsch
2008 * @license The MIT License (MIT)
2009 */
2010;(function($, window, document, undefined) {
2011
2012	/**
2013	 * Creates the auto height plugin.
2014	 * @class The Auto Height Plugin
2015	 * @param {Owl} carousel - The Owl Carousel
2016	 */
2017	var AutoHeight = function(carousel) {
2018		/**
2019		 * Reference to the core.
2020		 * @protected
2021		 * @type {Owl}
2022		 */
2023		this._core = carousel;
2024
2025		this._previousHeight = null;
2026
2027		/**
2028		 * All event handlers.
2029		 * @protected
2030		 * @type {Object}
2031		 */
2032		this._handlers = {
2033			'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
2034				if (e.namespace && this._core.settings.autoHeight) {
2035					this.update();
2036				}
2037			}, this),
2038			'changed.owl.carousel': $.proxy(function(e) {
2039				if (e.namespace && this._core.settings.autoHeight && e.property.name === 'position'){
2040					this.update();
2041				}
2042			}, this),
2043			'loaded.owl.lazy': $.proxy(function(e) {
2044				if (e.namespace && this._core.settings.autoHeight
2045					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
2046					this.update();
2047				}
2048			}, this)
2049		};
2050
2051		// set default options
2052		this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
2053
2054		// register event handlers
2055		this._core.$element.on(this._handlers);
2056		this._intervalId = null;
2057		var refThis = this;
2058
2059		// These changes have been taken from a PR by gavrochelegnou proposed in #1575
2060		// and have been made compatible with the latest jQuery version
2061		$(window).on('load', function() {
2062			if (refThis._core.settings.autoHeight) {
2063				refThis.update();
2064			}
2065		});
2066
2067		// Autoresize the height of the carousel when window is resized
2068		// When carousel has images, the height is dependent on the width
2069		// and should also change on resize
2070		$(window).resize(function() {
2071			if (refThis._core.settings.autoHeight) {
2072				if (refThis._intervalId != null) {
2073					clearTimeout(refThis._intervalId);
2074				}
2075
2076				refThis._intervalId = setTimeout(function() {
2077					refThis.update();
2078				}, 250);
2079			}
2080		});
2081
2082	};
2083
2084	/**
2085	 * Default options.
2086	 * @public
2087	 */
2088	AutoHeight.Defaults = {
2089		autoHeight: false,
2090		autoHeightClass: 'owl-height'
2091	};
2092
2093	/**
2094	 * Updates the view.
2095	 */
2096	AutoHeight.prototype.update = function() {
2097		var start = this._core._current,
2098			end = start + this._core.settings.items,
2099			lazyLoadEnabled = this._core.settings.lazyLoad,
2100			visible = this._core.$stage.children().toArray().slice(start, end),
2101			heights = [],
2102			maxheight = 0;
2103
2104		$.each(visible, function(index, item) {
2105			heights.push($(item).height());
2106		});
2107
2108		maxheight = Math.max.apply(null, heights);
2109
2110		if (maxheight <= 1 && lazyLoadEnabled && this._previousHeight) {
2111			maxheight = this._previousHeight;
2112		}
2113
2114		this._previousHeight = maxheight;
2115
2116		this._core.$stage.parent()
2117			.height(maxheight)
2118			.addClass(this._core.settings.autoHeightClass);
2119	};
2120
2121	AutoHeight.prototype.destroy = function() {
2122		var handler, property;
2123
2124		for (handler in this._handlers) {
2125			this._core.$element.off(handler, this._handlers[handler]);
2126		}
2127		for (property in Object.getOwnPropertyNames(this)) {
2128			typeof this[property] !== 'function' && (this[property] = null);
2129		}
2130	};
2131
2132	$.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
2133
2134})(window.Zepto || window.jQuery, window, document);
2135
2136/**
2137 * Video Plugin
2138 * @version 2.3.4
2139 * @author Bartosz Wojciechowski
2140 * @author David Deutsch
2141 * @license The MIT License (MIT)
2142 */
2143;(function($, window, document, undefined) {
2144
2145	/**
2146	 * Creates the video plugin.
2147	 * @class The Video Plugin
2148	 * @param {Owl} carousel - The Owl Carousel
vendor: 5,347 bytes, lines 2149-2346
2149	 */
2150	var Video = function(carousel) {
2151		/**
2152		 * Reference to the core.
2153		 * @protected
2154		 * @type {Owl}
2155		 */
2156		this._core = carousel;
2157
2158		/**
2159		 * Cache all video URLs.
2160		 * @protected
2161		 * @type {Object}
2162		 */
2163		this._videos = {};
2164
2165		/**
2166		 * Current playing item.
2167		 * @protected
2168		 * @type {jQuery}
2169		 */
2170		this._playing = null;
2171
2172		/**
2173		 * All event handlers.
2174		 * @todo The cloned content removale is too late
2175		 * @protected
2176		 * @type {Object}
2177		 */
2178		this._handlers = {
2179			'initialized.owl.carousel': $.proxy(function(e) {
2180				if (e.namespace) {
2181					this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
2182				}
2183			}, this),
2184			'resize.owl.carousel': $.proxy(function(e) {
2185				if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
2186					e.preventDefault();
2187				}
2188			}, this),
2189			'refreshed.owl.carousel': $.proxy(function(e) {
2190				if (e.namespace && this._core.is('resizing')) {
2191					this._core.$stage.find('.cloned .owl-video-frame').remove();
2192				}
2193			}, this),
2194			'changed.owl.carousel': $.proxy(function(e) {
2195				if (e.namespace && e.property.name === 'position' && this._playing) {
2196					this.stop();
2197				}
2198			}, this),
2199			'prepared.owl.carousel': $.proxy(function(e) {
2200				if (!e.namespace) {
2201					return;
2202				}
2203
2204				var $element = $(e.content).find('.owl-video');
2205
2206				if ($element.length) {
2207					$element.css('display', 'none');
2208					this.fetch($element, $(e.content));
2209				}
2210			}, this)
2211		};
2212
2213		// set default options
2214		this._core.options = $.extend({}, Video.Defaults, this._core.options);
2215
2216		// register event handlers
2217		this._core.$element.on(this._handlers);
2218
2219		this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
2220			this.play(e);
2221		}, this));
2222	};
2223
2224	/**
2225	 * Default options.
2226	 * @public
2227	 */
2228	Video.Defaults = {
2229		video: false,
2230		videoHeight: false,
2231		videoWidth: false
2232	};
2233
2234	/**
2235	 * Gets the video ID and the type (YouTube/Vimeo/vzaar only).
2236	 * @protected
2237	 * @param {jQuery} target - The target containing the video data.
2238	 * @param {jQuery} item - The item containing the video.
2239	 */
2240	Video.prototype.fetch = function(target, item) {
2241			var type = (function() {
2242					if (target.attr('data-vimeo-id')) {
2243						return 'vimeo';
2244					} else if (target.attr('data-vzaar-id')) {
2245						return 'vzaar'
2246					} else {
2247						return 'youtube';
2248					}
2249				})(),
2250				id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'),
2251				width = target.attr('data-width') || this._core.settings.videoWidth,
2252				height = target.attr('data-height') || this._core.settings.videoHeight,
2253				url = target.attr('href');
2254
2255		if (url) {
2256
2257			/*
2258					Parses the id's out of the following urls (and probably more):
2259					https://www.youtube.com/watch?v=:id
2260					https://youtu.be/:id
2261					https://vimeo.com/:id
2262					https://vimeo.com/channels/:channel/:id
2263					https://vimeo.com/groups/:group/videos/:id
2264					https://app.vzaar.com/videos/:id
2265
2266					Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F
2267			*/
2268
2269			id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
2270
2271			if (id[3].indexOf('youtu') > -1) {
2272				type = 'youtube';
2273			} else if (id[3].indexOf('vimeo') > -1) {
2274				type = 'vimeo';
2275			} else if (id[3].indexOf('vzaar') > -1) {
2276				type = 'vzaar';
2277			} else {
2278				throw new Error('Video URL not supported.');
2279			}
2280			id = id[6];
2281		} else {
2282			throw new Error('Missing video URL.');
2283		}
2284
2285		this._videos[url] = {
2286			type: type,
2287			id: id,
2288			width: width,
2289			height: height
2290		};
2291
2292		item.attr('data-video', url);
2293
2294		this.thumbnail(target, this._videos[url]);
2295	};
2296
2297	/**
2298	 * Creates video thumbnail.
2299	 * @protected
2300	 * @param {jQuery} target - The target containing the video data.
2301	 * @param {Object} info - The video info object.
2302	 * @see `fetch`
2303	 */
2304	Video.prototype.thumbnail = function(target, video) {
2305		var tnLink,
2306			icon,
2307			path,
2308			dimensions = video.width && video.height ? 'width:' + video.width + 'px;height:' + video.height + 'px;' : '',
2309			customTn = target.find('img'),
2310			srcType = 'src',
2311			lazyClass = '',
2312			settings = this._core.settings,
2313			create = function(path) {
2314				icon = '<div class="owl-video-play-icon"></div>';
2315
2316				if (settings.lazyLoad) {
2317					tnLink = $('<div/>',{
2318						"class": 'owl-video-tn ' + lazyClass,
2319						"srcType": path
2320					});
2321				} else {
2322					tnLink = $( '<div/>', {
2323						"class": "owl-video-tn",
2324						"style": 'opacity:1;background-image:url(' + path + ')'
2325					});
2326				}
2327				target.after(tnLink);
2328				target.after(icon);
2329			};
2330
2331		// wrap video content into owl-video-wrapper div
2332		target.wrap( $( '<div/>', {
2333			"class": "owl-video-wrapper",
2334			"style": dimensions
2335		}));
2336
2337		if (this._core.settings.lazyLoad) {
2338			srcType = 'data-src';
2339			lazyClass = 'owl-lazy';
2340		}
2341
2342		// custom thumbnail
2343		if (customTn.length) {
2344			create(customTn.attr(srcType));
2345			customTn.remove();
2346			return false;
vendor: 15,908 bytes, lines 2347-2984
2347		}
2348
2349		if (video.type === 'youtube') {
2350			path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
2351			create(path);
2352		} else if (video.type === 'vimeo') {
2353			$.ajax({
2354				type: 'GET',
2355				url: '//vimeo.com/api/v2/video/' + video.id + '.json',
2356				jsonp: 'callback',
2357				dataType: 'jsonp',
2358				success: function(data) {
2359					path = data[0].thumbnail_large;
2360					create(path);
2361				}
2362			});
2363		} else if (video.type === 'vzaar') {
2364			$.ajax({
2365				type: 'GET',
2366				url: '//vzaar.com/api/videos/' + video.id + '.json',
2367				jsonp: 'callback',
2368				dataType: 'jsonp',
2369				success: function(data) {
2370					path = data.framegrab_url;
2371					create(path);
2372				}
2373			});
2374		}
2375	};
2376
2377	/**
2378	 * Stops the current video.
2379	 * @public
2380	 */
2381	Video.prototype.stop = function() {
2382		this._core.trigger('stop', null, 'video');
2383		this._playing.find('.owl-video-frame').remove();
2384		this._playing.removeClass('owl-video-playing');
2385		this._playing = null;
2386		this._core.leave('playing');
2387		this._core.trigger('stopped', null, 'video');
2388	};
2389
2390	/**
2391	 * Starts the current video.
2392	 * @public
2393	 * @param {Event} event - The event arguments.
2394	 */
2395	Video.prototype.play = function(event) {
2396		var target = $(event.target),
2397			item = target.closest('.' + this._core.settings.itemClass),
2398			video = this._videos[item.attr('data-video')],
2399			width = video.width || '100%',
2400			height = video.height || this._core.$stage.height(),
2401			html,
2402			iframe;
2403
2404		if (this._playing) {
2405			return;
2406		}
2407
2408		this._core.enter('playing');
2409		this._core.trigger('play', null, 'video');
2410
2411		item = this._core.items(this._core.relative(item.index()));
2412
2413		this._core.reset(item.index());
2414
2415		html = $( '<iframe frameborder="0" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>' );
2416		html.attr( 'height', height );
2417		html.attr( 'width', width );
2418		if (video.type === 'youtube') {
2419			html.attr( 'src', '//www.youtube.com/embed/' + video.id + '?autoplay=1&rel=0&v=' + video.id );
2420		} else if (video.type === 'vimeo') {
2421			html.attr( 'src', '//player.vimeo.com/video/' + video.id + '?autoplay=1' );
2422		} else if (video.type === 'vzaar') {
2423			html.attr( 'src', '//view.vzaar.com/' + video.id + '/player?autoplay=true' );
2424		}
2425
2426		iframe = $(html).wrap( '<div class="owl-video-frame" />' ).insertAfter(item.find('.owl-video'));
2427
2428		this._playing = item.addClass('owl-video-playing');
2429	};
2430
2431	/**
2432	 * Checks whether an video is currently in full screen mode or not.
2433	 * @todo Bad style because looks like a readonly method but changes members.
2434	 * @protected
2435	 * @returns {Boolean}
2436	 */
2437	Video.prototype.isInFullScreen = function() {
2438		var element = document.fullscreenElement || document.mozFullScreenElement ||
2439				document.webkitFullscreenElement;
2440
2441		return element && $(element).parent().hasClass('owl-video-frame');
2442	};
2443
2444	/**
2445	 * Destroys the plugin.
2446	 */
2447	Video.prototype.destroy = function() {
2448		var handler, property;
2449
2450		this._core.$element.off('click.owl.video');
2451
2452		for (handler in this._handlers) {
2453			this._core.$element.off(handler, this._handlers[handler]);
2454		}
2455		for (property in Object.getOwnPropertyNames(this)) {
2456			typeof this[property] != 'function' && (this[property] = null);
2457		}
2458	};
2459
2460	$.fn.owlCarousel.Constructor.Plugins.Video = Video;
2461
2462})(window.Zepto || window.jQuery, window, document);
2463
2464/**
2465 * Animate Plugin
2466 * @version 2.3.4
2467 * @author Bartosz Wojciechowski
2468 * @author David Deutsch
2469 * @license The MIT License (MIT)
2470 */
2471;(function($, window, document, undefined) {
2472
2473	/**
2474	 * Creates the animate plugin.
2475	 * @class The Navigation Plugin
2476	 * @param {Owl} scope - The Owl Carousel
2477	 */
2478	var Animate = function(scope) {
2479		this.core = scope;
2480		this.core.options = $.extend({}, Animate.Defaults, this.core.options);
2481		this.swapping = true;
2482		this.previous = undefined;
2483		this.next = undefined;
2484
2485		this.handlers = {
2486			'change.owl.carousel': $.proxy(function(e) {
2487				if (e.namespace && e.property.name == 'position') {
2488					this.previous = this.core.current();
2489					this.next = e.property.value;
2490				}
2491			}, this),
2492			'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
2493				if (e.namespace) {
2494					this.swapping = e.type == 'translated';
2495				}
2496			}, this),
2497			'translate.owl.carousel': $.proxy(function(e) {
2498				if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
2499					this.swap();
2500				}
2501			}, this)
2502		};
2503
2504		this.core.$element.on(this.handlers);
2505	};
2506
2507	/**
2508	 * Default options.
2509	 * @public
2510	 */
2511	Animate.Defaults = {
2512		animateOut: false,
2513		animateIn: false
2514	};
2515
2516	/**
2517	 * Toggles the animation classes whenever an translations starts.
2518	 * @protected
2519	 * @returns {Boolean|undefined}
2520	 */
2521	Animate.prototype.swap = function() {
2522
2523		if (this.core.settings.items !== 1) {
2524			return;
2525		}
2526
2527		if (!$.support.animation || !$.support.transition) {
2528			return;
2529		}
2530
2531		this.core.speed(0);
2532
2533		var left,
2534			clear = $.proxy(this.clear, this),
2535			previous = this.core.$stage.children().eq(this.previous),
2536			next = this.core.$stage.children().eq(this.next),
2537			incoming = this.core.settings.animateIn,
2538			outgoing = this.core.settings.animateOut;
2539
2540		if (this.core.current() === this.previous) {
2541			return;
2542		}
2543
2544		if (outgoing) {
2545			left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
2546			previous.one($.support.animation.end, clear)
2547				.css( { 'left': left + 'px' } )
2548				.addClass('animated owl-animated-out')
2549				.addClass(outgoing);
2550		}
2551
2552		if (incoming) {
2553			next.one($.support.animation.end, clear)
2554				.addClass('animated owl-animated-in')
2555				.addClass(incoming);
2556		}
2557	};
2558
2559	Animate.prototype.clear = function(e) {
2560		$(e.target).css( { 'left': '' } )
2561			.removeClass('animated owl-animated-out owl-animated-in')
2562			.removeClass(this.core.settings.animateIn)
2563			.removeClass(this.core.settings.animateOut);
2564		this.core.onTransitionEnd();
2565	};
2566
2567	/**
2568	 * Destroys the plugin.
2569	 * @public
2570	 */
2571	Animate.prototype.destroy = function() {
2572		var handler, property;
2573
2574		for (handler in this.handlers) {
2575			this.core.$element.off(handler, this.handlers[handler]);
2576		}
2577		for (property in Object.getOwnPropertyNames(this)) {
2578			typeof this[property] != 'function' && (this[property] = null);
2579		}
2580	};
2581
2582	$.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
2583
2584})(window.Zepto || window.jQuery, window, document);
2585
2586/**
2587 * Autoplay Plugin
2588 * @version 2.3.4
2589 * @author Bartosz Wojciechowski
2590 * @author Artus Kolanowski
2591 * @author David Deutsch
2592 * @author Tom De Caluwé
2593 * @license The MIT License (MIT)
2594 */
2595;(function($, window, document, undefined) {
2596
2597	/**
2598	 * Creates the autoplay plugin.
2599	 * @class The Autoplay Plugin
2600	 * @param {Owl} scope - The Owl Carousel
2601	 */
2602	var Autoplay = function(carousel) {
2603		/**
2604		 * Reference to the core.
2605		 * @protected
2606		 * @type {Owl}
2607		 */
2608		this._core = carousel;
2609
2610		/**
2611		 * The autoplay timeout id.
2612		 * @type {Number}
2613		 */
2614		this._call = null;
2615
2616		/**
2617		 * Depending on the state of the plugin, this variable contains either
2618		 * the start time of the timer or the current timer value if it's
2619		 * paused. Since we start in a paused state we initialize the timer
2620		 * value.
2621		 * @type {Number}
2622		 */
2623		this._time = 0;
2624
2625		/**
2626		 * Stores the timeout currently used.
2627		 * @type {Number}
2628		 */
2629		this._timeout = 0;
2630
2631		/**
2632		 * Indicates whenever the autoplay is paused.
2633		 * @type {Boolean}
2634		 */
2635		this._paused = true;
2636
2637		/**
2638		 * All event handlers.
2639		 * @protected
2640		 * @type {Object}
2641		 */
2642		this._handlers = {
2643			'changed.owl.carousel': $.proxy(function(e) {
2644				if (e.namespace && e.property.name === 'settings') {
2645					if (this._core.settings.autoplay) {
2646						this.play();
2647					} else {
2648						this.stop();
2649					}
2650				} else if (e.namespace && e.property.name === 'position' && this._paused) {
2651					// Reset the timer. This code is triggered when the position
2652					// of the carousel was changed through user interaction.
2653					this._time = 0;
2654				}
2655			}, this),
2656			'initialized.owl.carousel': $.proxy(function(e) {
2657				if (e.namespace && this._core.settings.autoplay) {
2658					this.play();
2659				}
2660			}, this),
2661			'play.owl.autoplay': $.proxy(function(e, t, s) {
2662				if (e.namespace) {
2663					this.play(t, s);
2664				}
2665			}, this),
2666			'stop.owl.autoplay': $.proxy(function(e) {
2667				if (e.namespace) {
2668					this.stop();
2669				}
2670			}, this),
2671			'mouseover.owl.autoplay': $.proxy(function() {
2672				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
2673					this.pause();
2674				}
2675			}, this),
2676			'mouseleave.owl.autoplay': $.proxy(function() {
2677				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
2678					this.play();
2679				}
2680			}, this),
2681			'touchstart.owl.core': $.proxy(function() {
2682				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
2683					this.pause();
2684				}
2685			}, this),
2686			'touchend.owl.core': $.proxy(function() {
2687				if (this._core.settings.autoplayHoverPause) {
2688					this.play();
2689				}
2690			}, this)
2691		};
2692
2693		// register event handlers
2694		this._core.$element.on(this._handlers);
2695
2696		// set default options
2697		this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
2698	};
2699
2700	/**
2701	 * Default options.
2702	 * @public
2703	 */
2704	Autoplay.Defaults = {
2705		autoplay: false,
2706		autoplayTimeout: 5000,
2707		autoplayHoverPause: false,
2708		autoplaySpeed: false
2709	};
2710
2711	/**
2712	 * Transition to the next slide and set a timeout for the next transition.
2713	 * @private
2714	 * @param {Number} [speed] - The animation speed for the animations.
2715	 */
2716	Autoplay.prototype._next = function(speed) {
2717		this._call = window.setTimeout(
2718			$.proxy(this._next, this, speed),
2719			this._timeout * (Math.round(this.read() / this._timeout) + 1) - this.read()
2720		);
2721
2722		if (this._core.is('interacting') || document.hidden) {
2723			return;
2724		}
2725		this._core.next(speed || this._core.settings.autoplaySpeed);
2726	}
2727
2728	/**
2729	 * Reads the current timer value when the timer is playing.
2730	 * @public
2731	 */
2732	Autoplay.prototype.read = function() {
2733		return new Date().getTime() - this._time;
2734	};
2735
2736	/**
2737	 * Starts the autoplay.
2738	 * @public
2739	 * @param {Number} [timeout] - The interval before the next animation starts.
2740	 * @param {Number} [speed] - The animation speed for the animations.
2741	 */
2742	Autoplay.prototype.play = function(timeout, speed) {
2743		var elapsed;
2744
2745		if (!this._core.is('rotating')) {
2746			this._core.enter('rotating');
2747		}
2748
2749		timeout = timeout || this._core.settings.autoplayTimeout;
2750
2751		// Calculate the elapsed time since the last transition. If the carousel
2752		// wasn't playing this calculation will yield zero.
2753		elapsed = Math.min(this._time % (this._timeout || timeout), timeout);
2754
2755		if (this._paused) {
2756			// Start the clock.
2757			this._time = this.read();
2758			this._paused = false;
2759		} else {
2760			// Clear the active timeout to allow replacement.
2761			window.clearTimeout(this._call);
2762		}
2763
2764		// Adjust the origin of the timer to match the new timeout value.
2765		this._time += this.read() % timeout - elapsed;
2766
2767		this._timeout = timeout;
2768		this._call = window.setTimeout($.proxy(this._next, this, speed), timeout - elapsed);
2769	};
2770
2771	/**
2772	 * Stops the autoplay.
2773	 * @public
2774	 */
2775	Autoplay.prototype.stop = function() {
2776		if (this._core.is('rotating')) {
2777			// Reset the clock.
2778			this._time = 0;
2779			this._paused = true;
2780
2781			window.clearTimeout(this._call);
2782			this._core.leave('rotating');
2783		}
2784	};
2785
2786	/**
2787	 * Pauses the autoplay.
2788	 * @public
2789	 */
2790	Autoplay.prototype.pause = function() {
2791		if (this._core.is('rotating') && !this._paused) {
2792			// Pause the clock.
2793			this._time = this.read();
2794			this._paused = true;
2795
2796			window.clearTimeout(this._call);
2797		}
2798	};
2799
2800	/**
2801	 * Destroys the plugin.
2802	 */
2803	Autoplay.prototype.destroy = function() {
2804		var handler, property;
2805
2806		this.stop();
2807
2808		for (handler in this._handlers) {
2809			this._core.$element.off(handler, this._handlers[handler]);
2810		}
2811		for (property in Object.getOwnPropertyNames(this)) {
2812			typeof this[property] != 'function' && (this[property] = null);
2813		}
2814	};
2815
2816	$.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
2817
2818})(window.Zepto || window.jQuery, window, document);
2819
2820/**
2821 * Navigation Plugin
2822 * @version 2.3.4
2823 * @author Artus Kolanowski
2824 * @author David Deutsch
2825 * @license The MIT License (MIT)
2826 */
2827;(function($, window, document, undefined) {
2828	'use strict';
2829
2830	/**
2831	 * Creates the navigation plugin.
2832	 * @class The Navigation Plugin
2833	 * @param {Owl} carousel - The Owl Carousel.
2834	 */
2835	var Navigation = function(carousel) {
2836		/**
2837		 * Reference to the core.
2838		 * @protected
2839		 * @type {Owl}
2840		 */
2841		this._core = carousel;
2842
2843		/**
2844		 * Indicates whether the plugin is initialized or not.
2845		 * @protected
2846		 * @type {Boolean}
2847		 */
2848		this._initialized = false;
2849
2850		/**
2851		 * The current paging indexes.
2852		 * @protected
2853		 * @type {Array}
2854		 */
2855		this._pages = [];
2856
2857		/**
2858		 * All DOM elements of the user interface.
2859		 * @protected
2860		 * @type {Object}
2861		 */
2862		this._controls = {};
2863
2864		/**
2865		 * Markup for an indicator.
2866		 * @protected
2867		 * @type {Array.<String>}
2868		 */
2869		this._templates = [];
2870
2871		/**
2872		 * The carousel element.
2873		 * @type {jQuery}
2874		 */
2875		this.$element = this._core.$element;
2876
2877		/**
2878		 * Overridden methods of the carousel.
2879		 * @protected
2880		 * @type {Object}
2881		 */
2882		this._overrides = {
2883			next: this._core.next,
2884			prev: this._core.prev,
2885			to: this._core.to
2886		};
2887
2888		/**
2889		 * All event handlers.
2890		 * @protected
2891		 * @type {Object}
2892		 */
2893		this._handlers = {
2894			'prepared.owl.carousel': $.proxy(function(e) {
2895				if (e.namespace && this._core.settings.dotsData) {
2896					this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
2897						$(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '</div>');
2898				}
2899			}, this),
2900			'added.owl.carousel': $.proxy(function(e) {
2901				if (e.namespace && this._core.settings.dotsData) {
2902					this._templates.splice(e.position, 0, this._templates.pop());
2903				}
2904			}, this),
2905			'remove.owl.carousel': $.proxy(function(e) {
2906				if (e.namespace && this._core.settings.dotsData) {
2907					this._templates.splice(e.position, 1);
2908				}
2909			}, this),
2910			'changed.owl.carousel': $.proxy(function(e) {
2911				if (e.namespace && e.property.name == 'position') {
2912					this.draw();
2913				}
2914			}, this),
2915			'initialized.owl.carousel': $.proxy(function(e) {
2916				if (e.namespace && !this._initialized) {
2917					this._core.trigger('initialize', null, 'navigation');
2918					this.initialize();
2919					this.update();
2920					this.draw();
2921					this._initialized = true;
2922					this._core.trigger('initialized', null, 'navigation');
2923				}
2924			}, this),
2925			'refreshed.owl.carousel': $.proxy(function(e) {
2926				if (e.namespace && this._initialized) {
2927					this._core.trigger('refresh', null, 'navigation');
2928					this.update();
2929					this.draw();
2930					this._core.trigger('refreshed', null, 'navigation');
2931				}
2932			}, this)
2933		};
2934
2935		// set default options
2936		this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
2937
2938		// register event handlers
2939		this.$element.on(this._handlers);
2940	};
2941
2942	/**
2943	 * Default options.
2944	 * @public
2945	 * @todo Rename `slideBy` to `navBy`
2946	 */
2947	Navigation.Defaults = {
2948		nav: false,
2949		navText: [
2950			'<span aria-label="' + 'Previous' + '">&#x2039;</span>',
2951			'<span aria-label="' + 'Next' + '">&#x203a;</span>'
2952		],
2953		navSpeed: false,
2954		navElement: 'button type="button" role="presentation"',
2955		navContainer: false,
2956		navContainerClass: 'owl-nav',
2957		navClass: [
2958			'owl-prev',
2959			'owl-next'
2960		],
2961		slideBy: 1,
2962		dotClass: 'owl-dot',
2963		dotsClass: 'owl-dots',
2964		dots: true,
2965		dotsEach: false,
2966		dotsData: false,
2967		dotsSpeed: false,
2968		dotsContainer: false
2969	};
2970
2971	/**
2972	 * Initializes the layout of the plugin and extends the carousel.
2973	 * @protected
2974	 */
2975	Navigation.prototype.initialize = function() {
2976		var override,
2977			settings = this._core.settings;
2978
2979		// create DOM structure for relative navigation
2980		this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
2981			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
2982
2983		this._controls.$previous = $('<' + settings.navElement + '>')
2984			.addClass(settings.navClass[0])
vendor: 4,756 bytes, lines 2985-3146
2985			.html(settings.navText[0])
2986			.prependTo(this._controls.$relative)
2987			.on('click', $.proxy(function(e) {
2988				this.prev(settings.navSpeed);
2989			}, this));
2990		this._controls.$next = $('<' + settings.navElement + '>')
2991			.addClass(settings.navClass[1])
2992			.html(settings.navText[1])
2993			.appendTo(this._controls.$relative)
2994			.on('click', $.proxy(function(e) {
2995				this.next(settings.navSpeed);
2996			}, this));
2997
2998		// create DOM structure for absolute navigation
2999		if (!settings.dotsData) {
3000			this._templates = [ $('<button role="button">')
3001				.addClass(settings.dotClass)
3002				.append($('<span>'))
3003				.prop('outerHTML') ];
3004		}
3005
3006		this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
3007			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
3008
3009		this._controls.$absolute.on('click', 'button', $.proxy(function(e) {
3010			var index = $(e.target).parent().is(this._controls.$absolute)
3011				? $(e.target).index() : $(e.target).parent().index();
3012
3013			e.preventDefault();
3014
3015			this.to(index, settings.dotsSpeed);
3016		}, this));
3017
3018		/*$el.on('focusin', function() {
3019			$(document).off(".carousel");
3020
3021			$(document).on('keydown.carousel', function(e) {
3022				if(e.keyCode == 37) {
3023					$el.trigger('prev.owl')
3024				}
3025				if(e.keyCode == 39) {
3026					$el.trigger('next.owl')
3027				}
3028			});
3029		});*/
3030
3031		// override public methods of the carousel
3032		for (override in this._overrides) {
3033			this._core[override] = $.proxy(this[override], this);
3034		}
3035	};
3036
3037	/**
3038	 * Destroys the plugin.
3039	 * @protected
3040	 */
3041	Navigation.prototype.destroy = function() {
3042		var handler, control, property, override, settings;
3043		settings = this._core.settings;
3044
3045		for (handler in this._handlers) {
3046			this.$element.off(handler, this._handlers[handler]);
3047		}
3048		for (control in this._controls) {
3049			if (control === '$relative' && settings.navContainer) {
3050				this._controls[control].html('');
3051			} else {
3052				this._controls[control].remove();
3053			}
3054		}
3055		for (override in this.overides) {
3056			this._core[override] = this._overrides[override];
3057		}
3058		for (property in Object.getOwnPropertyNames(this)) {
3059			typeof this[property] != 'function' && (this[property] = null);
3060		}
3061	};
3062
3063	/**
3064	 * Updates the internal state.
3065	 * @protected
3066	 */
3067	Navigation.prototype.update = function() {
3068		var i, j, k,
3069			lower = this._core.clones().length / 2,
3070			upper = lower + this._core.items().length,
3071			maximum = this._core.maximum(true),
3072			settings = this._core.settings,
3073			size = settings.center || settings.autoWidth || settings.dotsData
3074				? 1 : settings.dotsEach || settings.items;
3075
3076		if (settings.slideBy !== 'page') {
3077			settings.slideBy = Math.min(settings.slideBy, settings.items);
3078		}
3079
3080		if (settings.dots || settings.slideBy == 'page') {
3081			this._pages = [];
3082
3083			for (i = lower, j = 0, k = 0; i < upper; i++) {
3084				if (j >= size || j === 0) {
3085					this._pages.push({
3086						start: Math.min(maximum, i - lower),
3087						end: i - lower + size - 1
3088					});
3089					if (Math.min(maximum, i - lower) === maximum) {
3090						break;
3091					}
3092					j = 0, ++k;
3093				}
3094				j += this._core.mergers(this._core.relative(i));
3095			}
3096		}
3097	};
3098
3099	/**
3100	 * Draws the user interface.
3101	 * @todo The option `dotsData` wont work.
3102	 * @protected
3103	 */
3104	Navigation.prototype.draw = function() {
3105		var difference,
3106			settings = this._core.settings,
3107			disabled = this._core.items().length <= settings.items,
3108			index = this._core.relative(this._core.current()),
3109			loop = settings.loop || settings.rewind;
3110
3111		this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
3112
3113		if (settings.nav) {
3114			this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
3115			this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
3116		}
3117
3118		this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
3119
3120		if (settings.dots) {
3121			difference = this._pages.length - this._controls.$absolute.children().length;
3122
3123			if (settings.dotsData && difference !== 0) {
3124				this._controls.$absolute.html(this._templates.join(''));
3125			} else if (difference > 0) {
3126				this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
3127			} else if (difference < 0) {
3128				this._controls.$absolute.children().slice(difference).remove();
3129			}
3130
3131			this._controls.$absolute.find('.active').removeClass('active');
3132			this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
3133		}
3134	};
3135
3136	/**
3137	 * Extends event data.
3138	 * @protected
3139	 * @param {Event} event - The event object which gets thrown.
3140	 */
3141	Navigation.prototype.onTrigger = function(event) {
3142		var settings = this._core.settings;
3143
3144		event.page = {
3145			index: $.inArray(this.current(), this._pages),
3146			count: this._pages.length,
vendor: 7,284 bytes, lines 3147-3432
3147			size: settings && (settings.center || settings.autoWidth || settings.dotsData
3148				? 1 : settings.dotsEach || settings.items)
3149		};
3150	};
3151
3152	/**
3153	 * Gets the current page position of the carousel.
3154	 * @protected
3155	 * @returns {Number}
3156	 */
3157	Navigation.prototype.current = function() {
3158		var current = this._core.relative(this._core.current());
3159		return $.grep(this._pages, $.proxy(function(page, index) {
3160			return page.start <= current && page.end >= current;
3161		}, this)).pop();
3162	};
3163
3164	/**
3165	 * Gets the current succesor/predecessor position.
3166	 * @protected
3167	 * @returns {Number}
3168	 */
3169	Navigation.prototype.getPosition = function(successor) {
3170		var position, length,
3171			settings = this._core.settings;
3172
3173		if (settings.slideBy == 'page') {
3174			position = $.inArray(this.current(), this._pages);
3175			length = this._pages.length;
3176			successor ? ++position : --position;
3177			position = this._pages[((position % length) + length) % length].start;
3178		} else {
3179			position = this._core.relative(this._core.current());
3180			length = this._core.items().length;
3181			successor ? position += settings.slideBy : position -= settings.slideBy;
3182		}
3183
3184		return position;
3185	};
3186
3187	/**
3188	 * Slides to the next item or page.
3189	 * @public
3190	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
3191	 */
3192	Navigation.prototype.next = function(speed) {
3193		$.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
3194	};
3195
3196	/**
3197	 * Slides to the previous item or page.
3198	 * @public
3199	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
3200	 */
3201	Navigation.prototype.prev = function(speed) {
3202		$.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
3203	};
3204
3205	/**
3206	 * Slides to the specified item or page.
3207	 * @public
3208	 * @param {Number} position - The position of the item or page.
3209	 * @param {Number} [speed] - The time in milliseconds for the transition.
3210	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
3211	 */
3212	Navigation.prototype.to = function(position, speed, standard) {
3213		var length;
3214
3215		if (!standard && this._pages.length) {
3216			length = this._pages.length;
3217			$.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
3218		} else {
3219			$.proxy(this._overrides.to, this._core)(position, speed);
3220		}
3221	};
3222
3223	$.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
3224
3225})(window.Zepto || window.jQuery, window, document);
3226
3227/**
3228 * Hash Plugin
3229 * @version 2.3.4
3230 * @author Artus Kolanowski
3231 * @author David Deutsch
3232 * @license The MIT License (MIT)
3233 */
3234;(function($, window, document, undefined) {
3235	'use strict';
3236
3237	/**
3238	 * Creates the hash plugin.
3239	 * @class The Hash Plugin
3240	 * @param {Owl} carousel - The Owl Carousel
3241	 */
3242	var Hash = function(carousel) {
3243		/**
3244		 * Reference to the core.
3245		 * @protected
3246		 * @type {Owl}
3247		 */
3248		this._core = carousel;
3249
3250		/**
3251		 * Hash index for the items.
3252		 * @protected
3253		 * @type {Object}
3254		 */
3255		this._hashes = {};
3256
3257		/**
3258		 * The carousel element.
3259		 * @type {jQuery}
3260		 */
3261		this.$element = this._core.$element;
3262
3263		/**
3264		 * All event handlers.
3265		 * @protected
3266		 * @type {Object}
3267		 */
3268		this._handlers = {
3269			'initialized.owl.carousel': $.proxy(function(e) {
3270				if (e.namespace && this._core.settings.startPosition === 'URLHash') {
3271					$(window).trigger('hashchange.owl.navigation');
3272				}
3273			}, this),
3274			'prepared.owl.carousel': $.proxy(function(e) {
3275				if (e.namespace) {
3276					var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
3277
3278					if (!hash) {
3279						return;
3280					}
3281
3282					this._hashes[hash] = e.content;
3283				}
3284			}, this),
3285			'changed.owl.carousel': $.proxy(function(e) {
3286				if (e.namespace && e.property.name === 'position') {
3287					var current = this._core.items(this._core.relative(this._core.current())),
3288						hash = $.map(this._hashes, function(item, hash) {
3289							return item === current ? hash : null;
3290						}).join();
3291
3292					if (!hash || window.location.hash.slice(1) === hash) {
3293						return;
3294					}
3295
3296					window.location.hash = hash;
3297				}
3298			}, this)
3299		};
3300
3301		// set default options
3302		this._core.options = $.extend({}, Hash.Defaults, this._core.options);
3303
3304		// register the event handlers
3305		this.$element.on(this._handlers);
3306
3307		// register event listener for hash navigation
3308		$(window).on('hashchange.owl.navigation', $.proxy(function(e) {
3309			var hash = window.location.hash.substring(1),
3310				items = this._core.$stage.children(),
3311				position = this._hashes[hash] && items.index(this._hashes[hash]);
3312
3313			if (position === undefined || position === this._core.current()) {
3314				return;
3315			}
3316
3317			this._core.to(this._core.relative(position), false, true);
3318		}, this));
3319	};
3320
3321	/**
3322	 * Default options.
3323	 * @public
3324	 */
3325	Hash.Defaults = {
3326		URLhashListener: false
3327	};
3328
3329	/**
3330	 * Destroys the plugin.
3331	 * @public
3332	 */
3333	Hash.prototype.destroy = function() {
3334		var handler, property;
3335
3336		$(window).off('hashchange.owl.navigation');
3337
3338		for (handler in this._handlers) {
3339			this._core.$element.off(handler, this._handlers[handler]);
3340		}
3341		for (property in Object.getOwnPropertyNames(this)) {
3342			typeof this[property] != 'function' && (this[property] = null);
3343		}
3344	};
3345
3346	$.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
3347
3348})(window.Zepto || window.jQuery, window, document);
3349
3350/**
3351 * Support Plugin
3352 *
3353 * @version 2.3.4
3354 * @author Vivid Planet Software GmbH
3355 * @author Artus Kolanowski
3356 * @author David Deutsch
3357 * @license The MIT License (MIT)
3358 */
3359;(function($, window, document, undefined) {
3360
3361	var style = $('<support>').get(0).style,
3362		prefixes = 'Webkit Moz O ms'.split(' '),
3363		events = {
3364			transition: {
3365				end: {
3366					WebkitTransition: 'webkitTransitionEnd',
3367					MozTransition: 'transitionend',
3368					OTransition: 'oTransitionEnd',
3369					transition: 'transitionend'
3370				}
3371			},
3372			animation: {
3373				end: {
3374					WebkitAnimation: 'webkitAnimationEnd',
3375					MozAnimation: 'animationend',
3376					OAnimation: 'oAnimationEnd',
3377					animation: 'animationend'
3378				}
3379			}
3380		},
3381		tests = {
3382			csstransforms: function() {
3383				return !!test('transform');
3384			},
3385			csstransforms3d: function() {
3386				return !!test('perspective');
3387			},
3388			csstransitions: function() {
3389				return !!test('transition');
3390			},
3391			cssanimations: function() {
3392				return !!test('animation');
3393			}
3394		};
3395
3396	function test(property, prefixed) {
3397		var result = false,
3398			upper = property.charAt(0).toUpperCase() + property.slice(1);
3399
3400		$.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
3401			if (style[property] !== undefined) {
3402				result = prefixed ? property : true;
3403				return false;
3404			}
3405		});
3406
3407		return result;
3408	}
3409
3410	function prefixed(property) {
3411		return test(property, true);
3412	}
3413
3414	if (tests.csstransitions()) {
3415		/* jshint -W053 */
3416		$.support.transition = new String(prefixed('transition'))
3417		$.support.transition.end = events.transition.end[ $.support.transition ];
3418	}
3419
3420	if (tests.cssanimations()) {
3421		/* jshint -W053 */
3422		$.support.animation = new String(prefixed('animation'))
3423		$.support.animation.end = events.animation.end[ $.support.animation ];
3424	}
3425
3426	if (tests.csstransforms()) {
3427		/* jshint -W053 */
3428		$.support.transform = new String(prefixed('transform'));
3429		$.support.transform3d = tests.csstransforms3d();
3430	}
3431
3432})(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.