PageSourceSearch

https://www.backsplash.com/wp-content/plugins/woocommerce-tm-extra…/assets/js/owl.carousel.js?ver=7.6

js backsplash.com collected 2026-09-25 23:41:00 UTC 97,179 bytes, 3,840 lines download raw bytes

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

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.