PageSourceSearch

https://www.arabosai.org/typo3temp/assets/compressed/merged-a4beba…349a326b83c4fd403a3c7f147ea0b.js?1789407416

js arabosai.org collected 2026-10-02 22:26:55 UTC 206,560 bytes, 6,240 lines download raw bytes

1
vendor: 23,216 bytes, lines 2-948
2/**
3 * Owl Carousel v2.3.4
4 * Copyright 2013-2018 David Deutsch
5 * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
6 */
7/**
8 * Owl carousel
9 * @version 2.3.4
10 * @author Bartosz Wojciechowski
11 * @author David Deutsch
12 * @license The MIT License (MIT)
13 * @todo Lazy Load Icon
14 * @todo prevent animationend bubling
15 * @todo itemsScaleUp
16 * @todo Test Zepto
17 * @todo stagePadding calculate wrong active classes
18 */
19;(function($, window, document, undefined) {
20
21	/**
22	 * Creates a carousel.
23	 * @class The Owl Carousel.
24	 * @public
25	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
26	 * @param {Object} [options] - The options
27	 */
28	function Owl(element, options) {
29
30		/**
31		 * Current settings for the carousel.
32		 * @public
33		 */
34		this.settings = null;
35
36		/**
37		 * Current options set by the caller including defaults.
38		 * @public
39		 */
40		this.options = $.extend({}, Owl.Defaults, options);
41
42		/**
43		 * Plugin element.
44		 * @public
45		 */
46		this.$element = $(element);
47
48		/**
49		 * Proxied event handlers.
50		 * @protected
51		 */
52		this._handlers = {};
53
54		/**
55		 * References to the running plugins of this carousel.
56		 * @protected
57		 */
58		this._plugins = {};
59
60		/**
61		 * Currently suppressed events to prevent them from being retriggered.
62		 * @protected
63		 */
64		this._supress = {};
65
66		/**
67		 * Absolute current position.
68		 * @protected
69		 */
70		this._current = null;
71
72		/**
73		 * Animation speed in milliseconds.
74		 * @protected
75		 */
76		this._speed = null;
77
78		/**
79		 * Coordinates of all items in pixel.
80		 * @todo The name of this member is missleading.
81		 * @protected
82		 */
83		this._coordinates = [];
84
85		/**
86		 * Current breakpoint.
87		 * @todo Real media queries would be nice.
88		 * @protected
89		 */
90		this._breakpoint = null;
91
92		/**
93		 * Current width of the plugin element.
94		 */
95		this._width = null;
96
97		/**
98		 * All real items.
99		 * @protected
100		 */
101		this._items = [];
102
103		/**
104		 * All cloned items.
105		 * @protected
106		 */
107		this._clones = [];
108
109		/**
110		 * Merge values of all items.
111		 * @todo Maybe this could be part of a plugin.
112		 * @protected
113		 */
114		this._mergers = [];
115
116		/**
117		 * Widths of all items.
118		 */
119		this._widths = [];
120
121		/**
122		 * Invalidated parts within the update process.
123		 * @protected
124		 */
125		this._invalidated = {};
126
127		/**
128		 * Ordered list of workers for the update process.
129		 * @protected
130		 */
131		this._pipe = [];
132
133		/**
134		 * Current state information for the drag operation.
135		 * @todo #261
136		 * @protected
137		 */
138		this._drag = {
139			time: null,
140			target: null,
141			pointer: null,
142			stage: {
143				start: null,
144				current: null
145			},
146			direction: null
147		};
148
149		/**
150		 * Current state information and their tags.
151		 * @type {Object}
152		 * @protected
153		 */
154		this._states = {
155			current: {},
156			tags: {
157				'initializing': [ 'busy' ],
158				'animating': [ 'busy' ],
159				'dragging': [ 'interacting' ]
160			}
161		};
162
163		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
164			this._handlers[handler] = $.proxy(this[handler], this);
165		}, this));
166
167		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
168			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
169				= new plugin(this);
170		}, this));
171
172		$.each(Owl.Workers, $.proxy(function(priority, worker) {
173			this._pipe.push({
174				'filter': worker.filter,
175				'run': $.proxy(worker.run, this)
176			});
177		}, this));
178
179		this.setup();
180		this.initialize();
181	}
182
183	/**
184	 * Default options for the carousel.
185	 * @public
186	 */
187	Owl.Defaults = {
188		items: 3,
189		loop: false,
190		center: false,
191		rewind: false,
192		checkVisibility: true,
193
194		mouseDrag: true,
195		touchDrag: true,
196		pullDrag: true,
197		freeDrag: false,
198
199		margin: 0,
200		stagePadding: 0,
201
202		merge: false,
203		mergeFit: true,
204		autoWidth: false,
205
206		startPosition: 0,
207		rtl: false,
208
209		smartSpeed: 250,
210		fluidSpeed: false,
211		dragEndSpeed: false,
212
213		responsive: {},
214		responsiveRefreshRate: 200,
215		responsiveBaseElement: window,
216
217		fallbackEasing: 'swing',
218		slideTransition: '',
219
220		info: false,
221
222		nestedItemSelector: false,
223		itemElement: 'div',
224		stageElement: 'div',
225
226		refreshClass: 'owl-refresh',
227		loadedClass: 'owl-loaded',
228		loadingClass: 'owl-loading',
229		rtlClass: 'owl-rtl',
230		responsiveClass: 'owl-responsive',
231		dragClass: 'owl-drag',
232		itemClass: 'owl-item',
233		stageClass: 'owl-stage',
234		stageOuterClass: 'owl-stage-outer',
235		grabClass: 'owl-grab'
236	};
237
238	/**
239	 * Enumeration for width.
240	 * @public
241	 * @readonly
242	 * @enum {String}
243	 */
244	Owl.Width = {
245		Default: 'default',
246		Inner: 'inner',
247		Outer: 'outer'
248	};
249
250	/**
251	 * Enumeration for types.
252	 * @public
253	 * @readonly
254	 * @enum {String}
255	 */
256	Owl.Type = {
257		Event: 'event',
258		State: 'state'
259	};
260
261	/**
262	 * Contains all registered plugins.
263	 * @public
264	 */
265	Owl.Plugins = {};
266
267	/**
268	 * List of workers involved in the update process.
269	 */
270	Owl.Workers = [ {
271		filter: [ 'width', 'settings' ],
272		run: function() {
273			this._width = this.$element.width();
274		}
275	}, {
276		filter: [ 'width', 'items', 'settings' ],
277		run: function(cache) {
278			cache.current = this._items && this._items[this.relative(this._current)];
279		}
280	}, {
281		filter: [ 'items', 'settings' ],
282		run: function() {
283			this.$stage.children('.cloned').remove();
284		}
285	}, {
286		filter: [ 'width', 'items', 'settings' ],
287		run: function(cache) {
288			var margin = this.settings.margin || '',
289				grid = !this.settings.autoWidth,
290				rtl = this.settings.rtl,
291				css = {
292					'width': 'auto',
293					'margin-left': rtl ? margin : '',
294					'margin-right': rtl ? '' : margin
295				};
296
297			!grid && this.$stage.children().css(css);
298
299			cache.css = css;
300		}
301	}, {
302		filter: [ 'width', 'items', 'settings' ],
303		run: function(cache) {
304			var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
305				merge = null,
306				iterator = this._items.length,
307				grid = !this.settings.autoWidth,
308				widths = [];
309
310			cache.items = {
311				merge: false,
312				width: width
313			};
314
315			while (iterator--) {
316				merge = this._mergers[iterator];
317				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
318
319				cache.items.merge = merge > 1 || cache.items.merge;
320
321				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
322			}
323
324			this._widths = widths;
325		}
326	}, {
327		filter: [ 'items', 'settings' ],
328		run: function() {
329			var clones = [],
330				items = this._items,
331				settings = this.settings,
332				// TODO: Should be computed from number of min width items in stage
333				view = Math.max(settings.items * 2, 4),
334				size = Math.ceil(items.length / 2) * 2,
335				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
336				append = '',
337				prepend = '';
338
339			repeat /= 2;
340
341			while (repeat > 0) {
342				// Switch to only using appended clones
343				clones.push(this.normalize(clones.length / 2, true));
344				append = append + items[clones[clones.length - 1]][0].outerHTML;
345				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
346				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
347				repeat -= 1;
348			}
349
350			this._clones = clones;
351
352			$(append).addClass('cloned').appendTo(this.$stage);
353			$(prepend).addClass('cloned').prependTo(this.$stage);
354		}
355	}, {
356		filter: [ 'width', 'items', 'settings' ],
357		run: function() {
358			var rtl = this.settings.rtl ? 1 : -1,
359				size = this._clones.length + this._items.length,
360				iterator = -1,
361				previous = 0,
362				current = 0,
363				coordinates = [];
364
365			while (++iterator < size) {
366				previous = coordinates[iterator - 1] || 0;
367				current = this._widths[this.relative(iterator)] + this.settings.margin;
368				coordinates.push(previous + current * rtl);
369			}
370
371			this._coordinates = coordinates;
372		}
373	}, {
374		filter: [ 'width', 'items', 'settings' ],
375		run: function() {
376			var padding = this.settings.stagePadding,
377				coordinates = this._coordinates,
378				css = {
379					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
380					'padding-left': padding || '',
381					'padding-right': padding || ''
382				};
383
384			this.$stage.css(css);
385		}
386	}, {
387		filter: [ 'width', 'items', 'settings' ],
388		run: function(cache) {
389			var iterator = this._coordinates.length,
390				grid = !this.settings.autoWidth,
391				items = this.$stage.children();
392
393			if (grid && cache.items.merge) {
394				while (iterator--) {
395					cache.css.width = this._widths[this.relative(iterator)];
396					items.eq(iterator).css(cache.css);
397				}
398			} else if (grid) {
399				cache.css.width = cache.items.width;
400				items.css(cache.css);
401			}
402		}
403	}, {
404		filter: [ 'items' ],
405		run: function() {
406			this._coordinates.length < 1 && this.$stage.removeAttr('style');
407		}
408	}, {
409		filter: [ 'width', 'items', 'settings' ],
410		run: function(cache) {
411			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
412			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
413			this.reset(cache.current);
414		}
415	}, {
416		filter: [ 'position' ],
417		run: function() {
418			this.animate(this.coordinates(this._current));
419		}
420	}, {
421		filter: [ 'width', 'position', 'items', 'settings' ],
422		run: function() {
423			var rtl = this.settings.rtl ? 1 : -1,
424				padding = this.settings.stagePadding * 2,
425				begin = this.coordinates(this.current()) + padding,
426				end = begin + this.width() * rtl,
427				inner, outer, matches = [], i, n;
428
429			for (i = 0, n = this._coordinates.length; i < n; i++) {
430				inner = this._coordinates[i - 1] || 0;
431				outer = Math.abs(this._coordinates[i]) + padding * rtl;
432
433				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
434					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
435					matches.push(i);
436				}
437			}
438
439			this.$stage.children('.active').removeClass('active');
440			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
441
442			this.$stage.children('.center').removeClass('center');
443			if (this.settings.center) {
444				this.$stage.children().eq(this.current()).addClass('center');
445			}
446		}
447	} ];
448
449	/**
450	 * Create the stage DOM element
451	 */
452	Owl.prototype.initializeStage = function() {
453		this.$stage = this.$element.find('.' + this.settings.stageClass);
454
455		// if the stage is already in the DOM, grab it and skip stage initialization
456		if (this.$stage.length) {
457			return;
458		}
459
460		this.$element.addClass(this.options.loadingClass);
461
462		// create stage
463		this.$stage = $('<' + this.settings.stageElement + '>', {
464			"class": this.settings.stageClass
465		}).wrap( $( '<div/>', {
466			"class": this.settings.stageOuterClass
467		}));
468
469		// append stage
470		this.$element.append(this.$stage.parent());
471	};
472
473	/**
474	 * Create item DOM elements
475	 */
476	Owl.prototype.initializeItems = function() {
477		var $items = this.$element.find('.owl-item');
478
479		// if the items are already in the DOM, grab them and skip item initialization
480		if ($items.length) {
481			this._items = $items.get().map(function(item) {
482				return $(item);
483			});
484
485			this._mergers = this._items.map(function() {
486				return 1;
487			});
488
489			this.refresh();
490
491			return;
492		}
493
494		// append content
495		this.replace(this.$element.children().not(this.$stage.parent()));
496
497		// check visibility
498		if (this.isVisible()) {
499			// update view
500			this.refresh();
501		} else {
502			// invalidate width
503			this.invalidate('width');
504		}
505
506		this.$element
507			.removeClass(this.options.loadingClass)
508			.addClass(this.options.loadedClass);
509	};
510
511	/**
512	 * Initializes the carousel.
513	 * @protected
514	 */
515	Owl.prototype.initialize = function() {
516		this.enter('initializing');
517		this.trigger('initialize');
518
519		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
520
521		if (this.settings.autoWidth && !this.is('pre-loading')) {
522			var imgs, nestedSelector, width;
523			imgs = this.$element.find('img');
524			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
525			width = this.$element.children(nestedSelector).width();
526
527			if (imgs.length && width <= 0) {
528				this.preloadAutoWidthImages(imgs);
529			}
530		}
531
532		this.initializeStage();
533		this.initializeItems();
534
535		// register event handlers
536		this.registerEventHandlers();
537
538		this.leave('initializing');
539		this.trigger('initialized');
540	};
541
542	/**
543	 * @returns {Boolean} visibility of $element
544	 *                    if you know the carousel will always be visible you can set `checkVisibility` to `false` to
545	 *                    prevent the expensive browser layout forced reflow the $element.is(':visible') does
546	 */
547	Owl.prototype.isVisible = function() {
548		return this.settings.checkVisibility
549			? this.$element.is(':visible')
550			: true;
551	};
552
553	/**
554	 * Setups the current settings.
555	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
556	 * @todo Support for media queries by using `matchMedia` would be nice.
557	 * @public
558	 */
559	Owl.prototype.setup = function() {
560		var viewport = this.viewport(),
561			overwrites = this.options.responsive,
562			match = -1,
563			settings = null;
564
565		if (!overwrites) {
566			settings = $.extend({}, this.options);
567		} else {
568			$.each(overwrites, function(breakpoint) {
569				if (breakpoint <= viewport && breakpoint > match) {
570					match = Number(breakpoint);
571				}
572			});
573
574			settings = $.extend({}, this.options, overwrites[match]);
575			if (typeof settings.stagePadding === 'function') {
576				settings.stagePadding = settings.stagePadding();
577			}
578			delete settings.responsive;
579
580			// responsive class
581			if (settings.responsiveClass) {
582				this.$element.attr('class',
583					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
584				);
585			}
586		}
587
588		this.trigger('change', { property: { name: 'settings', value: settings } });
589		this._breakpoint = match;
590		this.settings = settings;
591		this.invalidate('settings');
592		this.trigger('changed', { property: { name: 'settings', value: this.settings } });
593	};
594
595	/**
596	 * Updates option logic if necessery.
597	 * @protected
598	 */
599	Owl.prototype.optionsLogic = function() {
600		if (this.settings.autoWidth) {
601			this.settings.stagePadding = false;
602			this.settings.merge = false;
603		}
604	};
605
606	/**
607	 * Prepares an item before add.
608	 * @todo Rename event parameter `content` to `item`.
609	 * @protected
610	 * @returns {jQuery|HTMLElement} - The item container.
611	 */
612	Owl.prototype.prepare = function(item) {
613		var event = this.trigger('prepare', { content: item });
614
615		if (!event.data) {
616			event.data = $('<' + this.settings.itemElement + '/>')
617				.addClass(this.options.itemClass).append(item)
618		}
619
620		this.trigger('prepared', { content: event.data });
621
622		return event.data;
623	};
624
625	/**
626	 * Updates the view.
627	 * @public
628	 */
629	Owl.prototype.update = function() {
630		var i = 0,
631			n = this._pipe.length,
632			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
633			cache = {};
634
635		while (i < n) {
636			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
637				this._pipe[i].run(cache);
638			}
639			i++;
640		}
641
642		this._invalidated = {};
643
644		!this.is('valid') && this.enter('valid');
645	};
646
647	/**
648	 * Gets the width of the view.
649	 * @public
650	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
651	 * @returns {Number} - The width of the view in pixel.
652	 */
653	Owl.prototype.width = function(dimension) {
654		dimension = dimension || Owl.Width.Default;
655		switch (dimension) {
656			case Owl.Width.Inner:
657			case Owl.Width.Outer:
658				return this._width;
659			default:
660				return this._width - this.settings.stagePadding * 2 + this.settings.margin;
661		}
662	};
663
664	/**
665	 * Refreshes the carousel primarily for adaptive purposes.
666	 * @public
667	 */
668	Owl.prototype.refresh = function() {
669		this.enter('refreshing');
670		this.trigger('refresh');
671
672		this.setup();
673
674		this.optionsLogic();
675
676		this.$element.addClass(this.options.refreshClass);
677
678		this.update();
679
680		this.$element.removeClass(this.options.refreshClass);
681
682		this.leave('refreshing');
683		this.trigger('refreshed');
684	};
685
686	/**
687	 * Checks window `resize` event.
688	 * @protected
689	 */
690	Owl.prototype.onThrottledResize = function() {
691		window.clearTimeout(this.resizeTimer);
692		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
693	};
694
695	/**
696	 * Checks window `resize` event.
697	 * @protected
698	 */
699	Owl.prototype.onResize = function() {
700		if (!this._items.length) {
701			return false;
702		}
703
704		if (this._width === this.$element.width()) {
705			return false;
706		}
707
708		if (!this.isVisible()) {
709			return false;
710		}
711
712		this.enter('resizing');
713
714		if (this.trigger('resize').isDefaultPrevented()) {
715			this.leave('resizing');
716			return false;
717		}
718
719		this.invalidate('width');
720
721		this.refresh();
722
723		this.leave('resizing');
724		this.trigger('resized');
725	};
726
727	/**
728	 * Registers event handlers.
729	 * @todo Check `msPointerEnabled`
730	 * @todo #261
731	 * @protected
732	 */
733	Owl.prototype.registerEventHandlers = function() {
734		if ($.support.transition) {
735			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
736		}
737
738		if (this.settings.responsive !== false) {
739			this.on(window, 'resize', this._handlers.onThrottledResize);
740		}
741
742		if (this.settings.mouseDrag) {
743			this.$element.addClass(this.options.dragClass);
744			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
745			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
746		}
747
748		if (this.settings.touchDrag){
749			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
750			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
751		}
752	};
753
754	/**
755	 * Handles `touchstart` and `mousedown` events.
756	 * @todo Horizontal swipe threshold as option
757	 * @todo #261
758	 * @protected
759	 * @param {Event} event - The event arguments.
760	 */
761	Owl.prototype.onDragStart = function(event) {
762		var stage = null;
763
764		if (event.which === 3) {
765			return;
766		}
767
768		if ($.support.transform) {
769			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
770			stage = {
771				x: stage[stage.length === 16 ? 12 : 4],
772				y: stage[stage.length === 16 ? 13 : 5]
773			};
774		} else {
775			stage = this.$stage.position();
776			stage = {
777				x: this.settings.rtl ?
778					stage.left + this.$stage.width() - this.width() + this.settings.margin :
779					stage.left,
780				y: stage.top
781			};
782		}
783
784		if (this.is('animating')) {
785			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
786			this.invalidate('position');
787		}
788
789		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
790
791		this.speed(0);
792
793		this._drag.time = new Date().getTime();
794		this._drag.target = $(event.target);
795		this._drag.stage.start = stage;
796		this._drag.stage.current = stage;
797		this._drag.pointer = this.pointer(event);
798
799		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
800
801		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
802			var delta = this.difference(this._drag.pointer, this.pointer(event));
803
804			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
805
806			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
807				return;
808			}
809
810			event.preventDefault();
811
812			this.enter('dragging');
813			this.trigger('drag');
814		}, this));
815	};
816
817	/**
818	 * Handles the `touchmove` and `mousemove` events.
819	 * @todo #261
820	 * @protected
821	 * @param {Event} event - The event arguments.
822	 */
823	Owl.prototype.onDragMove = function(event) {
824		var minimum = null,
825			maximum = null,
826			pull = null,
827			delta = this.difference(this._drag.pointer, this.pointer(event)),
828			stage = this.difference(this._drag.stage.start, delta);
829
830		if (!this.is('dragging')) {
831			return;
832		}
833
834		event.preventDefault();
835
836		if (this.settings.loop) {
837			minimum = this.coordinates(this.minimum());
838			maximum = this.coordinates(this.maximum() + 1) - minimum;
839			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
840		} else {
841			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
842			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
843			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
844			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
845		}
846
847		this._drag.stage.current = stage;
848
849		this.animate(stage.x);
850	};
851
852	/**
853	 * Handles the `touchend` and `mouseup` events.
854	 * @todo #261
855	 * @todo Threshold for click event
856	 * @protected
857	 * @param {Event} event - The event arguments.
858	 */
859	Owl.prototype.onDragEnd = function(event) {
860		var delta = this.difference(this._drag.pointer, this.pointer(event)),
861			stage = this._drag.stage.current,
862			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
863
864		$(document).off('.owl.core');
865
866		this.$element.removeClass(this.options.grabClass);
867
868		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
869			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
870			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
871			this.invalidate('position');
872			this.update();
873
874			this._drag.direction = direction;
875
876			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
877				this._drag.target.one('click.owl.core', function() { return false; });
878			}
879		}
880
881		if (!this.is('dragging')) {
882			return;
883		}
884
885		this.leave('dragging');
886		this.trigger('dragged');
887	};
888
889	/**
890	 * Gets absolute position of the closest item for a coordinate.
891	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
892	 * @protected
893	 * @param {Number} coordinate - The coordinate in pixel.
894	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
895	 * @return {Number} - The absolute position of the closest item.
896	 */
897	Owl.prototype.closest = function(coordinate, direction) {
898		var position = -1,
899			pull = 30,
900			width = this.width(),
901			coordinates = this.coordinates();
902
903		if (!this.settings.freeDrag) {
904			// check closest item
905			$.each(coordinates, $.proxy(function(index, value) {
906				// on a left pull, check on current index
907				if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {
908					position = index;
909				// on a right pull, check on previous index
910				// to do so, subtract width from value and set position = index + 1
911				} else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {
912					position = index + 1;
913				} else if (this.op(coordinate, '<', value)
914					&& this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) {
915					position = direction === 'left' ? index + 1 : index;
916				}
917				return position === -1;
918			}, this));
919		}
920
921		if (!this.settings.loop) {
922			// non loop boundries
923			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
924				position = coordinate = this.minimum();
925			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
926				position = coordinate = this.maximum();
927			}
928		}
929
930		return position;
931	};
932
933	/**
934	 * Animates the stage.
935	 * @todo #270
936	 * @public
937	 * @param {Number} coordinate - The coordinate in pixels.
938	 */
939	Owl.prototype.animate = function(coordinate) {
940		var animate = this.speed() > 0;
941
942		this.is('animating') && this.onTransitionEnd();
943
944		if (animate) {
945			this.enter('animating');
946			this.trigger('translate');
947		}
948
vendor: 10,524 bytes, lines 949-1316
949		if ($.support.transform3d && $.support.transition) {
950			this.$stage.css({
951				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
952				transition: (this.speed() / 1000) + 's' + (
953					this.settings.slideTransition ? ' ' + this.settings.slideTransition : ''
954				)
955			});
956		} else if (animate) {
957			this.$stage.animate({
958				left: coordinate + 'px'
959			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
960		} else {
961			this.$stage.css({
962				left: coordinate + 'px'
963			});
964		}
965	};
966
967	/**
968	 * Checks whether the carousel is in a specific state or not.
969	 * @param {String} state - The state to check.
970	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
971	 */
972	Owl.prototype.is = function(state) {
973		return this._states.current[state] && this._states.current[state] > 0;
974	};
975
976	/**
977	 * Sets the absolute position of the current item.
978	 * @public
979	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
980	 * @returns {Number} - The absolute position of the current item.
981	 */
982	Owl.prototype.current = function(position) {
983		if (position === undefined) {
984			return this._current;
985		}
986
987		if (this._items.length === 0) {
988			return undefined;
989		}
990
991		position = this.normalize(position);
992
993		if (this._current !== position) {
994			var event = this.trigger('change', { property: { name: 'position', value: position } });
995
996			if (event.data !== undefined) {
997				position = this.normalize(event.data);
998			}
999
1000			this._current = position;
1001
1002			this.invalidate('position');
1003
1004			this.trigger('changed', { property: { name: 'position', value: this._current } });
1005		}
1006
1007		return this._current;
1008	};
1009
1010	/**
1011	 * Invalidates the given part of the update routine.
1012	 * @param {String} [part] - The part to invalidate.
1013	 * @returns {Array.<String>} - The invalidated parts.
1014	 */
1015	Owl.prototype.invalidate = function(part) {
1016		if ($.type(part) === 'string') {
1017			this._invalidated[part] = true;
1018			this.is('valid') && this.leave('valid');
1019		}
1020		return $.map(this._invalidated, function(v, i) { return i });
1021	};
1022
1023	/**
1024	 * Resets the absolute position of the current item.
1025	 * @public
1026	 * @param {Number} position - The absolute position of the new item.
1027	 */
1028	Owl.prototype.reset = function(position) {
1029		position = this.normalize(position);
1030
1031		if (position === undefined) {
1032			return;
1033		}
1034
1035		this._speed = 0;
1036		this._current = position;
1037
1038		this.suppress([ 'translate', 'translated' ]);
1039
1040		this.animate(this.coordinates(position));
1041
1042		this.release([ 'translate', 'translated' ]);
1043	};
1044
1045	/**
1046	 * Normalizes an absolute or a relative position of an item.
1047	 * @public
1048	 * @param {Number} position - The absolute or relative position to normalize.
1049	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
1050	 * @returns {Number} - The normalized position.
1051	 */
1052	Owl.prototype.normalize = function(position, relative) {
1053		var n = this._items.length,
1054			m = relative ? 0 : this._clones.length;
1055
1056		if (!this.isNumeric(position) || n < 1) {
1057			position = undefined;
1058		} else if (position < 0 || position >= n + m) {
1059			position = ((position - m / 2) % n + n) % n + m / 2;
1060		}
1061
1062		return position;
1063	};
1064
1065	/**
1066	 * Converts an absolute position of an item into a relative one.
1067	 * @public
1068	 * @param {Number} position - The absolute position to convert.
1069	 * @returns {Number} - The converted position.
1070	 */
1071	Owl.prototype.relative = function(position) {
1072		position -= this._clones.length / 2;
1073		return this.normalize(position, true);
1074	};
1075
1076	/**
1077	 * Gets the maximum position for the current item.
1078	 * @public
1079	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1080	 * @returns {Number}
1081	 */
1082	Owl.prototype.maximum = function(relative) {
1083		var settings = this.settings,
1084			maximum = this._coordinates.length,
1085			iterator,
1086			reciprocalItemsWidth,
1087			elementWidth;
1088
1089		if (settings.loop) {
1090			maximum = this._clones.length / 2 + this._items.length - 1;
1091		} else if (settings.autoWidth || settings.merge) {
1092			iterator = this._items.length;
1093			if (iterator) {
1094				reciprocalItemsWidth = this._items[--iterator].width();
1095				elementWidth = this.$element.width();
1096				while (iterator--) {
1097					reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin;
1098					if (reciprocalItemsWidth > elementWidth) {
1099						break;
1100					}
1101				}
1102			}
1103			maximum = iterator + 1;
1104		} else if (settings.center) {
1105			maximum = this._items.length - 1;
1106		} else {
1107			maximum = this._items.length - settings.items;
1108		}
1109
1110		if (relative) {
1111			maximum -= this._clones.length / 2;
1112		}
1113
1114		return Math.max(maximum, 0);
1115	};
1116
1117	/**
1118	 * Gets the minimum position for the current item.
1119	 * @public
1120	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
1121	 * @returns {Number}
1122	 */
1123	Owl.prototype.minimum = function(relative) {
1124		return relative ? 0 : this._clones.length / 2;
1125	};
1126
1127	/**
1128	 * Gets an item at the specified relative position.
1129	 * @public
1130	 * @param {Number} [position] - The relative position of the item.
1131	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1132	 */
1133	Owl.prototype.items = function(position) {
1134		if (position === undefined) {
1135			return this._items.slice();
1136		}
1137
1138		position = this.normalize(position, true);
1139		return this._items[position];
1140	};
1141
1142	/**
1143	 * Gets an item at the specified relative position.
1144	 * @public
1145	 * @param {Number} [position] - The relative position of the item.
1146	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
1147	 */
1148	Owl.prototype.mergers = function(position) {
1149		if (position === undefined) {
1150			return this._mergers.slice();
1151		}
1152
1153		position = this.normalize(position, true);
1154		return this._mergers[position];
1155	};
1156
1157	/**
1158	 * Gets the absolute positions of clones for an item.
1159	 * @public
1160	 * @param {Number} [position] - The relative position of the item.
1161	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
1162	 */
1163	Owl.prototype.clones = function(position) {
1164		var odd = this._clones.length / 2,
1165			even = odd + this._items.length,
1166			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
1167
1168		if (position === undefined) {
1169			return $.map(this._clones, function(v, i) { return map(i) });
1170		}
1171
1172		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
1173	};
1174
1175	/**
1176	 * Sets the current animation speed.
1177	 * @public
1178	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
1179	 * @returns {Number} - The current animation speed in milliseconds.
1180	 */
1181	Owl.prototype.speed = function(speed) {
1182		if (speed !== undefined) {
1183			this._speed = speed;
1184		}
1185
1186		return this._speed;
1187	};
1188
1189	/**
1190	 * Gets the coordinate of an item.
1191	 * @todo The name of this method is missleanding.
1192	 * @public
1193	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
1194	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
1195	 */
1196	Owl.prototype.coordinates = function(position) {
1197		var multiplier = 1,
1198			newPosition = position - 1,
1199			coordinate;
1200
1201		if (position === undefined) {
1202			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
1203				return this.coordinates(index);
1204			}, this));
1205		}
1206
1207		if (this.settings.center) {
1208			if (this.settings.rtl) {
1209				multiplier = -1;
1210				newPosition = position + 1;
1211			}
1212
1213			coordinate = this._coordinates[position];
1214			coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;
1215		} else {
1216			coordinate = this._coordinates[newPosition] || 0;
1217		}
1218
1219		coordinate = Math.ceil(coordinate);
1220
1221		return coordinate;
1222	};
1223
1224	/**
1225	 * Calculates the speed for a translation.
1226	 * @protected
1227	 * @param {Number} from - The absolute position of the start item.
1228	 * @param {Number} to - The absolute position of the target item.
1229	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
1230	 * @returns {Number} - The time in milliseconds for the translation.
1231	 */
1232	Owl.prototype.duration = function(from, to, factor) {
1233		if (factor === 0) {
1234			return 0;
1235		}
1236
1237		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
1238	};
1239
1240	/**
1241	 * Slides to the specified item.
1242	 * @public
1243	 * @param {Number} position - The position of the item.
1244	 * @param {Number} [speed] - The time in milliseconds for the transition.
1245	 */
1246	Owl.prototype.to = function(position, speed) {
1247		var current = this.current(),
1248			revert = null,
1249			distance = position - this.relative(current),
1250			direction = (distance > 0) - (distance < 0),
1251			items = this._items.length,
1252			minimum = this.minimum(),
1253			maximum = this.maximum();
1254
1255		if (this.settings.loop) {
1256			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
1257				distance += direction * -1 * items;
1258			}
1259
1260			position = current + distance;
1261			revert = ((position - minimum) % items + items) % items + minimum;
1262
1263			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
1264				current = revert - distance;
1265				position = revert;
1266				this.reset(current);
1267			}
1268		} else if (this.settings.rewind) {
1269			maximum += 1;
1270			position = (position % maximum + maximum) % maximum;
1271		} else {
1272			position = Math.max(minimum, Math.min(maximum, position));
1273		}
1274
1275		this.speed(this.duration(current, position, speed));
1276		this.current(position);
1277
1278		if (this.isVisible()) {
1279			this.update();
1280		}
1281	};
1282
1283	/**
1284	 * Slides to the next item.
1285	 * @public
1286	 * @param {Number} [speed] - The time in milliseconds for the transition.
1287	 */
1288	Owl.prototype.next = function(speed) {
1289		speed = speed || false;
1290		this.to(this.relative(this.current()) + 1, speed);
1291	};
1292
1293	/**
1294	 * Slides to the previous item.
1295	 * @public
1296	 * @param {Number} [speed] - The time in milliseconds for the transition.
1297	 */
1298	Owl.prototype.prev = function(speed) {
1299		speed = speed || false;
1300		this.to(this.relative(this.current()) - 1, speed);
1301	};
1302
1303	/**
1304	 * Handles the end of an animation.
1305	 * @protected
1306	 * @param {Event} event - The event arguments.
1307	 */
1308	Owl.prototype.onTransitionEnd = function(event) {
1309
1310		// if css2 animation then event object is undefined
1311		if (event !== undefined) {
1312			event.stopPropagation();
1313
1314			// Catch only owl-stage transitionEnd event
1315			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
1316				return false;
vendor: 22,957 bytes, lines 1317-2165
1317			}
1318		}
1319
1320		this.leave('animating');
1321		this.trigger('translated');
1322	};
1323
1324	/**
1325	 * Gets viewport width.
1326	 * @protected
1327	 * @return {Number} - The width in pixel.
1328	 */
1329	Owl.prototype.viewport = function() {
1330		var width;
1331		if (this.options.responsiveBaseElement !== window) {
1332			width = $(this.options.responsiveBaseElement).width();
1333		} else if (window.innerWidth) {
1334			width = window.innerWidth;
1335		} else if (document.documentElement && document.documentElement.clientWidth) {
1336			width = document.documentElement.clientWidth;
1337		} else {
1338			console.warn('Can not detect viewport width.');
1339		}
1340		return width;
1341	};
1342
1343	/**
1344	 * Replaces the current content.
1345	 * @public
1346	 * @param {HTMLElement|jQuery|String} content - The new content.
1347	 */
1348	Owl.prototype.replace = function(content) {
1349		this.$stage.empty();
1350		this._items = [];
1351
1352		if (content) {
1353			content = (content instanceof jQuery) ? content : $(content);
1354		}
1355
1356		if (this.settings.nestedItemSelector) {
1357			content = content.find('.' + this.settings.nestedItemSelector);
1358		}
1359
1360		content.filter(function() {
1361			return this.nodeType === 1;
1362		}).each($.proxy(function(index, item) {
1363			item = this.prepare(item);
1364			this.$stage.append(item);
1365			this._items.push(item);
1366			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1367		}, this));
1368
1369		this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
1370
1371		this.invalidate('items');
1372	};
1373
1374	/**
1375	 * Adds an item.
1376	 * @todo Use `item` instead of `content` for the event arguments.
1377	 * @public
1378	 * @param {HTMLElement|jQuery|String} content - The item content to add.
1379	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
1380	 */
1381	Owl.prototype.add = function(content, position) {
1382		var current = this.relative(this._current);
1383
1384		position = position === undefined ? this._items.length : this.normalize(position, true);
1385		content = content instanceof jQuery ? content : $(content);
1386
1387		this.trigger('add', { content: content, position: position });
1388
1389		content = this.prepare(content);
1390
1391		if (this._items.length === 0 || position === this._items.length) {
1392			this._items.length === 0 && this.$stage.append(content);
1393			this._items.length !== 0 && this._items[position - 1].after(content);
1394			this._items.push(content);
1395			this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1396		} else {
1397			this._items[position].before(content);
1398			this._items.splice(position, 0, content);
1399			this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
1400		}
1401
1402		this._items[current] && this.reset(this._items[current].index());
1403
1404		this.invalidate('items');
1405
1406		this.trigger('added', { content: content, position: position });
1407	};
1408
1409	/**
1410	 * Removes an item by its position.
1411	 * @todo Use `item` instead of `content` for the event arguments.
1412	 * @public
1413	 * @param {Number} position - The relative position of the item to remove.
1414	 */
1415	Owl.prototype.remove = function(position) {
1416		position = this.normalize(position, true);
1417
1418		if (position === undefined) {
1419			return;
1420		}
1421
1422		this.trigger('remove', { content: this._items[position], position: position });
1423
1424		this._items[position].remove();
1425		this._items.splice(position, 1);
1426		this._mergers.splice(position, 1);
1427
1428		this.invalidate('items');
1429
1430		this.trigger('removed', { content: null, position: position });
1431	};
1432
1433	/**
1434	 * Preloads images with auto width.
1435	 * @todo Replace by a more generic approach
1436	 * @protected
1437	 */
1438	Owl.prototype.preloadAutoWidthImages = function(images) {
1439		images.each($.proxy(function(i, element) {
1440			this.enter('pre-loading');
1441			element = $(element);
1442			$(new Image()).one('load', $.proxy(function(e) {
1443				element.attr('src', e.target.src);
1444				element.css('opacity', 1);
1445				this.leave('pre-loading');
1446				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
1447			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
1448		}, this));
1449	};
1450
1451	/**
1452	 * Destroys the carousel.
1453	 * @public
1454	 */
1455	Owl.prototype.destroy = function() {
1456
1457		this.$element.off('.owl.core');
1458		this.$stage.off('.owl.core');
1459		$(document).off('.owl.core');
1460
1461		if (this.settings.responsive !== false) {
1462			window.clearTimeout(this.resizeTimer);
1463			this.off(window, 'resize', this._handlers.onThrottledResize);
1464		}
1465
1466		for (var i in this._plugins) {
1467			this._plugins[i].destroy();
1468		}
1469
1470		this.$stage.children('.cloned').remove();
1471
1472		this.$stage.unwrap();
1473		this.$stage.children().contents().unwrap();
1474		this.$stage.children().unwrap();
1475		this.$stage.remove();
1476		this.$element
1477			.removeClass(this.options.refreshClass)
1478			.removeClass(this.options.loadingClass)
1479			.removeClass(this.options.loadedClass)
1480			.removeClass(this.options.rtlClass)
1481			.removeClass(this.options.dragClass)
1482			.removeClass(this.options.grabClass)
1483			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
1484			.removeData('owl.carousel');
1485	};
1486
1487	/**
1488	 * Operators to calculate right-to-left and left-to-right.
1489	 * @protected
1490	 * @param {Number} [a] - The left side operand.
1491	 * @param {String} [o] - The operator.
1492	 * @param {Number} [b] - The right side operand.
1493	 */
1494	Owl.prototype.op = function(a, o, b) {
1495		var rtl = this.settings.rtl;
1496		switch (o) {
1497			case '<':
1498				return rtl ? a > b : a < b;
1499			case '>':
1500				return rtl ? a < b : a > b;
1501			case '>=':
1502				return rtl ? a <= b : a >= b;
1503			case '<=':
1504				return rtl ? a >= b : a <= b;
1505			default:
1506				break;
1507		}
1508	};
1509
1510	/**
1511	 * Attaches to an internal event.
1512	 * @protected
1513	 * @param {HTMLElement} element - The event source.
1514	 * @param {String} event - The event name.
1515	 * @param {Function} listener - The event handler to attach.
1516	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
1517	 */
1518	Owl.prototype.on = function(element, event, listener, capture) {
1519		if (element.addEventListener) {
1520			element.addEventListener(event, listener, capture);
1521		} else if (element.attachEvent) {
1522			element.attachEvent('on' + event, listener);
1523		}
1524	};
1525
1526	/**
1527	 * Detaches from an internal event.
1528	 * @protected
1529	 * @param {HTMLElement} element - The event source.
1530	 * @param {String} event - The event name.
1531	 * @param {Function} listener - The attached event handler to detach.
1532	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
1533	 */
1534	Owl.prototype.off = function(element, event, listener, capture) {
1535		if (element.removeEventListener) {
1536			element.removeEventListener(event, listener, capture);
1537		} else if (element.detachEvent) {
1538			element.detachEvent('on' + event, listener);
1539		}
1540	};
1541
1542	/**
1543	 * Triggers a public event.
1544	 * @todo Remove `status`, `relatedTarget` should be used instead.
1545	 * @protected
1546	 * @param {String} name - The event name.
1547	 * @param {*} [data=null] - The event data.
1548	 * @param {String} [namespace=carousel] - The event namespace.
1549	 * @param {String} [state] - The state which is associated with the event.
1550	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
1551	 * @returns {Event} - The event arguments.
1552	 */
1553	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
1554		var status = {
1555			item: { count: this._items.length, index: this.current() }
1556		}, handler = $.camelCase(
1557			$.grep([ 'on', name, namespace ], function(v) { return v })
1558				.join('-').toLowerCase()
1559		), event = $.Event(
1560			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
1561			$.extend({ relatedTarget: this }, status, data)
1562		);
1563
1564		if (!this._supress[name]) {
1565			$.each(this._plugins, function(name, plugin) {
1566				if (plugin.onTrigger) {
1567					plugin.onTrigger(event);
1568				}
1569			});
1570
1571			this.register({ type: Owl.Type.Event, name: name });
1572			this.$element.trigger(event);
1573
1574			if (this.settings && typeof this.settings[handler] === 'function') {
1575				this.settings[handler].call(this, event);
1576			}
1577		}
1578
1579		return event;
1580	};
1581
1582	/**
1583	 * Enters a state.
1584	 * @param name - The state name.
1585	 */
1586	Owl.prototype.enter = function(name) {
1587		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1588			if (this._states.current[name] === undefined) {
1589				this._states.current[name] = 0;
1590			}
1591
1592			this._states.current[name]++;
1593		}, this));
1594	};
1595
1596	/**
1597	 * Leaves a state.
1598	 * @param name - The state name.
1599	 */
1600	Owl.prototype.leave = function(name) {
1601		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
1602			this._states.current[name]--;
1603		}, this));
1604	};
1605
1606	/**
1607	 * Registers an event or state.
1608	 * @public
1609	 * @param {Object} object - The event or state to register.
1610	 */
1611	Owl.prototype.register = function(object) {
1612		if (object.type === Owl.Type.Event) {
1613			if (!$.event.special[object.name]) {
1614				$.event.special[object.name] = {};
1615			}
1616
1617			if (!$.event.special[object.name].owl) {
1618				var _default = $.event.special[object.name]._default;
1619				$.event.special[object.name]._default = function(e) {
1620					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
1621						return _default.apply(this, arguments);
1622					}
1623					return e.namespace && e.namespace.indexOf('owl') > -1;
1624				};
1625				$.event.special[object.name].owl = true;
1626			}
1627		} else if (object.type === Owl.Type.State) {
1628			if (!this._states.tags[object.name]) {
1629				this._states.tags[object.name] = object.tags;
1630			} else {
1631				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
1632			}
1633
1634			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
1635				return $.inArray(tag, this._states.tags[object.name]) === i;
1636			}, this));
1637		}
1638	};
1639
1640	/**
1641	 * Suppresses events.
1642	 * @protected
1643	 * @param {Array.<String>} events - The events to suppress.
1644	 */
1645	Owl.prototype.suppress = function(events) {
1646		$.each(events, $.proxy(function(index, event) {
1647			this._supress[event] = true;
1648		}, this));
1649	};
1650
1651	/**
1652	 * Releases suppressed events.
1653	 * @protected
1654	 * @param {Array.<String>} events - The events to release.
1655	 */
1656	Owl.prototype.release = function(events) {
1657		$.each(events, $.proxy(function(index, event) {
1658			delete this._supress[event];
1659		}, this));
1660	};
1661
1662	/**
1663	 * Gets unified pointer coordinates from event.
1664	 * @todo #261
1665	 * @protected
1666	 * @param {Event} - The `mousedown` or `touchstart` event.
1667	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
1668	 */
1669	Owl.prototype.pointer = function(event) {
1670		var result = { x: null, y: null };
1671
1672		event = event.originalEvent || event || window.event;
1673
1674		event = event.touches && event.touches.length ?
1675			event.touches[0] : event.changedTouches && event.changedTouches.length ?
1676				event.changedTouches[0] : event;
1677
1678		if (event.pageX) {
1679			result.x = event.pageX;
1680			result.y = event.pageY;
1681		} else {
1682			result.x = event.clientX;
1683			result.y = event.clientY;
1684		}
1685
1686		return result;
1687	};
1688
1689	/**
1690	 * Determines if the input is a Number or something that can be coerced to a Number
1691	 * @protected
1692	 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested
1693	 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number
1694	 */
1695	Owl.prototype.isNumeric = function(number) {
1696		return !isNaN(parseFloat(number));
1697	};
1698
1699	/**
1700	 * Gets the difference of two vectors.
1701	 * @todo #261
1702	 * @protected
1703	 * @param {Object} - The first vector.
1704	 * @param {Object} - The second vector.
1705	 * @returns {Object} - The difference.
1706	 */
1707	Owl.prototype.difference = function(first, second) {
1708		return {
1709			x: first.x - second.x,
1710			y: first.y - second.y
1711		};
1712	};
1713
1714	/**
1715	 * The jQuery Plugin for the Owl Carousel
1716	 * @todo Navigation plugin `next` and `prev`
1717	 * @public
1718	 */
1719	$.fn.owlCarousel = function(option) {
1720		var args = Array.prototype.slice.call(arguments, 1);
1721
1722		return this.each(function() {
1723			var $this = $(this),
1724				data = $this.data('owl.carousel');
1725
1726			if (!data) {
1727				data = new Owl(this, typeof option == 'object' && option);
1728				$this.data('owl.carousel', data);
1729
1730				$.each([
1731					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
1732				], function(i, event) {
1733					data.register({ type: Owl.Type.Event, name: event });
1734					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
1735						if (e.namespace && e.relatedTarget !== this) {
1736							this.suppress([ event ]);
1737							data[event].apply(this, [].slice.call(arguments, 1));
1738							this.release([ event ]);
1739						}
1740					}, data));
1741				});
1742			}
1743
1744			if (typeof option == 'string' && option.charAt(0) !== '_') {
1745				data[option].apply(data, args);
1746			}
1747		});
1748	};
1749
1750	/**
1751	 * The constructor for the jQuery Plugin
1752	 * @public
1753	 */
1754	$.fn.owlCarousel.Constructor = Owl;
1755
1756})(window.Zepto || window.jQuery, window, document);
1757
1758/**
1759 * AutoRefresh Plugin
1760 * @version 2.3.4
1761 * @author Artus Kolanowski
1762 * @author David Deutsch
1763 * @license The MIT License (MIT)
1764 */
1765;(function($, window, document, undefined) {
1766
1767	/**
1768	 * Creates the auto refresh plugin.
1769	 * @class The Auto Refresh Plugin
1770	 * @param {Owl} carousel - The Owl Carousel
1771	 */
1772	var AutoRefresh = function(carousel) {
1773		/**
1774		 * Reference to the core.
1775		 * @protected
1776		 * @type {Owl}
1777		 */
1778		this._core = carousel;
1779
1780		/**
1781		 * Refresh interval.
1782		 * @protected
1783		 * @type {number}
1784		 */
1785		this._interval = null;
1786
1787		/**
1788		 * Whether the element is currently visible or not.
1789		 * @protected
1790		 * @type {Boolean}
1791		 */
1792		this._visible = null;
1793
1794		/**
1795		 * All event handlers.
1796		 * @protected
1797		 * @type {Object}
1798		 */
1799		this._handlers = {
1800			'initialized.owl.carousel': $.proxy(function(e) {
1801				if (e.namespace && this._core.settings.autoRefresh) {
1802					this.watch();
1803				}
1804			}, this)
1805		};
1806
1807		// set default options
1808		this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
1809
1810		// register event handlers
1811		this._core.$element.on(this._handlers);
1812	};
1813
1814	/**
1815	 * Default options.
1816	 * @public
1817	 */
1818	AutoRefresh.Defaults = {
1819		autoRefresh: true,
1820		autoRefreshInterval: 500
1821	};
1822
1823	/**
1824	 * Watches the element.
1825	 */
1826	AutoRefresh.prototype.watch = function() {
1827		if (this._interval) {
1828			return;
1829		}
1830
1831		this._visible = this._core.isVisible();
1832		this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
1833	};
1834
1835	/**
1836	 * Refreshes the element.
1837	 */
1838	AutoRefresh.prototype.refresh = function() {
1839		if (this._core.isVisible() === this._visible) {
1840			return;
1841		}
1842
1843		this._visible = !this._visible;
1844
1845		this._core.$element.toggleClass('owl-hidden', !this._visible);
1846
1847		this._visible && (this._core.invalidate('width') && this._core.refresh());
1848	};
1849
1850	/**
1851	 * Destroys the plugin.
1852	 */
1853	AutoRefresh.prototype.destroy = function() {
1854		var handler, property;
1855
1856		window.clearInterval(this._interval);
1857
1858		for (handler in this._handlers) {
1859			this._core.$element.off(handler, this._handlers[handler]);
1860		}
1861		for (property in Object.getOwnPropertyNames(this)) {
1862			typeof this[property] != 'function' && (this[property] = null);
1863		}
1864	};
1865
1866	$.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
1867
1868})(window.Zepto || window.jQuery, window, document);
1869
1870/**
1871 * Lazy Plugin
1872 * @version 2.3.4
1873 * @author Bartosz Wojciechowski
1874 * @author David Deutsch
1875 * @license The MIT License (MIT)
1876 */
1877;(function($, window, document, undefined) {
1878
1879	/**
1880	 * Creates the lazy plugin.
1881	 * @class The Lazy Plugin
1882	 * @param {Owl} carousel - The Owl Carousel
1883	 */
1884	var Lazy = function(carousel) {
1885
1886		/**
1887		 * Reference to the core.
1888		 * @protected
1889		 * @type {Owl}
1890		 */
1891		this._core = carousel;
1892
1893		/**
1894		 * Already loaded items.
1895		 * @protected
1896		 * @type {Array.<jQuery>}
1897		 */
1898		this._loaded = [];
1899
1900		/**
1901		 * Event handlers.
1902		 * @protected
1903		 * @type {Object}
1904		 */
1905		this._handlers = {
1906			'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) {
1907				if (!e.namespace) {
1908					return;
1909				}
1910
1911				if (!this._core.settings || !this._core.settings.lazyLoad) {
1912					return;
1913				}
1914
1915				if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
1916					var settings = this._core.settings,
1917						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
1918						i = ((settings.center && n * -1) || 0),
1919						position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i,
1920						clones = this._core.clones().length,
1921						load = $.proxy(function(i, v) { this.load(v) }, this);
1922					//TODO: Need documentation for this new option
1923					if (settings.lazyLoadEager > 0) {
1924						n += settings.lazyLoadEager;
1925						// If the carousel is looping also preload images that are to the "left"
1926						if (settings.loop) {
1927              position -= settings.lazyLoadEager;
1928              n++;
1929            }
1930					}
1931
1932					while (i++ < n) {
1933						this.load(clones / 2 + this._core.relative(position));
1934						clones && $.each(this._core.clones(this._core.relative(position)), load);
1935						position++;
1936					}
1937				}
1938			}, this)
1939		};
1940
1941		// set the default options
1942		this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
1943
1944		// register event handler
1945		this._core.$element.on(this._handlers);
1946	};
1947
1948	/**
1949	 * Default options.
1950	 * @public
1951	 */
1952	Lazy.Defaults = {
1953		lazyLoad: false,
1954		lazyLoadEager: 0
1955	};
1956
1957	/**
1958	 * Loads all resources of an item at the specified position.
1959	 * @param {Number} position - The absolute position of the item.
1960	 * @protected
1961	 */
1962	Lazy.prototype.load = function(position) {
1963		var $item = this._core.$stage.children().eq(position),
1964			$elements = $item && $item.find('.owl-lazy');
1965
1966		if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
1967			return;
1968		}
1969
1970		$elements.each($.proxy(function(index, element) {
1971			var $element = $(element), image,
1972                url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src') || $element.attr('data-srcset');
1973
1974			this._core.trigger('load', { element: $element, url: url }, 'lazy');
1975
1976			if ($element.is('img')) {
1977				$element.one('load.owl.lazy', $.proxy(function() {
1978					$element.css('opacity', 1);
1979					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1980				}, this)).attr('src', url);
1981            } else if ($element.is('source')) {
1982                $element.one('load.owl.lazy', $.proxy(function() {
1983                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1984                }, this)).attr('srcset', url);
1985			} else {
1986				image = new Image();
1987				image.onload = $.proxy(function() {
1988					$element.css({
1989						'background-image': 'url("' + url + '")',
1990						'opacity': '1'
1991					});
1992					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
1993				}, this);
1994				image.src = url;
1995			}
1996		}, this));
1997
1998		this._loaded.push($item.get(0));
1999	};
2000
2001	/**
2002	 * Destroys the plugin.
2003	 * @public
2004	 */
2005	Lazy.prototype.destroy = function() {
2006		var handler, property;
2007
2008		for (handler in this.handlers) {
2009			this._core.$element.off(handler, this.handlers[handler]);
2010		}
2011		for (property in Object.getOwnPropertyNames(this)) {
2012			typeof this[property] != 'function' && (this[property] = null);
2013		}
2014	};
2015
2016	$.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
2017
2018})(window.Zepto || window.jQuery, window, document);
2019
2020/**
2021 * AutoHeight Plugin
2022 * @version 2.3.4
2023 * @author Bartosz Wojciechowski
2024 * @author David Deutsch
2025 * @license The MIT License (MIT)
2026 */
2027;(function($, window, document, undefined) {
2028
2029	/**
2030	 * Creates the auto height plugin.
2031	 * @class The Auto Height Plugin
2032	 * @param {Owl} carousel - The Owl Carousel
2033	 */
2034	var AutoHeight = function(carousel) {
2035		/**
2036		 * Reference to the core.
2037		 * @protected
2038		 * @type {Owl}
2039		 */
2040		this._core = carousel;
2041
2042		this._previousHeight = null;
2043
2044		/**
2045		 * All event handlers.
2046		 * @protected
2047		 * @type {Object}
2048		 */
2049		this._handlers = {
2050			'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
2051				if (e.namespace && this._core.settings.autoHeight) {
2052					this.update();
2053				}
2054			}, this),
2055			'changed.owl.carousel': $.proxy(function(e) {
2056				if (e.namespace && this._core.settings.autoHeight && e.property.name === 'position'){
2057					this.update();
2058				}
2059			}, this),
2060			'loaded.owl.lazy': $.proxy(function(e) {
2061				if (e.namespace && this._core.settings.autoHeight
2062					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
2063					this.update();
2064				}
2065			}, this)
2066		};
2067
2068		// set default options
2069		this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
2070
2071		// register event handlers
2072		this._core.$element.on(this._handlers);
2073		this._intervalId = null;
2074		var refThis = this;
2075
2076		// These changes have been taken from a PR by gavrochelegnou proposed in #1575
2077		// and have been made compatible with the latest jQuery version
2078		$(window).on('load', function() {
2079			if (refThis._core.settings.autoHeight) {
2080				refThis.update();
2081			}
2082		});
2083
2084		// Autoresize the height of the carousel when window is resized
2085		// When carousel has images, the height is dependent on the width
2086		// and should also change on resize
2087		$(window).resize(function() {
2088			if (refThis._core.settings.autoHeight) {
2089				if (refThis._intervalId != null) {
2090					clearTimeout(refThis._intervalId);
2091				}
2092
2093				refThis._intervalId = setTimeout(function() {
2094					refThis.update();
2095				}, 250);
2096			}
2097		});
2098
2099	};
2100
2101	/**
2102	 * Default options.
2103	 * @public
2104	 */
2105	AutoHeight.Defaults = {
2106		autoHeight: false,
2107		autoHeightClass: 'owl-height'
2108	};
2109
2110	/**
2111	 * Updates the view.
2112	 */
2113	AutoHeight.prototype.update = function() {
2114		var start = this._core._current,
2115			end = start + this._core.settings.items,
2116			lazyLoadEnabled = this._core.settings.lazyLoad,
2117			visible = this._core.$stage.children().toArray().slice(start, end),
2118			heights = [],
2119			maxheight = 0;
2120
2121		$.each(visible, function(index, item) {
2122			heights.push($(item).height());
2123		});
2124
2125		maxheight = Math.max.apply(null, heights);
2126
2127		if (maxheight <= 1 && lazyLoadEnabled && this._previousHeight) {
2128			maxheight = this._previousHeight;
2129		}
2130
2131		this._previousHeight = maxheight;
2132
2133		this._core.$stage.parent()
2134			.height(maxheight)
2135			.addClass(this._core.settings.autoHeightClass);
2136	};
2137
2138	AutoHeight.prototype.destroy = function() {
2139		var handler, property;
2140
2141		for (handler in this._handlers) {
2142			this._core.$element.off(handler, this._handlers[handler]);
2143		}
2144		for (property in Object.getOwnPropertyNames(this)) {
2145			typeof this[property] !== 'function' && (this[property] = null);
2146		}
2147	};
2148
2149	$.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
2150
2151})(window.Zepto || window.jQuery, window, document);
2152
2153/**
2154 * Video Plugin
2155 * @version 2.3.4
2156 * @author Bartosz Wojciechowski
2157 * @author David Deutsch
2158 * @license The MIT License (MIT)
2159 */
2160;(function($, window, document, undefined) {
2161
2162	/**
2163	 * Creates the video plugin.
2164	 * @class The Video Plugin
2165	 * @param {Owl} carousel - The Owl Carousel
vendor: 5,347 bytes, lines 2166-2363
2166	 */
2167	var Video = function(carousel) {
2168		/**
2169		 * Reference to the core.
2170		 * @protected
2171		 * @type {Owl}
2172		 */
2173		this._core = carousel;
2174
2175		/**
2176		 * Cache all video URLs.
2177		 * @protected
2178		 * @type {Object}
2179		 */
2180		this._videos = {};
2181
2182		/**
2183		 * Current playing item.
2184		 * @protected
2185		 * @type {jQuery}
2186		 */
2187		this._playing = null;
2188
2189		/**
2190		 * All event handlers.
2191		 * @todo The cloned content removale is too late
2192		 * @protected
2193		 * @type {Object}
2194		 */
2195		this._handlers = {
2196			'initialized.owl.carousel': $.proxy(function(e) {
2197				if (e.namespace) {
2198					this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
2199				}
2200			}, this),
2201			'resize.owl.carousel': $.proxy(function(e) {
2202				if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
2203					e.preventDefault();
2204				}
2205			}, this),
2206			'refreshed.owl.carousel': $.proxy(function(e) {
2207				if (e.namespace && this._core.is('resizing')) {
2208					this._core.$stage.find('.cloned .owl-video-frame').remove();
2209				}
2210			}, this),
2211			'changed.owl.carousel': $.proxy(function(e) {
2212				if (e.namespace && e.property.name === 'position' && this._playing) {
2213					this.stop();
2214				}
2215			}, this),
2216			'prepared.owl.carousel': $.proxy(function(e) {
2217				if (!e.namespace) {
2218					return;
2219				}
2220
2221				var $element = $(e.content).find('.owl-video');
2222
2223				if ($element.length) {
2224					$element.css('display', 'none');
2225					this.fetch($element, $(e.content));
2226				}
2227			}, this)
2228		};
2229
2230		// set default options
2231		this._core.options = $.extend({}, Video.Defaults, this._core.options);
2232
2233		// register event handlers
2234		this._core.$element.on(this._handlers);
2235
2236		this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
2237			this.play(e);
2238		}, this));
2239	};
2240
2241	/**
2242	 * Default options.
2243	 * @public
2244	 */
2245	Video.Defaults = {
2246		video: false,
2247		videoHeight: false,
2248		videoWidth: false
2249	};
2250
2251	/**
2252	 * Gets the video ID and the type (YouTube/Vimeo/vzaar only).
2253	 * @protected
2254	 * @param {jQuery} target - The target containing the video data.
2255	 * @param {jQuery} item - The item containing the video.
2256	 */
2257	Video.prototype.fetch = function(target, item) {
2258			var type = (function() {
2259					if (target.attr('data-vimeo-id')) {
2260						return 'vimeo';
2261					} else if (target.attr('data-vzaar-id')) {
2262						return 'vzaar'
2263					} else {
2264						return 'youtube';
2265					}
2266				})(),
2267				id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'),
2268				width = target.attr('data-width') || this._core.settings.videoWidth,
2269				height = target.attr('data-height') || this._core.settings.videoHeight,
2270				url = target.attr('href');
2271
2272		if (url) {
2273
2274			/*
2275					Parses the id's out of the following urls (and probably more):
2276					https://www.youtube.com/watch?v=:id
2277					https://youtu.be/:id
2278					https://vimeo.com/:id
2279					https://vimeo.com/channels/:channel/:id
2280					https://vimeo.com/groups/:group/videos/:id
2281					https://app.vzaar.com/videos/:id
2282
2283					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
2284			*/
2285
2286			id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
2287
2288			if (id[3].indexOf('youtu') > -1) {
2289				type = 'youtube';
2290			} else if (id[3].indexOf('vimeo') > -1) {
2291				type = 'vimeo';
2292			} else if (id[3].indexOf('vzaar') > -1) {
2293				type = 'vzaar';
2294			} else {
2295				throw new Error('Video URL not supported.');
2296			}
2297			id = id[6];
2298		} else {
2299			throw new Error('Missing video URL.');
2300		}
2301
2302		this._videos[url] = {
2303			type: type,
2304			id: id,
2305			width: width,
2306			height: height
2307		};
2308
2309		item.attr('data-video', url);
2310
2311		this.thumbnail(target, this._videos[url]);
2312	};
2313
2314	/**
2315	 * Creates video thumbnail.
2316	 * @protected
2317	 * @param {jQuery} target - The target containing the video data.
2318	 * @param {Object} info - The video info object.
2319	 * @see `fetch`
2320	 */
2321	Video.prototype.thumbnail = function(target, video) {
2322		var tnLink,
2323			icon,
2324			path,
2325			dimensions = video.width && video.height ? 'width:' + video.width + 'px;height:' + video.height + 'px;' : '',
2326			customTn = target.find('img'),
2327			srcType = 'src',
2328			lazyClass = '',
2329			settings = this._core.settings,
2330			create = function(path) {
2331				icon = '<div class="owl-video-play-icon"></div>';
2332
2333				if (settings.lazyLoad) {
2334					tnLink = $('<div/>',{
2335						"class": 'owl-video-tn ' + lazyClass,
2336						"srcType": path
2337					});
2338				} else {
2339					tnLink = $( '<div/>', {
2340						"class": "owl-video-tn",
2341						"style": 'opacity:1;background-image:url(' + path + ')'
2342					});
2343				}
2344				target.after(tnLink);
2345				target.after(icon);
2346			};
2347
2348		// wrap video content into owl-video-wrapper div
2349		target.wrap( $( '<div/>', {
2350			"class": "owl-video-wrapper",
2351			"style": dimensions
2352		}));
2353
2354		if (this._core.settings.lazyLoad) {
2355			srcType = 'data-src';
2356			lazyClass = 'owl-lazy';
2357		}
2358
2359		// custom thumbnail
2360		if (customTn.length) {
2361			create(customTn.attr(srcType));
2362			customTn.remove();
2363			return false;
vendor: 15,908 bytes, lines 2364-3001
2364		}
2365
2366		if (video.type === 'youtube') {
2367			path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
2368			create(path);
2369		} else if (video.type === 'vimeo') {
2370			$.ajax({
2371				type: 'GET',
2372				url: '//vimeo.com/api/v2/video/' + video.id + '.json',
2373				jsonp: 'callback',
2374				dataType: 'jsonp',
2375				success: function(data) {
2376					path = data[0].thumbnail_large;
2377					create(path);
2378				}
2379			});
2380		} else if (video.type === 'vzaar') {
2381			$.ajax({
2382				type: 'GET',
2383				url: '//vzaar.com/api/videos/' + video.id + '.json',
2384				jsonp: 'callback',
2385				dataType: 'jsonp',
2386				success: function(data) {
2387					path = data.framegrab_url;
2388					create(path);
2389				}
2390			});
2391		}
2392	};
2393
2394	/**
2395	 * Stops the current video.
2396	 * @public
2397	 */
2398	Video.prototype.stop = function() {
2399		this._core.trigger('stop', null, 'video');
2400		this._playing.find('.owl-video-frame').remove();
2401		this._playing.removeClass('owl-video-playing');
2402		this._playing = null;
2403		this._core.leave('playing');
2404		this._core.trigger('stopped', null, 'video');
2405	};
2406
2407	/**
2408	 * Starts the current video.
2409	 * @public
2410	 * @param {Event} event - The event arguments.
2411	 */
2412	Video.prototype.play = function(event) {
2413		var target = $(event.target),
2414			item = target.closest('.' + this._core.settings.itemClass),
2415			video = this._videos[item.attr('data-video')],
2416			width = video.width || '100%',
2417			height = video.height || this._core.$stage.height(),
2418			html,
2419			iframe;
2420
2421		if (this._playing) {
2422			return;
2423		}
2424
2425		this._core.enter('playing');
2426		this._core.trigger('play', null, 'video');
2427
2428		item = this._core.items(this._core.relative(item.index()));
2429
2430		this._core.reset(item.index());
2431
2432		html = $( '<iframe frameborder="0" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>' );
2433		html.attr( 'height', height );
2434		html.attr( 'width', width );
2435		if (video.type === 'youtube') {
2436			html.attr( 'src', '//www.youtube.com/embed/' + video.id + '?autoplay=1&rel=0&v=' + video.id );
2437		} else if (video.type === 'vimeo') {
2438			html.attr( 'src', '//player.vimeo.com/video/' + video.id + '?autoplay=1' );
2439		} else if (video.type === 'vzaar') {
2440			html.attr( 'src', '//view.vzaar.com/' + video.id + '/player?autoplay=true' );
2441		}
2442
2443		iframe = $(html).wrap( '<div class="owl-video-frame" />' ).insertAfter(item.find('.owl-video'));
2444
2445		this._playing = item.addClass('owl-video-playing');
2446	};
2447
2448	/**
2449	 * Checks whether an video is currently in full screen mode or not.
2450	 * @todo Bad style because looks like a readonly method but changes members.
2451	 * @protected
2452	 * @returns {Boolean}
2453	 */
2454	Video.prototype.isInFullScreen = function() {
2455		var element = document.fullscreenElement || document.mozFullScreenElement ||
2456				document.webkitFullscreenElement;
2457
2458		return element && $(element).parent().hasClass('owl-video-frame');
2459	};
2460
2461	/**
2462	 * Destroys the plugin.
2463	 */
2464	Video.prototype.destroy = function() {
2465		var handler, property;
2466
2467		this._core.$element.off('click.owl.video');
2468
2469		for (handler in this._handlers) {
2470			this._core.$element.off(handler, this._handlers[handler]);
2471		}
2472		for (property in Object.getOwnPropertyNames(this)) {
2473			typeof this[property] != 'function' && (this[property] = null);
2474		}
2475	};
2476
2477	$.fn.owlCarousel.Constructor.Plugins.Video = Video;
2478
2479})(window.Zepto || window.jQuery, window, document);
2480
2481/**
2482 * Animate Plugin
2483 * @version 2.3.4
2484 * @author Bartosz Wojciechowski
2485 * @author David Deutsch
2486 * @license The MIT License (MIT)
2487 */
2488;(function($, window, document, undefined) {
2489
2490	/**
2491	 * Creates the animate plugin.
2492	 * @class The Navigation Plugin
2493	 * @param {Owl} scope - The Owl Carousel
2494	 */
2495	var Animate = function(scope) {
2496		this.core = scope;
2497		this.core.options = $.extend({}, Animate.Defaults, this.core.options);
2498		this.swapping = true;
2499		this.previous = undefined;
2500		this.next = undefined;
2501
2502		this.handlers = {
2503			'change.owl.carousel': $.proxy(function(e) {
2504				if (e.namespace && e.property.name == 'position') {
2505					this.previous = this.core.current();
2506					this.next = e.property.value;
2507				}
2508			}, this),
2509			'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
2510				if (e.namespace) {
2511					this.swapping = e.type == 'translated';
2512				}
2513			}, this),
2514			'translate.owl.carousel': $.proxy(function(e) {
2515				if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
2516					this.swap();
2517				}
2518			}, this)
2519		};
2520
2521		this.core.$element.on(this.handlers);
2522	};
2523
2524	/**
2525	 * Default options.
2526	 * @public
2527	 */
2528	Animate.Defaults = {
2529		animateOut: false,
2530		animateIn: false
2531	};
2532
2533	/**
2534	 * Toggles the animation classes whenever an translations starts.
2535	 * @protected
2536	 * @returns {Boolean|undefined}
2537	 */
2538	Animate.prototype.swap = function() {
2539
2540		if (this.core.settings.items !== 1) {
2541			return;
2542		}
2543
2544		if (!$.support.animation || !$.support.transition) {
2545			return;
2546		}
2547
2548		this.core.speed(0);
2549
2550		var left,
2551			clear = $.proxy(this.clear, this),
2552			previous = this.core.$stage.children().eq(this.previous),
2553			next = this.core.$stage.children().eq(this.next),
2554			incoming = this.core.settings.animateIn,
2555			outgoing = this.core.settings.animateOut;
2556
2557		if (this.core.current() === this.previous) {
2558			return;
2559		}
2560
2561		if (outgoing) {
2562			left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
2563			previous.one($.support.animation.end, clear)
2564				.css( { 'left': left + 'px' } )
2565				.addClass('animated owl-animated-out')
2566				.addClass(outgoing);
2567		}
2568
2569		if (incoming) {
2570			next.one($.support.animation.end, clear)
2571				.addClass('animated owl-animated-in')
2572				.addClass(incoming);
2573		}
2574	};
2575
2576	Animate.prototype.clear = function(e) {
2577		$(e.target).css( { 'left': '' } )
2578			.removeClass('animated owl-animated-out owl-animated-in')
2579			.removeClass(this.core.settings.animateIn)
2580			.removeClass(this.core.settings.animateOut);
2581		this.core.onTransitionEnd();
2582	};
2583
2584	/**
2585	 * Destroys the plugin.
2586	 * @public
2587	 */
2588	Animate.prototype.destroy = function() {
2589		var handler, property;
2590
2591		for (handler in this.handlers) {
2592			this.core.$element.off(handler, this.handlers[handler]);
2593		}
2594		for (property in Object.getOwnPropertyNames(this)) {
2595			typeof this[property] != 'function' && (this[property] = null);
2596		}
2597	};
2598
2599	$.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
2600
2601})(window.Zepto || window.jQuery, window, document);
2602
2603/**
2604 * Autoplay Plugin
2605 * @version 2.3.4
2606 * @author Bartosz Wojciechowski
2607 * @author Artus Kolanowski
2608 * @author David Deutsch
2609 * @author Tom De Caluwé
2610 * @license The MIT License (MIT)
2611 */
2612;(function($, window, document, undefined) {
2613
2614	/**
2615	 * Creates the autoplay plugin.
2616	 * @class The Autoplay Plugin
2617	 * @param {Owl} scope - The Owl Carousel
2618	 */
2619	var Autoplay = function(carousel) {
2620		/**
2621		 * Reference to the core.
2622		 * @protected
2623		 * @type {Owl}
2624		 */
2625		this._core = carousel;
2626
2627		/**
2628		 * The autoplay timeout id.
2629		 * @type {Number}
2630		 */
2631		this._call = null;
2632
2633		/**
2634		 * Depending on the state of the plugin, this variable contains either
2635		 * the start time of the timer or the current timer value if it's
2636		 * paused. Since we start in a paused state we initialize the timer
2637		 * value.
2638		 * @type {Number}
2639		 */
2640		this._time = 0;
2641
2642		/**
2643		 * Stores the timeout currently used.
2644		 * @type {Number}
2645		 */
2646		this._timeout = 0;
2647
2648		/**
2649		 * Indicates whenever the autoplay is paused.
2650		 * @type {Boolean}
2651		 */
2652		this._paused = true;
2653
2654		/**
2655		 * All event handlers.
2656		 * @protected
2657		 * @type {Object}
2658		 */
2659		this._handlers = {
2660			'changed.owl.carousel': $.proxy(function(e) {
2661				if (e.namespace && e.property.name === 'settings') {
2662					if (this._core.settings.autoplay) {
2663						this.play();
2664					} else {
2665						this.stop();
2666					}
2667				} else if (e.namespace && e.property.name === 'position' && this._paused) {
2668					// Reset the timer. This code is triggered when the position
2669					// of the carousel was changed through user interaction.
2670					this._time = 0;
2671				}
2672			}, this),
2673			'initialized.owl.carousel': $.proxy(function(e) {
2674				if (e.namespace && this._core.settings.autoplay) {
2675					this.play();
2676				}
2677			}, this),
2678			'play.owl.autoplay': $.proxy(function(e, t, s) {
2679				if (e.namespace) {
2680					this.play(t, s);
2681				}
2682			}, this),
2683			'stop.owl.autoplay': $.proxy(function(e) {
2684				if (e.namespace) {
2685					this.stop();
2686				}
2687			}, this),
2688			'mouseover.owl.autoplay': $.proxy(function() {
2689				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
2690					this.pause();
2691				}
2692			}, this),
2693			'mouseleave.owl.autoplay': $.proxy(function() {
2694				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
2695					this.play();
2696				}
2697			}, this),
2698			'touchstart.owl.core': $.proxy(function() {
2699				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
2700					this.pause();
2701				}
2702			}, this),
2703			'touchend.owl.core': $.proxy(function() {
2704				if (this._core.settings.autoplayHoverPause) {
2705					this.play();
2706				}
2707			}, this)
2708		};
2709
2710		// register event handlers
2711		this._core.$element.on(this._handlers);
2712
2713		// set default options
2714		this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
2715	};
2716
2717	/**
2718	 * Default options.
2719	 * @public
2720	 */
2721	Autoplay.Defaults = {
2722		autoplay: false,
2723		autoplayTimeout: 5000,
2724		autoplayHoverPause: false,
2725		autoplaySpeed: false
2726	};
2727
2728	/**
2729	 * Transition to the next slide and set a timeout for the next transition.
2730	 * @private
2731	 * @param {Number} [speed] - The animation speed for the animations.
2732	 */
2733	Autoplay.prototype._next = function(speed) {
2734		this._call = window.setTimeout(
2735			$.proxy(this._next, this, speed),
2736			this._timeout * (Math.round(this.read() / this._timeout) + 1) - this.read()
2737		);
2738
2739		if (this._core.is('interacting') || document.hidden) {
2740			return;
2741		}
2742		this._core.next(speed || this._core.settings.autoplaySpeed);
2743	}
2744
2745	/**
2746	 * Reads the current timer value when the timer is playing.
2747	 * @public
2748	 */
2749	Autoplay.prototype.read = function() {
2750		return new Date().getTime() - this._time;
2751	};
2752
2753	/**
2754	 * Starts the autoplay.
2755	 * @public
2756	 * @param {Number} [timeout] - The interval before the next animation starts.
2757	 * @param {Number} [speed] - The animation speed for the animations.
2758	 */
2759	Autoplay.prototype.play = function(timeout, speed) {
2760		var elapsed;
2761
2762		if (!this._core.is('rotating')) {
2763			this._core.enter('rotating');
2764		}
2765
2766		timeout = timeout || this._core.settings.autoplayTimeout;
2767
2768		// Calculate the elapsed time since the last transition. If the carousel
2769		// wasn't playing this calculation will yield zero.
2770		elapsed = Math.min(this._time % (this._timeout || timeout), timeout);
2771
2772		if (this._paused) {
2773			// Start the clock.
2774			this._time = this.read();
2775			this._paused = false;
2776		} else {
2777			// Clear the active timeout to allow replacement.
2778			window.clearTimeout(this._call);
2779		}
2780
2781		// Adjust the origin of the timer to match the new timeout value.
2782		this._time += this.read() % timeout - elapsed;
2783
2784		this._timeout = timeout;
2785		this._call = window.setTimeout($.proxy(this._next, this, speed), timeout - elapsed);
2786	};
2787
2788	/**
2789	 * Stops the autoplay.
2790	 * @public
2791	 */
2792	Autoplay.prototype.stop = function() {
2793		if (this._core.is('rotating')) {
2794			// Reset the clock.
2795			this._time = 0;
2796			this._paused = true;
2797
2798			window.clearTimeout(this._call);
2799			this._core.leave('rotating');
2800		}
2801	};
2802
2803	/**
2804	 * Pauses the autoplay.
2805	 * @public
2806	 */
2807	Autoplay.prototype.pause = function() {
2808		if (this._core.is('rotating') && !this._paused) {
2809			// Pause the clock.
2810			this._time = this.read();
2811			this._paused = true;
2812
2813			window.clearTimeout(this._call);
2814		}
2815	};
2816
2817	/**
2818	 * Destroys the plugin.
2819	 */
2820	Autoplay.prototype.destroy = function() {
2821		var handler, property;
2822
2823		this.stop();
2824
2825		for (handler in this._handlers) {
2826			this._core.$element.off(handler, this._handlers[handler]);
2827		}
2828		for (property in Object.getOwnPropertyNames(this)) {
2829			typeof this[property] != 'function' && (this[property] = null);
2830		}
2831	};
2832
2833	$.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
2834
2835})(window.Zepto || window.jQuery, window, document);
2836
2837/**
2838 * Navigation Plugin
2839 * @version 2.3.4
2840 * @author Artus Kolanowski
2841 * @author David Deutsch
2842 * @license The MIT License (MIT)
2843 */
2844;(function($, window, document, undefined) {
2845	'use strict';
2846
2847	/**
2848	 * Creates the navigation plugin.
2849	 * @class The Navigation Plugin
2850	 * @param {Owl} carousel - The Owl Carousel.
2851	 */
2852	var Navigation = function(carousel) {
2853		/**
2854		 * Reference to the core.
2855		 * @protected
2856		 * @type {Owl}
2857		 */
2858		this._core = carousel;
2859
2860		/**
2861		 * Indicates whether the plugin is initialized or not.
2862		 * @protected
2863		 * @type {Boolean}
2864		 */
2865		this._initialized = false;
2866
2867		/**
2868		 * The current paging indexes.
2869		 * @protected
2870		 * @type {Array}
2871		 */
2872		this._pages = [];
2873
2874		/**
2875		 * All DOM elements of the user interface.
2876		 * @protected
2877		 * @type {Object}
2878		 */
2879		this._controls = {};
2880
2881		/**
2882		 * Markup for an indicator.
2883		 * @protected
2884		 * @type {Array.<String>}
2885		 */
2886		this._templates = [];
2887
2888		/**
2889		 * The carousel element.
2890		 * @type {jQuery}
2891		 */
2892		this.$element = this._core.$element;
2893
2894		/**
2895		 * Overridden methods of the carousel.
2896		 * @protected
2897		 * @type {Object}
2898		 */
2899		this._overrides = {
2900			next: this._core.next,
2901			prev: this._core.prev,
2902			to: this._core.to
2903		};
2904
2905		/**
2906		 * All event handlers.
2907		 * @protected
2908		 * @type {Object}
2909		 */
2910		this._handlers = {
2911			'prepared.owl.carousel': $.proxy(function(e) {
2912				if (e.namespace && this._core.settings.dotsData) {
2913					this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
2914						$(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '</div>');
2915				}
2916			}, this),
2917			'added.owl.carousel': $.proxy(function(e) {
2918				if (e.namespace && this._core.settings.dotsData) {
2919					this._templates.splice(e.position, 0, this._templates.pop());
2920				}
2921			}, this),
2922			'remove.owl.carousel': $.proxy(function(e) {
2923				if (e.namespace && this._core.settings.dotsData) {
2924					this._templates.splice(e.position, 1);
2925				}
2926			}, this),
2927			'changed.owl.carousel': $.proxy(function(e) {
2928				if (e.namespace && e.property.name == 'position') {
2929					this.draw();
2930				}
2931			}, this),
2932			'initialized.owl.carousel': $.proxy(function(e) {
2933				if (e.namespace && !this._initialized) {
2934					this._core.trigger('initialize', null, 'navigation');
2935					this.initialize();
2936					this.update();
2937					this.draw();
2938					this._initialized = true;
2939					this._core.trigger('initialized', null, 'navigation');
2940				}
2941			}, this),
2942			'refreshed.owl.carousel': $.proxy(function(e) {
2943				if (e.namespace && this._initialized) {
2944					this._core.trigger('refresh', null, 'navigation');
2945					this.update();
2946					this.draw();
2947					this._core.trigger('refreshed', null, 'navigation');
2948				}
2949			}, this)
2950		};
2951
2952		// set default options
2953		this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
2954
2955		// register event handlers
2956		this.$element.on(this._handlers);
2957	};
2958
2959	/**
2960	 * Default options.
2961	 * @public
2962	 * @todo Rename `slideBy` to `navBy`
2963	 */
2964	Navigation.Defaults = {
2965		nav: false,
2966		navText: [
2967			'<span aria-label="' + 'Previous' + '">&#x2039;</span>',
2968			'<span aria-label="' + 'Next' + '">&#x203a;</span>'
2969		],
2970		navSpeed: false,
2971		navElement: 'button type="button" role="presentation"',
2972		navContainer: false,
2973		navContainerClass: 'owl-nav',
2974		navClass: [
2975			'owl-prev',
2976			'owl-next'
2977		],
2978		slideBy: 1,
2979		dotClass: 'owl-dot',
2980		dotsClass: 'owl-dots',
2981		dots: true,
2982		dotsEach: false,
2983		dotsData: false,
2984		dotsSpeed: false,
2985		dotsContainer: false
2986	};
2987
2988	/**
2989	 * Initializes the layout of the plugin and extends the carousel.
2990	 * @protected
2991	 */
2992	Navigation.prototype.initialize = function() {
2993		var override,
2994			settings = this._core.settings;
2995
2996		// create DOM structure for relative navigation
2997		this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
2998			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
2999
3000		this._controls.$previous = $('<' + settings.navElement + '>')
3001			.addClass(settings.navClass[0])
vendor: 4,756 bytes, lines 3002-3163
3002			.html(settings.navText[0])
3003			.prependTo(this._controls.$relative)
3004			.on('click', $.proxy(function(e) {
3005				this.prev(settings.navSpeed);
3006			}, this));
3007		this._controls.$next = $('<' + settings.navElement + '>')
3008			.addClass(settings.navClass[1])
3009			.html(settings.navText[1])
3010			.appendTo(this._controls.$relative)
3011			.on('click', $.proxy(function(e) {
3012				this.next(settings.navSpeed);
3013			}, this));
3014
3015		// create DOM structure for absolute navigation
3016		if (!settings.dotsData) {
3017			this._templates = [ $('<button role="button">')
3018				.addClass(settings.dotClass)
3019				.append($('<span>'))
3020				.prop('outerHTML') ];
3021		}
3022
3023		this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
3024			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
3025
3026		this._controls.$absolute.on('click', 'button', $.proxy(function(e) {
3027			var index = $(e.target).parent().is(this._controls.$absolute)
3028				? $(e.target).index() : $(e.target).parent().index();
3029
3030			e.preventDefault();
3031
3032			this.to(index, settings.dotsSpeed);
3033		}, this));
3034
3035		/*$el.on('focusin', function() {
3036			$(document).off(".carousel");
3037
3038			$(document).on('keydown.carousel', function(e) {
3039				if(e.keyCode == 37) {
3040					$el.trigger('prev.owl')
3041				}
3042				if(e.keyCode == 39) {
3043					$el.trigger('next.owl')
3044				}
3045			});
3046		});*/
3047
3048		// override public methods of the carousel
3049		for (override in this._overrides) {
3050			this._core[override] = $.proxy(this[override], this);
3051		}
3052	};
3053
3054	/**
3055	 * Destroys the plugin.
3056	 * @protected
3057	 */
3058	Navigation.prototype.destroy = function() {
3059		var handler, control, property, override, settings;
3060		settings = this._core.settings;
3061
3062		for (handler in this._handlers) {
3063			this.$element.off(handler, this._handlers[handler]);
3064		}
3065		for (control in this._controls) {
3066			if (control === '$relative' && settings.navContainer) {
3067				this._controls[control].html('');
3068			} else {
3069				this._controls[control].remove();
3070			}
3071		}
3072		for (override in this.overides) {
3073			this._core[override] = this._overrides[override];
3074		}
3075		for (property in Object.getOwnPropertyNames(this)) {
3076			typeof this[property] != 'function' && (this[property] = null);
3077		}
3078	};
3079
3080	/**
3081	 * Updates the internal state.
3082	 * @protected
3083	 */
3084	Navigation.prototype.update = function() {
3085		var i, j, k,
3086			lower = this._core.clones().length / 2,
3087			upper = lower + this._core.items().length,
3088			maximum = this._core.maximum(true),
3089			settings = this._core.settings,
3090			size = settings.center || settings.autoWidth || settings.dotsData
3091				? 1 : settings.dotsEach || settings.items;
3092
3093		if (settings.slideBy !== 'page') {
3094			settings.slideBy = Math.min(settings.slideBy, settings.items);
3095		}
3096
3097		if (settings.dots || settings.slideBy == 'page') {
3098			this._pages = [];
3099
3100			for (i = lower, j = 0, k = 0; i < upper; i++) {
3101				if (j >= size || j === 0) {
3102					this._pages.push({
3103						start: Math.min(maximum, i - lower),
3104						end: i - lower + size - 1
3105					});
3106					if (Math.min(maximum, i - lower) === maximum) {
3107						break;
3108					}
3109					j = 0, ++k;
3110				}
3111				j += this._core.mergers(this._core.relative(i));
3112			}
3113		}
3114	};
3115
3116	/**
3117	 * Draws the user interface.
3118	 * @todo The option `dotsData` wont work.
3119	 * @protected
3120	 */
3121	Navigation.prototype.draw = function() {
3122		var difference,
3123			settings = this._core.settings,
3124			disabled = this._core.items().length <= settings.items,
3125			index = this._core.relative(this._core.current()),
3126			loop = settings.loop || settings.rewind;
3127
3128		this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
3129
3130		if (settings.nav) {
3131			this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
3132			this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
3133		}
3134
3135		this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
3136
3137		if (settings.dots) {
3138			difference = this._pages.length - this._controls.$absolute.children().length;
3139
3140			if (settings.dotsData && difference !== 0) {
3141				this._controls.$absolute.html(this._templates.join(''));
3142			} else if (difference > 0) {
3143				this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
3144			} else if (difference < 0) {
3145				this._controls.$absolute.children().slice(difference).remove();
3146			}
3147
3148			this._controls.$absolute.find('.active').removeClass('active');
3149			this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
3150		}
3151	};
3152
3153	/**
3154	 * Extends event data.
3155	 * @protected
3156	 * @param {Event} event - The event object which gets thrown.
3157	 */
3158	Navigation.prototype.onTrigger = function(event) {
3159		var settings = this._core.settings;
3160
3161		event.page = {
3162			index: $.inArray(this.current(), this._pages),
3163			count: this._pages.length,
vendor: 7,284 bytes, lines 3164-3449
3164			size: settings && (settings.center || settings.autoWidth || settings.dotsData
3165				? 1 : settings.dotsEach || settings.items)
3166		};
3167	};
3168
3169	/**
3170	 * Gets the current page position of the carousel.
3171	 * @protected
3172	 * @returns {Number}
3173	 */
3174	Navigation.prototype.current = function() {
3175		var current = this._core.relative(this._core.current());
3176		return $.grep(this._pages, $.proxy(function(page, index) {
3177			return page.start <= current && page.end >= current;
3178		}, this)).pop();
3179	};
3180
3181	/**
3182	 * Gets the current succesor/predecessor position.
3183	 * @protected
3184	 * @returns {Number}
3185	 */
3186	Navigation.prototype.getPosition = function(successor) {
3187		var position, length,
3188			settings = this._core.settings;
3189
3190		if (settings.slideBy == 'page') {
3191			position = $.inArray(this.current(), this._pages);
3192			length = this._pages.length;
3193			successor ? ++position : --position;
3194			position = this._pages[((position % length) + length) % length].start;
3195		} else {
3196			position = this._core.relative(this._core.current());
3197			length = this._core.items().length;
3198			successor ? position += settings.slideBy : position -= settings.slideBy;
3199		}
3200
3201		return position;
3202	};
3203
3204	/**
3205	 * Slides to the next item or page.
3206	 * @public
3207	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
3208	 */
3209	Navigation.prototype.next = function(speed) {
3210		$.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
3211	};
3212
3213	/**
3214	 * Slides to the previous item or page.
3215	 * @public
3216	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
3217	 */
3218	Navigation.prototype.prev = function(speed) {
3219		$.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
3220	};
3221
3222	/**
3223	 * Slides to the specified item or page.
3224	 * @public
3225	 * @param {Number} position - The position of the item or page.
3226	 * @param {Number} [speed] - The time in milliseconds for the transition.
3227	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
3228	 */
3229	Navigation.prototype.to = function(position, speed, standard) {
3230		var length;
3231
3232		if (!standard && this._pages.length) {
3233			length = this._pages.length;
3234			$.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
3235		} else {
3236			$.proxy(this._overrides.to, this._core)(position, speed);
3237		}
3238	};
3239
3240	$.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
3241
3242})(window.Zepto || window.jQuery, window, document);
3243
3244/**
3245 * Hash Plugin
3246 * @version 2.3.4
3247 * @author Artus Kolanowski
3248 * @author David Deutsch
3249 * @license The MIT License (MIT)
3250 */
3251;(function($, window, document, undefined) {
3252	'use strict';
3253
3254	/**
3255	 * Creates the hash plugin.
3256	 * @class The Hash Plugin
3257	 * @param {Owl} carousel - The Owl Carousel
3258	 */
3259	var Hash = function(carousel) {
3260		/**
3261		 * Reference to the core.
3262		 * @protected
3263		 * @type {Owl}
3264		 */
3265		this._core = carousel;
3266
3267		/**
3268		 * Hash index for the items.
3269		 * @protected
3270		 * @type {Object}
3271		 */
3272		this._hashes = {};
3273
3274		/**
3275		 * The carousel element.
3276		 * @type {jQuery}
3277		 */
3278		this.$element = this._core.$element;
3279
3280		/**
3281		 * All event handlers.
3282		 * @protected
3283		 * @type {Object}
3284		 */
3285		this._handlers = {
3286			'initialized.owl.carousel': $.proxy(function(e) {
3287				if (e.namespace && this._core.settings.startPosition === 'URLHash') {
3288					$(window).trigger('hashchange.owl.navigation');
3289				}
3290			}, this),
3291			'prepared.owl.carousel': $.proxy(function(e) {
3292				if (e.namespace) {
3293					var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
3294
3295					if (!hash) {
3296						return;
3297					}
3298
3299					this._hashes[hash] = e.content;
3300				}
3301			}, this),
3302			'changed.owl.carousel': $.proxy(function(e) {
3303				if (e.namespace && e.property.name === 'position') {
3304					var current = this._core.items(this._core.relative(this._core.current())),
3305						hash = $.map(this._hashes, function(item, hash) {
3306							return item === current ? hash : null;
3307						}).join();
3308
3309					if (!hash || window.location.hash.slice(1) === hash) {
3310						return;
3311					}
3312
3313					window.location.hash = hash;
3314				}
3315			}, this)
3316		};
3317
3318		// set default options
3319		this._core.options = $.extend({}, Hash.Defaults, this._core.options);
3320
3321		// register the event handlers
3322		this.$element.on(this._handlers);
3323
3324		// register event listener for hash navigation
3325		$(window).on('hashchange.owl.navigation', $.proxy(function(e) {
3326			var hash = window.location.hash.substring(1),
3327				items = this._core.$stage.children(),
3328				position = this._hashes[hash] && items.index(this._hashes[hash]);
3329
3330			if (position === undefined || position === this._core.current()) {
3331				return;
3332			}
3333
3334			this._core.to(this._core.relative(position), false, true);
3335		}, this));
3336	};
3337
3338	/**
3339	 * Default options.
3340	 * @public
3341	 */
3342	Hash.Defaults = {
3343		URLhashListener: false
3344	};
3345
3346	/**
3347	 * Destroys the plugin.
3348	 * @public
3349	 */
3350	Hash.prototype.destroy = function() {
3351		var handler, property;
3352
3353		$(window).off('hashchange.owl.navigation');
3354
3355		for (handler in this._handlers) {
3356			this._core.$element.off(handler, this._handlers[handler]);
3357		}
3358		for (property in Object.getOwnPropertyNames(this)) {
3359			typeof this[property] != 'function' && (this[property] = null);
3360		}
3361	};
3362
3363	$.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
3364
3365})(window.Zepto || window.jQuery, window, document);
3366
3367/**
3368 * Support Plugin
3369 *
3370 * @version 2.3.4
3371 * @author Vivid Planet Software GmbH
3372 * @author Artus Kolanowski
3373 * @author David Deutsch
3374 * @license The MIT License (MIT)
3375 */
3376;(function($, window, document, undefined) {
3377
3378	var style = $('<support>').get(0).style,
3379		prefixes = 'Webkit Moz O ms'.split(' '),
3380		events = {
3381			transition: {
3382				end: {
3383					WebkitTransition: 'webkitTransitionEnd',
3384					MozTransition: 'transitionend',
3385					OTransition: 'oTransitionEnd',
3386					transition: 'transitionend'
3387				}
3388			},
3389			animation: {
3390				end: {
3391					WebkitAnimation: 'webkitAnimationEnd',
3392					MozAnimation: 'animationend',
3393					OAnimation: 'oAnimationEnd',
3394					animation: 'animationend'
3395				}
3396			}
3397		},
3398		tests = {
3399			csstransforms: function() {
3400				return !!test('transform');
3401			},
3402			csstransforms3d: function() {
3403				return !!test('perspective');
3404			},
3405			csstransitions: function() {
3406				return !!test('transition');
3407			},
3408			cssanimations: function() {
3409				return !!test('animation');
3410			}
3411		};
3412
3413	function test(property, prefixed) {
3414		var result = false,
3415			upper = property.charAt(0).toUpperCase() + property.slice(1);
3416
3417		$.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
3418			if (style[property] !== undefined) {
3419				result = prefixed ? property : true;
3420				return false;
3421			}
3422		});
3423
3424		return result;
3425	}
3426
3427	function prefixed(property) {
3428		return test(property, true);
3429	}
3430
3431	if (tests.csstransitions()) {
3432		/* jshint -W053 */
3433		$.support.transition = new String(prefixed('transition'))
3434		$.support.transition.end = events.transition.end[ $.support.transition ];
3435	}
3436
3437	if (tests.cssanimations()) {
3438		/* jshint -W053 */
3439		$.support.animation = new String(prefixed('animation'))
3440		$.support.animation.end = events.animation.end[ $.support.animation ];
3441	}
3442
3443	if (tests.csstransforms()) {
3444		/* jshint -W053 */
3445		$.support.transform = new String(prefixed('transform'));
3446		$.support.transform3d = tests.csstransforms3d();
3447	}
3448
3449})(window.Zepto || window.jQuery, window, document);
3450
3451/*! lightgallery - v1.7.0 - 2020-05-03
3452* http://sachinchoolur.github.io/lightGallery/
3453* Copyright (c) 2020 Sachin N; Licensed GPLv3 */
3454(function (root, factory) {
3455    if (typeof define === 'function' && define.amd) {
3456      // AMD. Register as an anonymous module unless amdModuleId is set
3457      define(['jquery'], function (a0) {
3458        return (factory(a0));
3459      });
3460    } else if (typeof module === 'object' && module.exports) {
3461      // Node. Does not work with strict CommonJS, but
3462      // only CommonJS-like environments that support module.exports,
3463      // like Node.
3464      module.exports = factory(require('jquery'));
3465    } else {
3466      factory(root["jQuery"]);
3467    }
3468  }(this, function ($) {
3469  
3470  (function() {
3471      'use strict';
3472  
3473      var defaults = {
3474  
3475          mode: 'lg-slide',
3476  
3477          // Ex : 'ease'
3478          cssEasing: 'ease',
3479  
3480          //'for jquery animation'
3481          easing: 'linear',
3482          speed: 600,
3483          height: '100%',
3484          width: '100%',
3485          addClass: '',
3486          startClass: 'lg-start-zoom',
3487          backdropDuration: 150,
3488          hideBarsDelay: 6000,
3489  
3490          useLeft: false,
3491  
3492          // aria-labelledby attribute fot gallery
3493          ariaLabelledby: '',
3494          
3495          //aria-describedby attribute for gallery
3496          ariaDescribedby: '',
3497  
3498          closable: true,
3499          loop: true,
3500          escKey: true,
3501          keyPress: true,
3502          controls: true,
3503          slideEndAnimatoin: true,
3504          hideControlOnEnd: false,
3505          mousewheel: true,
3506  
3507          getCaptionFromTitleOrAlt: true,
3508  
3509          // .lg-item || '.lg-sub-html'
3510          appendSubHtmlTo: '.lg-sub-html',
3511  
3512          subHtmlSelectorRelative: false,
3513  
3514          /**
3515           * @desc number of preload slides
3516           * will exicute only after the current slide is fully loaded.
3517           *
3518           * @ex you clicked on 4th image and if preload = 1 then 3rd slide and 5th
3519           * slide will be loaded in the background after the 4th slide is fully loaded..
3520           * if preload is 2 then 2nd 3rd 5th 6th slides will be preloaded.. ... ...
3521           *
3522           */
3523          preload: 1,
3524          showAfterLoad: true,
3525          selector: '',
3526          selectWithin: '',
3527          nextHtml: '',
3528          prevHtml: '',
3529  
3530          // 0, 1
3531          index: false,
3532  
3533          iframeMaxWidth: '100%',
3534  
3535          download: true,
3536          counter: true,
3537          appendCounterTo: '.lg-toolbar',
3538  
3539          swipeThreshold: 50,
3540          enableSwipe: true,
3541          enableDrag: true,
3542  
3543          dynamic: false,
3544          dynamicEl: [],
3545          galleryId: 1
3546      };
3547  
3548      function Plugin(element, options) {
3549  
3550          // Current lightGallery element
3551          this.el = element;
3552  
3553          // Current jquery element
3554          this.$el = $(element);
3555  
3556          // lightGallery settings
3557          this.s = $.extend({}, defaults, options);
3558  
3559          // When using dynamic mode, ensure dynamicEl is an array
3560          if (this.s.dynamic && this.s.dynamicEl !== 'undefined' && this.s.dynamicEl.constructor === Array && !this.s.dynamicEl.length) {
3561              throw ('When using dynamic mode, you must also define dynamicEl as an Array.');
3562          }
3563  
3564          // lightGallery modules
3565          this.modules = {};
3566  
3567          // false when lightgallery complete first slide;
3568          this.lGalleryOn = false;
3569  
3570          this.lgBusy = false;
3571  
3572          // Timeout function for hiding controls;
3573          this.hideBartimeout = false;
3574  
3575          // To determine browser supports for touch events;
3576          this.isTouch = ('ontouchstart' in document.documentElement);
3577  
3578          // Disable hideControlOnEnd if sildeEndAnimation is true
3579          if (this.s.slideEndAnimatoin) {
3580              this.s.hideControlOnEnd = false;
3581          }
3582  
3583          // Gallery items
3584          if (this.s.dynamic) {
3585              this.$items = this.s.dynamicEl;
3586          } else {
3587              if (this.s.selector === 'this') {
3588                  this.$items = this.$el;
3589              } else if (this.s.selector !== '') {
3590                  if (this.s.selectWithin) {
3591                      this.$items = $(this.s.selectWithin).find(this.s.selector);
3592                  } else {
3593                      this.$items = this.$el.find($(this.s.selector));
3594                  }
3595              } else {
3596                  this.$items = this.$el.children();
3597              }
3598          }
3599  
3600          // .lg-item
3601          this.$slide = '';
3602  
3603          // .lg-outer
3604          this.$outer = '';
3605  
3606          this.init();
3607  
3608          return this;
3609      }
3610  
3611      Plugin.prototype.init = function() {
3612  
3613          var _this = this;
3614  
3615          // s.preload should not be more than $item.length
3616          if (_this.s.preload > _this.$items.length) {
3617              _this.s.preload = _this.$items.length;
3618          }
3619  
3620          // if dynamic option is enabled execute immediately
3621          var _hash = window.location.hash;
3622          if (_hash.indexOf('lg=' + this.s.galleryId) > 0) {
3623  
3624              _this.index = parseInt(_hash.split('&slide=')[1], 10);
3625  
3626              $('body').addClass('lg-from-hash');
3627              if (!$('body').hasClass('lg-on')) {
3628                  setTimeout(function() {
3629                      _this.build(_this.index);
3630                  });
3631  
3632                  $('body').addClass('lg-on');
3633              }
3634          }
3635  
3636          if (_this.s.dynamic) {
3637  
3638              _this.$el.trigger('onBeforeOpen.lg');
3639  
3640              _this.index = _this.s.index || 0;
3641  
3642              // prevent accidental double execution
3643              if (!$('body').hasClass('lg-on')) {
3644                  setTimeout(function() {
3645                      _this.build(_this.index);
3646                      $('body').addClass('lg-on');
3647                  });
3648              }
3649          } else {
3650  
3651              // Using different namespace for click because click event should not unbind if selector is same object('this')
3652              _this.$items.on('click.lgcustom', function(event) {
3653  
3654                  // For IE8
3655                  try {
3656                      event.preventDefault();
3657                      event.preventDefault();
3658                  } catch (er) {
3659                      event.returnValue = false;
3660                  }
3661  
3662                  _this.$el.trigger('onBeforeOpen.lg');
3663  
3664                  _this.index = _this.s.index || _this.$items.index(this);
3665  
3666                  // prevent accidental double execution
3667                  if (!$('body').hasClass('lg-on')) {
3668                      _this.build(_this.index);
3669                      $('body').addClass('lg-on');
3670                  }
3671              });
3672          }
3673  
3674      };
3675  
3676      Plugin.prototype.build = function(index) {
3677  
3678          var _this = this;
3679  
3680          _this.structure();
3681  
3682          // module constructor
3683          $.each($.fn.lightGallery.modules, function(key) {
3684              _this.modules[key] = new $.fn.lightGallery.modules[key](_this.el);
3685          });
3686  
3687          // initiate slide function
3688          _this.slide(index, false, false, false);
3689  
3690          if (_this.s.keyPress) {
3691              _this.keyPress();
3692          }
3693  
3694          if (_this.$items.length > 1) {
3695  
3696              _this.arrow();
3697  
3698              setTimeout(function() {
3699                  _this.enableDrag();
3700                  _this.enableSwipe();
3701              }, 50);
3702  
3703              if (_this.s.mousewheel) {
3704                  _this.mousewheel();
3705              }
3706          } else {
3707              _this.$slide.on('click.lg', function() {
3708                  _this.$el.trigger('onSlideClick.lg');
3709              });
3710          }
3711  
3712          _this.counter();
3713  
3714          _this.closeGallery();
3715  
3716          _this.$el.trigger('onAfterOpen.lg');
3717  
3718          // Hide controllers if mouse doesn't move for some period
3719          _this.$outer.on('mousemove.lg click.lg touchstart.lg', function() {
3720  
3721              _this.$outer.removeClass('lg-hide-items');
3722  
3723              clearTimeout(_this.hideBartimeout);
3724  
3725              // Timeout will be cleared on each slide movement also
3726              _this.hideBartimeout = setTimeout(function() {
3727                  _this.$outer.addClass('lg-hide-items');
3728              }, _this.s.hideBarsDelay);
3729  
3730          });
3731  
3732          _this.$outer.trigger('mousemove.lg');
3733  
3734      };
3735  
3736      Plugin.prototype.structure = function() {
3737          var list = '';
3738          var controls = '';
3739          var i = 0;
3740          var subHtmlCont = '';
3741          var template;
3742          var _this = this;
3743  
3744          $('body').append('<div class="lg-backdrop"></div>');
3745          $('.lg-backdrop').css('transition-duration', this.s.backdropDuration + 'ms');
3746  
3747          // Create gallery items
3748          for (i = 0; i < this.$items.length; i++) {
3749              list += '<div class="lg-item"></div>';
3750          }
3751  
3752          // Create controlls
3753          if (this.s.controls && this.$items.length > 1) {
3754              controls = '<div class="lg-actions">' +
3755                  '<button aria-label="Previous slide" class="lg-prev lg-icon">' + this.s.prevHtml + '</button>' +
3756                  '<button aria-label="Next slide" class="lg-next lg-icon">' + this.s.nextHtml + '</button>' +
3757                  '</div>';
3758          }
3759  
3760          if (this.s.appendSubHtmlTo === '.lg-sub-html') {
3761              subHtmlCont = '<div role="status" aria-live="polite" class="lg-sub-html"></div>';
3762          }
3763  
3764          var ariaLabelledby = this.s.ariaLabelledby ?
3765              'aria-labelledby="' + this.s.ariaLabelledby + '"' : '';
3766          var ariaDescribedby = this.s.ariaDescribedby ?
3767              'aria-describedby="' + this.s.ariaDescribedby + '"' : '';
3768  
3769          template = '<div tabindex="-1" aria-modal="true" ' + ariaLabelledby + ' ' + ariaDescribedby + ' role="dialog" class="lg-outer ' + this.s.addClass + ' ' + this.s.startClass + '">' +
3770              '<div class="lg" style="width:' + this.s.width + '; height:' + this.s.height + '">' +
3771              '<div class="lg-inner">' + list + '</div>' +
3772              '<div class="lg-toolbar lg-group">' +
3773              '<button aria-label="Close gallery" class="lg-close lg-icon"></button>' +
3774              '</div>' +
3775              controls +
3776              subHtmlCont +
3777              '</div>' +
3778              '</div>';
3779  
3780          $('body').append(template);
3781          this.$outer = $('.lg-outer');
3782          this.$outer.focus();
3783          this.$slide = this.$outer.find('.lg-item');
3784  
3785          if (this.s.useLeft) {
3786              this.$outer.addClass('lg-use-left');
3787  
3788              // Set mode lg-slide if use left is true;
3789              this.s.mode = 'lg-slide';
3790          } else {
3791              this.$outer.addClass('lg-use-css3');
3792          }
3793  
3794          // For fixed height gallery
3795          _this.setTop();
3796          $(window).on('resize.lg orientationchange.lg', function() {
3797              setTimeout(function() {
3798                  _this.setTop();
3799              }, 100);
3800          });
3801  
3802          // add class lg-current to remove initial transition
3803          this.$slide.eq(this.index).addClass('lg-current');
3804  
3805          // add Class for css support and transition mode
3806          if (this.doCss()) {
3807              this.$outer.addClass('lg-css3');
3808          } else {
3809              this.$outer.addClass('lg-css');
3810  
3811              // Set speed 0 because no animation will happen if browser doesn't support css3
3812              this.s.speed = 0;
3813          }
3814  
3815          this.$outer.addClass(this.s.mode);
3816  
3817          if (this.s.enableDrag && this.$items.length > 1) {
3818              this.$outer.addClass('lg-grab');
3819          }
3820  
3821          if (this.s.showAfterLoad) {
3822              this.$outer.addClass('lg-show-after-load');
3823          }
3824  
3825          if (this.doCss()) {
3826              var $inner = this.$outer.find('.lg-inner');
3827              $inner.css('transition-timing-function', this.s.cssEasing);
3828              $inner.css('transition-duration', this.s.speed + 'ms');
3829          }
3830  
3831          setTimeout(function() {
3832              $('.lg-backdrop').addClass('in');
3833          });
3834  
3835          setTimeout(function() {
3836              _this.$outer.addClass('lg-visible');
3837          }, this.s.backdropDuration);
3838  
3839          if (this.s.download) {
3840              this.$outer.find('.lg-toolbar').append('<a id="lg-download" aria-label="Download" target="_blank" download class="lg-download lg-icon"></a>');
3841          }
3842  
3843          // Store the current scroll top value to scroll back after closing the gallery..
3844          this.prevScrollTop = $(window).scrollTop();
3845  
3846      };
3847  
3848      // For fixed height gallery
3849      Plugin.prototype.setTop = function() {
3850          if (this.s.height !== '100%') {
3851              var wH = $(window).height();
3852              var top = (wH - parseInt(this.s.height, 10)) / 2;
3853              var $lGallery = this.$outer.find('.lg');
3854              if (wH >= parseInt(this.s.height, 10)) {
3855                  $lGallery.css('top', top + 'px');
3856              } else {
3857                  $lGallery.css('top', '0px');
3858              }
3859          }
3860      };
3861  
3862      // Find css3 support
3863      Plugin.prototype.doCss = function() {
3864          // check for css animation support
3865          var support = function() {
3866              var transition = ['transition', 'MozTransition', 'WebkitTransition', 'OTransition', 'msTransition', 'KhtmlTransition'];
3867              var root = document.documentElement;
3868              var i = 0;
3869              for (i = 0; i < transition.length; i++) {
3870                  if (transition[i] in root.style) {
3871                      return true;
3872                  }
3873              }
3874          };
3875  
3876          if (support()) {
3877              return true;
3878          }
3879  
3880          return false;
3881      };
3882  
3883      /**
3884       *  @desc Check the given src is video
3885       *  @param {String} src
3886       *  @return {Object} video type
3887       *  Ex:{ youtube  :  ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] }
3888       */
3889      Plugin.prototype.isVideo = function(src, index) {
3890  
3891          var html;
3892          if (this.s.dynamic) {
3893              html = this.s.dynamicEl[index].html;
3894          } else {
3895              html = this.$items.eq(index).attr('data-html');
3896          }
3897  
3898          if (!src) {
3899              if (html) {
3900                  return {
3901                      html5: true
3902                  };
3903              } else {
3904                  console.error('lightGallery :- data-src is not provided on slide item ' + (index + 1) + '. Please make sure the selector property is properly configured. More info - http://sachinchoolur.github.io/lightGallery/demos/html-markup.html');
3905                  return false;
3906              }
3907          }
3908  
3909          var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)/i);
3910          var vimeo = src.match(/\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i);
3911          var dailymotion = src.match(/\/\/(?:www\.)?dai.ly\/([0-9a-z\-_]+)/i);
3912          var vk = src.match(/\/\/(?:www\.)?(?:vk\.com|vkontakte\.ru)\/(?:video_ext\.php\?)(.*)/i);
3913  
3914          if (youtube) {
3915              return {
3916                  youtube: youtube
3917              };
3918          } else if (vimeo) {
3919              return {
3920                  vimeo: vimeo
3921              };
3922          } else if (dailymotion) {
3923              return {
3924                  dailymotion: dailymotion
3925              };
3926          } else if (vk) {
3927              return {
3928                  vk: vk
3929              };
3930          }
3931      };
3932  
3933      /**
3934       *  @desc Create image counter
3935       *  Ex: 1/10
3936       */
3937      Plugin.prototype.counter = function() {
3938          if (this.s.counter) {
3939              $(this.s.appendCounterTo).append('<div id="lg-counter" role="status" aria-live="polite"><span id="lg-counter-current">' + (parseInt(this.index, 10) + 1) + '</span> / <span id="lg-counter-all">' + this.$items.length + '</span></div>');
3940          }
3941      };
3942  
3943      /**
3944       *  @desc add sub-html into the slide
3945       *  @param {Number} index - index of the slide
3946       */
3947      Plugin.prototype.addHtml = function(index) {
3948          var subHtml = null;
3949          var subHtmlUrl;
3950          var $currentEle;
3951          if (this.s.dynamic) {
3952              if (this.s.dynamicEl[index].subHtmlUrl) {
3953                  subHtmlUrl = this.s.dynamicEl[index].subHtmlUrl;
3954              } else {
3955                  subHtml = this.s.dynamicEl[index].subHtml;
3956              }
3957          } else {
3958              $currentEle = this.$items.eq(index);
3959              if ($currentEle.attr('data-sub-html-url')) {
3960                  subHtmlUrl = $currentEle.attr('data-sub-html-url');
3961              } else {
3962                  subHtml = $currentEle.attr('data-sub-html');
3963                  if (this.s.getCaptionFromTitleOrAlt && !subHtml) {
3964                      subHtml = $currentEle.attr('title') || $currentEle.find('img').first().attr('alt');
3965                  }
3966              }
3967          }
3968  
3969          if (!subHtmlUrl) {
3970              if (typeof subHtml !== 'undefined' && subHtml !== null) {
3971  
3972                  // get first letter of subhtml
3973                  // if first letter starts with . or # get the html form the jQuery object
3974                  var fL = subHtml.substring(0, 1);
3975                  if (fL === '.' || fL === '#') {
3976                      if (this.s.subHtmlSelectorRelative && !this.s.dynamic) {
3977                          subHtml = $currentEle.find(subHtml).html();
3978                      } else {
3979                          subHtml = $(subHtml).html();
3980                      }
3981                  }
3982              } else {
3983                  subHtml = '';
3984              }
3985          }
3986  
3987          if (this.s.appendSubHtmlTo === '.lg-sub-html') {
3988  
3989              if (subHtmlUrl) {
3990                  this.$outer.find(this.s.appendSubHtmlTo).load(subHtmlUrl);
3991              } else {
3992                  this.$outer.find(this.s.appendSubHtmlTo).html(subHtml);
3993              }
3994  
3995          } else {
3996  
3997              if (subHtmlUrl) {
3998                  this.$slide.eq(index).load(subHtmlUrl);
3999              } else {
4000                  this.$slide.eq(index).append(subHtml);
4001              }
4002          }
4003  
4004          // Add lg-empty-html class if title doesn't exist
4005          if (typeof subHtml !== 'undefined' && subHtml !== null) {
4006              if (subHtml === '') {
4007                  this.$outer.find(this.s.appendSubHtmlTo).addClass('lg-empty-html');
4008              } else {
4009                  this.$outer.find(this.s.appendSubHtmlTo).removeClass('lg-empty-html');
4010              }
4011          }
4012  
4013          this.$el.trigger('onAfterAppendSubHtml.lg', [index]);
4014      };
4015  
4016      /**
4017       *  @desc Preload slides
4018       *  @param {Number} index - index of the slide
4019       */
4020      Plugin.prototype.preload = function(index) {
4021          var i = 1;
4022          var j = 1;
4023          for (i = 1; i <= this.s.preload; i++) {
4024              if (i >= this.$items.length - index) {
4025                  break;
4026              }
4027  
4028              this.loadContent(index + i, false, 0);
4029          }
4030  
4031          for (j = 1; j <= this.s.preload; j++) {
4032              if (index - j < 0) {
4033                  break;
4034              }
4035  
4036              this.loadContent(index - j, false, 0);
4037          }
4038      };
4039  
4040      /**
4041       *  @desc Load slide content into slide.
4042       *  @param {Number} index - index of the slide.
4043       *  @param {Boolean} rec - if true call loadcontent() function again.
4044       *  @param {Boolean} delay - delay for adding complete class. it is 0 except first time.
4045       */
4046      Plugin.prototype.loadContent = function(index, rec, delay) {
4047  
4048          var _this = this;
4049          var _hasPoster = false;
4050          var _$img;
4051          var _src;
4052          var _poster;
4053          var _srcset;
4054          var _sizes;
4055          var _html;
4056          var _alt;
4057          var getResponsiveSrc = function(srcItms) {
4058              var rsWidth = [];
4059              var rsSrc = [];
4060              for (var i = 0; i < srcItms.length; i++) {
4061                  var __src = srcItms[i].split(' ');
4062  
4063                  // Manage empty space
4064                  if (__src[0] === '') {
4065                      __src.splice(0, 1);
4066                  }
4067  
4068                  rsSrc.push(__src[0]);
4069                  rsWidth.push(__src[1]);
4070              }
4071  
4072              var wWidth = $(window).width();
4073              for (var j = 0; j < rsWidth.length; j++) {
4074                  if (parseInt(rsWidth[j], 10) > wWidth) {
4075                      _src = rsSrc[j];
4076                      break;
4077                  }
4078              }
4079          };
4080  
4081          if (_this.s.dynamic) {
4082  
4083              if (_this.s.dynamicEl[index].poster) {
4084                  _hasPoster = true;
4085                  _poster = _this.s.dynamicEl[index].poster;
4086              }
4087  
4088              _html = _this.s.dynamicEl[index].html;
4089              _src = _this.s.dynamicEl[index].src;
4090              _alt = _this.s.dynamicEl[index].alt;
4091  
4092              if (_this.s.dynamicEl[index].responsive) {
4093                  var srcDyItms = _this.s.dynamicEl[index].responsive.split(',');
4094                  getResponsiveSrc(srcDyItms);
4095              }
4096  
4097              _srcset = _this.s.dynamicEl[index].srcset;
4098              _sizes = _this.s.dynamicEl[index].sizes;
4099  
4100          } else {
4101              var $currentEle = _this.$items.eq(index);
4102              if ($currentEle.attr('data-poster')) {
4103                  _hasPoster = true;
4104                  _poster = $currentEle.attr('data-poster');
4105              }
4106  
4107              _html = $currentEle.attr('data-html');
4108              _src = $currentEle.attr('href') || $currentEle.attr('data-src');
4109              _alt = $currentEle.attr('title') || $currentEle.find('img').first().attr('alt');
4110  
4111              if ($currentEle.attr('data-responsive')) {
4112                  var srcItms = $currentEle.attr('data-responsive').split(',');
4113                  getResponsiveSrc(srcItms);
4114              }
4115  
4116              _srcset = $currentEle.attr('data-srcset');
4117              _sizes = $currentEle.attr('data-sizes');
4118  
4119          }
4120  
4121          //if (_src || _srcset || _sizes || _poster) {
4122  
4123          var iframe = false;
4124          if (_this.s.dynamic) {
4125              if (_this.s.dynamicEl[index].iframe) {
4126                  iframe = true;
4127              }
4128          } else {
4129              if (_this.$items.eq(index).attr('data-iframe') === 'true') {
4130                  iframe = true;
4131              }
4132          }
4133  
4134          var _isVideo = _this.isVideo(_src, index);
4135          if (!_this.$slide.eq(index).hasClass('lg-loaded')) {
4136              if (iframe) {
4137                  _this.$slide.eq(index).prepend('<div class="lg-video-cont lg-has-iframe" style="max-width:' + _this.s.iframeMaxWidth + '"><div class="lg-video"><iframe class="lg-object" frameborder="0" src="' + _src + '"  allowfullscreen="true"></iframe></div></div>');
4138              } else if (_hasPoster) {
4139                  var videoClass = '';
4140                  if (_isVideo && _isVideo.youtube) {
4141                      videoClass = 'lg-has-youtube';
4142                  } else if (_isVideo && _isVideo.vimeo) {
4143                      videoClass = 'lg-has-vimeo';
4144                  } else {
4145                      videoClass = 'lg-has-html5';
4146                  }
4147  
4148                  _this.$slide.eq(index).prepend('<div class="lg-video-cont ' + videoClass + ' "><div class="lg-video"><span class="lg-video-play"></span><img class="lg-object lg-has-poster" src="' + _poster + '" /></div></div>');
4149  
4150              } else if (_isVideo) {
4151                  _this.$slide.eq(index).prepend('<div class="lg-video-cont "><div class="lg-video"></div></div>');
4152                  _this.$el.trigger('hasVideo.lg', [index, _src, _html]);
4153              } else {
4154                  _alt = _alt ? 'alt="' + _alt + '"' : '';
4155                  _this.$slide.eq(index).prepend('<div class="lg-img-wrap"><img class="lg-object lg-image" ' + _alt + ' src="' + _src + '" /></div>');
4156              }
4157  
4158              _this.$el.trigger('onAferAppendSlide.lg', [index]);
4159  
4160              _$img = _this.$slide.eq(index).find('.lg-object');
4161              if (_sizes) {
4162                  _$img.attr('sizes', _sizes);
4163              }
4164  
4165              if (_srcset) {
4166                  _$img.attr('srcset', _srcset);
4167                  try {
4168                      picturefill({
4169                          elements: [_$img[0]]
4170                      });
4171                  } catch (e) {
4172                      console.warn('lightGallery :- If you want srcset to be supported for older browser please include picturefil version 2 javascript library in your document.');
4173                  }
4174              }
4175  
4176              if (this.s.appendSubHtmlTo !== '.lg-sub-html') {
4177                  _this.addHtml(index);
4178              }
4179  
4180              _this.$slide.eq(index).addClass('lg-loaded');
4181          }
4182  
4183          _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
4184  
4185              // For first time add some delay for displaying the start animation.
4186              var _speed = 0;
4187  
4188              // Do not change the delay value because it is required for zoom plugin.
4189              // If gallery opened from direct url (hash) speed value should be 0
4190              if (delay && !$('body').hasClass('lg-from-hash')) {
4191                  _speed = delay;
4192              }
4193  
4194              setTimeout(function() {
4195                  _this.$slide.eq(index).addClass('lg-complete');
4196                  _this.$el.trigger('onSlideItemLoad.lg', [index, delay || 0]);
4197              }, _speed);
4198  
4199          });
4200  
4201          // @todo check load state for html5 videos
4202          if (_isVideo && _isVideo.html5 && !_hasPoster) {
4203              _this.$slide.eq(index).addClass('lg-complete');
4204          }
4205  
4206          if (rec === true) {
4207              if (!_this.$slide.eq(index).hasClass('lg-complete')) {
4208                  _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
4209                      _this.preload(index);
4210                  });
4211              } else {
4212                  _this.preload(index);
4213              }
4214          }
4215  
4216          //}
4217      };
4218  
4219      /**
4220      *   @desc slide function for lightgallery
4221          ** Slide() gets call on start
4222          ** ** Set lg.on true once slide() function gets called.
4223          ** Call loadContent() on slide() function inside setTimeout
4224          ** ** On first slide we do not want any animation like slide of fade
4225          ** ** So on first slide( if lg.on if false that is first slide) loadContent() should start loading immediately
4226          ** ** Else loadContent() should wait for the transition to complete.
4227          ** ** So set timeout s.speed + 50
4228      <=> ** loadContent() will load slide content in to the particular slide
4229          ** ** It has recursion (rec) parameter. if rec === true loadContent() will call preload() function.
4230          ** ** preload will execute only when the previous slide is fully loaded (images iframe)
4231          ** ** avoid simultaneous image load
4232      <=> ** Preload() will check for s.preload value and call loadContent() again accoring to preload value
4233          ** loadContent()  <====> Preload();
4234  
4235      *   @param {Number} index - index of the slide
4236      *   @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
4237      *   @param {Boolean} fromThumb - true if slide function called via thumbnail click
4238      *   @param {String} direction - Direction of the slide(next/prev)
4239      */
4240      Plugin.prototype.slide = function(index, fromTouch, fromThumb, direction) {
4241  
4242          var _prevIndex = this.$outer.find('.lg-current').index();
4243          var _this = this;
4244  
4245          // Prevent if multiple call
4246          // Required for hsh plugin
4247          if (_this.lGalleryOn && (_prevIndex === index)) {
4248              return;
4249          }
4250  
4251          var _length = this.$slide.length;
4252          var _time = _this.lGalleryOn ? this.s.speed : 0;
4253  
4254          if (!_this.lgBusy) {
4255  
4256              if (this.s.download) {
4257                  var _src;
4258                  if (_this.s.dynamic) {
4259                      _src = _this.s.dynamicEl[index].downloadUrl !== false && (_this.s.dynamicEl[index].downloadUrl || _this.s.dynamicEl[index].src);
4260                  } else {
4261                      _src = _this.$items.eq(index).attr('data-download-url') !== 'false' && (_this.$items.eq(index).attr('data-download-url') || _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src'));
4262  
4263                  }
4264  
4265                  if (_src) {
4266                      $('#lg-download').attr('href', _src);
4267                      _this.$outer.removeClass('lg-hide-download');
4268                  } else {
4269                      _this.$outer.addClass('lg-hide-download');
4270                  }
4271              }
4272  
4273              this.$el.trigger('onBeforeSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
4274  
4275              _this.lgBusy = true;
4276  
4277              clearTimeout(_this.hideBartimeout);
4278  
4279              // Add title if this.s.appendSubHtmlTo === lg-sub-html
4280              if (this.s.appendSubHtmlTo === '.lg-sub-html') {
4281  
4282                  // wait for slide animation to complete
4283                  setTimeout(function() {
4284                      _this.addHtml(index);
4285                  }, _time);
4286              }
4287  
4288              this.arrowDisable(index);
4289  
4290              if (!direction) {
4291                  if (index < _prevIndex) {
4292                      direction = 'prev';
4293                  } else if (index > _prevIndex) {
4294                      direction = 'next';
4295                  }
4296              }
4297  
4298              if (!fromTouch) {
4299  
4300                  // remove all transitions
4301                  _this.$outer.addClass('lg-no-trans');
4302  
4303                  this.$slide.removeClass('lg-prev-slide lg-next-slide');
4304  
4305                  if (direction === 'prev') {
4306  
4307                      //prevslide
4308                      this.$slide.eq(index).addClass('lg-prev-slide');
4309                      this.$slide.eq(_prevIndex).addClass('lg-next-slide');
4310                  } else {
4311  
4312                      // next slide
4313                      this.$slide.eq(index).addClass('lg-next-slide');
4314                      this.$slide.eq(_prevIndex).addClass('lg-prev-slide');
4315                  }
4316  
4317                  // give 50 ms for browser to add/remove class
4318                  setTimeout(function() {
4319                      _this.$slide.removeClass('lg-current');
4320  
4321                      //_this.$slide.eq(_prevIndex).removeClass('lg-current');
4322                      _this.$slide.eq(index).addClass('lg-current');
4323  
4324                      // reset all transitions
4325                      _this.$outer.removeClass('lg-no-trans');
4326                  }, 50);
4327              } else {
4328  
4329                  this.$slide.removeClass('lg-prev-slide lg-current lg-next-slide');
4330                  var touchPrev;
4331                  var touchNext;
4332                  if (_length > 2) {
4333                      touchPrev = index - 1;
4334                      touchNext = index + 1;
4335  
4336                      if ((index === 0) && (_prevIndex === _length - 1)) {
4337  
4338                          // next slide
4339                          touchNext = 0;
4340                          touchPrev = _length - 1;
4341                      } else if ((index === _length - 1) && (_prevIndex === 0)) {
4342  
4343                          // prev slide
4344                          touchNext = 0;
4345                          touchPrev = _length - 1;
4346                      }
4347  
4348                  } else {
4349                      touchPrev = 0;
4350                      touchNext = 1;
4351                  }
4352  
4353                  if (direction === 'prev') {
4354                      _this.$slide.eq(touchNext).addClass('lg-next-slide');
4355                  } else {
4356                      _this.$slide.eq(touchPrev).addClass('lg-prev-slide');
4357                  }
4358  
4359                  _this.$slide.eq(index).addClass('lg-current');
4360              }
4361  
4362              if (_this.lGalleryOn) {
4363                  setTimeout(function() {
4364                      _this.loadContent(index, true, 0);
4365                  }, this.s.speed + 50);
4366  
4367                  setTimeout(function() {
4368                      _this.lgBusy = false;
4369                      _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
4370                  }, this.s.speed);
4371  
4372              } else {
4373                  _this.loadContent(index, true, _this.s.backdropDuration);
4374  
4375                  _this.lgBusy = false;
4376                  _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
4377              }
4378  
4379              _this.lGalleryOn = true;
4380  
4381              if (this.s.counter) {
4382                  $('#lg-counter-current').text(index + 1);
4383              }
4384  
4385          }
4386          _this.index = index;
4387  
4388      };
4389  
4390      /**
4391       *  @desc Go to next slide
4392       *  @param {Boolean} fromTouch - true if slide function called via touch event
4393       */
4394      Plugin.prototype.goToNextSlide = function(fromTouch) {
4395          var _this = this;
4396          var _loop = _this.s.loop;
4397          if (fromTouch && _this.$slide.length < 3) {
4398              _loop = false;
4399          }
4400  
4401          if (!_this.lgBusy) {
4402              if ((_this.index + 1) < _this.$slide.length) {
4403                  _this.index++;
4404                  _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
4405                  _this.slide(_this.index, fromTouch, false, 'next');
4406              } else {
4407                  if (_loop) {
4408                      _this.index = 0;
4409                      _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
4410                      _this.slide(_this.index, fromTouch, false, 'next');
4411                  } else if (_this.s.slideEndAnimatoin && !fromTouch) {
4412                      _this.$outer.addClass('lg-right-end');
4413                      setTimeout(function() {
4414                          _this.$outer.removeClass('lg-right-end');
4415                      }, 400);
4416                  }
4417              }
4418          }
4419      };
4420  
4421      /**
4422       *  @desc Go to previous slide
4423       *  @param {Boolean} fromTouch - true if slide function called via touch event
4424       */
4425      Plugin.prototype.goToPrevSlide = function(fromTouch) {
4426          var _this = this;
4427          var _loop = _this.s.loop;
4428          if (fromTouch && _this.$slide.length < 3) {
4429              _loop = false;
4430          }
4431  
4432          if (!_this.lgBusy) {
4433              if (_this.index > 0) {
4434                  _this.index--;
4435                  _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
4436                  _this.slide(_this.index, fromTouch, false, 'prev');
4437              } else {
4438                  if (_loop) {
4439                      _this.index = _this.$items.length - 1;
4440                      _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
4441                      _this.slide(_this.index, fromTouch, false, 'prev');
4442                  } else if (_this.s.slideEndAnimatoin && !fromTouch) {
4443                      _this.$outer.addClass('lg-left-end');
4444                      setTimeout(function() {
4445                          _this.$outer.removeClass('lg-left-end');
4446                      }, 400);
4447                  }
4448              }
4449          }
4450      };
4451  
4452      Plugin.prototype.keyPress = function() {
4453          var _this = this;
4454          if (this.$items.length > 1) {
4455              $(window).on('keyup.lg', function(e) {
4456                  if (_this.$items.length > 1) {
4457                      if (e.keyCode === 37) {
4458                          e.preventDefault();
4459                          _this.goToPrevSlide();
4460                      }
4461  
4462                      if (e.keyCode === 39) {
4463                          e.preventDefault();
4464                          _this.goToNextSlide();
4465                      }
4466                  }
4467              });
4468          }
4469  
4470          $(window).on('keydown.lg', function(e) {
4471              if (_this.s.escKey === true && e.keyCode === 27) {
4472                  e.preventDefault();
4473                  if (!_this.$outer.hasClass('lg-thumb-open')) {
4474                      _this.destroy();
4475                  } else {
4476                      _this.$outer.removeClass('lg-thumb-open');
4477                  }
4478              }
4479          });
4480      };
4481  
4482      Plugin.prototype.arrow = function() {
4483          var _this = this;
4484          this.$outer.find('.lg-prev').on('click.lg', function() {
4485              _this.goToPrevSlide();
4486          });
4487  
4488          this.$outer.find('.lg-next').on('click.lg', function() {
4489              _this.goToNextSlide();
4490          });
4491      };
4492  
4493      Plugin.prototype.arrowDisable = function(index) {
4494  
4495          // Disable arrows if s.hideControlOnEnd is true
4496          if (!this.s.loop && this.s.hideControlOnEnd) {
4497              if ((index + 1) < this.$slide.length) {
4498                  this.$outer.find('.lg-next').removeAttr('disabled').removeClass('disabled');
4499              } else {
4500                  this.$outer.find('.lg-next').attr('disabled', 'disabled').addClass('disabled');
4501              }
4502  
4503              if (index > 0) {
4504                  this.$outer.find('.lg-prev').removeAttr('disabled').removeClass('disabled');
4505              } else {
4506                  this.$outer.find('.lg-prev').attr('disabled', 'disabled').addClass('disabled');
4507              }
4508          }
4509      };
4510  
4511      Plugin.prototype.setTranslate = function($el, xValue, yValue) {
4512          // jQuery supports Automatic CSS prefixing since jQuery 1.8.0
4513          if (this.s.useLeft) {
4514              $el.css('left', xValue);
4515          } else {
4516              $el.css({
4517                  transform: 'translate3d(' + (xValue) + 'px, ' + yValue + 'px, 0px)'
4518              });
4519          }
4520      };
4521  
4522      Plugin.prototype.touchMove = function(startCoords, endCoords) {
4523  
4524          var distance = endCoords - startCoords;
4525  
4526          if (Math.abs(distance) > 15) {
4527              // reset opacity and transition duration
4528              this.$outer.addClass('lg-dragging');
4529  
4530              // move current slide
4531              this.setTranslate(this.$slide.eq(this.index), distance, 0);
4532  
4533              // move next and prev slide with current slide
4534              this.setTranslate($('.lg-prev-slide'), -this.$slide.eq(this.index).width() + distance, 0);
4535              this.setTranslate($('.lg-next-slide'), this.$slide.eq(this.index).width() + distance, 0);
4536          }
4537      };
4538  
4539      Plugin.prototype.touchEnd = function(distance) {
4540          var _this = this;
4541  
4542          // keep slide animation for any mode while dragg/swipe
4543          if (_this.s.mode !== 'lg-slide') {
4544              _this.$outer.addClass('lg-slide');
4545          }
4546  
4547          this.$slide.not('.lg-current, .lg-prev-slide, .lg-next-slide').css('opacity', '0');
4548  
4549          // set transition duration
4550          setTimeout(function() {
4551              _this.$outer.removeClass('lg-dragging');
4552              if ((distance < 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
4553                  _this.goToNextSlide(true);
4554              } else if ((distance > 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
4555                  _this.goToPrevSlide(true);
4556              } else if (Math.abs(distance) < 5) {
4557  
4558                  // Trigger click if distance is less than 5 pix
4559                  _this.$el.trigger('onSlideClick.lg');
4560              }
4561  
4562              _this.$slide.removeAttr('style');
4563          });
4564  
4565          // remove slide class once drag/swipe is completed if mode is not slide
4566          setTimeout(function() {
4567              if (!_this.$outer.hasClass('lg-dragging') && _this.s.mode !== 'lg-slide') {
4568                  _this.$outer.removeClass('lg-slide');
4569              }
4570          }, _this.s.speed + 100);
4571  
4572      };
4573  
4574      Plugin.prototype.enableSwipe = function() {
4575          var _this = this;
4576          var startCoords = 0;
4577          var endCoords = 0;
4578          var isMoved = false;
4579  
4580          if (_this.s.enableSwipe && _this.doCss()) {
4581  
4582              _this.$slide.on('touchstart.lg', function(e) {
4583                  if (!_this.$outer.hasClass('lg-zoomed') && !_this.lgBusy) {
4584                      e.preventDefault();
4585                      _this.manageSwipeClass();
4586                      startCoords = e.originalEvent.targetTouches[0].pageX;
4587                  }
4588              });
4589  
4590              _this.$slide.on('touchmove.lg', function(e) {
4591                  if (!_this.$outer.hasClass('lg-zoomed')) {
4592                      e.preventDefault();
4593                      endCoords = e.originalEvent.targetTouches[0].pageX;
4594                      _this.touchMove(startCoords, endCoords);
4595                      isMoved = true;
4596                  }
4597              });
4598  
4599              _this.$slide.on('touchend.lg', function() {
4600                  if (!_this.$outer.hasClass('lg-zoomed')) {
4601                      if (isMoved) {
4602                          isMoved = false;
4603                          _this.touchEnd(endCoords - startCoords);
4604                      } else {
4605                          _this.$el.trigger('onSlideClick.lg');
4606                      }
4607                  }
4608              });
4609          }
4610  
4611      };
4612  
4613      Plugin.prototype.enableDrag = function() {
4614          var _this = this;
4615          var startCoords = 0;
4616          var endCoords = 0;
4617          var isDraging = false;
4618          var isMoved = false;
4619          if (_this.s.enableDrag && _this.doCss()) {
4620              _this.$slide.on('mousedown.lg', function(e) {
4621                  if (!_this.$outer.hasClass('lg-zoomed') && !_this.lgBusy && !$(e.target).text().trim()) {
4622                      e.preventDefault();
4623                      _this.manageSwipeClass();
4624                      startCoords = e.pageX;
4625                      isDraging = true;
4626  
4627                      // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
4628                      _this.$outer.scrollLeft += 1;
4629                      _this.$outer.scrollLeft -= 1;
4630  
4631                      // *
4632  
4633                      _this.$outer.removeClass('lg-grab').addClass('lg-grabbing');
4634  
4635                      _this.$el.trigger('onDragstart.lg');
4636                  }
4637              });
4638  
4639              $(window).on('mousemove.lg', function(e) {
4640                  if (isDraging) {
4641                      isMoved = true;
4642                      endCoords = e.pageX;
4643                      _this.touchMove(startCoords, endCoords);
4644                      _this.$el.trigger('onDragmove.lg');
4645                  }
4646              });
4647  
4648              $(window).on('mouseup.lg', function(e) {
4649                  if (isMoved) {
4650                      isMoved = false;
4651                      _this.touchEnd(endCoords - startCoords);
4652                      _this.$el.trigger('onDragend.lg');
4653                  } else if ($(e.target).hasClass('lg-object') || $(e.target).hasClass('lg-video-play')) {
4654                      _this.$el.trigger('onSlideClick.lg');
4655                  }
4656  
4657                  // Prevent execution on click
4658                  if (isDraging) {
4659                      isDraging = false;
4660                      _this.$outer.removeClass('lg-grabbing').addClass('lg-grab');
4661                  }
4662              });
4663  
4664          }
4665      };
4666  
4667      Plugin.prototype.manageSwipeClass = function() {
4668          var _touchNext = this.index + 1;
4669          var _touchPrev = this.index - 1;
4670          if (this.s.loop && this.$slide.length > 2) {
4671              if (this.index === 0) {
4672                  _touchPrev = this.$slide.length - 1;
4673              } else if (this.index === this.$slide.length - 1) {
4674                  _touchNext = 0;
4675              }
4676          }
4677  
4678          this.$slide.removeClass('lg-next-slide lg-prev-slide');
4679          if (_touchPrev > -1) {
4680              this.$slide.eq(_touchPrev).addClass('lg-prev-slide');
4681          }
4682  
4683          this.$slide.eq(_touchNext).addClass('lg-next-slide');
4684      };
4685  
4686      Plugin.prototype.mousewheel = function() {
4687          var _this = this;
4688          _this.$outer.on('mousewheel.lg', function(e) {
4689  
4690              if (!e.deltaY) {
4691                  return;
4692              }
4693  
4694              if (e.deltaY > 0) {
4695                  _this.goToPrevSlide();
4696              } else {
4697                  _this.goToNextSlide();
4698              }
4699  
4700              e.preventDefault();
4701          });
4702  
4703      };
4704  
4705      Plugin.prototype.closeGallery = function() {
4706  
4707          var _this = this;
4708          var mousedown = false;
4709          this.$outer.find('.lg-close').on('click.lg', function() {
4710              _this.destroy();
4711          });
4712  
4713          if (_this.s.closable) {
4714  
4715              // If you drag the slide and release outside gallery gets close on chrome
4716              // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
4717              _this.$outer.on('mousedown.lg', function(e) {
4718  
4719                  if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap')) {
4720                      mousedown = true;
4721                  } else {
4722                      mousedown = false;
4723                  }
4724  
4725              });
4726  
4727              _this.$outer.on('mousemove.lg', function() {
4728                  mousedown = false;
4729              });
4730  
4731              _this.$outer.on('mouseup.lg', function(e) {
4732  
4733                  if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap') && mousedown) {
4734                      if (!_this.$outer.hasClass('lg-dragging')) {
4735                          _this.destroy();
4736                      }
4737                  }
4738  
4739              });
4740  
4741          }
4742  
4743      };
4744  
4745      Plugin.prototype.destroy = function(d) {
4746  
4747          var _this = this;
4748  
4749          if (!d) {
4750              _this.$el.trigger('onBeforeClose.lg');
4751              $(window).scrollTop(_this.prevScrollTop);
4752          }
4753  
4754  
4755          /**
4756           * if d is false or undefined destroy will only close the gallery
4757           * plugins instance remains with the element
4758           *
4759           * if d is true destroy will completely remove the plugin
4760           */
4761  
4762          if (d) {
4763              if (!_this.s.dynamic) {
4764                  // only when not using dynamic mode is $items a jquery collection
4765                  this.$items.off('click.lg click.lgcustom');
4766              }
4767  
4768              $.removeData(_this.el, 'lightGallery');
4769          }
4770  
4771          // Unbind all events added by lightGallery
4772          this.$el.off('.lg.tm');
4773  
4774          // destroy all lightGallery modules
4775          $.each($.fn.lightGallery.modules, function(key) {
4776              if (_this.modules[key]) {
4777                  _this.modules[key].destroy();
4778              }
4779          });
4780  
4781          this.lGalleryOn = false;
4782  
4783          clearTimeout(_this.hideBartimeout);
4784          this.hideBartimeout = false;
4785          $(window).off('.lg');
4786          $('body').removeClass('lg-on lg-from-hash');
4787  
4788          if (_this.$outer) {
4789              _this.$outer.removeClass('lg-visible');
4790          }
4791  
4792          $('.lg-backdrop').removeClass('in');
4793  
4794          setTimeout(function() {
4795              if (_this.$outer) {
4796                  _this.$outer.remove();
4797              }
4798  
4799              $('.lg-backdrop').remove();
4800  
4801              if (!d) {
4802                  _this.$el.trigger('onCloseAfter.lg');
4803              }
4804              _this.$el.focus();
4805  
4806          }, _this.s.backdropDuration + 50);
4807      };
4808  
4809      $.fn.lightGallery = function(options) {
4810          return this.each(function() {
4811              if (!$.data(this, 'lightGallery')) {
4812                  $.data(this, 'lightGallery', new Plugin(this, options));
4813              } else {
4814                  try {
4815                      $(this).data('lightGallery').init();
4816                  } catch (err) {
4817                      console.error('lightGallery has not initiated properly');
4818                  }
4819              }
4820          });
4821      };
4822  
4823      $.fn.lightGallery.modules = {};
4824  
4825  })();
4826  
4827  
4828  }));
4829  
4830/*! jquery-gi-thewall v1.0.2 || Goldinteractive <[email protected]> (http://goldinteractive.ch) */
4831!function(a,b,c,d,e,f){"use strict";f.support.transition=function(){var b=function(){var b,c=a.createElement("GI"),d={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(b in d)if(void 0!==c.style[b])return d[b]}();return b&&{end:b}}();var g=0,h=function(c,e){var h=this,i={onBeforeInit:null,onReady:null,onViewPortUpdate:null,onItemChange:null,onDestroy:null,onShow:null,onHide:null,onContentLoading:null,onContentLoaded:null,margin:{top:10,bottom:10},scrollerElm:null,scrollOffset:150,arrows:!0,closebutton:!0,keyboardNavigation:!0,animationSpeed:300,autoscroll:!0,responsive:!0,initialWrapperHeight:600,dynamicHeight:!0,nextButtonClass:"",prevButtonClass:"",closeButtonClass:""},j="ontouchstart"in b||b.DocumentTouch&&a instanceof DocumentTouch,k=[33,34,35,36,37,38,39,40,27],l=!1,m=f.supp
4831ort.transition,n=!1,o=0,p=".GITheWall"+g,q={click:j?"touchstart":"click",mousedown:j?"touchstart":"mousedown",mouseup:j?"touchend":"mouseup",mousemove:j?"touchmove":"mousemove",mouseleave:j?"touchleave":"mouseleave"},r=f.extend(i,e);this.$el=c,this.$expanderWrapper=f('<div class="GI_TW_expander"></div>'),this.$contentPointer=f('<div class="GI_TW_pointer"></div>'),this.$expanderInner=f('<div class="GI_TW_expander-inner"></div>'),this.$list=f("> ul",this.$el).eq(0),this.$items=f("> li",this.$list),this.itemsLength=this.$items.length,this.currentIndex=null,this.currentRowIndex=null,this.$selectedli=null,this.selectedLiData=null,Function.prototype.debounce=function(a,b){var c,d,e=this;return function(){var f=this,g=arguments,h=function(){c=null,b||(d=e.apply(f,g))},i=b&&!c;return clearTimeout(c),c=setTimeout(h,a),i&&(d=e.apply(f,g)),d}};var s=function(a,b){"function"==typeof a&&f.proxy(a,h,b)()},t=function(){this.$expanderWrapper.append('<span class="GI_TW_arrow GI_TW_prev GI_TW_Controls"><span class="'+r.prevButtonClass+'"></span></span><span class="GI_TW_arrow GI_TW_next GI_TW_Controls"><span class="'+r.nextButtonClass+'"></span></span>'),this.$next=f(".GI_TW_next",this.$expanderWrapper),this.$prev=f(".GI_TW_prev",this.$expanderWrapper)},u=function(){h.$prev.toggleClass("GI_TW_hidden",h.currentIndex<=0),h.$next.toggleClass("GI_TW_hidden",h.currentIndex>=h.itemsLength-1)},v=function(a){return r.autoscroll?void f(r.scrollerElm||"html,body").animate({scrollTop:a}):!1},w=function(){h.$items.removeClass("GI_TW_Current"),"number"==typeof h.currentIndex&&h.$items.eq(h.currentIndex).addClass("GI_TW_Current")},x=function(){this.$contentPointer.css({left:this.selectedLiData.offset.left+this.$selectedli.width()/2})},y=function(a){var b=new f.Deferred,c=f(a).html();if(!c.length)throw new Error('No element can be found using the "'+a+'" selector');return h.$expanderInner.html(c),b.resolve(),b.promise()},z=function(a){var b=new f.Deferred,c=new Image;return c.onload=function(){h.$expanderInner.html('<div class="GI_TW_fullimg"><img src="'+a+'" /></div>'),b.resolve(),c=null},c.src=a,b.promise()},A=function(a){var b=new f.Deferred;return f.get(a,function(a){h.$expanderInner.html(a),b.resolve()}),b.promise()},B=function(a){this.$expanderInner.css({height:a}),a!==o&&(o=a,this.$expanderWrapper.stop(!0,!1).addClass(m?"animating":"")[m?"css":"animate"]({height:a},r.animationSpeed),this.updateElementsPosition())},C=function(){this.selectedLiData.index<0||this.selectedLiData.index>=this.itemsLength||(this.currentIndex=this.selectedLiData.index,this.loadInnerContents(),s(r.onItemChange,this.currentIndex))},D=function(a){this.isOpened()&&void 0===a.target.form&&(a.target.isContentEditable||(f.inArray(a.keyCode,k)>-1&&a.preventDefault(),39===a.keyCode?this.next():37===a.keyCode?this.prev():27===a.keyCode&&this.hideExpander()))},E=function(a){a.stopImmediatePropagation(),a.preventDefault();var b=f(a.currentTarget);b.hasClass("GI_TW_next")?this.next():this.prev()},F=function(){s(r.onBeforeInit),r.arrows&&(t.call(this),u()),r.closebutton&&(this.$expanderWrapper.append('<div class="GI_TW_close GI_TW_Controls"><span class="'+r.closeButtonClass+'"></span></div>'),this.$closebutton=f(".GI_TW_items",this.$expanderWrapper)),this.$expanderWrapper.append(this.$contentPointer),this.$expanderWrapper.append(this.$expanderInner),this.$el.prepend(this.$expanderWrapper),this.bindAll(),s(r.onReady),g++};return this.setLisOffsets=function(){var a,b=0,c=0;this.$items.each(f.proxy(function(d,e){var g=f(e),h=g.data();g.removeClass("GI_TW_First GI_TW_Last GI_TW_Index-"+h.index+" GI_TW_Row-"+h.rowIndex);var i=!1,j=g.position(),k={top:~~j.top,left:~~j.left};(k.top>=b+3||k.top<=b-3)&&(a&&a.addClass("GI_TW_Last"),i=!0,c++),g.addClass((i?"GI_TW_First ":" ")+"GI_TW_Index-"+d+" GI_TW_Row-"+c),g.data({rowIndex:c,offset:k,index:d}),a=g,b=k.top},this))},this.setViewport=function(){l&&(this.setLisOffsets(),this.updateElementsPosition(),x.call(this),s(r.onViewPortUpdate))},this.loadInnerContents=function(){var a,b=this.$selectedli.find("a"),c=this.selectedLiData.href||b.attr("href");if(n=!0,this.$expanderInner.html('<div class="GI_TW_loading"></div>'),!c)return void console.warn("sorry.. it was not possible to load any content");switch(s(r.onContentLoading),this.selectedLiData.contenttype){case"ajax":a=A(c);break;case"inline":a=y(c);break;default:a=z(c)}a.then(function(){h.$expanderInner.css({height:"auto"});var a=r.dynamicHeight?h.$expanderInner.outerHeight():r.initialWrapperHeight;B.call(h,a),h.update(),v(h.$expanderWrapper.offset().top-r.scrollOffset),s(r.onContentLoaded),n=!1})},this.showExpander=function(a){return a.preventDefault(),this.$selectedli=f(a.currentTarget),this.$selectedli.length&&this.$selectedli.hasClass("GI_TW_Current")?void this.hideExpander():(this.selectedLiData=this.$selectedli.data(),l?void C.call(this):(l=!0,this.$expanderWrapper.addClass("opened"),this.setViewport(),C.call(this),void s(r.onShow)))},this.hideExpander=function(){this.$expanderWrapper.removeClass("opened").stop(!0,!1)[m?"css":"animate"]({height:0},r.animationSpeed),this.$expanderInner.empty(),this.currentRowIndex=null,this.$selectedli=null,this.selectedLiData=null,this.currentIndex=null,o=0,this.$items.removeClass("GI_TW_Selected_Row").animate({marginBottom:0},r.animationSpeed),l=!1,w(),s(r.onHide)},this.refresh=function(){this.$list=f("> ul",this.$el).eq(0),this.$items=f("> li",this.$list),this.$list.has(this.$selectedli).length||this.hideExpander(),this.itemsLength=this.$items.length,l&&(this.setLisOffsets(),this.update())},this.update=function(){this.selectedLiData=this.$selectedli.data(),x.call(this),this.selectedLiData.rowIndex!==this.currentRowIndex&&this.updateElementsPosition(),r.arrows&&u(),w.call(this),this.currentRowIndex=this.selectedLiData.rowIndex},this.updateElementsPosition=function(){this.$items.each(function(a,b){var c=f(b),d=c.data(),e=d&&d.rowIndex===h.selectedLiData.rowIndex;c.toggleClass("GI_TW_Selected_Row",e).stop(!0,!1)[m?"css":"animate"]({marginBottom:e?Number(o+r.margin.bottom):0},e?r.animationSpeed:0)}),this.setLisOffsets(),this.updateExpanderPosition()},this.updateExpanderPosition=function(){if(l){var a=this.selectedLiData.offset.top+this.$selectedli.height()+r.margin.top;this.$expanderWrapper.css({top:a})}},this.resizeHeight=function(a){B.call(this,a),this.setViewport()},this.showItemByIndex=function(a){var b=this.$items.eq(a);
4831b.length&&(this.$selectedli=b,this.selectedLiData=b.data(),C.call(this))},this.isOpened=function(){return l},this.next=function(){!n&&l&&this.currentIndex!==this.itemsLength-1&&this.showItemByIndex(this.currentIndex+1)},this.prev=function(){!n&&l&&0!==this.currentIndex&&this.showItemByIndex(this.currentIndex-1)},this.bindAll=function(){m&&this.$expanderWrapper.on(m.end+p,function(){f(this).removeClass("animating")}),r.arrows&&this.$el.on(q.click+p,".GI_TW_arrow",this.$expanderWrapper,f.proxy(E,this)),r.closebutton&&this.$el.on(q.click+p,".GI_TW_close",this.$expanderWrapper,f.proxy(this.hideExpander,this)),this.$el.on("click"+p,"> ul > li",f.proxy(this.showExpander,this)),r.responsive&&d.on("resize"+p+" orientationchange"+p,f.proxy(this.setViewport.debounce(300),this)),r.keyboardNavigation&&d.on("keydown"+p,f.proxy(D,this))},this.unbindAll=function(){this.$el.off(p),this.$expanderWrapper.off(p)},this.destroy=function(a){a&&(a.preventDefault(),a.stopImmediatePropagation()),this.hideExpander(),this.unbindAll(),this.$expanderWrapper.remove(),s(r.onDestroy)},F.call(this),this};f.fn.GITheWall=function(a){return this.length?new h(this,a):void 0}}(document,window,$(document),$(window),$("body"),jQuery);
4832// code for lazyload background img
4833var $body = $('body');
4834
4835document.addEventListener('lazybeforeunveil', function (e) {
4836    var bg = e.target.getAttribute('data-bg');
4837    if (bg) {
4838        e.target.style.backgroundImage = 'url(' + bg + ')';
4839    }
4840});
4841
4842$(document).ready(function () {
4843
4844    //slider gallery setting 
4845    if ($('.ns-gallery-thumb-slider-wrap').length) {
4846        var nsGallerySlider = $('.ns-gallery-slider-init');
4847              
4848        nsGallerySlider.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
4849            $('.slick-current .ns-gallery-slide-video-wrap').removeClass('video-played');
4850            if ($('.slick-current .ns-gallery-slide-video-wrap').hasClass('video-internal')) {
4851                var $vid = $('.slick-current .ns-gallery-slide-video-wrap .video');
4852                $vid[0].pause();
4853                $vid[0].currentTime = 0;
4854            } else if ($('.slick-current .ns-gallery-slide-video-wrap').hasClass('video-external')) {
4855                var $vid = $('.slick-current .ns-gallery-slide-video-wrap iframe.video');
4856                $vid[0].src = '';
4857            }
4858        });
4859    }    
4860
4861    // code for video play button
4862    $('.btn-video-play').on('click', function(){
4863        $(this).parents('.ns-gallery-slide-video-wrap').addClass('video-played');
4864        if ($(this).parents('.ns-gallery-slide-video-wrap').hasClass('video-internal')) {
4865            var $vid = $(this).parents('.ns-gallery-slide-video-wrap').find('.video');
4866            $vid.get(0).play();
4867        }else {
4868            var $extVideo = $(this).parents('.ns-gallery-slide-video-wrap').find('iframe.video').data('src');
4869            console.log($extVideo);
4870            $(this).parents('.ns-gallery-slide-video-wrap').find('iframe.video').attr('src', $extVideo+'?autoplay=1');
4871        }
4872    });
4873});
4874
4875
4876$(document).ready(function () {
4877    var wall = [];
4878    
4879    if ($('.ns-gallery-google-view').length) {
4880        $('.GITheWall').each(function(index, item) {
4881            var initialHeight = 500;
4882            wall[index] = $(this).GITheWall({
4883                nextButtonClass: 'nsgallery-icon nsgallery-next-icon',
4884                prevButtonClass: 'nsgallery-icon nsgallery-prev-icon',
4885                closeButtonClass: 'nsgallery-icon nsgallery-close-icon',
4886                initialWrapperHeight: initialHeight
4887            });        
4888        });
4889    }
4890
4891    var paginationType = $('#paginationType').val();  
4892    themeClass = 'ns-gallery-arrow--icon-circle video-not-supported';
4893
4894    function getTotPage($totalPage, $perPage){
4895        var totPages2 = Math.ceil($totalPage / $perPage);
4896        return totPages2;
4897    }
4898
4899    $('#cover-spin').hide();    
4900
4901    var checkCurrentGallery = [];
4902    $(document).on('click', '.article-load-more', function (e) {
4903        if (paginationType == 'pagination') {
4904            var getParentID = $(this).parent().parent().parent().parent().attr('id');
4905        } else {
4906            var getParentID = $(this).parent().parent().attr('id');
4907        }
4908
4909        var totNews = $('#totNews-' + getParentID).val();
4910        var perPage = $('#perPage-' + getParentID).val();
4911        var totPages = getTotPage(totNews, perPage);        
4912        
4913
4914        if (checkCurrentGallery.includes(getParentID)) {   
4915            var galleryPage = checkCurrentGallery[getParentID][0];
4916            checkCurrentGallery[getParentID]= [galleryPage+1];
4917            curPage = galleryPage+1;
4918        } else {
4919            curPage = 1;
4920            checkCurrentGallery.push(getParentID);            
4921            checkCurrentGallery[getParentID] = [];
4922            checkCurrentGallery[getParentID].push(curPage);            
4923        }
4924        
4925        e.preventDefault();
4926        $('#cover-spin').show();
4927        curPage = curPage + 1;
4928        var curPageUrl = $(this).attr('href');
4929        var nextPageUrl = curPageUrl;
4930
4931        $.ajax({
4932            type: 'GET',
4933            url: nextPageUrl,
4934            success: function (response) {
4935
4936                if (paginationType == 'pagination') {
4937                    var findNextPageURL = $(response).find('#' + getParentID).find('.pagination-block').html();
4938                    $('#' + getParentID + ' .pagination-block').html(findNextPageURL);
4939                } else {
4940                    var findNextPageURL = $(response).find('.article-load-more').attr('href');
4941                    $('#' + getParentID + ' .article-load-more').attr('href', findNextPageURL);
4942                }
4943
4944                var findNReplace = '#' + getParentID + ' .cus-row';
4945                var disdata = $(response).find(findNReplace).html();
4946                disdata = $(disdata + ' .ajaxBlock').addClass('page-' + curPage);
4947
4948                if (paginationType == 'pagination') {
4949                    $(findNReplace).html(disdata).fadeIn('slow');
4950                } else {
4951                    $(findNReplace).append(disdata).fadeIn('slow');
4952                    if (totPages == curPage) {
4953                        $('#' + getParentID + ' .pagination-block .article-load-more').fadeOut();
4954                    }
4955                }               
4956                $('.GITheWall').each(function(index, item) {
4957                    wall[index].refresh();
4958                });     
4959                try {
4960                    $('.' + getParentID).data('lightGallery').destroy(true);
4961                } catch (ex) { };
4962                
4963                var gallerySettings = $('#gallery-settings-' + getParentID).val();
4964                if (gallerySettings) {
4965                    var getSettings = gallerySettings.split(',');
4966                    getSettings.forEach(settVal => {
4967                        var getKey = settVal.split(':');
4968                        switch (getKey[0]) {                            
4969                            case "controls":
4970                                $controls = getKey[1];
4971                                if ($controls == 'true' || $controls == 1) {
4972                                    $controls = true;
4973                                } else {
4974                                    $controls = false;
4975                                }
4976                                break;
4977                        }
4978                    });
4979    
4980                    //and then re-initiate gallery again
4981                    $('.' + getParentID).lightGallery({
4982                        selector: '.ns-gallery-item',
4983                        addClass: themeClass,                       
4984                        controls : $controls,
4985                        download:false,
4986                    });
4987                }
4988                $('#cover-spin').hide();
4989            }
4990        });
4991    });
4992
4993});
4994
4995//
4996// Google maps
4997// Example:
4998// <div class="google-map" data-title="Radical.Design 3"
4999// data-latitude="51.96464" data-longitude="7.561069999999972"
5000// data-zoom="12" data-style="primaryColored"
5001// data-description="Strasse<br />33333 Ort"
5002// data-open-tooltip="immediately"></div>
5003//
5004// Options for data-style:
5005// primaryColored: Colored in theme primary color
5006// normal: Googles default colors
5007// grayScaled: Gray scaled
5008//
5009// Options for data-open-tooltip:
5010// immediately: Show tooltip immediately on startup
5011// onclick: Show tooltip on click
5012jQuery.each(jQuery('.google-map'), function(key) {
5013	var object = jQuery(this);
5014	var zoom = parseInt(object.attr('data-zoom'), 10);
5015	var title = object.attr('data-title');
5016	var description = object.attr('data-description');
5017	var latitude = object.attr('data-latitude');
5018	var longitude = object.attr('data-longitude');
5019	var openTooltip = object.attr('data-open-tooltip');
5020	// Map id
5021	var id = 'map-' + key;
5022	object.attr('id', id);
5023	// Primary color
5024	var color = jQuery('body').attr('data-color-primary');
5025	if(typeof color === 'undefined') {
5026		color = '#ddb0b7';
5027	}
5028	// Map style
5029	var style = object.attr('data-style');
5030	// Default styles
5031	// Gray scale
5032	var mapStyles = [
5033		{
5034			featureType: 'all',
5035			stylers: [
5036				{saturation: -100},
5037				{gamma: 0.90}
5038			]
5039		}
5040	];
5041	if(style === 'primaryColored') {
5042		mapStyles = [
5043			{
5044				stylers: [
5045					{hue: color},
5046					{saturation: -70},
5047					{lightness: 30},
5048					{gamma: 1}
5049				]
5050			}
5051		];
5052	}
5053	else if (style === 'normal') {
5054		mapStyles = [];
5055	}
5056	//
5057	var latlng = new google.maps.LatLng(latitude, longitude);
5058	var myOptions = {
5059		zoom: zoom,
5060		center: latlng,
5061		zoomControl: true,
5062		scaleControl: true,
5063		scrollwheel: false,
5064		mapTypeId: google.maps.MapTypeId.ROADMAP
5065	};
5066	var map = new google.maps.Map(document.getElementById(id), myOptions);
5067	map.setOptions({styles: mapStyles});
5068	//
5069	// Set marker
5070
5071
5072	var width = parseInt(object.attr('data-marker-width'), 10);
5073	var height = parseInt(object.attr('data-marker-height'), 10);
5074	var svg = object.attr('data-marker-svg');
5075	var icon = {
5076		anchor: new google.maps.Point((width/2), height),
5077		scaledSize: new google.maps.Size(width, height),
5078		origin: new google.maps.Point(0,0),
5079		url: 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg)
5080	};
5081	var marker = new google.maps.Marker({
5082		position: latlng,
5083		icon: icon,
5084		map: map
5085	});
5086	/*
5087	var marker = new HtmlMarker(latlng, map, {
5088		class: 'google-map-marker',
5089		id: id + '-marker',
5090		innerHTML: '<span class="icon icon-pin icon-lg" title="' + title + '"><div class="information">' + title + '<br />' + description + '</div></span>',
5091		position: 'CT',
5092		title: title
5093	});
5094	*/
5095	// Show name
5096	google.maps.event.addListener(marker, 'click', function () {
5097		jQuery('#' + this.args.id + ' .information').fadeIn();
5098	});
5099	if(openTooltip === 'immediately') {
5100		setTimeout(function() {
5101			jQuery('#' + id + ' .information').fadeIn();
5102		}, 1000);
5103	}
5104	// Hide name
5105	google.maps.event.addListener(marker, 'mouseout', function () {
5106		//var marker = jQuery('#' + this.args.id + ' .information').fadeOut();
5107	});
5108});
5109
5110/**
5111 * TYPO3 AddressManager
5112 *
5113 * @author Thomas Deuling, coding.ms
5114 * @constructor
5115 */
5116var AddressManager = function () {
5117
5118    /**
5119     * @type {jQuery} searchForm
5120     */
5121    this.searchForm = null;
5122
5123    /**
5124     * @type {jQuery} positionSelect
5125     */
5126    this.positionSelect = null;
5127
5128    /**
5129     * @type {jQuery} groupSelect
5130     */
5131    this.groupSelect = null;
5132
5133    /**
5134     * @type {jQuery} organisationSelect
5135     */
5136    this.organisationSelect = null;
5137    this.limitSelect = null;
5138    this.searchField = null;
5139    this.locationField = null;
5140    this.distanceSelect = null;
5141
5142
5143    this.locationAutoComplete = null;
5144
5145    // Maps
5146    this.map = null;
5147    this.mapsMarker = [];
5148    this.mapBounds = null;
5149    this.mapsMarkerCluster = null;
5150    this.countryRestriction = [];
5151
5152    /**
5153     * and/or
5154     * @type {string}
5155     */
5156    this.searchFieldConcat = 'or';
5157
5158    /**
5159     * Uid of the address list plugin
5160     * @type {number}
5161     */
5162    this.listUid = 0;
5163
5164    /**
5165     * Search parameter dummy
5166     * @type {{tx_addressmanager_jsonapi: {group: number, position: number, organisation: number, limit: number, searchWord: string, listUid: number}}}
5167     */
5168    this.searchData = {
5169        tx_addressmanager_jsonapi: {
5170            group: 0,
5171            position: 0,
5172            organisation: 0,
5173            offset: 0,
5174            limit: 15,
5175            searchWord: '',
5176            customString: '',
5177            listUid: 0,
5178            latitude: 0.0,
5179            longitude: 0.0,
5180            distance: 0
5181        }
5182    };
5183
5184    /**
5185     * Initiate object
5186     */
5187    this.initialize = function () {
5188        //
5189        // Fetch initial values for offset and limit
5190        var listWrapper = jQuery('.address-list-wrapper');
5191        if (listWrapper.length > 0) {
5192            this.searchData.tx_addressmanager_jsonapi.offset = parseInt(listWrapper.attr('data-address-list-offset'), 10);
5193            this.searchData.tx_addressmanager_jsonapi.limit = parseInt(listWrapper.attr('data-address-list-limit'), 10);
5194        }
5195        //
5196        // Filter form found -> bind own submit and read list uid
5197        this.searchForm = jQuery('.tx-address-manager #address-search-form');
5198        if (this.searchForm.length === 1) {
5199            this.searchForm.on("submit", function () {
5200                address_manager.refreshData();
5201                return false;
5202            });
5203            this.listUid = jQuery('.tx-address-manager #address-list-uid');
5204            if (this.searchForm.length === 1) {
5205                address_manager.searchData.tx_addressmanager_jsonapi.listUid = parseInt(this.listUid.val(), 10);
5206            }
5207        }
5208        //
5209        // group
5210        this.groupSelect = jQuery('.tx-address-manager #address-group-select');
5211        if (this.groupSelect.length === 1) {
5212            this.groupSelect.val(0);
5213            this.groupSelect.on("change", function () {
5214                var newValue = parseInt(jQuery(this).val(), 10);
5215                var filterSelectNumber = jQuery(this).data('order');
5216                if (newValue > 0) {
5217                    // activate next select
5218                    if (filterSelectNumber === 0) {
5219                        address_manager.resetFilterSelect(1);
5220                        address_manager.activateFilterSelect(1);
5221                        address_manager.resetFilterSelect(2);
5222                    }
5223                    else if (filterSelectNumber === 1) {
5224                        address_manager.resetFilterSelect(2);
5225                        address_manager.activateFilterSelect(2);
5226                    }
5227                }
5228                else {
5229                    // deactivate all higher selects
5230                    if (filterSelectNumber === 0) {
5231                        address_manager.resetFilterSelect(1);
5232                        address_manager.resetFilterSelect(2);
5233                    }
5234                    else if (filterSelectNumber === 1) {
5235                        address_manager.resetFilterSelect(2);
5236                    }
5237                }
5238                // reset search word field
5239                if (filterSelectNumber === 0 && address_manager.searchFieldConcat === 'or') {
5240                    address_manager.searchField.val('');
5241                    address_manager.searchData.tx_addressmanager_jsonapi.searchWord = '';
5242                    address_manager.searchData.tx_addressmanager_jsonapi.customString = '';
5243                }
5244                address_manager.searchData.tx_addressmanager_jsonapi.group = newValue;
5245                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5246                address_manager.refreshData();
5247            });
5248        }
5249        // position
5250        this.positionSelect = jQuery('.tx-address-manager #address-position-select');
5251        if (this.positionSelect.length === 1) {
5252            this.positionSelect.val(0);
5253            this.positionSelect.on("change", function () {
5254                var newValue = parseInt(jQuery(this).val(), 10);
5255                var filterSelectNumber = jQuery(this).data('order');
5256                if (newValue > 0) {
5257                    // activate next select
5258                    if (filterSelectNumber === 0) {
5259                        address_manager.resetFilterSelect(1);
5260                        address_manager.activateFilterSelect(1);
5261                        address_manager.resetFilterSelect(2);
5262                    }
5263                    else if (filterSelectNumber === 1) {
5264                        address_manager.resetFilterSelect(2);
5265                        address_manager.activateFilterSelect(2);
5266                    }
5267                }
5268                else {
5269                    // deactivate all higher selects
5270                    if (filterSelectNumber === 0) {
5271                        address_manager.resetFilterSelect(1);
5272                        address_manager.resetFilterSelect(2);
5273                    }
5274                    else if (filterSelectNumber === 1) {
5275                        address_manager.resetFilterSelect(2);
5276                    }
5277                }
5278                // reset search word field
5279                if (filterSelectNumber === 0 && address_manager.searchFieldConcat === 'or') {
5280                    address_manager.searchField.val('');
5281                    address_manager.searchData.tx_addressmanager_jsonapi.searchWord = '';
5282                    address_manager.searchData.tx_addressmanager_jsonapi.customString = '';
5283                }
5284                address_manager.searchData.tx_addressmanager_jsonapi.position = newValue;
5285                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5286                address_manager.refreshData();
5287
5288            });
5289        }
5290        // organisation
5291        this.organisationSelect = jQuery('.tx-address-manager #address-organisation-select');
5292        if (this.organisationSelect.length === 1) {
5293            this.organisationSelect.val(0);
5294            this.organisationSelect.on("change", function () {
5295                var newValue = parseInt(jQuery(this).val(), 10);
5296                var filterSelectNumber = jQuery(this).data('order');
5297                if (newValue > 0) {
5298                    // activate next select
5299                    if (filterSelectNumber === 0) {
5300                        address_manager.resetFilterSelect(1);
5301                        address_manager.activateFilterSelect(1);
5302                        address_manager.resetFilterSelect(2);
5303                    }
5304                    else if (filterSelectNumber === 1) {
5305                        address_manager.resetFilterSelect(2);
5306                        address_manager.activateFilterSelect(2);
5307                    }
5308                }
5309                else {
5310                    // deactivate all higher selects
5311                    if (filterSelectNumber === 0) {
5312                        address_manager.resetFilterSelect(1);
5313                        address_manager.resetFilterSelect(2);
5314                    }
5315                    else if (filterSelectNumber === 1) {
5316                        address_manager.resetFilterSelect(2);
5317                    }
5318                }
5319                // reset search word field
5320                if (filterSelectNumber === 0 && address_manager.searchFieldConcat === 'or') {
5321                    address_manager.searchField.val('');
5322                    address_manager.searchData.tx_addressmanager_jsonapi.searchWord = '';
5323                    address_manager.searchData.tx_addressmanager_jsonapi.customString = '';
5324                }
5325                address_manager.searchData.tx_addressmanager_jsonapi.organisation = newValue;
5326                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5327                address_manager.refreshData();
5328            });
5329        }
5330        //
5331        // limit
5332        this.limitSelect = jQuery('.tx-address-manager #address-limit-select');
5333        if (this.limitSelect.length === 1) {
5334            this.limitSelect.on("change", function () {
5335                address_manager.searchData.tx_addressmanager_jsonapi.limit = parseInt(jQuery(this).val(), 10);
5336                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5337                address_manager.refreshData();
5338            });
5339        }
5340        //
5341        // name/word
5342        this.searchField = jQuery('.tx-address-manager #address-search-word');
5343        if (this.searchField.length === 1) {
5344            this.searchField.val('');
5345            this.searchField.on('input', function (event) {
5346                if (address_manager.searchFieldConcat === 'or') {
5347                    address_manager.resetFilterSelect(0);
5348                    address_manager.resetFilterSelect(1);
5349                    address_manager.resetFilterSelect(2);
5350                }
5351                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5352                address_manager.searchData.tx_addressmanager_jsonapi.searchWord = jQuery(this).val();
5353                /*
5354                 Don't use key up, because some users press enter and the the search is send twice!!
5355                 //address_manager.setSearchWord(jQuery(this).attr('value'));
5356                 if (address_manager.searchTimer) {
5357                 clearTimeout(address_manager.searchTimer);
5358                 }
5359                 address_manager.searchTimer = setTimeout(function() {
5360                 address_manager.refreshData();
5361                 }, 1000);
5362                 */
5363                if (event.keyCode === 13) {
5364                    if(jQuery('[data-search-word-submit-on-enter]').attr('data-search-word-submit-on-enter') === '1') {
5365                        address_manager.refreshData();
5366                    }
5367                }
5368            });
5369        }
5370        //
5371        // custom string
5372        this.customStringField = jQuery('.tx-address-manager #address-custom-string');
5373        if (this.customStringField.length === 1) {
5374            this.customStringField.val('');
5375            this.customStringField.on('input', function () {
5376                if (address_manager.searchFieldConcat === 'or') {
5377                    address_manager.resetFilterSelect(0);
5378                    address_manager.resetFilterSelect(1);
5379                    address_manager.resetFilterSelect(2);
5380                }
5381                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5382                address_manager.searchData.tx_addressmanager_jsonapi.customString = jQuery(this).val();
5383                /*
5384                 * Don't use key up, because some users press enter and the the search is send twice!!
5385                 */
5386            });
5387        }
5388        //
5389        // Location
5390        this.locationField = jQuery('.tx-address-manager #address-location-field');
5391        if (this.locationField.length === 1) {
5392            address_manager.searchData.tx_addressmanager_jsonapi.latitude = jQuery('.tx-address-manager #address-latitude-field').val();
5393            address_manager.searchData.tx_addressmanager_jsonapi.longitude = jQuery('.tx-address-manager #address-longitude-field').val();
5394            //
5395            // Create the auto-complete object, restricting the search to geographical location types.
5396            var options = {
5397                componentRestrictions: {
5398                    country: this.countryRestriction
5399                }
5400            };
5401            if(typeof google !== 'undefined') {
5402                this.locationAutoComplete = new google.maps.places.Autocomplete(this.locationField[0], options);
5403                //
5404                // When the user selects an address from the dropdown, populate the address fields in the form.
5405                this.locationAutoComplete.addListener('place_changed', function () {
5406                    // Get the place details from the autocomplete object.
5407                    var place = address_manager.locationAutoComplete.getPlace();
5408                    if (typeof place.geometry !== 'undefined') {
5409                        address_manager.searchData.tx_addressmanager_jsonapi.latitude = place.geometry.location.lat();
5410                        address_manager.searchData.tx_addressmanager_jsonapi.longitude = place.geometry.location.lng();
5411                    }
5412                    else {
5413                        address_manager.searchData.tx_addressmanager_jsonapi.latitude = 0.0;
5414                        address_manager.searchData.tx_addressmanager_jsonapi.longitude = 0.0;
5415                    }
5416                    //
5417                    // Insert into HTML fields.
5418                    // That is necessary in case of sending values by page request.
5419                    jQuery('#address-latitude-field').val(address_manager.searchData.tx_addressmanager_jsonapi.latitude);
5420                    jQuery('#address-longitude-field').val(address_manager.searchData.tx_addressmanager_jsonapi.longitude);
5421                    //
5422                    // Ensure to show first page of result
5423                    address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5424                });
5425                //
5426                // Get geo location on enter
5427                this.locationField.on('keydown', function (event) {
5428                    //
5429                    // If location field is empty, reset latitude/longitude
5430                    if(jQuery(this).val() === '') {
5431                        address_manager.searchData.tx_addressmanager_jsonapi.latitude = 0.0;
5432                        address_manager.searchData.tx_addressmanager_jsonapi.longitude = 0.0;
5433                    }
5434                    if (event.keyCode === 13) {
5435                        //
5436                        jQuery(event.target).blur();
5437                        var firstResult = '';
5438                        var firstItemText = jQuery('.pac-container .pac-item:first span:eq(3)').text();
5439                        if (firstItemText === '') {
5440                            firstResult = jQuery('.pac-container .pac-item:first .pac-item-query').text();
5441                        }
5442                        else {
5443                            firstResult = jQuery('.pac-container .pac-item:first .pac-item-query').text() + ', ' + firstItemText;
5444                        }
5445                        //
5446                        var geocoder = new google.maps.Geocoder();
5447                        geocoder.geocode({'address': firstResult}, function (results, status) {
5448                            if (status === google.maps.GeocoderStatus.OK) {
5449                                place = results[0];
5450                                event.target.value = firstResult;
5451                                if (typeof place.geometry !== 'undefined') {
5452                                    address_manager.searchData.tx_addressmanager_jsonapi.latitude = place.geometry.location.lat();
5453                                    address_manager.searchData.tx_addressmanager_jsonapi.longitude = place.geometry.location.lng();
5454                                }
5455                                else {
5456                                    address_manager.searchData.tx_addressmanager_jsonapi.latitude = 0.0;
5457                                    address_manager.searchData.tx_addressmanager_jsonapi.longitude = 0.0;
5458                                }
5459                                //
5460                                // Insert into HTML fields.
5461                                // That is necessary in case of sending values by page request.
5462                                jQuery('#address-latitude-field').val(address_manager.searchData.tx_addressmanager_jsonapi.latitude);
5463                                jQuery('#address-longitude-field').val(address_manager.searchData.tx_addressmanager_jsonapi.longitude);
5464                                //
5465                                // Ensure to show first page of result
5466                                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5467                            }
5468                        });
5469                        if(jQuery('[data-location-submit-on-enter]').attr('data-location-submit-on-enter') === '1') {
5470                            address_manager.refreshData();
5471                        }
5472                    }
5473                });
5474            }
5475        }
5476        //
5477        // Distance
5478        this.distanceSelect = jQuery('.tx-address-manager #address-distance-select');
5479        if (this.distanceSelect.length === 1) {
5480            address_manager.searchData.tx_addressmanager_jsonapi.distance = parseInt(this.distanceSelect.val());
5481            this.distanceSelect.on("change", function () {
5482                var selectedValue = jQuery('option:selected', jQuery(this)).val();
5483                address_manager.searchData.tx_addressmanager_jsonapi.distance = parseInt(selectedValue, 10);
5484                address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5485            });
5486        }
5487        //
5488        // Reset second and third select field
5489        address_manager.resetFilterSelect(1);
5490        address_manager.resetFilterSelect(2);
5491        //
5492        // Initialize google map
5493        if(typeof google !== 'undefined') {
5494            // initialize only if google maps library available
5495            address_manager.initializeGoogleMap();
5496        }
5497        //
5498        // Initialize pagination
5499        address_manager.refreshPagination();
5500        //
5501        // Bind events
5502        jQuery(window).on('address_manager.result', address_manager.onResult);
5503        jQuery(window).on('address_manager.no_result', address_manager.onNoResult);
5504        //
5505        // Fire event after initialization
5506        jQuery.event.trigger({
5507            type: 'address_manager.after_initialize'
5508        });
5509        //
5510        // Process address group initial value
5511        var reloadWithInitialValues = false;
5512        if(this.searchField.length === 1) {
5513            var searchFieldInitialValue = this.searchField.attr('data-initial-value');
5514            if(searchFieldInitialValue !== '') {
5515                this.searchField.val(searchFieldInitialValue).trigger('input');
5516                reloadWithInitialValues = true;
5517            }
5518        }
5519        if(this.customStringField.length === 1) {
5520            var customStringFieldInitialValue = this.customStringField.attr('data-initial-value');
5521            if(customStringFieldInitialValue !== '') {
5522                this.customStringField.val(customStringFieldInitialValue).trigger('input');
5523                reloadWithInitialValues = true;
5524            }
5525        }
5526        if (this.groupSelect.length === 1) {
5527            var groupInitialValue = this.groupSelect.attr('data-initial-value');
5528            if(groupInitialValue !== '') {
5529                groupInitialValue = parseInt(groupInitialValue, 10);
5530                if(groupInitialValue > 0) {
5531                    this.groupSelect.val(groupInitialValue).change();
5532                    reloadWithInitialValues = false;
5533                }
5534            }
5535        }
5536        if(reloadWithInitialValues) {
5537            this.searchForm.submit();
5538        }
5539    };
5540
5541    /**
5542     * Initialize google map
5543     */
5544    this.initializeGoogleMap = function () {
5545        //
5546        // List map
5547        var mapWrapper = jQuery('#address-list-map');
5548        if (mapWrapper.length > 0) {
5549            var maxZoom = parseInt(mapWrapper.attr('data-max-zoom'), 10);
5550            //
5551            // Prepare country restriction
5552            var countryRestrictionString = mapWrapper.attr('data-country-restriction');
5553            if(typeof countryRestrictionString !== 'undefined') {
5554                var countryRestrictionArray = countryRestrictionString.split(',');
5555                for(var i=0 ; i<countryRestrictionArray.length ; i++) {
5556                    this.countryRestriction.push(countryRestrictionArray[i].trim());
5557                }
5558            }
5559            //
5560            address_manager.mapBounds = new google.maps.LatLngBounds();
5561            address_manager.infoWindow = new google.maps.InfoWindow();
5562            var defaultLatitude = mapWrapper.attr('data-default-latitude');
5563            if(typeof defaultLatitude === 'undefined' || defaultLatitude === '') {
5564                defaultLatitude = 51.96066490000001;
5565            }
5566            else {
5567                defaultLatitude = parseFloat(defaultLatitude);
5568            }
5569            var defaultLongitude = mapWrapper.attr('data-default-longitude');
5570            if(typeof defaultLongitude === 'undefined' || defaultLongitude === '') {
5571                defaultLongitude = 7.626134699999966;
5572            }
5573            else {
5574                defaultLongitude = parseFloat(defaultLongitude);
5575            }
5576            console.log(defaultLatitude, defaultLongitude);
5577            var latlng = new google.maps.LatLng(defaultLatitude, defaultLongitude);
5578            var myOptions = {
5579                zoom: 12,
5580                center: latlng,
5581                zoomControl: true,
5582                scaleControl: true,
5583                scrollwheel: false,
5584                mapTypeId: google.maps.MapTypeId.ROADMAP
5585            };
5586            address_manager.map = new google.maps.Map(document.getElementById("address-list-map-canvas"), myOptions);
5587            address_manager.map.setOptions({styles: address_manager.getMapStyles(mapWrapper)});
5588            // Prepare clustering
5589            var clusteringActive = parseInt(mapWrapper.attr('data-clustering-active'), 10);
5590            var clusteringImagePath = mapWrapper.attr('data-clustering-image-path');
5591            // Process address items
5592            var items = jQuery('.address-list-item');
5593            if(items.length > 0) {
5594                jQuery.each(items, function (key) {
5595                    var latitude = parseFloat(jQuery(this).data('map-latitude'));
5596                    var longitude = parseFloat(jQuery(this).data('map-longitude'));
5597                    latitude = address_manager.validateLatitude(latitude);
5598                    longitude = address_manager.validateLongitude(longitude);
5599                    var svg = jQuery(this).data('map-marker');
5600                    if (latitude !== 0 && longitude !== 0 && !isNaN(latitude) && !isNaN(longitude)) {
5601                        // Create address marker
5602                        var marker = new google.maps.Marker({
5603                            position: new google.maps.LatLng(latitude, longitude),
5604                            icon: address_manager.getIcon(mapWrapper, svg),
5605                            map: address_manager.map
5606                        });
5607                        // remind marker for bounds
5608                        address_manager.mapBounds.extend(marker.position);
5609                        // Show popup window on click
5610                        if (jQuery(this).data('map-tooltip') !== '') {
5611                            google.maps.event.addListener(marker, 'click', (function (marker, key, item) {
5612                                return function () {
5613                                    address_manager.infoWindow.setContent(jQuery(item).data('map-tooltip'));
5614                                    address_manager.infoWindow.open(address_manager.map, marker);
5615                                }
5616                            })(marker, key, jQuery(this)));
5617                        }
5618                        // Remind used markers
5619                        address_manager.mapsMarker.push(marker);
5620                    }
5621                });
5622                //
5623                // Initialize clustering
5624                if (clusteringActive === 1) {
5625                    address_manager.mapsMarkerCluster = new MarkerClusterer(this.map, address_manager.mapsMarker, {imagePath: clusteringImagePath});
5626                }
5627                address_manager.refreshMarkerCluster();
5628                // Now fit the map to the newly inclusive bounds
5629                address_manager.map.fitBounds(address_manager.mapBounds);
5630                // Set zoom
5631                google.maps.event.addListenerOnce(address_manager.map, 'bounds_changed', function () {
5632                    //if (this.getZoom() > maxZoom) {
5633                    //	this.setZoom(maxZoom);
5634                    //}
5635                });
5636            }
5637            else {
5638                //
5639                // Initialize clustering
5640                if (clusteringActive === 1) {
5641                    address_manager.mapsMarkerCluster = new MarkerClusterer(this.map, [], {imagePath: clusteringImagePath});
5642                }
5643            }
5644        }
5645        //
5646        // Detail map
5647        mapWrapper = jQuery('#address-detail-map');
5648        if (mapWrapper.length > 0) {
5649            var zoom = parseInt(mapWrapper.attr('data-zoom'), 10);
5650            var latitude = parseFloat(mapWrapper.attr('data-latitude'));
5651            var longitude = parseFloat(mapWrapper.attr('data-longitude'));
5652            var svg = mapWrapper.data('map-marker');
5653            address_manager.infoWindow = new google.maps.InfoWindow();
5654            address_manager.map = new google.maps.Map(mapWrapper[0], {
5655                zoom: zoom,
5656                center: new google.maps.LatLng(latitude, longitude),
5657                zoomControl: true,
5658                scaleControl: true,
5659                scrollwheel: false,
5660                mapTypeId: google.maps.MapTypeId.ROADMAP
5661            });
5662            address_manager.map.setOptions({styles: address_manager.getMapStyles(mapWrapper)});
5663            // Create address marker
5664            var marker = new google.maps.Marker({
5665                position: new google.maps.LatLng(latitude, longitude),
5666                icon: address_manager.getIcon(mapWrapper, svg),
5667                map: address_manager.map
5668            });
5669            // Show popup window on click
5670            if (mapWrapper.data('tooltip') !== '') {
5671                address_manager.infoWindow.setContent(mapWrapper.data('tooltip'));
5672                google.maps.event.addListener(marker, 'click', function () {
5673                    address_manager.infoWindow.open(address_manager.map, marker);
5674                });
5675            }
5676        }
5677    };
5678
5679    /**
5680     * Rebuilding google map after refreshing address data
5681     */
5682    this.rebuildGoogleMap = function () {
5683        var mapWrapper = jQuery('#address-list-map');
5684        if (mapWrapper.length > 0) {
5685            var maxZoom = parseInt(mapWrapper.attr('data-max-zoom'), 10);
5686            // Remove All Markers
5687            while (address_manager.mapsMarker.length) {
5688                address_manager.mapsMarker.pop().setMap(null);
5689            }
5690            // Reset bounds
5691            address_manager.mapBounds = new google.maps.LatLngBounds();
5692            // Set current marker
5693            jQuery.each(jQuery('.address-list-item'), function (key) {
5694                var latitude = parseFloat(jQuery(this).data('map-latitude'));
5695                var longitude = parseFloat(jQuery(this).data('map-longitude'));
5696                latitude = address_manager.validateLatitude(latitude);
5697                longitude = address_manager.validateLongitude(longitude);
5698                var svg = jQuery(this).data('map-marker');
5699                if (latitude !== 0 && longitude !== 0 && !isNaN(latitude) && !isNaN(longitude)) {
5700                    // Create address marker
5701                    var marker = new google.maps.Marker({
5702                        position: new google.maps.LatLng(latitude, longitude),
5703                        icon: address_manager.getIcon(mapWrapper, svg),
5704                        map: address_manager.map
5705                    });
5706                    // remind marker for bounds
5707                    address_manager.mapBounds.extend(marker.position);
5708                    if (jQuery(this).data('map-tooltip') !== '') {
5709                        google.maps.event.addListener(marker, 'click', (function (marker, key, item) {
5710                            return function () {
5711                                address_manager.infoWindow.setContent(jQuery(item).data('map-tooltip'));
5712                                address_manager.infoWindow.open(address_manager.map, marker);
5713                            }
5714                        })(marker, key, jQuery(this)));
5715                    }
5716                    // remind marker
5717                    address_manager.mapsMarker.push(marker);
5718                }
5719            });
5720            address_manager.refreshMarkerCluster();
5721            // Now fit the map to the newly inclusive bounds
5722            address_manager.map.fitBounds(address_manager.mapBounds);
5723            // Set zoom
5724            google.maps.event.addListenerOnce(address_manager.map, 'bounds_changed', function () {
5725                //if (this.getZoom() > maxZoom) {
5726                //	this.setZoom(maxZoom);
5727                //}
5728            });
5729            if (address_manager.map.getZoom() === 22) {
5730                address_manager.map.setZoom(maxZoom);
5731            }
5732        }
5733    };
5734
5735    this.refreshMarkerCluster = function () {
5736        var mapWrapper = jQuery('#address-list-map');
5737        var clusteringActive = parseInt(mapWrapper.attr('data-clustering-active'), 10);
5738        if (clusteringActive === 1) {
5739            address_manager.mapsMarkerCluster.clearMarkers();
5740            address_manager.mapsMarkerCluster.addMarkers(address_manager.mapsMarker);
5741        }
5742    };
5743
5744    /**
5745     * Reset select boxes, but not the limit select box
5746     * @param number 0-3
5747     */
5748    this.resetFilterSelect = function (number) {
5749        var selector = '.tx-address-manager select[data-order=\'' + number + '\']';
5750        var select = jQuery(selector);
5751        for (var i = 0; i < select.length; i++) {
5752            var forSelect = jQuery(select[i]);
5753            // Don't process limit select box
5754            if (forSelect.attr('id') !== 'address-limit-select') {
5755                if (number > 0) {
5756                    forSelect.attr('disabled', 'disabled');
5757                }
5758                forSelect.val('0');
5759                var id = forSelect.attr('id').replace('address-', '').replace('-select', '');
5760                address_manager.searchData.tx_addressmanager_jsonapi[id] = 0;
5761            }
5762        }
5763    };
5764
5765    /**
5766     * Reset of all filter and shown data
5767     */
5768    this.resetAllData = function() {
5769        for(var i=0 ; i<4 ; i++) {
5770            address_manager.resetFilterSelect(i);
5771        }
5772        jQuery('#address-search-word').val('');
5773        jQuery('#address-custom-string').val('');
5774        jQuery('#address-location-field').val('');
5775        jQuery('#address-latitude-field').val('');
5776        jQuery('#address-longitude-field').val('');
5777        address_manager.searchData.tx_addressmanager_jsonapi.searchWord = '';
5778        address_manager.searchData.tx_addressmanager_jsonapi.customString = '';
5779        address_manager.searchData.tx_addressmanager_jsonapi.latitude = 0.0;
5780        address_manager.searchData.tx_addressmanager_jsonapi.longitude = 0.0;
5781        address_manager.searchData.tx_addressmanager_jsonapi.offset = 0;
5782        address_manager.refreshData();
5783    };
5784
5785    /**
5786     * Activates the filter select by giving number
5787     * @param number 0-3
5788     */
5789    this.activateFilterSelect = function (number) {
5790        var selector = '.tx-address-manager select[data-order=\'' + number + '\']';
5791        var select = jQuery(selector);
5792        if (select.length > 0) {
5793            select.val('0').removeAttr('disabled');
5794        }
5795    };
5796
5797    /**
5798     * Toggles the loading information
5799     */
5800    this.toggleLoading = function () {
5801        jQuery('.address-list').animate({
5802            height: 'toggle',
5803            opacity: 'toggle'
5804        }, 400);
5805        var addressListLoading = jQuery('.address-list-loading');
5806        var addressListLoadingClass = addressListLoading.attr('data-hidden-class');
5807        if (addressListLoading.length > 0) {
5808            if (addressListLoading.hasClass(addressListLoadingClass)) {
5809                addressListLoading.removeClass(addressListLoadingClass);
5810            }
5811            else {
5812                addressListLoading.addClass(addressListLoadingClass);
5813            }
5814        }
5815    };
5816
5817    /**
5818     * Refresh displayed addresses and filter
5819     */
5820    this.refreshData = function () {
5821        this.toggleLoading();
5822        jQuery.ajax({
5823            dataType: 'json',
5824            url: address_manager.searchForm.attr('action'),
5825            data: address_manager.searchData,
5826            method: 'POST',
5827            success: function (result) {
5828                address_manager.toggleLoading();
5829                if (result.list.items.length > 0) {
5830                    // Remove previously displayed addresses
5831                    jQuery('.address-list').html('');
5832                    // Insert new searched addresses
5833                    jQuery.each(result.list.items, function (key, address) {
5834                        var html = atob(address.html);
5835                        html = decodeURIComponent(escape(html));
5836                        jQuery('.address-list').append(html);
5837                    });
5838                    //
5839                    // Filter the second filter
5840                    if (typeof(result.list.filterFieldSecond) !== 'undefined') {
5841                        if (typeof(result.list.filterFieldSecond.items) !== 'undefined') {
5842                            var selectSecond = jQuery('select[data-order=\'1\']');
5843                            if (selectSecond.length > 0) {
5844                                // Set please choose label
5845                                var labelSecond = jQuery('select[data-order=\'1\'] option[value=\'0\']').html();
5846                                selectSecond.html('<option value="0">' + labelSecond + '</option>');
5847                                // Set items
5848                                jQuery.each(result.list.filterFieldSecond.items, function (index, item) {
5849                                    var selected = '';
5850                                    if (parseInt(result.list.filterFieldSecond.selected, 10) === parseInt(item.uid, 10)) {
5851                                        selected = 'selected="selected"';
5852                                    }
5853                                    // rebuild select options
5854                                    var html = '<option value="' + item.uid + '" ' + selected + '>' + item.title + '</option>';
5855                                    jQuery('select[data-order=\'1\']').append(html);
5856                                });
5857                            }
5858                        }
5859                    }
5860                    //
5861                    // Filter the third filter
5862                    if (typeof(result.list.filterFieldThird) !== 'undefined') {
5863                        var selectThird = jQuery('select[data-order=\'2\']');
5864                        if (typeof(result.list.filterFieldThird.items) !== 'undefined') {
5865                            if (selectThird.length > 0) {
5866                                selectThird.removeAttr('disabled', 'disabled');
5867                                // Set please choose label
5868                                var labelThird = jQuery('select[data-order=\'2\'] option[value=\'0\']').html();
5869                                selectThird.html('<option value="0">' + labelThird + '</option>');
5870                                // Set items
5871                                jQuery.each(result.list.filterFieldThird.items, function (index, item) {
5872                                    var selected = '';
5873                                    if (parseInt(result.list.filterFieldThird.selected, 10) === parseInt(item.uid, 10)) {
5874                                        selected = 'selected="selected"';
5875                                    }
5876                                    var html = '<option value="' + item.uid + '" ' + selected + '>' + item.title + '</option>';
5877                                    jQuery('select[data-order=\'2\']').append(html);
5878                                });
5879                            }
5880                        }
5881                        else {
5882                            if (selectThird.length > 0) {
5883                                selectThird.attr('disabled', 'disabled');
5884                            }
5885                        }
5886                    }
5887                    jQuery.event.trigger({
5888                        type: 'address_manager.result',
5889                        result: result
5890                    });
5891                }
5892                else {
5893                    jQuery.event.trigger({
5894                        type: 'address_manager.no_result',
5895                        result: result
5896                    });
5897                }
5898                //
5899                // Insert current count
5900                var listWrapper = jQuery('.address-list-wrapper');
5901                listWrapper.attr('data-address-list-count', result.list.count);
5902                //
5903                // Rebuild google map
5904                address_manager.rebuildGoogleMap();
5905                //
5906                // Refresh pagination
5907                address_manager.refreshPagination();
5908            }
5909        });
5910    };
5911
5912    this.onResult = function (result) {
5913        jQuery('#address-list-map').slideDown();
5914        jQuery('.address-list-pagination').slideDown();
5915    };
5916    this.onNoResult = function (result) {
5917        /**
5918         * @todo translate, in <div> in template verlagern und nur ein/aus schalten!
5919         */
5920		var langValue = $('html').attr('lang');
5921
5922		if(langValue=='ar'){
5923			jQuery('.address-list').html('<div class="address-list-no-results col-md-12"><div class="alert alert-info alert-address-result">لم يتم العثور على أي نتيجة !</div></div>');
5924		}
5925		else{			
5926			jQuery('.address-list').html('<div class="address-list-no-results col-md-12"><div class="alert alert-info alert-address-result">No result found !</div></div>');
5927		}
5928        
5929        jQuery('#address-list-map').slideUp();
5930        jQuery('.address-list-pagination').slideUp();
5931    };
5932
5933    this.refreshPagination = function () {
5934        jQuery.each(jQuery('.address-list-pagination'), function () {
5935            var listWrapper = jQuery('.address-list-wrapper');
5936            var pagination = jQuery(this);
5937            var count = parseInt(listWrapper.attr('data-address-list-count'), 10);
5938            var limit = address_manager.searchData.tx_addressmanager_jsonapi.limit;
5939            var offset = address_manager.searchData.tx_addressmanager_jsonapi.offset;
5940            var pageCount = Math.ceil(count / limit);
5941            var currentPageNo = (offset / limit) + 1;
5942            //
5943            // Remove all page items
5944            jQuery('.page-item.clone', pagination).remove();
5945            //
5946            // Currently on first page
5947            var paginationPrevious = jQuery('.page-item.previous');
5948            if (currentPageNo === 1) {
5949                paginationPrevious.addClass('disabled');
5950            }
5951            else if (paginationPrevious.hasClass('disabled')) {
5952                paginationPrevious.removeClass('disabled');
5953            }
5954            if (!paginationPrevious.hasClass('initialized')) {
5955                paginationPrevious.addClass('initialized');
5956                paginationPrevious.on('click', function () {
5957                    var limit = address_manager.searchData.tx_addressmanager_jsonapi.limit;
5958                    var offset = address_manager.searchData.tx_addressmanager_jsonapi.offset;
5959                    // Increase offset
5960                    offset -= limit;
5961                    if (offset >= 0) {
5962                        address_manager.searchData.tx_addressmanager_jsonapi.offset = offset;
5963                        address_manager.refreshData();
5964                    }
5965                    return false;
5966                });
5967            }
5968            //
5969            // Currently on last page
5970            var paginationNext = jQuery('.page-item.next');
5971            if (currentPageNo === pageCount) {
5972                paginationNext.addClass('disabled');
5973            }
5974            else if (paginationNext.hasClass('disabled')) {
5975                paginationNext.removeClass('disabled');
5976            }
5977            if (!paginationNext.hasClass('initialized')) {
5978                paginationNext.addClass('initialized');
5979                paginationNext.on('click', function () {
5980                    var count = parseInt(listWrapper.attr('data-address-list-count'), 10);
5981                    var limit = address_manager.searchData.tx_addressmanager_jsonapi.limit;
5982                    var offset = address_manager.searchData.tx_addressmanager_jsonapi.offset;
5983                    // Increase offset
5984                    offset += limit;
5985                    if (offset < count) {
5986                        address_manager.searchData.tx_addressmanager_jsonapi.offset = offset;
5987                        address_manager.refreshData();
5988                    }
5989                    return false;
5990                });
5991            }
5992            //
5993            // Build page links
5994            var pageNo = 1;
5995            for (var i = 0; i < count; i += limit) {
5996                var pageItemTemplate = jQuery('.page-item.template', pagination).clone();
5997                pageItemTemplate.removeClass('template').addClass('clone').removeAttr('style');
5998                jQuery('a', pageItemTemplate).attr('data-page-no', pageNo).text(pageNo);
5999                // is current page
6000                if (pageNo === currentPageNo) {
6001                    pageItemTemplate.addClass('active');
6002                }
6003                jQuery(pageItemTemplate).insertBefore(jQuery('.page-item.template', pagination));
6004                pageNo++;
6005            }
6006            jQuery('.page-item.clone a', pagination).on('click', function () {
6007                var pageLink = jQuery(this);
6008                var pageNo = parseInt(pageLink.attr('data-page-no'), 10);
6009                var limit = address_manager.searchData.tx_addressmanager_jsonapi.limit;
6010                address_manager.searchData.tx_addressmanager_jsonapi.offset = limit * (pageNo - 1);
6011                address_manager.refreshData();
6012                return false;
6013            });
6014        });
6015    };
6016
6017    this.getIcon = function (mapWrapper, svg) {
6018        var width = parseInt(mapWrapper.attr('data-marker-width'), 10);
6019        var height = parseInt(mapWrapper.attr('data-marker-height'), 10);
6020        return icon = {
6021            anchor: new google.maps.Point((width / 2), height),
6022            scaledSize: new google.maps.Size(width, height),
6023            origin: new google.maps.Point(0, 0),
6024            url: 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg)
6025        };
6026    };
6027
6028    this.getMapStyles = function (mapWrapper) {
6029        //
6030        // Primary color
6031        var color = jQuery('body').attr('data-color-primary');
6032        if (typeof color === 'undefined') {
6033            color = '#ddb0b7';
6034        }
6035        // Map style
6036        var style = mapWrapper.attr('data-style');
6037        // Default styles
6038        // Gray scale
6039        var mapStyles = [
6040            {
6041                featureType: 'landscape',
6042                stylers: [
6043                    {saturation: -100},
6044                    {gamma: 0.90}
6045                ]
6046            },
6047            {
6048                featureType: 'road',
6049                stylers: [
6050                    {saturation: -100},
6051                    {gamma: 0.90}
6052                ]
6053            },
6054            {
6055                featureType: 'poi',
6056                stylers: [
6057                    {saturation: -100},
6058                    {gamma: 0.90}
6059                ]
6060            },
6061            {
6062                featureType: 'transit',
6063                stylers: [
6064                    {saturation: -100},
6065                    {gamma: 0.90}
6066                ]
6067            },
6068            {
6069                featureType: 'water',
6070                elementType: 'geometry.fill',
6071                stylers: [
6072                    {hue: '#5aa7d5'}
6073                ]
6074            }
6075        ];
6076        if (style === 'primaryColored') {
6077            mapStyles = [
6078                {
6079                    stylers: [
6080                        {hue: color},
6081                        {saturation: -70},
6082                        {lightness: 30},
6083                        {gamma: 1}
6084                    ]
6085                }
6086            ];
6087        }
6088        else if (style === 'normal') {
6089            mapStyles = [];
6090        }
6091        return mapStyles;
6092    };
6093
6094    this.validateLatitude = function (latitude) {
6095        if (latitude > 85 || latitude < -85) {
6096            latitude = 0.0;
6097        }
6098        return latitude;
6099    };
6100
6101    this.validateLongitude = function (longitude) {
6102        if (longitude > 180 || longitude < -180) {
6103            longitude = 0.0;
6104        }
6105        return longitude;
6106    };
6107
6108};
6109var address_manager = new AddressManager();
6110jQuery(document).ready(function () {
6111    address_manager.initialize();
6112	$('#address-position-select').prop("disabled", false);
6113    $('#address-group-select').prop("disabled", false);
6114    $('select[name="tx_addressmanager_jsonapi[groupSelect]"]').prop("disabled", false);
6115  	$("#address-position-select").attr('disabled',false); 
6116	
6117	$('.organisation-select').on('change', function() {
6118		//alert( this.value );
6119		$('#address-position-select').prop("disabled", false);
6120		$('#address-group-select').prop("disabled", false);
6121		$('select[name="tx_addressmanager_jsonapi[groupSelect]"]').prop("disabled", false);
6122		$("#address-position-select").attr('disabled',false); 
6123	});
6124	
6125	$('.group-select').on('change', function() {
6126		//alert( this.value );
6127		$('#address-position-select').prop("disabled", false);
6128		$('#address-group-select').prop("disabled", false);
6129		$('select[name="tx_addressmanager_jsonapi[groupSelect]"]').prop("disabled", false);
6130		$("#address-position-select").attr('disabled',false); 
6131	});
6132	
6133	$('.position-select').on('change', function() {
6134		//alert( this.value );
6135		$('#address-position-select').prop("disabled", false);
6136		$('#address-group-select').prop("disabled", false);
6137		$('select[name="tx_addressmanager_jsonapi[groupSelect]"]').prop("disabled", false);
6138		$("#address-position-select").attr('disabled',false); 
6139	});
6140	$('.custom-string').keyup(function(){
6141		$('#address-position-select').prop("disabled", false);
6142		$('#address-group-select').prop("disabled", false);
6143		$('select[name="tx_addressmanager_jsonapi[groupSelect]"]').prop("disabled", false);
6144		$("#address-position-select").attr('disabled',false); 
6145	});
6146	
6147	var langValue = $('html').attr('lang');
6148
6149	if(langValue=='ar'){
6150		jQuery('.previous a').attr('title','الصفحة السابقة')
6151		jQuery('.next a').attr('title','الصفحة التالية')
6152	}
6153	
6154});
6155
6156/**
6157 * Fetch user geo location on button click and submit search form.
6158 *
6159 * Example button:
6160 * <div id="get-location-button" data-location-text="Eigener Standort">Get location</div>
6161 *
6162 */
6163var AddressManagerGetGeoLocation = {
6164
6165    /**
6166     *
6167     */
6168    eventType: 'click',
6169
6170    /**
6171     * Initiate the shop object
6172     */
6173    initialize: function () {
6174        //
6175        // Identify event type!
6176        if (jQuery('html.touch').length === 1) {
6177            AddressManagerGetGeoLocation.eventType = 'touchend';
6178        }
6179        //
6180        // Get geo location button
6181        let getLocationButton = jQuery('#get-location-button');
6182        if(getLocationButton.length > 0) {
6183            if (navigator.geolocation) {
6184                getLocationButton.on(AddressManagerGetGeoLocation.eventType, function() {
6185                    navigator.geolocation.getCurrentPosition(
6186                        AddressManagerGetGeoLocation.processCurrentPosition,
6187                        AddressManagerGetGeoLocation.processCurrentPositionError
6188                    );
6189                });
6190
6191            } else {
6192                // Geo location is not supported by current browser
6193                getLocationButton.hide();
6194            }
6195        }
6196    },
6197
6198    /**
6199     * Insert passed geo coordinates and request
6200     * @param location
6201     */
6202    processCurrentPosition: function(location) {
6203        // Insert values for page request
6204        jQuery('#address-latitude-field').val(location.coords.latitude);
6205        jQuery('#address-longitude-field').val(location.coords.longitude);
6206        // Insert values for AJAX request
6207        address_manager.searchData.tx_addressmanager_jsonapi.latitude = location.coords.latitude;
6208        address_manager.searchData.tx_addressmanager_jsonapi.longitude = location.coords.longitude;
6209        jQuery('#address-location-field').val(jQuery('#get-location-button').attr('data-location-text'));
6210        jQuery('#address-search-form').submit();
6211    },
6212
6213    /**
6214     * Error handling for geo location feature
6215     * @param error
6216     */
6217    processCurrentPositionError: function(error) {
6218        let message = '';
6219        switch(error.code) {
6220            case error.PERMISSION_DENIED:
6221                message = "User denied the request for Geolocation.";
6222                break;
6223            case error.POSITION_UNAVAILABLE:
6224                message = "Location information is unavailable.";
6225                break;
6226            case error.TIMEOUT:
6227                message = "The request to get user location timed out.";
6228                break;
6229            case error.UNKNOWN_ERROR:
6230                message = "An unknown error occurred.";
6231                break;
6232        }
6233        alert(message);
6234    }
6235
6236};
6237
6238jQuery(document).ready(function () {
6239    AddressManagerGetGeoLocation.initialize();
6240});

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.