PageSourceSearch

https://www.supertennis.tv/Areas/Supertennis/Scripts/frontend-init-min.js

js supertennis.tv collected 2026-09-24 09:39:50 UTC 170,859 bytes, 6,164 lines download raw bytes

1/*!
2 * Waves v0.6.4
3 * http://fian.my.id/Waves
4 *
5 * Copyright 2014 Alfiana E. Sibuea and other contributors
6 * Released under the MIT license
7 * https://github.com/fians/Waves/blob/master/LICENSE
8 */
9
10;(function(window) {
11    'use strict';
12
13    var waves_effect = "we";
14	
15	var wavesElement = document.getElementsByClassName("we");
16	if (wavesElement.length == 0) return;
17
18    var Waves = Waves || {};
19    var $$ = document.querySelectorAll.bind(document);
20
21    // Find exact position of element
22    function isWindow(obj) {
23        return obj !== null && obj === obj.window;
24    }
25
26    function getWindow(elem) {
27        return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
28    }
29
30    function offset(elem) {
31        var docElem, win,
32            box = {top: 0, left: 0},
33            doc = elem && elem.ownerDocument;
34
35        docElem = doc.documentElement;
36
37        if (typeof elem.getBoundingClientRect !== typeof undefined) {
38            box = elem.getBoundingClientRect();
39        }
40        win = getWindow(doc);
41        return {
42            top: box.top + win.pageYOffset - docElem.clientTop,
43            left: box.left + win.pageXOffset - docElem.clientLeft
44        };
45    }
46
47    function convertStyle(obj) {
48        var style = '';
49
50        for (var a in obj) {
51            if (obj.hasOwnProperty(a)) {
52                style += (a + ':' + obj[a] + ';');
53            }
54        }
55
56        return style;
57    }
58
59    var Effect = {
60
61        // Effect delay
62        duration: 750,
63
64        show: function(e, element) {
65
66            // Disable right click
67            if (e.button === 2) {
68                return false;
69            }
70
71            var el = element || this;
72
73            // Create ripple
74            var ripple = document.createElement('div');
75            ripple.className = 'waves-ripple';
76            el.appendChild(ripple);
77
78            // Get click coordinate and element witdh
79            var pos         = offset(el);
80            var relativeY   = (e.pageY - pos.top);
81            var relativeX   = (e.pageX - pos.left);
82            var scale       = 'scale('+((el.clientWidth / 100) * 10)+')';
83
84            // Support for touch devices
85            if ('touches' in e) {
86              relativeY   = (e.touches[0].pageY - pos.top);
87              relativeX   = (e.touches[0].pageX - pos.left);
88            }
89
90            // Attach data to element
91            ripple.setAttribute('data-hold', Date.now());
92            ripple.setAttribute('data-scale', scale);
93            ripple.setAttribute('data-x', relativeX);
94            ripple.setAttribute('data-y', relativeY);
95
96            // Set ripple position
97            var rippleStyle = {
98                'top': relativeY+'px',
99                'left': relativeX+'px'
100            };
101
102            ripple.className = ripple.className + ' waves-notransition';
103            ripple.setAttribute('style', convertStyle(rippleStyle));
104            ripple.className = ripple.className.replace('waves-notransition', '');
105
106            // Scale the ripple
107            rippleStyle['-webkit-transform'] = scale;
108            rippleStyle['-moz-transform'] = scale;
109            rippleStyle['-ms-transform'] = scale;
110            rippleStyle['-o-transform'] = scale;
111            rippleStyle.transform = scale;
112            rippleStyle.opacity   = '1';
113
114            rippleStyle['-webkit-transition-duration'] = Effect.duration + 'ms';
115            rippleStyle['-moz-transition-duration']    = Effect.duration + 'ms';
116            rippleStyle['-o-transition-duration']      = Effect.duration + 'ms';
117            rippleStyle['transition-duration']         = Effect.duration + 'ms';
118
119            rippleStyle['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
120            rippleStyle['-moz-transition-timing-function']    = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
121            rippleStyle['-o-transition-timing-function']      = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
122            rippleStyle['transition-timing-function']         = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
123
124            ripple.setAttribute('style', convertStyle(rippleStyle));
125        },
126
127        hide: function(e) {
128            TouchHandler.touchup(e);
129
130            var el = this;
131            var width = el.clientWidth * 1.4;
132
133            // Get first ripple
134            var ripple = null;
135            var ripples = el.getElementsByClassName('waves-ripple');
136            if (ripples.length > 0) {
137                ripple = ripples[ripples.length - 1];
138            } else {
139                return false;
140            }
141
142            var relativeX   = ripple.getAttribute('data-x');
143            var relativeY   = ripple.getAttribute('data-y');
144            var scale       = ripple.getAttribute('data-scale');
145
146            // Get delay beetween mousedown and mouse leave
147            var diff = Date.now() - Number(ripple.getAttribute('data-hold'));
148            var delay = 350 - diff;
149
150            if (delay < 0) {
151                delay = 0;
152            }
153
154            // Fade out ripple after delay
155            setTimeout(function() {
156                var style = {
157                    'top': relativeY+'px',
158                    'left': relativeX+'px',
159                    'opacity': '0',
160
161                    // Duration
162                    '-webkit-transition-duration': Effect.duration + 'ms',
163                    '-moz-transition-duration': Effect.duration + 'ms',
164                    '-o-transition-duration': Effect.duration + 'ms',
165                    'transition-duration': Effect.duration + 'ms',
166                    '-webkit-transform': scale,
167                    '-moz-transform': scale,
168                    '-ms-transform': scale,
169                    '-o-transform': scale,
170                    'transform': scale,
171                };
172
173                ripple.setAttribute('style', convertStyle(style));
174
175                setTimeout(function() {
176                    try {
177                        el.removeChild(ripple);
178                    } catch(e) {
179                        return false;
180                    }
181                }, Effect.duration);
182            }, delay);
183        },
184
185        // Little hack to make <input> can perform waves effect
186        wrapInput: function(elements) {
187            for (var a = 0; a < elements.length; a++) {
188                var el = elements[a];
189
190                if (el.tagName.toLowerCase() === 'input') {
191                    var parent = el.parentNode;
192
193                    // If input already have parent just pass through
194                    if (parent.tagName.toLowerCase() === 'i' && parent.className.indexOf(waves_effect) !== -1) {
195                        continue;
196                    }
197
198                    // Put element class and style to the specified parent
199                    var wrapper = document.createElement('i');
200                    wrapper.className = el.className + ' waves-input-wrapper';
201
202                    var elementStyle = el.getAttribute('style');
203
204                    if (!elementStyle) {
205                        elementStyle = '';
206                    }
207
208                    wrapper.setAttribute('style', elementStyle);
209
210                    el.className = 'waves-button-input';
211                    el.removeAttribute('style');
212
213                    // Put element as child
214                    parent.replaceChild(wrapper, el);
215                    wrapper.appendChild(el);
216                }
217            }
218        }
219    };
220
221
222    /**
223     * Disable mousedown event for 500ms during and after touch
224     */
225    var TouchHandler = {
226        /* uses an integer rather than bool so there's no issues with
227         * needing to clear timeouts if another touch event occurred
228         * within the 500ms. Cannot mouseup between touchstart and
229         * touchend, nor in the 500ms after touchend. */
230        touches: 0,
231        allowEvent: function(e) {
232            var allow = true;
233
234            if (e.type === 'touchstart') {
235                TouchHandler.touches += 1; //push
236            } else if (e.type === 'touchend' || e.type === 'touchcancel') {
237                setTimeout(function() {
238                    if (TouchHandler.touches > 0) {
239                        TouchHandler.touches -= 1; //pop after 500ms
240                    }
241                }, 500);
242            } else if (e.type === 'mousedown' && TouchHandler.touches > 0) {
243                allow = false;
244            }
245
246            return allow;
247        },
248        touchup: function(e) {
249            TouchHandler.allowEvent(e);
250        }
251    };
252
253
254    /**
255     * Delegated click handler for .waves-effect element.
256     * returns null when .waves-effect element not in "click tree"
257     */
258    function getWavesEffectElement(e) {
259        if (TouchHandler.allowEvent(e) === false) {
260            return null;
261        }
262
263        var element = null;
264        var target = e.target || e.srcElement;
265
266        while (target.parentNode !== null) {
267            if (!(target instanceof SVGElement) && target.className.indexOf(waves_effect) !== -1) {
268                element = target;
269                break;
270            }
271            target = target.parentNode;
272        }
273        return element;
274    }
275
276    /**
277     * Bubble the click and show effect if .waves-effect elem was found
278     */
279    function showEffect(e) {
280        var element = getWavesEffectElement(e);
281
282        if (element !== null) {
283            Effect.show(e, element);
284
285            if ('ontouchstart' in window) {
286                element.addEventListener('touchend', Effect.hide, false);
287                element.addEventListener('touchcancel', Effect.hide, false);
288            }
289
290            element.addEventListener('mouseup', Effect.hide, false);
291            element.addEventListener('mouseleave', Effect.hide, false);
292            element.addEventListener('dragend', Effect.hide, false);
293        }
294    }
295
296    Waves.displayEffect = function(options) {
297        options = options || {};
298
299        if ('duration' in options) {
300            Effect.duration = options.duration;
301        }
302
303        //Wrap input inside <i> tag
304        Effect.wrapInput($$('.we'));
305
306        if ('ontouchstart' in window) {
307            document.body.addEventListener('touchstart', showEffect, false);
308        }
309
310        document.body.addEventListener('mousedown', showEffect, false);
311    };
312
313    /**
314     * Attach Waves to an input element (or any element which doesn't
315     * bubble mouseup/mousedown events).
316     *   Intended to be used with dynamically loaded forms/inputs, or
317     * where the user doesn't want a delegated click handler.
318     */
319    Waves.attach = function(element) {
320        //FUTURE: automatically add waves classes and allow users
321        // to specify them with an options param? Eg. light/classic/button
322        if (element.tagName.toLowerCase() === 'input') {
323            Effect.wrapInput([element]);
324            element = element.parentNode;
325        }
326
327        if ('ontouchstart' in window) {
328            element.addEventListener('touchstart', showEffect, false);
329        }
330
331        element.addEventListener('mousedown', showEffect, false);
332    };
333
334    window.Waves = Waves;
335
336    document.addEventListener('DOMContentLoaded', function() {
337        Waves.displayEffect();
338    }, false);
339
340})(window);
341
342
343/*
344 _ _      _       _
345 ___| (_) ___| | __  (_)___
346 / __| | |/ __| |/ /  | / __|
347 \__ \ | | (__|   < _ | \__ \
348 |___/_|_|\___|_|\_(_)/ |___/
349 |__/
350
351 Version: 1.6.0
352 Author: Ken Wheeler
353 Website: http://kenwheeler.github.io
354 Docs: http://kenwheeler.github.io/slick
355 Repo: http://github.com/kenwheeler/slick
356 Issues: http://github.com/kenwheeler/slick/issues
357
358 */
359/* global window, document, define, jQuery, setInterval, clearInterval */
360(function(factory) {
361	'use strict';
362	if (typeof define === 'function' && define.amd) {
363		define(['jquery'], factory);
364	} else if (typeof exports !== 'undefined') {
365		module.exports = factory(require('jquery'));
366	} else {
367		factory(jQuery);
368	}
369
370}(function($) {
371	'use strict';
372	var Slick = window.Slick || {};
373
374	Slick = (function() {
375
376		var instanceUid = 0;
377
378		function Slick(element, settings) {
379
380			var _ = this, dataSettings;
381
382			_.defaults = {
383				accessibility: true,
384				adaptiveHeight: false,
385				appendArrows: $(element),
386				appendDots: $(element),
387				arrows: true,
388				asNavFor: null,
389				prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',
390				nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',
391				autoplay: false,
392				autoplaySpeed: 3000,
393				centerMode: false,
394				centerPadding: '50px',
395				cssEase: 'ease',
396				customPaging: function(slider, i) {
397					return $('<button type="button" data-role="none" role="button" tabindex="0" />').text(i + 1);
398				},
399				dots: false,
400				dotsClass: 'slick-dots',
401				draggable: true,
402				easing: 'linear',
403				edgeFriction: 0.35,
404				fade: false,
405				focusOnSelect: false,
406				infinite: true,
407				initialSlide: 0,
408				lazyLoad: 'ondemand',
409				mobileFirst: false,
410				pauseOnHover: true,
411				pauseOnFocus: true,
412				pauseOnDotsHover: false,
413				respondTo: 'window',
414				responsive: null,
415				rows: 1,
416				rtl: false,
417				slide: '',
418				slidesPerRow: 1,
419				slidesToShow: 1,
420				slidesToScroll: 1,
421				speed: 500,
422				swipe: true,
423				swipeToSlide: false,
424				touchMove: true,
425				touchThreshold: 5,
426				useCSS: true,
427				useTransform: true,
428				variableWidth: false,
429				vertical: false,
430				verticalSwiping: false,
431				waitForAnimate: true,
432				zIndex: 1000
433			};
434
435			_.initials = {
436				animating: false,
437				dragging: false,
438				autoPlayTimer: null,
439				currentDirection: 0,
440				currentLeft: null,
441				currentSlide: 0,
442				direction: 1,
443				$dots: null,
444				listWidth: null,
445				listHeight: null,
446				loadIndex: 0,
447				$nextArrow: null,
448				$prevArrow: null,
449				slideCount: null,
450				slideWidth: null,
451				$slideTrack: null,
452				$slides: null,
453				sliding: false,
454				slideOffset: 0,
455				swipeLeft: null,
456				$list: null,
457				touchObject: {},
458				transformsEnabled: false,
459				unslicked: false
460			};
461
462			$.extend(_, _.initials);
463
464			_.activeBreakpoint = null;
465			_.animType = null;
466			_.animProp = null;
467			_.breakpoints = [];
468			_.breakpointSettings = [];
469			_.cssTransitions = false;
470			_.focussed = false;
471			_.interrupted = false;
472			_.hidden = 'hidden';
473			_.paused = true;
474			_.positionProp = null;
475			_.respondTo = null;
476			_.rowCount = 1;
477			_.shouldClick = true;
478			_.$slider = $(element);
479			_.$slidesCache = null;
480			_.transformType = null;
481			_.transitionType = null;
482			_.visibilityChange = 'visibilitychange';
483			_.windowWidth = 0;
484			_.windowTimer = null;
485
486			dataSettings = $(element).data('slick') || {};
487
488			_.options = $.extend({}, _.defaults, settings, dataSettings);
489
490			_.currentSlide = _.options.initialSlide;
491
492			_.originalSettings = _.options;
493
494			if (typeof document.mozHidden !== 'undefined') {
495				_.hidden = 'mozHidden';
496				_.visibilityChange = 'mozvisibilitychange';
497			} else if (typeof document.webkitHidden !== 'undefined') {
498				_.hidden = 'webkitHidden';
499				_.visibilityChange = 'webkitvisibilitychange';
500			}
501
502			_.autoPlay = $.proxy(_.autoPlay, _);
503			_.autoPlayClear = $.proxy(_.autoPlayClear, _);
504			_.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
505			_.changeSlide = $.proxy(_.changeSlide, _);
506			_.clickHandler = $.proxy(_.clickHandler, _);
507			_.selectHandler = $.proxy(_.selectHandler, _);
508			_.setPosition = $.proxy(_.setPosition, _);
509			_.swipeHandler = $.proxy(_.swipeHandler, _);
510			_.dragHandler = $.proxy(_.dragHandler, _);
511			_.keyHandler = $.proxy(_.keyHandler, _);
512
513			_.instanceUid = instanceUid++;
514
515			// A simple way to check for HTML strings
516			// Strict HTML recognition (must start with <)
517			// Extracted from jQuery v1.11 source
518			_.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
519
520
521			_.registerBreakpoints();
522			_.init(true);
523
524		}
525
526		return Slick;
527
528	}());
529
530	Slick.prototype.activateADA = function() {
531		var _ = this;
532
533		_.$slideTrack.find('.slick-active').attr({
534			'aria-hidden': 'false'
535		}).find('a, input, button, select').attr({
536			'tabindex': '0'
537		});
538
539	};
540
541	Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
542
543		var _ = this;
544
545		if (typeof(index) === 'boolean') {
546			addBefore = index;
547			index = null;
548		} else if (index < 0 || (index >= _.slideCount)) {
549			return false;
550		}
551
552		_.unload();
553
554		if (typeof(index) === 'number') {
555			if (index === 0 && _.$slides.length === 0) {
556				$(markup).appendTo(_.$slideTrack);
557			} else if (addBefore) {
558				$(markup).insertBefore(_.$slides.eq(index));
559			} else {
560				$(markup).insertAfter(_.$slides.eq(index));
561			}
562		} else {
563			if (addBefore === true) {
564				$(markup).prependTo(_.$slideTrack);
565			} else {
566				$(markup).appendTo(_.$slideTrack);
567			}
568		}
569
570		_.$slides = _.$slideTrack.children(this.options.slide);
571
572		_.$slideTrack.children(this.options.slide).detach();
573
574		_.$slideTrack.append(_.$slides);
575
576		_.$slides.each(function(index, element) {
577			$(element).attr('data-slick-index', index);
578		});
579
580		_.$slidesCache = _.$slides;
581
582		_.reinit();
583
584	};
585
586	Slick.prototype.animateHeight = function() {
587		var _ = this;
588		if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
589			var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
590			_.$list.animate({
591				height: targetHeight
592			}, _.options.speed);
593		}
594	};
595
596	Slick.prototype.animateSlide = function(targetLeft, callback) {
597
598		var animProps = {},
599			_ = this;
600
601		_.animateHeight();
602
603		if (_.options.rtl === true && _.options.vertical === false) {
604			targetLeft = -targetLeft;
605		}
606		if (_.transformsEnabled === false) {
607			if (_.options.vertical === false) {
608				_.$slideTrack.animate({
609					left: targetLeft
610				}, _.options.speed, _.options.easing, callback);
611			} else {
612				_.$slideTrack.animate({
613					top: targetLeft
614				}, _.options.speed, _.options.easing, callback);
615			}
616
617		} else {
618
619			if (_.cssTransitions === false) {
620				if (_.options.rtl === true) {
621					_.currentLeft = -(_.currentLeft);
622				}
623				$({
624					animStart: _.currentLeft
625				}).animate({
626					animStart: targetLeft
627				}, {
628					duration: _.options.speed,
629					easing: _.options.easing,
630					step: function(now) {
631						now = Math.ceil(now);
632						if (_.options.vertical === false) {
633							animProps[_.animType] = 'translate(' +
634								now + 'px, 0px)';
635							_.$slideTrack.css(animProps);
636						} else {
637							animProps[_.animType] = 'translate(0px,' +
638								now + 'px)';
639							_.$slideTrack.css(animProps);
640						}
641					},
642					complete: function() {
643						if (callback) {
644							callback.call();
645						}
646					}
647				});
648
649			} else {
650
651				_.applyTransition();
652				targetLeft = Math.ceil(targetLeft);
653
654				if (_.options.vertical === false) {
655					animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
656				} else {
657					animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
658				}
659				_.$slideTrack.css(animProps);
660
661				if (callback) {
662					setTimeout(function() {
663
664						_.disableTransition();
665
666						callback.call();
667					}, _.options.speed);
668				}
669
670			}
671
672		}
673
674	};
675
676	Slick.prototype.getNavTarget = function() {
677
678		var _ = this,
679			asNavFor = _.options.asNavFor;
680
681		if ( asNavFor && asNavFor !== null ) {
682			asNavFor = $(asNavFor).not(_.$slider);
683		}
684
685		return asNavFor;
686
687	};
688
689	Slick.prototype.asNavFor = function(index) {
690
691		var _ = this,
692			asNavFor = _.getNavTarget();
693
694		if ( asNavFor !== null && typeof asNavFor === 'object' ) {
695			asNavFor.each(function() {
696				var target = $(this).slick('getSlick');
697				if(!target.unslicked) {
698					target.slideHandler(index, true);
699				}
700			});
701		}
702
703	};
704
705	Slick.prototype.applyTransition = function(slide) {
706
707		var _ = this,
708			transition = {};
709
710		if (_.options.fade === false) {
711			transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
712		} else {
713			transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
714		}
715
716		if (_.options.fade === false) {
717			_.$slideTrack.css(transition);
718		} else {
719			_.$slides.eq(slide).css(transition);
720		}
721
722	};
723
724	Slick.prototype.autoPlay = function() {
725
726		var _ = this;
727
728		_.autoPlayClear();
729
730		if ( _.slideCount > _.options.slidesToShow ) {
731			_.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed );
732		}
733
734	};
735
736	Slick.prototype.autoPlayClear = function() {
737
738		var _ = this;
739
740		if (_.autoPlayTimer) {
741			clearInterval(_.autoPlayTimer);
742		}
743
744	};
745
746	Slick.prototype.autoPlayIterator = function() {
747
748		var _ = this,
749			slideTo = _.currentSlide + _.options.slidesToScroll;
750
751		if ( !_.paused && !_.interrupted && !_.focussed ) {
752
753			if ( _.options.infinite === false ) {
754
755				if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) {
756					_.direction = 0;
757				}
758
759				else if ( _.direction === 0 ) {
760
761					slideTo = _.currentSlide - _.options.slidesToScroll;
762
763					if ( _.currentSlide - 1 === 0 ) {
764						_.direction = 1;
765					}
766
767				}
768
769			}
770
771			_.slideHandler( slideTo );
772
773		}
774
775	};
776
777	Slick.prototype.buildArrows = function() {
778
779		var _ = this;
780
781		if (_.options.arrows === true ) {
782
783			_.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
784			_.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
785
786			if( _.slideCount > _.options.slidesToShow ) {
787
788				_.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
789				_.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
790
791				if (_.htmlExpr.test(_.options.prevArrow)) {
792					_.$prevArrow.prependTo(_.options.appendArrows);
793				}
794
795				if (_.htmlExpr.test(_.options.nextArrow)) {
796					_.$nextArrow.appendTo(_.options.appendArrows);
797				}
798
799				if (_.options.infinite !== true) {
800					_.$prevArrow
801						.addClass('slick-disabled')
802						.attr('aria-disabled', 'true')
803						.attr('disabled', 'disabled');
804				}
805
806			} else {
807
808				_.$prevArrow.add( _.$nextArrow )
809
810					.addClass('slick-hidden')
811					.attr({
812						'aria-disabled': 'true',
813						'disabled': 'disabled',
814						'tabindex': '-1'
815					});
816
817			}
818
819		}
820
821	};
822
823	Slick.prototype.buildDots = function() {
824
825		var _ = this,
826			i, dot;
827
828		if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
829
830			_.$slider.addClass('slick-dotted');
831
832			dot = $('<ul />').addClass(_.options.dotsClass);
833
834			for (i = 0; i <= _.getDotCount(); i += 1) {
835				dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
836			}
837
838			_.$dots = dot.appendTo(_.options.appendDots);
839
840			_.$dots.find('li').first().addClass('slick-active').attr('aria-hidden', 'false');
841
842		}
843
844	};
845
846	Slick.prototype.buildOut = function() {
847
848		var _ = this;
849
850		_.$slides =
851			_.$slider
852				.children( _.options.slide + ':not(.slick-cloned)')
853				.addClass('slick-slide');
854
855		_.slideCount = _.$slides.length;
856
857		_.$slides.each(function(index, element) {
858			$(element)
859				.attr('data-slick-index', index)
860				.data('originalStyling', $(element).attr('style') || '');
861		});
862
863		_.$slider.addClass('slick-slider');
864
865		_.$slideTrack = (_.slideCount === 0) ?
866			$('<div class="slick-track"/>').appendTo(_.$slider) :
867			_.$slides.wrapAll('<div class="slick-track"/>').parent();
868
869		_.$list = _.$slideTrack.wrap(
870			'<div aria-live="polite" class="slick-list"/>').parent();
871		_.$slideTrack.css('opacity', 0);
872
873		if (_.options.centerMode === true || _.options.swipeToSlide === true) {
874			_.options.slidesToScroll = 1;
875		}
876
877		$('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
878
879		_.setupInfinite();
880
881		_.buildArrows();
882
883		_.buildDots();
884
885		_.updateDots();
886
887
888		_.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
889
890		if (_.options.draggable === true) {
891			_.$list.addClass('draggable');
892		}
893
894	};
895
896	Slick.prototype.buildRows = function() {
897
898		var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection;
899
900		newSlides = document.createDocumentFragment();
901		originalSlides = _.$slider.children();
902
903		if(_.options.rows > 1) {
904
905			slidesPerSection = _.options.slidesPerRow * _.options.rows;
906			numOfSlides = Math.ceil(
907				originalSlides.length / slidesPerSection
908			);
909
910			for(a = 0; a < numOfSlides; a++){
911				var slide = document.createElement('div');
912				for(b = 0; b < _.options.rows; b++) {
913					var row = document.createElement('div');
914					for(c = 0; c < _.options.slidesPerRow; c++) {
915						var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
916						if (originalSlides.get(target)) {
917							row.appendChild(originalSlides.get(target));
918						}
919					}
920					slide.appendChild(row);
921				}
922				newSlides.appendChild(slide);
923			}
924
925			_.$slider.empty().append(newSlides);
926			_.$slider.children().children().children()
927				.css({
928					'width':(100 / _.options.slidesPerRow) + '%',
929					'display': 'inline-block'
930				});
931
932		}
933
934	};
935
936	Slick.prototype.checkResponsive = function(initial, forceUpdate) {
937
938		var _ = this,
939			breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
940		var sliderWidth = _.$slider.width();
941		var windowWidth = window.innerWidth || $(window).width();
942
943		if (_.respondTo === 'window') {
944			respondToWidth = windowWidth;
945		} else if (_.respondTo === 'slider') {
946			respondToWidth = sliderWidth;
947		} else if (_.respondTo === 'min') {
948			respondToWidth = Math.min(windowWidth, sliderWidth);
949		}
950
951		if ( _.options.responsive &&
952			_.options.responsive.length &&
953			_.options.responsive !== null) {
954
955			targetBreakpoint = null;
956
957			for (breakpoint in _.breakpoints) {
958				if (_.breakpoints.hasOwnProperty(breakpoint)) {
959					if (_.originalSettings.mobileFirst === false) {
960						if (respondToWidth < _.breakpoints[breakpoint]) {
961							targetBreakpoint = _.breakpoints[breakpoint];
962						}
963					} else {
964						if (respondToWidth > _.breakpoints[breakpoint]) {
965							targetBreakpoint = _.breakpoints[breakpoint];
966						}
967					}
968				}
969			}
970
971			if (targetBreakpoint !== null) {
972				if (_.activeBreakpoint !== null) {
973					if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
974						_.activeBreakpoint =
975							targetBreakpoint;
976						if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
977							_.unslick(targetBreakpoint);
978						} else {
979							_.options = $.extend({}, _.originalSettings,
980								_.breakpointSettings[
981									targetBreakpoint]);
982							if (initial === true) {
983								_.currentSlide = _.options.initialSlide;
984							}
985							_.refresh(initial);
986						}
987						triggerBreakpoint = targetBreakpoint;
988					}
989				} else {
990					_.activeBreakpoint = targetBreakpoint;
991					if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
992						_.unslick(targetBreakpoint);
993					} else {
994						_.options = $.extend({}, _.originalSettings,
995							_.breakpointSettings[
996								targetBreakpoint]);
997						if (initial === true) {
998							_.currentSlide = _.options.initialSlide;
999						}
1000						_.refresh(initial);
1001					}
1002					triggerBreakpoint = targetBreakpoint;
1003				}
1004			} else {
1005				if (_.activeBreakpoint !== null) {
1006					_.activeBreakpoint = null;
1007					_.options = _.originalSettings;
1008					if (initial === true) {
1009						_.currentSlide = _.options.initialSlide;
1010					}
1011					_.refresh(initial);
1012					triggerBreakpoint = targetBreakpoint;
1013				}
1014			}
1015
1016			// only trigger breakpoints during an actual break. not on initialize.
1017			if( !initial && triggerBreakpoint !== false ) {
1018				_.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
1019			}
1020		}
1021
1022	};
1023
1024	Slick.prototype.changeSlide = function(event, dontAnimate) {
1025
1026		var _ = this,
1027			$target = $(event.currentTarget),
1028			indexOffset, slideOffset, unevenOffset;
1029
1030		// If target is a link, prevent default action.
1031		if($target.is('a')) {
1032			event.preventDefault();
1033		}
1034
1035		// If target is not the <li> element (ie: a child), find the <li>.
1036		if(!$target.is('li')) {
1037			$target = $target.closest('li');
1038		}
1039
1040		unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
1041		indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
1042
1043		switch (event.data.message) {
1044
1045			case 'previous':
1046				slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
1047				if (_.slideCount > _.options.slidesToShow) {
1048					_.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
1049				}
1050				break;
1051
1052			case 'next':
1053				slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
1054				if (_.slideCount > _.options.slidesToShow) {
1055					_.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
1056				}
1057				break;
1058
1059			case 'index':
1060				var index = event.data.index === 0 ? 0 :
1061				event.data.index || $target.index() * _.options.slidesToScroll;
1062
1063				_.slideHandler(_.checkNavigable(index), false, dontAnimate);
1064				$target.children().trigger('focus');
1065				break;
1066
1067			default:
1068				return;
1069		}
1070
1071	};
1072
1073	Slick.prototype.checkNavigable = function(index) {
1074
1075		var _ = this,
1076			navigables, prevNavigable;
1077
1078		navigables = _.getNavigableIndexes();
1079		prevNavigable = 0;
1080		if (index > navigables[navigables.length - 1]) {
1081			index = navigables[navigables.length - 1];
1082		} else {
1083			for (var n in navigables) {
1084				if (index < navigables[n]) {
1085					index = prevNavigable;
1086					break;
1087				}
1088				prevNavigable = navigables[n];
1089			}
1090		}
1091
1092		return index;
1093	};
1094
1095	Slick.prototype.cleanUpEvents = function() {
1096
1097		var _ = this;
1098
1099		if (_.options.dots && _.$dots !== null) {
1100
1101			$('li', _.$dots)
1102				.off('click.slick', _.changeSlide)
1103				.off('mouseenter.slick', $.proxy(_.interrupt, _, true))
1104				.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
1105
1106		}
1107
1108		_.$slider.off('focus.slick blur.slick');
1109
1110		if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
1111			_.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
1112			_.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
1113		}
1114
1115		_.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
1116		_.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
1117		_.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
1118		_.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
1119
1120		_.$list.off('click.slick', _.clickHandler);
1121
1122		$(document).off(_.visibilityChange, _.visibility);
1123
1124		_.cleanUpSlideEvents();
1125
1126		if (_.options.accessibility === true) {
1127			_.$list.off('keydown.slick', _.keyHandler);
1128		}
1129
1130		if (_.options.focusOnSelect === true) {
1131			$(_.$slideTrack).children().off('click.slick', _.selectHandler);
1132		}
1133
1134		$(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
1135
1136		$(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
1137
1138		$('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
1139
1140		$(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
1141		$(document).off('ready.slick.slick-' + _.instanceUid, _.setPosition);
1142
1143	};
1144
1145	Slick.prototype.cleanUpSlideEvents = function() {
1146
1147		var _ = this;
1148
1149		_.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
1150		_.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
1151
1152	};
1153
1154	Slick.prototype.cleanUpRows = function() {
1155
1156		var _ = this, originalSlides;
1157
1158		if(_.options.rows > 1) {
1159			originalSlides = _.$slides.children().children();
1160			originalSlides.removeAttr('style');
1161			_.$slider.empty().append(originalSlides);
1162		}
1163
1164	};
1165
1166	Slick.prototype.clickHandler = function(event) {
1167
1168		var _ = this;
1169
1170		if (_.shouldClick === false) {
1171			event.stopImmediatePropagation();
1172			event.stopPropagation();
1173			event.preventDefault();
1174		}
1175
1176	};
1177
1178	Slick.prototype.destroy = function(refresh) {
1179
1180		var _ = this;
1181
1182		_.autoPlayClear();
1183
1184		_.touchObject = {};
1185
1186		_.cleanUpEvents();
1187
1188		$('.slick-cloned', _.$slider).detach();
1189
1190		if (_.$dots) {
1191			_.$dots.remove();
1192		}
1193
1194
1195		if ( _.$prevArrow && _.$prevArrow.length ) {
1196
1197			_.$prevArrow
1198				.removeClass('slick-disabled slick-arrow slick-hidden')
1199				.removeAttr('aria-hidden aria-disabled disabled tabindex')
1200				.css('display','');
1201
1202			if ( _.htmlExpr.test( _.options.prevArrow )) {
1203				_.$prevArrow.remove();
1204			}
1205		}
1206
1207		if ( _.$nextArrow && _.$nextArrow.length ) {
1208
1209			_.$nextArrow
1210				.removeClass('slick-disabled slick-arrow slick-hidden')
1211				.removeAttr('aria-hidden aria-disabled disabled tabindex')
1212				.css('display','');
1213
1214			if ( _.htmlExpr.test( _.options.nextArrow )) {
1215				_.$nextArrow.remove();
1216			}
1217
1218		}
1219
1220
1221		if (_.$slides) {
1222
1223			_.$slides
1224				.removeClass('slick-slide slick-active slick-center slick-visible slick-current')
1225				.removeAttr('aria-hidden')
1226				.removeAttr('data-slick-index')
1227				.each(function(){
1228					$(this).attr('style', $(this).data('originalStyling'));
1229				});
1230
1231			_.$slideTrack.children(this.options.slide).detach();
1232
1233			_.$slideTrack.detach();
1234
1235			_.$list.detach();
1236
1237			_.$slider.append(_.$slides);
1238		}
1239
1240		_.cleanUpRows();
1241
1242		_.$slider.removeClass('slick-slider');
1243		_.$slider.removeClass('slick-initialized');
1244		_.$slider.removeClass('slick-dotted');
1245
1246		_.unslicked = true;
1247
1248		if(!refresh) {
1249			_.$slider.trigger('destroy', [_]);
1250		}
1251
1252	};
1253
1254	Slick.prototype.disableTransition = function(slide) {
1255
1256		var _ = this,
1257			transition = {};
1258
1259		transition[_.transitionType] = '';
1260
1261		if (_.options.fade === false) {
1262			_.$slideTrack.css(transition);
1263		} else {
1264			_.$slides.eq(slide).css(transition);
1265		}
1266
1267	};
1268
1269	Slick.prototype.fadeSlide = function(slideIndex, callback) {
1270
1271		var _ = this;
1272
1273		if (_.cssTransitions === false) {
1274
1275			_.$slides.eq(slideIndex).css({
1276				zIndex: _.options.zIndex
1277			});
1278
1279			_.$slides.eq(slideIndex).animate({
1280				opacity: 1
1281			}, _.options.speed, _.options.easing, callback);
1282
1283		} else {
1284
1285			_.applyTransition(slideIndex);
1286
1287			_.$slides.eq(slideIndex).css({
1288				opacity: 1,
1289				zIndex: _.options.zIndex
1290			});
1291
1292			if (callback) {
1293				setTimeout(function() {
1294
1295					_.disableTransition(slideIndex);
1296
1297					callback.call();
1298				}, _.options.speed);
1299			}
1300
1301		}
1302
1303	};
1304
1305	Slick.prototype.fadeSlideOut = function(slideIndex) {
1306
1307		var _ = this;
1308
1309		if (_.cssTransitions === false) {
1310
1311			_.$slides.eq(slideIndex).animate({
1312				opacity: 0,
1313				zIndex: _.options.zIndex - 2
1314			}, _.options.speed, _.options.easing);
1315
1316		} else {
1317
1318			_.applyTransition(slideIndex);
1319
1320			_.$slides.eq(slideIndex).css({
1321				opacity: 0,
1322				zIndex: _.options.zIndex - 2
1323			});
1324
1325		}
1326
1327	};
1328
1329	Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) {
1330
1331		var _ = this;
1332
1333		if (filter !== null) {
1334
1335			_.$slidesCache = _.$slides;
1336
1337			_.unload();
1338
1339			_.$slideTrack.children(this.options.slide).detach();
1340
1341			_.$slidesCache.filter(filter).appendTo(_.$slideTrack);
1342
1343			_.reinit();
1344
1345		}
1346
1347	};
1348
1349	Slick.prototype.focusHandler = function() {
1350
1351		var _ = this;
1352
1353		_.$slider
1354			.off('focus.slick blur.slick')
1355			.on('focus.slick blur.slick',
1356				'*:not(.slick-arrow)', function(event) {
1357
1358					event.stopImmediatePropagation();
1359					var $sf = $(this);
1360
1361					setTimeout(function() {
1362
1363						if( _.options.pauseOnFocus ) {
1364							_.focussed = $sf.is(':focus');
1365							_.autoPlay();
1366						}
1367
1368					}, 0);
1369
1370				});
1371	};
1372
1373	Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() {
1374
1375		var _ = this;
1376		return _.currentSlide;
1377
1378	};
1379
1380	Slick.prototype.getDotCount = function() {
1381
1382		var _ = this;
1383
1384		var breakPoint = 0;
1385		var counter = 0;
1386		var pagerQty = 0;
1387
1388		if (_.options.infinite === true) {
1389			while (breakPoint < _.slideCount) {
1390				++pagerQty;
1391				breakPoint = counter + _.options.slidesToScroll;
1392				counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
1393			}
1394		} else if (_.options.centerMode === true) {
1395			pagerQty = _.slideCount;
1396		} else if(!_.options.asNavFor) {
1397			pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
1398		}else {
1399			while (breakPoint < _.slideCount) {
1400				++pagerQty;
1401				breakPoint = counter + _.options.slidesToScroll;
1402				counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
1403			}
1404		}
1405
1406		return pagerQty - 1;
1407
1408	};
1409
1410	Slick.prototype.getLeft = function(slideIndex) {
1411
1412		var _ = this,
1413			targetLeft,
1414			verticalHeight,
1415			verticalOffset = 0,
1416			targetSlide;
1417
1418		_.slideOffset = 0;
1419		verticalHeight = _.$slides.first().outerHeight(true);
1420
1421		if (_.options.infinite === true) {
1422			if (_.slideCount > _.options.slidesToShow) {
1423				_.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
1424				verticalOffset = (verticalHeight * _.options.slidesToShow) * -1;
1425			}
1426			if (_.slideCount % _.options.slidesToScroll !== 0) {
1427				if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
1428					if (slideIndex > _.slideCount) {
1429						_.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
1430						verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
1431					} else {
1432						_.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
1433						verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
1434					}
1435				}
1436			}
1437		} else {
1438			if (slideIndex + _.options.slidesToShow > _.slideCount) {
1439				_.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
1440				verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
1441			}
1442		}
1443
1444		if (_.slideCount <= _.options.slidesToShow) {
1445			_.slideOffset = 0;
1446			verticalOffset = 0;
1447		}
1448
1449		if (_.options.centerMode === true && _.options.infinite === true) {
1450			_.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
1451		} else if (_.options.centerMode === true) {
1452			_.slideOffset = 0;
1453			_.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
1454		}
1455
1456		if (_.options.vertical === false) {
1457			targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
1458		} else {
1459			targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
1460		}
1461
1462		if (_.options.variableWidth === true) {
1463
1464			if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
1465				targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
1466			} else {
1467				targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
1468			}
1469
1470			if (_.options.rtl === true) {
1471				if (targetSlide[0]) {
1472					targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
1473				} else {
1474					targetLeft =  0;
1475				}
1476			} else {
1477				targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
1478			}
1479
1480			if (_.options.centerMode === true) {
1481				if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
1482					targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
1483				} else {
1484					targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
1485				}
1486
1487				if (_.options.rtl === true) {
1488					if (targetSlide[0]) {
1489						targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
1490					} else {
1491						targetLeft =  0;
1492					}
1493				} else {
1494					targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
1495				}
1496
1497				targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
1498			}
1499		}
1500
1501		return targetLeft;
1502
1503	};
1504
1505	Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) {
1506
1507		var _ = this;
1508
1509		return _.options[option];
1510
1511	};
1512
1513	Slick.prototype.getNavigableIndexes = function () {
1514
1515		var _ = this, breakPoint = 0, counter = 0, indexes = [], max;
1516
1517		if (_.options.infinite === false) {
1518			max = _.slideCount - _.options.slidesToShow + 1;
1519			if (_.options.centerMode === true) max = _.slideCount;
1520		} else {
1521			breakPoint = _.slideCount * -1;
1522			counter = _.slideCount * -1;
1523			max = _.slideCount * 2;
1524		}
1525
1526		while (breakPoint < max) {
1527			indexes.push(breakPoint);
1528			breakPoint = counter + _.options.slidesToScroll;
1529			counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
1530		}
1531
1532		if (indexes.indexOf(_.slideCount - _.options.slidesToShow) === -1) indexes.push(_.slideCount - _.options.slidesToShow);
1533
1534		return indexes;
1535
1536	};
1537
1538	Slick.prototype.getSlick = function() {
1539
1540		return this;
1541
1542	};
1543
1544	Slick.prototype.getSlideCount = function() {
1545
1546		var _ = this,
1547			slidesTraversed, swipedSlide, centerOffset;
1548
1549		centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
1550
1551		if (_.options.swipeToSlide === true) {
1552			_.$slideTrack.find('.slick-slide').each(function(index, slide) {
1553				if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
1554					swipedSlide = slide;
1555					return false;
1556				}
1557			});
1558
1559			slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
1560
1561			return slidesTraversed;
1562
1563		} else {
1564			return _.options.slidesToScroll;
1565		}
1566
1567	};
1568
1569	Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) {
1570
1571		var _ = this;
1572
1573		_.changeSlide({
1574			data: {
1575				message: 'index',
1576				index: parseInt(slide)
1577			}
1578		}, dontAnimate);
1579
1580	};
1581
1582	Slick.prototype.init = function(creation) {
1583
1584		var _ = this;
1585
1586		if (!$(_.$slider).hasClass('slick-initialized')) {
1587
1588			$(_.$slider).addClass('slick-initialized');
1589
1590			_.buildRows();
1591			_.buildOut();
1592			_.setProps();
1593			_.startLoad();
1594			_.loadSlider();
1595			_.initializeEvents();
1596			_.updateArrows();
1597			_.updateDots();
1598			_.checkResponsive(true);
1599			_.focusHandler();
1600
1601		}
1602
1603		if (creation) {
1604			_.$slider.trigger('init', [_]);
1605		}
1606
1607		if (_.options.accessibility === true) {
1608			_.initADA();
1609		}
1610
1611		if ( _.options.autoplay ) {
1612
1613			_.paused = false;
1614			_.autoPlay();
1615
1616		}
1617
1618	};
1619
1620	Slick.prototype.initADA = function() {
1621		var _ = this;
1622		_.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
1623			'aria-hidden': 'true',
1624			'tabindex': '-1'
1625		}).find('a, input, button, select').attr({
1626			'tabindex': '-1'
1627		});
1628
1629		_.$slideTrack.attr('role', 'listbox');
1630
1631		_.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
1632			$(this).attr({
1633				'role': 'option',
1634				'aria-describedby': 'slick-slide' + _.instanceUid + i + ''
1635			});
1636		});
1637
1638		if (_.$dots !== null) {
1639			_.$dots.attr('role', 'tablist').find('li').each(function(i) {
1640				$(this).attr({
1641					'role': 'presentation',
1642					'aria-selected': 'false',
1643					'aria-controls': 'navigation' + _.instanceUid + i + '',
1644					'id': 'slick-slide' + _.instanceUid + i + ''
1645				});
1646			})
1647				.first().attr('aria-selected', 'true').end()
1648				.find('button').attr('role', 'button').end()
1649				.closest('div').attr('role', 'toolbar');
1650		}
1651		_.activateADA();
1652
1653	};
1654
1655	Slick.prototype.initArrowEvents = function() {
1656
1657		var _ = this;
1658
1659		if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
1660			_.$prevArrow
1661				.off('click.slick')
1662				.on('click.slick', {
1663					message: 'previous'
1664				}, _.changeSlide);
1665			_.$nextArrow
1666				.off('click.slick')
1667				.on('click.slick', {
1668					message: 'next'
1669				}, _.changeSlide);
1670		}
1671
1672	};
1673
1674	Slick.prototype.initDotEvents = function() {
1675
1676		var _ = this;
1677
1678		if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
1679			$('li', _.$dots).on('click.slick', {
1680				message: 'index'
1681			}, _.changeSlide);
1682		}
1683
1684		if ( _.options.dots === true && _.options.pauseOnDotsHover === true ) {
1685
1686			$('li', _.$dots)
1687				.on('mouseenter.slick', $.proxy(_.interrupt, _, true))
1688				.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
1689
1690		}
1691
1692	};
1693
1694	Slick.prototype.initSlideEvents = function() {
1695
1696		var _ = this;
1697
1698		if ( _.options.pauseOnHover ) {
1699
1700			_.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
1701			_.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
1702
1703		}
1704
1705	};
1706
1707	Slick.prototype.initializeEvents = function() {
1708
1709		var _ = this;
1710
1711		_.initArrowEvents();
1712
1713		_.initDotEvents();
1714		_.initSlideEvents();
1715
1716		_.$list.on('touchstart.slick mousedown.slick', {
1717			action: 'start'
1718		}, _.swipeHandler);
1719		_.$list.on('touchmove.slick mousemove.slick', {
1720			action: 'move'
1721		}, _.swipeHandler);
1722		_.$list.on('touchend.slick mouseup.slick', {
1723			action: 'end'
1724		}, _.swipeHandler);
1725		_.$list.on('touchcancel.slick mouseleave.slick', {
1726			action: 'end'
1727		}, _.swipeHandler);
1728
1729		_.$list.on('click.slick', _.clickHandler);
1730
1731		$(document).on(_.visibilityChange, $.proxy(_.visibility, _));
1732
1733		if (_.options.accessibility === true) {
1734			_.$list.on('keydown.slick', _.keyHandler);
1735		}
1736
1737		if (_.options.focusOnSelect === true) {
1738			$(_.$slideTrack).children().on('click.slick', _.selectHandler);
1739		}
1740
1741		$(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
1742
1743		$(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
1744
1745		$('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
1746
1747		$(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
1748		$(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
1749
1750	};
1751
1752	Slick.prototype.initUI = function() {
1753
1754		var _ = this;
1755
1756		if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
1757
1758			_.$prevArrow.show();
1759			_.$nextArrow.show();
1760
1761		}
1762
1763		if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
1764
1765			_.$dots.show();
1766
1767		}
1768
1769	};
1770
1771	Slick.prototype.keyHandler = function(event) {
1772
1773		var _ = this;
1774		//Dont slide if the cursor is inside the form fields and arrow keys are pressed
1775		if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
1776			if (event.keyCode === 37 && _.options.accessibility === true) {
1777				_.changeSlide({
1778					data: {
1779						message: _.options.rtl === true ? 'next' :  'previous'
1780					}
1781				});
1782			} else if (event.keyCode === 39 && _.options.accessibility === true) {
1783				_.changeSlide({
1784					data: {
1785						message: _.options.rtl === true ? 'previous' : 'next'
1786					}
1787				});
1788			}
1789		}
1790
1791	};
1792
1793	Slick.prototype.lazyLoad = function() {
1794
1795		var _ = this,
1796			loadRange, cloneRange, rangeStart, rangeEnd;
1797
1798		function loadImages(imagesScope) {
1799
1800			$('img[data-lazy]', imagesScope).each(function() {
1801
1802				var image = $(this),
1803					imageSource = $(this).attr('data-lazy'),
1804					imageToLoad = document.createElement('img');
1805
1806				imageToLoad.onload = function() {
1807
1808					image
1809						.animate({ opacity: 0 }, 100, function() {
1810							image
1811								.attr('src', imageSource)
1812								.animate({ opacity: 1 }, 200, function() {
1813									image
1814										.removeAttr('data-lazy')
1815										.removeClass('slick-loading');
1816								});
1817							_.$slider.trigger('lazyLoaded', [_, image, imageSource]);
1818						});
1819
1820				};
1821
1822				imageToLoad.onerror = function() {
1823
1824					image
1825						.removeAttr( 'data-lazy' )
1826						.removeClass( 'slick-loading' )
1827						.addClass( 'slick-lazyload-error' );
1828
1829					_.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
1830
1831				};
1832
1833				imageToLoad.src = imageSource;
1834
1835			});
1836
1837		}
1838
1839		if (_.options.centerMode === true) {
1840			if (_.options.infinite === true) {
1841				rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
1842				rangeEnd = rangeStart + _.options.slidesToShow + 2;
1843			} else {
1844				rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
1845				rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
1846			}
1847		} else {
1848			rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
1849			rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
1850			if (_.options.fade === true) {
1851				if (rangeStart > 0) rangeStart--;
1852				if (rangeEnd <= _.slideCount) rangeEnd++;
1853			}
1854		}
1855
1856		loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
1857		loadImages(loadRange);
1858
1859		if (_.slideCount <= _.options.slidesToShow) {
1860			cloneRange = _.$slider.find('.slick-slide');
1861			loadImages(cloneRange);
1862		} else
1863		if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
1864			cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
1865			loadImages(cloneRange);
1866		} else if (_.currentSlide === 0) {
1867			cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
1868			loadImages(cloneRange);
1869		}
1870
1871	};
1872
1873	Slick.prototype.loadSlider = function() {
1874
1875		var _ = this;
1876
1877		_.setPosition();
1878
1879		_.$slideTrack.css({
1880			opacity: 1
1881		});
1882
1883		_.$slider.removeClass('slick-loading');
1884
1885		_.initUI();
1886
1887		if (_.options.lazyLoad === 'progressive') {
1888			_.progressiveLazyLoad();
1889		}
1890
1891	};
1892
1893	Slick.prototype.next = Slick.prototype.slickNext = function() {
1894
1895		var _ = this;
1896
1897		_.changeSlide({
1898			data: {
1899				message: 'next'
1900			}
1901		});
1902
1903	};
1904
1905	Slick.prototype.orientationChange = function() {
1906
1907		var _ = this;
1908
1909		_.checkResponsive();
1910		_.setPosition();
1911
1912	};
1913
1914	Slick.prototype.pause = Slick.prototype.slickPause = function() {
1915
1916		var _ = this;
1917
1918		_.autoPlayClear();
1919		_.paused = true;
1920
1921	};
1922
1923	Slick.prototype.play = Slick.prototype.slickPlay = function() {
1924
1925		var _ = this;
1926
1927		_.autoPlay();
1928		_.options.autoplay = true;
1929		_.paused = false;
1930		_.focussed = false;
1931		_.interrupted = false;
1932
1933	};
1934
1935	Slick.prototype.postSlide = function(index) {
1936
1937		var _ = this;
1938
1939		if( !_.unslicked ) {
1940
1941			_.$slider.trigger('afterChange', [_, index]);
1942
1943			_.animating = false;
1944
1945			_.setPosition();
1946
1947			_.swipeLeft = null;
1948
1949			if ( _.options.autoplay ) {
1950				_.autoPlay();
1951			}
1952
1953			if (_.options.accessibility === true) {
1954				_.initADA();
1955			}
1956
1957		}
1958
1959	};
1960
1961	Slick.prototype.prev = Slick.prototype.slickPrev = function() {
1962
1963		var _ = this;
1964
1965		_.changeSlide({
1966			data: {
1967				message: 'previous'
1968			}
1969		});
1970
1971	};
1972
1973	Slick.prototype.preventDefault = function(event) {
1974
1975		event.preventDefault();
1976
1977	};
1978
1979	Slick.prototype.progressiveLazyLoad = function( tryCount ) {
1980
1981		tryCount = tryCount || 1;
1982
1983		var _ = this,
1984			$imgsToLoad = $( 'img[data-lazy]', _.$slider ),
1985			image,
1986			imageSource,
1987			imageToLoad;
1988
1989		if ( $imgsToLoad.length ) {
1990
1991			image = $imgsToLoad.first();
1992			imageSource = image.attr('data-lazy');
1993			imageToLoad = document.createElement('img');
1994
1995			imageToLoad.onload = function() {
1996
1997				image
1998					.attr( 'src', imageSource )
1999					.removeAttr('data-lazy')
2000					.removeClass('slick-loading');
2001
2002				if ( _.options.adaptiveHeight === true ) {
2003					_.setPosition();
2004				}
2005
2006				_.$slider.trigger('lazyLoaded', [ _, image, imageSource ]);
2007				_.progressiveLazyLoad();
2008
2009			};
2010
2011			imageToLoad.onerror = function() {
2012
2013				if ( tryCount < 3 ) {
2014
2015					/**
2016					 * try to load the image 3 times,
2017					 * leave a slight delay so we don't get
2018					 * servers blocking the request.
2019					 */
2020					setTimeout( function() {
2021						_.progressiveLazyLoad( tryCount + 1 );
2022					}, 500 );
2023
2024				} else {
2025
2026					image
2027						.removeAttr( 'data-lazy' )
2028						.removeClass( 'slick-loading' )
2029						.addClass( 'slick-lazyload-error' );
2030
2031					_.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
2032
2033					_.progressiveLazyLoad();
2034
2035				}
2036
2037			};
2038
2039			imageToLoad.src = imageSource;
2040
2041		} else {
2042
2043			_.$slider.trigger('allImagesLoaded', [ _ ]);
2044
2045		}
2046
2047	};
2048
2049	Slick.prototype.refresh = function( initializing ) {
2050
2051		var _ = this, currentSlide, lastVisibleIndex;
2052
2053		lastVisibleIndex = _.slideCount - _.options.slidesToShow;
2054
2055		// in non-infinite sliders, we don't want to go past the
2056		// last visible index.
2057		if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) {
2058			_.currentSlide = lastVisibleIndex;
2059		}
2060
2061		// if less slides than to show, go to start.
2062		if ( _.slideCount <= _.options.slidesToShow ) {
2063			_.currentSlide = 0;
2064
2065		}
2066
2067		currentSlide = _.currentSlide;
2068
2069		_.destroy(true);
2070
2071		$.extend(_, _.initials, { currentSlide: currentSlide });
2072
2073		_.init();
2074
2075		if( !initializing ) {
2076
2077			_.changeSlide({
2078				data: {
2079					message: 'index',
2080					index: currentSlide
2081				}
2082			}, false);
2083
2084		}
2085
2086	};
2087
2088	Slick.prototype.registerBreakpoints = function() {
2089
2090		var _ = this, breakpoint, currentBreakpoint, l,
2091			responsiveSettings = _.options.responsive || null;
2092
2093		if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) {
2094
2095			_.respondTo = _.options.respondTo || 'window';
2096
2097			for ( breakpoint in responsiveSettings ) {
2098
2099				l = _.breakpoints.length-1;
2100				currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
2101
2102				if (responsiveSettings.hasOwnProperty(breakpoint)) {
2103
2104					// loop through the breakpoints and cut out any existing
2105					// ones with the same breakpoint number, we don't want dupes.
2106					while( l >= 0 ) {
2107						if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) {
2108							_.breakpoints.splice(l,1);
2109						}
2110						l--;
2111					}
2112
2113					_.breakpoints.push(currentBreakpoint);
2114					_.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
2115
2116				}
2117
2118			}
2119
2120			_.breakpoints.sort(function(a, b) {
2121				return ( _.options.mobileFirst ) ? a-b : b-a;
2122			});
2123
2124		}
2125
2126	};
2127
2128	Slick.prototype.reinit = function() {
2129
2130		var _ = this;
2131
2132		_.$slides =
2133			_.$slideTrack
2134				.children(_.options.slide)
2135				.addClass('slick-slide');
2136
2137		_.slideCount = _.$slides.length;
2138
2139		if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
2140			_.currentSlide = _.currentSlide - _.options.slidesToScroll;
2141		}
2142
2143		if (_.slideCount <= _.options.slidesToShow) {
2144			_.currentSlide = 0;
2145		}
2146
2147		_.registerBreakpoints();
2148
2149		_.setProps();
2150		_.setupInfinite();
2151		_.buildArrows();
2152		_.updateArrows();
2153		_.initArrowEvents();
2154		_.buildDots();
2155		_.updateDots();
2156		_.initDotEvents();
2157		_.cleanUpSlideEvents();
2158		_.initSlideEvents();
2159
2160		_.checkResponsive(false, true);
2161
2162		if (_.options.focusOnSelect === true) {
2163			$(_.$slideTrack).children().on('click.slick', _.selectHandler);
2164		}
2165
2166		_.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
2167
2168		_.setPosition();
2169		_.focusHandler();
2170
2171		_.paused = !_.options.autoplay;
2172		_.autoPlay();
2173
2174		_.$slider.trigger('reInit', [_]);
2175
2176	};
2177
2178	Slick.prototype.resize = function() {
2179
2180		var _ = this;
2181
2182		if ($(window).width() !== _.windowWidth) {
2183			clearTimeout(_.windowDelay);
2184			_.windowDelay = window.setTimeout(function() {
2185				_.windowWidth = $(window).width();
2186				_.checkResponsive();
2187				if( !_.unslicked ) { _.setPosition(); }
2188			}, 50);
2189		}
2190	};
2191
2192	Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) {
2193
2194		var _ = this;
2195
2196		if (typeof(index) === 'boolean') {
2197			removeBefore = index;
2198			index = removeBefore === true ? 0 : _.slideCount - 1;
2199		} else {
2200			index = removeBefore === true ? --index : index;
2201		}
2202
2203		if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
2204			return false;
2205		}
2206
2207		_.unload();
2208
2209		if (removeAll === true) {
2210			_.$slideTrack.children().remove();
2211		} else {
2212			_.$slideTrack.children(this.options.slide).eq(index).remove();
2213		}
2214
2215		_.$slides = _.$slideTrack.children(this.options.slide);
2216
2217		_.$slideTrack.children(this.options.slide).detach();
2218
2219		_.$slideTrack.append(_.$slides);
2220
2221		_.$slidesCache = _.$slides;
2222
2223		_.reinit();
2224
2225	};
2226
2227	Slick.prototype.setCSS = function(position) {
2228
2229		var _ = this,
2230			positionProps = {},
2231			x, y;
2232
2233		if (_.options.rtl === true) {
2234			position = -position;
2235		}
2236		x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
2237		y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
2238
2239		positionProps[_.positionProp] = position;
2240
2241		if (_.transformsEnabled === false) {
2242			_.$slideTrack.css(positionProps);
2243		} else {
2244			positionProps = {};
2245			if (_.cssTransitions === false) {
2246				positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
2247				_.$slideTrack.css(positionProps);
2248			} else {
2249				positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
2250				_.$slideTrack.css(positionProps);
2251			}
2252		}
2253
2254	};
2255
2256	Slick.prototype.setDimensions = function() {
2257
2258		var _ = this;
2259
2260		if (_.options.vertical === false) {
2261			if (_.options.centerMode === true) {
2262				_.$list.css({
2263					padding: ('0px ' + _.options.centerPadding)
2264				});
2265			}
2266		} else {
2267			_.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
2268			if (_.options.centerMode === true) {
2269				_.$list.css({
2270					padding: (_.options.centerPadding + ' 0px')
2271				});
2272			}
2273		}
2274
2275		_.listWidth = _.$list.width();
2276		_.listHeight = _.$list.height();
2277
2278
2279		if (_.options.vertical === false && _.options.variableWidth === false) {
2280			_.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
2281			_.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
2282
2283		} else if (_.options.variableWidth === true) {
2284			_.$slideTrack.width(5000 * _.slideCount);
2285		} else {
2286			_.slideWidth = Math.ceil(_.listWidth);
2287			_.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
2288		}
2289
2290		var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
2291		if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
2292
2293	};
2294
2295	Slick.prototype.setFade = function() {
2296
2297		var _ = this,
2298			targetLeft;
2299
2300		_.$slides.each(function(index, element) {
2301			targetLeft = (_.slideWidth * index) * -1;
2302			if (_.options.rtl === true) {
2303				$(element).css({
2304					position: 'relative',
2305					right: targetLeft,
2306					top: 0,
2307					zIndex: _.options.zIndex - 2,
2308					opacity: 0
2309				});
2310			} else {
2311				$(element).css({
2312					position: 'relative',
2313					left: targetLeft,
2314					top: 0,
2315					zIndex: _.options.zIndex - 2,
2316					opacity: 0
2317				});
2318			}
2319		});
2320
2321		_.$slides.eq(_.currentSlide).css({
2322			zIndex: _.options.zIndex - 1,
2323			opacity: 1
2324		});
2325
2326	};
2327
2328	Slick.prototype.setHeight = function() {
2329
2330		var _ = this;
2331
2332		if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
2333			var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
2334			_.$list.css('height', targetHeight);
2335		}
2336
2337	};
2338
2339	Slick.prototype.setOption =
2340		Slick.prototype.slickSetOption = function() {
2341
2342			/**
2343			 * accepts arguments in format of:
2344			 *
2345			 *  - for changing a single option's value:
2346			 *     .slick("setOption", option, value, refresh )
2347			 *
2348			 *  - for changing a set of responsive options:
2349			 *     .slick("setOption", 'responsive', [{}, ...], refresh )
2350			 *
2351			 *  - for updating multiple values at once (not responsive)
2352			 *     .slick("setOption", { 'option': value, ... }, refresh )
2353			 */
2354
2355			var _ = this, l, item, option, value, refresh = false, type;
2356
2357			if( $.type( arguments[0] ) === 'object' ) {
2358
2359				option =  arguments[0];
2360				refresh = arguments[1];
2361				type = 'multiple';
2362
2363			} else if ( $.type( arguments[0] ) === 'string' ) {
2364
2365				option =  arguments[0];
2366				value = arguments[1];
2367				refresh = arguments[2];
2368
2369				if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) {
2370
2371					type = 'responsive';
2372
2373				} else if ( typeof arguments[1] !== 'undefined' ) {
2374
2375					type = 'single';
2376
2377				}
2378
2379			}
2380
2381			if ( type === 'single' ) {
2382
2383				_.options[option] = value;
2384
2385
2386			} else if ( type === 'multiple' ) {
2387
2388				$.each( option , function( opt, val ) {
2389
2390					_.options[opt] = val;
2391
2392				});
2393
2394
2395			} else if ( type === 'responsive' ) {
2396
2397				for ( item in value ) {
2398
2399					if( $.type( _.options.responsive ) !== 'array' ) {
2400
2401						_.options.responsive = [ value[item] ];
2402
2403					} else {
2404
2405						l = _.options.responsive.length-1;
2406
2407						// loop through the responsive object and splice out duplicates.
2408						while( l >= 0 ) {
2409
2410							if( _.options.responsive[l].breakpoint === value[item].breakpoint ) {
2411
2412								_.options.responsive.splice(l,1);
2413
2414							}
2415
2416							l--;
2417
2418						}
2419
2420						_.options.responsive.push( value[item] );
2421
2422					}
2423
2424				}
2425
2426			}
2427
2428			if ( refresh ) {
2429
2430				_.unload();
2431				_.reinit();
2432
2433			}
2434
2435		};
2436
2437	Slick.prototype.setPosition = function() {
2438
2439		var _ = this;
2440
2441		_.setDimensions();
2442
2443		_.setHeight();
2444
2445		if (_.options.fade === false) {
2446			_.setCSS(_.getLeft(_.currentSlide));
2447		} else {
2448			_.setFade();
2449		}
2450
2451		_.$slider.trigger('setPosition', [_]);
2452
2453	};
2454
2455	Slick.prototype.setProps = function() {
2456
2457		var _ = this,
2458			bodyStyle = document.body.style;
2459
2460		_.positionProp = _.options.vertical === true ? 'top' : 'left';
2461
2462		if (_.positionProp === 'top') {
2463			_.$slider.addClass('slick-vertical');
2464		} else {
2465			_.$slider.removeClass('slick-vertical');
2466		}
2467
2468		if (bodyStyle.WebkitTransition !== undefined ||
2469			bodyStyle.MozTransition !== undefined ||
2470			bodyStyle.msTransition !== undefined) {
2471			if (_.options.useCSS === true) {
2472				_.cssTransitions = true;
2473			}
2474		}
2475
2476		if ( _.options.fade ) {
2477			if ( typeof _.options.zIndex === 'number' ) {
2478				if( _.options.zIndex < 3 ) {
2479					_.options.zIndex = 3;
2480				}
2481			} else {
2482				_.options.zIndex = _.defaults.zIndex;
2483			}
2484		}
2485
2486		if (bodyStyle.OTransform !== undefined) {
2487			_.animType = 'OTransform';
2488			_.transformType = '-o-transform';
2489			_.transitionType = 'OTransition';
2490			if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
2491		}
2492		if (bodyStyle.MozTransform !== undefined) {
2493			_.animType = 'MozTransform';
2494			_.transformType = '-moz-transform';
2495			_.transitionType = 'MozTransition';
2496			if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
2497		}
2498		if (bodyStyle.webkitTransform !== undefined) {
2499			_.animType = 'webkitTransform';
2500			_.transformType = '-webkit-transform';
2501			_.transitionType = 'webkitTransition';
2502			if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
2503		}
2504		if (bodyStyle.msTransform !== undefined) {
2505			_.animType = 'msTransform';
2506			_.transformType = '-ms-transform';
2507			_.transitionType = 'msTransition';
2508			if (bodyStyle.msTransform === undefined) _.animType = false;
2509		}
2510		if (bodyStyle.transform !== undefined && _.animType !== false) {
2511			_.animType = 'transform';
2512			_.transformType = 'transform';
2513			_.transitionType = 'transition';
2514		}
2515		_.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
2516	};
2517
2518
2519	Slick.prototype.setSlideClasses = function(index) {
2520
2521		var _ = this,
2522			centerOffset, allSlides, indexOffset, remainder;
2523
2524		allSlides = _.$slider
2525			.find('.slick-slide')
2526			.removeClass('slick-active slick-center slick-current')
2527			.attr('aria-hidden', 'true');
2528
2529		_.$slides
2530			.eq(index)
2531			.addClass('slick-current');
2532
2533		if (_.options.centerMode === true) {
2534
2535			centerOffset = Math.floor(_.options.slidesToShow / 2);
2536
2537			if (_.options.infinite === true) {
2538
2539				if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
2540
2541					_.$slides
2542						.slice(index - centerOffset, index + centerOffset + 1)
2543						.addClass('slick-active')
2544						.attr('aria-hidden', 'false');
2545
2546				} else {
2547
2548					indexOffset = _.options.slidesToShow + index;
2549					allSlides
2550						.slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2)
2551						.addClass('slick-active')
2552						.attr('aria-hidden', 'false');
2553
2554				}
2555
2556				if (index === 0) {
2557
2558					allSlides
2559						.eq(allSlides.length - 1 - _.options.slidesToShow)
2560						.addClass('slick-center');
2561
2562				} else if (index === _.slideCount - 1) {
2563
2564					allSlides
2565						.eq(_.options.slidesToShow)
2566						.addClass('slick-center');
2567
2568				}
2569
2570			}
2571
2572			_.$slides
2573				.eq(index)
2574				.addClass('slick-center');
2575
2576		} else {
2577
2578			if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
2579
2580				_.$slides
2581					.slice(index, index + _.options.slidesToShow)
2582					.addClass('slick-active')
2583					.attr('aria-hidden', 'false');
2584
2585			} else if (allSlides.length <= _.options.slidesToShow) {
2586
2587				allSlides
2588					.addClass('slick-active')
2589					.attr('aria-hidden', 'false');
2590
2591			} else {
2592
2593				remainder = _.slideCount % _.options.slidesToShow;
2594				indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
2595
2596				if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
2597
2598					allSlides
2599						.slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
2600						.addClass('slick-active')
2601						.attr('aria-hidden', 'false');
2602
2603				} else {
2604
2605					allSlides
2606						.slice(indexOffset, indexOffset + _.options.slidesToShow)
2607						.addClass('slick-active')
2608						.attr('aria-hidden', 'false');
2609
2610				}
2611
2612			}
2613
2614		}
2615
2616		if (_.options.lazyLoad === 'ondemand') {
2617			_.lazyLoad();
2618		}
2619
2620	};
2621
2622	Slick.prototype.setupInfinite = function() {
2623
2624		var _ = this,
2625			i, slideIndex, infiniteCount;
2626
2627		if (_.options.fade === true) {
2628			_.options.centerMode = false;
2629		}
2630
2631		if (_.options.infinite === true && _.options.fade === false) {
2632
2633			slideIndex = null;
2634
2635			if (_.slideCount > _.options.slidesToShow) {
2636
2637				if (_.options.centerMode === true) {
2638					infiniteCount = _.options.slidesToShow + 1;
2639				} else {
2640					infiniteCount = _.options.slidesToShow;
2641				}
2642
2643				for (i = _.slideCount; i > (_.slideCount -
2644				infiniteCount); i -= 1) {
2645					slideIndex = i - 1;
2646					$(_.$slides[slideIndex]).clone(true).attr('id', '')
2647						.attr('data-slick-index', slideIndex - _.slideCount)
2648						.prependTo(_.$slideTrack).addClass('slick-cloned');
2649				}
2650				for (i = 0; i < infiniteCount; i += 1) {
2651					slideIndex = i;
2652					$(_.$slides[slideIndex]).clone(true).attr('id', '')
2653						.attr('data-slick-index', slideIndex + _.slideCount)
2654						.appendTo(_.$slideTrack).addClass('slick-cloned');
2655				}
2656				_.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
2657					$(this).attr('id', '');
2658				});
2659
2660			}
2661
2662		}
2663
2664	};
2665
2666	Slick.prototype.interrupt = function( toggle ) {
2667
2668		var _ = this;
2669
2670		if( !toggle ) {
2671			_.autoPlay();
2672		}
2673		_.interrupted = toggle;
2674
2675	};
2676
2677	Slick.prototype.selectHandler = function(event) {
2678
2679		var _ = this;
2680
2681		var targetElement =
2682			$(event.target).is('.slick-slide') ?
2683				$(event.target) :
2684				$(event.target).parents('.slick-slide');
2685
2686		var index = parseInt(targetElement.attr('data-slick-index'));
2687
2688		if (!index) index = 0;
2689
2690		if (_.slideCount <= _.options.slidesToShow) {
2691
2692			_.setSlideClasses(index);
2693			_.asNavFor(index);
2694			return;
2695
2696		}
2697
2698		_.slideHandler(index);
2699
2700	};
2701
2702	Slick.prototype.slideHandler = function(index, sync, dontAnimate) {
2703
2704		var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
2705			_ = this, navTarget;
2706
2707		sync = sync || false;
2708
2709		if (_.animating === true && _.options.waitForAnimate === true) {
2710			return;
2711		}
2712
2713		if (_.options.fade === true && _.currentSlide === index) {
2714			return;
2715		}
2716
2717		if (_.slideCount <= _.options.slidesToShow) {
2718			return;
2719		}
2720
2721		if (sync === false) {
2722			_.asNavFor(index);
2723		}
2724
2725		targetSlide = index;
2726		targetLeft = _.getLeft(targetSlide);
2727		slideLeft = _.getLeft(_.currentSlide);
2728
2729		_.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
2730
2731		if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
2732			if (_.options.fade === false) {
2733				targetSlide = _.currentSlide;
2734				if (dontAnimate !== true) {
2735					_.animateSlide(slideLeft, function() {
2736						_.postSlide(targetSlide);
2737					});
2738				} else {
2739					_.postSlide(targetSlide);
2740				}
2741			}
2742			return;
2743		} else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
2744			if (_.options.fade === false) {
2745				targetSlide = _.currentSlide;
2746				if (dontAnimate !== true) {
2747					_.animateSlide(slideLeft, function() {
2748						_.postSlide(targetSlide);
2749					});
2750				} else {
2751					_.postSlide(targetSlide);
2752				}
2753			}
2754			return;
2755		}
2756
2757		if ( _.options.autoplay ) {
2758			clearInterval(_.autoPlayTimer);
2759		}
2760
2761		if (targetSlide < 0) {
2762			if (_.slideCount % _.options.slidesToScroll !== 0) {
2763				animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
2764			} else {
2765				animSlide = _.slideCount + targetSlide;
2766			}
2767		} else if (targetSlide >= _.slideCount) {
2768			if (_.slideCount % _.options.slidesToScroll !== 0) {
2769				animSlide = 0;
2770			} else {
2771				animSlide = targetSlide - _.slideCount;
2772			}
2773		} else {
2774			animSlide = targetSlide;
2775		}
2776
2777		_.animating = true;
2778
2779		_.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
2780
2781		oldSlide = _.currentSlide;
2782		_.currentSlide = animSlide;
2783
2784		_.setSlideClasses(_.currentSlide);
2785
2786		if ( _.options.asNavFor ) {
2787
2788			navTarget = _.getNavTarget();
2789			navTarget = navTarget.slick('getSlick');
2790
2791			if ( navTarget.slideCount <= navTarget.options.slidesToShow ) {
2792				navTarget.setSlideClasses(_.currentSlide);
2793			}
2794
2795		}
2796
2797		_.updateDots();
2798		_.updateArrows();
2799
2800		if (_.options.fade === true) {
2801			if (dontAnimate !== true) {
2802
2803				_.fadeSlideOut(oldSlide);
2804
2805				_.fadeSlide(animSlide, function() {
2806					_.postSlide(animSlide);
2807				});
2808
2809			} else {
2810				_.postSlide(animSlide);
2811			}
2812			_.animateHeight();
2813			return;
2814		}
2815
2816		if (dontAnimate !== true) {
2817			_.animateSlide(targetLeft, function() {
2818				_.postSlide(animSlide);
2819			});
2820		} else {
2821			_.postSlide(animSlide);
2822		}
2823
2824	};
2825
2826	Slick.prototype.startLoad = function() {
2827
2828		var _ = this;
2829
2830		if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
2831
2832			_.$prevArrow.hide();
2833			_.$nextArrow.hide();
2834
2835		}
2836
2837		if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
2838
2839			_.$dots.hide();
2840
2841		}
2842
2843		_.$slider.addClass('slick-loading');
2844
2845	};
2846
2847	Slick.prototype.swipeDirection = function() {
2848
2849		var xDist, yDist, r, swipeAngle, _ = this;
2850
2851		xDist = _.touchObject.startX - _.touchObject.curX;
2852		yDist = _.touchObject.startY - _.touchObject.curY;
2853		r = Math.atan2(yDist, xDist);
2854
2855		swipeAngle = Math.round(r * 180 / Math.PI);
2856		if (swipeAngle < 0) {
2857			swipeAngle = 360 - Math.abs(swipeAngle);
2858		}
2859
2860		if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
2861			return (_.options.rtl === false ? 'left' : 'right');
2862		}
2863		if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
2864			return (_.options.rtl === false ? 'left' : 'right');
2865		}
2866		if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
2867			return (_.options.rtl === false ? 'right' : 'left');
2868		}
2869		if (_.options.verticalSwiping === true) {
2870			if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
2871				return 'down';
2872			} else {
2873				return 'up';
2874			}
2875		}
2876
2877		return 'vertical';
2878
2879	};
2880
2881	Slick.prototype.swipeEnd = function(event) {
2882
2883		var _ = this,
2884			slideCount,
2885			direction;
2886
2887		_.dragging = false;
2888		_.interrupted = false;
2889		_.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true;
2890
2891		if ( _.touchObject.curX === undefined ) {
2892			return false;
2893		}
2894
2895		if ( _.touchObject.edgeHit === true ) {
2896			_.$slider.trigger('edge', [_, _.swipeDirection() ]);
2897		}
2898
2899		if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) {
2900
2901			direction = _.swipeDirection();
2902
2903			switch ( direction ) {
2904
2905				case 'left':
2906				case 'down':
2907
2908					slideCount =
2909						_.options.swipeToSlide ?
2910							_.checkNavigable( _.currentSlide + _.getSlideCount() ) :
2911						_.currentSlide + _.getSlideCount();
2912
2913					_.currentDirection = 0;
2914
2915					break;
2916
2917				case 'right':
2918				case 'up':
2919
2920					slideCount =
2921						_.options.swipeToSlide ?
2922							_.checkNavigable( _.currentSlide - _.getSlideCount() ) :
2923						_.currentSlide - _.getSlideCount();
2924
2925					_.currentDirection = 1;
2926
2927					break;
2928
2929				default:
2930
2931
2932			}
2933
2934			if( direction != 'vertical' ) {
2935
2936				_.slideHandler( slideCount );
2937				_.touchObject = {};
2938				_.$slider.trigger('swipe', [_, direction ]);
2939
2940			}
2941
2942		} else {
2943
2944			if ( _.touchObject.startX !== _.touchObject.curX ) {
2945
2946				_.slideHandler( _.currentSlide );
2947				_.touchObject = {};
2948
2949			}
2950
2951		}
2952
2953	};
2954
2955	Slick.prototype.swipeHandler = function(event) {
2956
2957		var _ = this;
2958
2959		if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
2960			return;
2961		} else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
2962			return;
2963		}
2964
2965		_.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
2966			event.originalEvent.touches.length : 1;
2967
2968		_.touchObject.minSwipe = _.listWidth / _.options
2969				.touchThreshold;
2970
2971		if (_.options.verticalSwiping === true) {
2972			_.touchObject.minSwipe = _.listHeight / _.options
2973					.touchThreshold;
2974		}
2975
2976		switch (event.data.action) {
2977
2978			case 'start':
2979				_.swipeStart(event);
2980				break;
2981
2982			case 'move':
2983				_.swipeMove(event);
2984				break;
2985
2986			case 'end':
2987				_.swipeEnd(event);
2988				break;
2989
2990		}
2991
2992	};
2993
2994	Slick.prototype.swipeMove = function(event) {
2995
2996		var _ = this,
2997			edgeWasHit = false,
2998			curLeft, swipeDirection, swipeLength, positionOffset, touches;
2999
3000		touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
3001
3002		if (!_.dragging || touches && touches.length !== 1) {
3003			return false;
3004		}
3005
3006		curLeft = _.getLeft(_.currentSlide);
3007
3008		_.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
3009		_.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
3010
3011		_.touchObject.swipeLength = Math.round(Math.sqrt(
3012			Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
3013
3014		if (_.options.verticalSwiping === true) {
3015			_.touchObject.swipeLength = Math.round(Math.sqrt(
3016				Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
3017		}
3018
3019		swipeDirection = _.swipeDirection();
3020
3021		if (swipeDirection === 'vertical') {
3022			return;
3023		}
3024
3025		if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
3026			event.preventDefault();
3027		}
3028
3029		positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
3030		if (_.options.verticalSwiping === true) {
3031			positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
3032		}
3033
3034
3035		swipeLength = _.touchObject.swipeLength;
3036
3037		_.touchObject.edgeHit = false;
3038
3039		if (_.options.infinite === false) {
3040			if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
3041				swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
3042				_.touchObject.edgeHit = true;
3043			}
3044		}
3045
3046		if (_.options.vertical === false) {
3047			_.swipeLeft = curLeft + swipeLength * positionOffset;
3048		} else {
3049			_.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
3050		}
3051		if (_.options.verticalSwiping === true) {
3052			_.swipeLeft = curLeft + swipeLength * positionOffset;
3053		}
3054
3055		if (_.options.fade === true || _.options.touchMove === false) {
3056			return false;
3057		}
3058
3059		if (_.animating === true) {
3060			_.swipeLeft = null;
3061			return false;
3062		}
3063
3064		_.setCSS(_.swipeLeft);
3065
3066	};
3067
3068	Slick.prototype.swipeStart = function(event) {
3069
3070		var _ = this,
3071			touches;
3072
3073		_.interrupted = true;
3074
3075		if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
3076			_.touchObject = {};
3077			return false;
3078		}
3079
3080		if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
3081			touches = event.originalEvent.touches[0];
3082		}
3083
3084		_.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
3085		_.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
3086
3087		_.dragging = true;
3088
3089	};
3090
3091	Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() {
3092
3093		var _ = this;
3094
3095		if (_.$slidesCache !== null) {
3096
3097			_.unload();
3098
3099			_.$slideTrack.children(this.options.slide).detach();
3100
3101			_.$slidesCache.appendTo(_.$slideTrack);
3102
3103			_.reinit();
3104
3105		}
3106
3107	};
3108
3109	Slick.prototype.unload = function() {
3110
3111		var _ = this;
3112
3113		$('.slick-cloned', _.$slider).remove();
3114
3115		if (_.$dots) {
3116			_.$dots.remove();
3117		}
3118
3119		if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
3120			_.$prevArrow.remove();
3121		}
3122
3123		if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
3124			_.$nextArrow.remove();
3125		}
3126
3127		_.$slides
3128			.removeClass('slick-slide slick-active slick-visible slick-current')
3129			.attr('aria-hidden', 'true')
3130			.css('width', '');
3131
3132	};
3133
3134	Slick.prototype.unslick = function(fromBreakpoint) {
3135
3136		var _ = this;
3137		_.$slider.trigger('unslick', [_, fromBreakpoint]);
3138		_.destroy();
3139
3140	};
3141
3142	Slick.prototype.updateArrows = function() {
3143
3144		var _ = this,
3145			centerOffset;
3146
3147		centerOffset = Math.floor(_.options.slidesToShow / 2);
3148
3149		if ( _.options.arrows === true &&
3150			_.slideCount > _.options.slidesToShow &&
3151			!_.options.infinite ) {
3152
3153			_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
3154			_.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
3155
3156			if (_.currentSlide === 0) {
3157
3158				_.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true').attr('disabled', 'disabled');
3159				_.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
3160
3161			} else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
3162
3163				_.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true').attr('disabled', 'disabled');
3164				_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
3165
3166			} else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
3167
3168				_.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true').attr('disabled', 'disabled');
3169				_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
3170
3171			}
3172
3173		}
3174
3175	};
3176
3177	Slick.prototype.updateDots = function() {
3178
3179		var _ = this;
3180
3181		if (_.$dots !== null) {
3182
3183			_.$dots
3184				.find('li')
3185				.removeClass('slick-active')
3186				.attr('aria-hidden', 'true');
3187
3188			_.$dots
3189				.find('li')
3190				.eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
3191				.addClass('slick-active')
3192				.attr('aria-hidden', 'false');
3193
3194		}
3195
3196	};
3197
3198	Slick.prototype.visibility = function() {
3199
3200		var _ = this;
3201
3202		if ( _.options.autoplay ) {
3203
3204			if ( document[_.hidden] ) {
3205
3206				_.interrupted = true;
3207
3208			} else {
3209
3210				_.interrupted = false;
3211
3212			}
3213
3214		}
3215
3216	};
3217
3218	$.fn.slick = function() {
3219		var _ = this,
3220			opt = arguments[0],
3221			args = Array.prototype.slice.call(arguments, 1),
3222			l = _.length,
3223			i,
3224			ret;
3225		for (i = 0; i < l; i++) {
3226			if (typeof opt == 'object' || typeof opt == 'undefined')
3227				_[i].slick = new Slick(_[i], opt);
3228			else
3229				ret = _[i].slick[opt].apply(_[i].slick, args);
3230			if (typeof ret != 'undefined') return ret;
3231		}
3232		return _;
3233	};
3234
3235}));
3236
3237
3238(function () {
3239    'use strict';
3240    function clamp(element, options) {
3241        options = options || {};
3242        var win = window;
3243        var opt = {
3244            clamp:              options.clamp || 2,
3245            useNativeClamp:     typeof options.useNativeClamp !== 'undefined' ? options.useNativeClamp : true,
3246            splitOnChars:       options.splitOnChars || ['.', '-', '–', '—', ' '], //Split on sentences (periods), hypens, en-dashes, em-dashes, and words (spaces).
3247            animate:            options.animate || false,
3248            truncationChar:     options.truncationChar || '…',
3249            truncationHTML:     options.truncationHTML
3250        };
3251        var sty = element.style;
3252        var originalText = element.innerHTML;
3253
3254        var supportsNativeClamp = typeof element.style.webkitLineClamp !== 'undefined';
3255        var clampValue = opt.clamp;
3256        var isCSSValue = clampValue.indexOf && (clampValue.indexOf('px') > -1 || clampValue.indexOf('em') > -1);
3257        var truncationHTMLContainer;
3258
3259        if (opt.truncationHTML) {
3260            truncationHTMLContainer = document.createElement('span');
3261            truncationHTMLContainer.innerHTML = opt.truncationHTML;
3262        }
3263        // UTILITY FUNCTIONS __________________________________________________________
3264        /**
3265         * Return the current style for an element.
3266         * @param {HTMLElement} elem The element to compute.
3267         * @param {string} prop The style property.
3268         * @returns {number}
3269         */
3270        function computeStyle(elem, prop) {
3271            if (!win.getComputedStyle) {
3272                win.getComputedStyle = function (el) {
3273                    this.el = el;
3274                    this.getPropertyValue = function (prop) {
3275                        var re = /(\-([a-z]){1})/g;
3276                        if (prop === 'float') {
3277                            prop = 'styleFloat';
3278                        }
3279                        if (re.test(prop)) {
3280                            prop = prop.replace(re, function () {
3281                                return arguments[2].toUpperCase();
3282                            });
3283                        }
3284                        return el.currentStyle && el.currentStyle[prop] ? el.currentStyle[prop] : null;
3285                    };
3286                    return this;
3287                };
3288            }
3289
3290            return win.getComputedStyle(elem, null).getPropertyValue(prop);
3291        }
3292        /**
3293         * Returns the line-height of an element as an integer.
3294         */
3295        function getLineHeight(elem) {
3296            var lh = computeStyle(elem, 'line-height');
3297            if (lh === 'normal') {
3298                // Normal line heights vary from browser to browser. The spec recommends
3299                // a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff.
3300                lh = parseFloat(computeStyle(elem, 'font-size')) * 1.2;
3301            }
3302            return parseFloat(lh);
3303        }
3304
3305        /**
3306         * Returns the maximum number of lines of text that should be rendered based
3307         * on the current height of the element and the line-height of the text.
3308         */
3309        function getMaxLines(height) {
3310            var availHeight = height || element.clientHeight;
3311            var lineHeight = getLineHeight(element);
3312            return Math.max(Math.floor(availHeight / lineHeight), 0);
3313        }
3314
3315        /**
3316         * Returns the maximum height a given element should have based on the line-
3317         * height of the text and the given clamp value.
3318         */
3319        function getMaxHeight(clmp) {
3320            var lineHeight = getLineHeight(element);
3321            return lineHeight * clmp;
3322        }
3323
3324        var splitOnChars = opt.splitOnChars.slice(0);
3325        var splitChar = splitOnChars[0];
3326        var chunks;
3327        var lastChunk;
3328
3329        /**
3330         * Gets an element's last child. That may be another node or a node's contents.
3331         */
3332        function getLastChild(elem) {
3333            //Current element has children, need to go deeper and get last child as a text node
3334            if (elem.lastChild.children && elem.lastChild.children.length > 0) {
3335                return getLastChild(Array.prototype.slice.call(elem.children).pop());
3336            }
3337            //This is the absolute last child, a text node, but something's wrong with it. Remove it and keep trying
3338            else if (!elem.lastChild || !elem.lastChild.nodeValue || elem.lastChild.nodeValue === '' ||
3339                elem.lastChild.nodeValue === opt.truncationChar) {
3340                elem.lastChild.parentNode.removeChild(elem.lastChild);
3341                return getLastChild(element);
3342            }
3343            //This is the last child we want, return it
3344            else {
3345                return elem.lastChild.nodeValue;
3346            }
3347        }
3348
3349        function applyEllipsis(elem, str) {
3350            return str + opt.truncationChar;
3351        }
3352
3353        /**
3354         * Removes one character at a time from the text until its width or
3355         * height is beneath the passed-in max param.
3356         */
3357        function truncate(targetValue, maxHeight) {
3358            if (!maxHeight) {return;}
3359
3360            /**
3361             * Resets global variables.
3362             */
3363            function reset() {
3364                splitOnChars = opt.splitOnChars.slice(0);
3365                splitChar = splitOnChars[0];
3366                chunks = null;
3367                lastChunk = null;
3368            }
3369
3370            var nodeValue = targetValue.replace(opt.truncationChar, '');
3371
3372            //Grab the next chunks
3373            if (!chunks) {
3374                //If there are more characters to try, grab the next one
3375                if (splitOnChars.length > 0) {
3376                    splitChar = splitOnChars.shift();
3377                }
3378                //No characters to chunk by. Go character-by-character
3379                else {
3380                    splitChar = '';
3381                }
3382
3383                chunks = nodeValue.split(splitChar);
3384            }
3385
3386            //If there are chunks left to remove, remove the last one and see if
3387            // the nodeValue fits.
3388            if (chunks.length > 1) {
3389                //console.log('chunks', chunks);
3390                lastChunk = chunks.pop();
3391                //console.log('lastChunk', lastChunk);
3392                targetValue = applyEllipsis(targetValue, chunks.join(splitChar));
3393            }
3394            //No more chunks can be removed using this character
3395            else {
3396                chunks = null;
3397            }
3398
3399            //Insert the custom HTML before the truncation character
3400            element.innerHTML = targetValue;
3401            if (truncationHTMLContainer) {
3402                targetValue = targetValue.replace(opt.truncationChar, '');
3403                element.innerHTML = targetValue + ' ' + truncationHTMLContainer.innerHTML + opt.truncationChar;
3404            }
3405
3406            //Search produced valid chunks
3407            if (chunks) {
3408                //It fits
3409                if (element.scrollHeight <= maxHeight) {
3410                    //There's still more characters to try splitting on, not quite done yet
3411                    if (splitOnChars.length >= 0 && splitChar !== '') {
3412                        targetValue = applyEllipsis(targetValue, chunks.join(splitChar) + splitChar + lastChunk);
3413                        chunks = null;
3414                    }
3415                    //Finished!
3416                    else {
3417                        return element.innerHTML;
3418                    }
3419                }
3420            }
3421            //No valid chunks produced
3422            else {
3423                //No valid chunks even when splitting by letter, time to move
3424                //on to the next node
3425                if (splitChar === '') {
3426                    targetValue = applyEllipsis(targetValue, '');
3427                    targetValue = getLastChild(element);
3428
3429                    reset();
3430                }
3431            }
3432
3433            //If you get here it means still too big, let's keep truncating
3434            if (opt.animate) {
3435                setTimeout(function () {
3436                    truncate(targetValue, maxHeight);
3437                }, opt.animate === true ? 10 : opt.animate);
3438            } else {
3439                return truncate(targetValue, maxHeight);
3440            }
3441        }
3442        // CONSTRUCTOR ________________________________________________________________
3443        if (clampValue === 'auto') {
3444            clampValue = getMaxLines();
3445        } else if (isCSSValue) {
3446            clampValue = getMaxLines(parseInt(clampValue, 10));
3447        }
3448
3449        var clampedText;
3450        if (supportsNativeClamp && opt.useNativeClamp) {
3451            sty.overflow = 'hidden';
3452            sty.textOverflow = 'ellipsis';
3453            sty.webkitBoxOrient = 'vertical';
3454            sty.display = '-webkit-box';
3455            sty.webkitLineClamp = clampValue;
3456
3457            if (isCSSValue) {
3458                sty.height = opt.clamp + 'px';
3459            }
3460        } else {
3461            var height = Math.ceil(getMaxHeight(clampValue));
3462            if (height < element.scrollHeight) {
3463                clampedText = truncate(getLastChild(element), height);
3464            }
3465        }
3466        return {
3467            'original': originalText,
3468            'clamped': clampedText
3469        };
3470    }
3471
3472    window.$clamp = clamp;
3473})();
3474
3475/*
3476 * Horizon Swiper
3477 * Version 1.1.0
3478 * Domain ( http://horizon-swiper.sebsauer.de/ )
3479 * Copyright 2015 Sebastian Sauer ( http://www.sebsauer.de/ )
3480 * Licensed under MIT ( https://github.com/sebsauer90/horizon-swiper/blob/master/LICENSE )
3481 */
3482
3483'use strict';
3484
3485(function (factory) {
3486    'use strict';
3487
3488    /**
3489     * Register plugin
3490     */
3491    if (typeof define === 'function' && define.amd) {
3492        define(['jquery'], factory);
3493    } else if (typeof exports === 'object') {
3494        factory(require('jquery'));
3495    } else {
3496        factory(jQuery);
3497    }
3498})(function ($) {
3499    'use strict';
3500
3501    /**
3502     * Global variables
3503     */
3504    var pluginName = 'horizonSwiper';
3505    var settings = {
3506
3507        // Default settings
3508        item: '.horizon-item',
3509        showItems: 'auto',
3510        dots: false,
3511        numberedDots: false,
3512        arrows: true,
3513        arrowPrevText: '',
3514        arrowNextText: '',
3515        animationSpeed: 500,
3516        mouseDrag: true,
3517
3518        // Methods and callbacks
3519        onStart: function onStart() {},
3520        onEnd: function onEnd() {},
3521        onSlideStart: function onSlideStart() {},
3522        onSlideEnd: function onSlideEnd() {},
3523        onDragStart: function onDragStart() {},
3524        onDragEnd: function onDragEnd() {}
3525    };
3526
3527    var defaults = {
3528        $window: $(window),
3529        $document: $(document),
3530
3531        innerClass: 'horizon-inner',
3532        outerClass: 'horizon-outer',
3533        dotContainer: '<nav class="horizon-dots"></nav>',
3534        arrowPrev: ['<button class="horizon-prev">', '</button>'],
3535        arrowNext: ['<button class="horizon-next">', '</button>'],
3536        showArrowsClass: 'arrows',
3537        showDotsClass: 'dots',
3538        initializedClass: 'initialized',
3539        mouseDragClass: 'mouse-drag',
3540        firstItemClass: 'first-item',
3541        lastItemClass: 'last-item'
3542    };
3543
3544    /**
3545     * Plugin class
3546     */
3547    var HorizonSwiper = (function () {
3548
3549        /**
3550         * Constructor
3551         */
3552        function Plugin(element, options) {
3553            var that = this;
3554            that.settings = $.extend({}, settings, options);
3555
3556            that.$element = $(element);
3557            that.$items = that.$element.find(this.settings.item);
3558            that.$inner = null;
3559            that.$outer = null;
3560            that.$dots = null;
3561            that.$arrowPrev = null;
3562            that.$arrowNext = null;
3563
3564            that.initialized = false;
3565            that.maxHeight = 0;
3566            that.innerContainerWidth = 0;
3567            that.viewportSize = 0;
3568            that.isAnimate = false;
3569
3570            // Initialize if the document is ready and window is loaded
3571
3572            var windowLoadFunction = function windowLoadFunction() {
3573                if (that.initialized) {
3574                    that.setSizes();
3575                } else {
3576                    setTimeout(function () {
3577                        windowLoadFunction();
3578                    }, 1000);
3579                }
3580            };
3581
3582            defaults.$document.ready(function () {
3583                that.init();
3584            });
3585
3586            defaults.$window.load(function () {
3587                windowLoadFunction();
3588            });
3589        }
3590
3591        /**
3592         * Initialize
3593         */
3594        Plugin.prototype.init = function () {
3595            var that = this;
3596
3597            that._setWrapper();
3598            that._addArrows();
3599            that._addDots();
3600            that._mouseDrag();
3601            that.setSizes();
3602            that._resize();
3603
3604            that._checkPosition();
3605            that.initialized = true;
3606        };
3607
3608        /**
3609         * Set variable sizes
3610         */
3611        Plugin.prototype.setSizes = function () {
3612            var that = this;
3613            that.maxHeight = 0;
3614            that.innerContainerWidth = 0;
3615
3616            for (var i = 0; i < that.$items.length; ++i) {
3617                var $item = $(that.$items[i]);
3618                var height = $item.outerHeight(true);
3619                var width = $item.outerWidth(true);
3620
3621                if (height > that.maxHeight) {
3622                    that.maxHeight = height;
3623                }
3624
3625                that.innerContainerWidth += width;
3626            }
3627
3628            that.viewportSize = that.$inner.width();
3629            that.$outer.css({ 'max-height': that.maxHeight + 'px' });
3630
3631            if (that.viewportSize < that.innerContainerWidth) {
3632                that.$element.addClass(defaults.initializedClass);
3633
3634                if (that.settings.arrows) {
3635                    that.$element.addClass(defaults.showArrowsClass);
3636                }
3637
3638                if (that.settings.dots) {
3639                    that.$element.addClass(defaults.showDotsClass);
3640                }
3641            } else {
3642                that.$element.removeClass(defaults.initializedClass);
3643                that.$element.addClass(defaults.showArrowsClass);
3644            }
3645        };
3646
3647        /**
3648         * Resize
3649         *
3650         * @private
3651         */
3652        Plugin.prototype._resize = function () {
3653            var that = this;
3654            var resizeTimeout = null;
3655
3656            var resizeFunction = function resizeFunction() {
3657                that.setSizes();
3658                that._checkPosition();
3659            };
3660
3661            defaults.$window.resize(function () {
3662                clearTimeout(resizeTimeout);
3663                setTimeout(function () {
3664                    resizeFunction();
3665                }, 250);
3666            });
3667        };
3668
3669        /**
3670         * Include the wrapper elements to the DOM
3671         *
3672         * @private
3673         */
3674        Plugin.prototype._setWrapper = function () {
3675            var that = this;
3676            var itemWidth = 0;
3677
3678            that.$items.wrapAll('<div class="' + defaults.outerClass + '">');
3679            that.$items.wrapAll('<div class="' + defaults.innerClass + '">');
3680            that.$inner = that.$element.find('.' + defaults.innerClass);
3681            that.$outer = that.$element.find('.' + defaults.outerClass);
3682
3683            if (that.settings.showItems !== 'auto' && that.settings.showItems === parseInt(that.settings.showItems, 10)) {
3684                itemWidth = 100 / that.settings.showItems;
3685                that.$items.css({ width: itemWidth + '%' });
3686            }
3687
3688            for (var i = 0; i < that.$items.length; ++i) {
3689                $(that.$items[i]).attr('data-horizon-index', i);
3690            }
3691        };
3692
3693        /**
3694         * Add dots to the swiper
3695         *
3696         * @private
3697         */
3698        Plugin.prototype._addDots = function () {
3699            var that = this;
3700
3701            if (that.settings.dots) {
3702                that.$dots = $(defaults.dotContainer);
3703
3704                for (var i = 0; i < that.$items.length; ++i) {
3705                    var dotName = that.settings.numberedDots ? i : '';
3706                    var $newDot = $('<button class="horizon-dot" data-horizon-target="' + i + '">' + dotName + '</button>');
3707                    that.$dots.append($newDot);
3708                }
3709
3710                that.$element.append(that.$dots);
3711
3712                that.$dots.find('button').on('click', function (e) {
3713                    e.preventDefault();
3714                    var horizonTarget = $(this).attr('data-horizon-target');
3715                    that._dotScroll(horizonTarget);
3716                });
3717            }
3718        };
3719
3720        /**
3721         * Scroll to a dot target
3722         *
3723         * @param horizonTarget
3724         * @private
3725         */
3726        Plugin.prototype._dotScroll = function (horizonTarget) {
3727            var that = this;
3728            var $target = that.$dots.find('[data-horizon-index="' + horizonTarget + '"]');
3729            var targetWidth = $target.outerWidth(true);
3730            var leftOffset = 0;
3731            var scrollTo = 0;
3732            var centerValue = that.viewportSize / 2 - targetWidth / 2;
3733
3734            that.isAnimate = true;
3735            that.settings.onSlideStart();
3736
3737            for (var i = 0; i < that.$items.length; ++i) {
3738                if (i < horizonTarget) {
3739                    leftOffset += $(that.$items[i]).outerWidth(true);
3740                }
3741            }
3742
3743            scrollTo = leftOffset - centerValue;
3744
3745            if (scrollTo < 0) {
3746                scrollTo = 0;
3747            } else if (scrollTo > that.innerContainerWidth - that.viewportSize) {
3748                scrollTo = that.innerContainerWidth - that.viewportSize;
3749            }
3750
3751            that.$inner.animate({
3752                scrollLeft: scrollTo
3753            }, that.settings.animationSpeed, function () {
3754                that._checkPosition();
3755                that.settings.onSlideEnd();
3756
3757                if (horizonTarget === that.$items.length) {
3758                    that.settings.onEnd();
3759                } else if (horizonTarget === 0) {
3760                    that.settings.onStart();
3761                }
3762
3763                that.isAnimate = false;
3764            });
3765        };
3766
3767        /**
3768         * Inlude navigation arrows to the DOM and bind click events
3769         *
3770         * @private
3771         */
3772        Plugin.prototype._addArrows = function () {
3773            var that = this;
3774
3775            if (that.settings.arrows === true) {
3776                that.$arrowPrev = $(defaults.arrowPrev[0] + that.settings.arrowPrevText + defaults.arrowPrev[1]);
3777                that.$arrowNext = $(defaults.arrowNext[0] + that.settings.arrowNextText + defaults.arrowNext[1]);
3778                that.$arrowNext.insertAfter(that.$outer);
3779                that.$arrowPrev.insertAfter(that.$outer);
3780
3781                that.$element.addClass(defaults.firstItemClass);
3782                that.$arrowPrev.attr('disabled', 'disabled');
3783
3784                that.$arrowPrev.on('click', function (e) {
3785                    e.preventDefault();
3786                    if (!that.isAnimate) {
3787                        that._scrollTo('previous');
3788                    }
3789                });
3790
3791                that.$arrowNext.on('click', function (e) {
3792                    e.preventDefault();
3793                    if (!that.isAnimate) {
3794                        that._scrollTo('next');
3795                    }
3796                });
3797            }
3798        };
3799
3800        /**
3801         *  Scroll to the previous or next item
3802         *
3803         * @param direction
3804         * @private
3805         */
3806        Plugin.prototype._scrollTo = function (direction) {
3807            var that = this;
3808            var offset = that._getOffset(direction);
3809            that.isAnimate = true;
3810
3811            if (offset === 'end' || offset === 'start') {
3812                that.isAnimate = false;
3813                return;
3814            }
3815
3816            that.settings.onSlideStart();
3817
3818            that.$inner.animate({
3819                scrollLeft: offset[0]
3820            }, that.settings.animationSpeed, function () {
3821                if (offset[1] === 'end') {
3822                    that.settings.onEnd();
3823                } else if (offset[1] === 'start') {
3824                    that.settings.onStart();
3825                }
3826
3827                that._checkPosition();
3828                that.settings.onSlideEnd();
3829                that.isAnimate = false;
3830            });
3831        };
3832
3833        /**
3834         *  Get the offset to scroll to the next or previous item
3835         *
3836         * @param direction
3837         * @returns [offset, position]
3838         * @private
3839         */
3840        Plugin.prototype._getOffset = function (direction) {
3841            var that = this;
3842            var offsetState = that.$inner.scrollLeft();
3843            var calcActiveItem = 0;
3844            var viewWidth = offsetState + that.viewportSize;
3845
3846            if (direction === 'next' && offsetState + that.viewportSize === that.innerContainerWidth) {
3847                return 'end';
3848            } else if (direction === 'previous' && offsetState === 0) {
3849                return 'start';
3850            }
3851
3852            for (var i = 0; i < that.$items.length; ++i) {
3853                var width = $(that.$items[i]).outerWidth(true);
3854                var state = '';
3855
3856                calcActiveItem += width;
3857
3858                if (direction === 'next' && calcActiveItem > viewWidth) {
3859                    if (i + 1 === that.$items.length) {
3860                        state = 'end';
3861                    }
3862                    return [calcActiveItem - that.viewportSize, state];
3863                } else if (direction === 'previous' && calcActiveItem >= offsetState) {
3864                    if (calcActiveItem - width <= 0) {
3865                        state = 'start';
3866                    }
3867                    return [calcActiveItem - width, state];
3868                }
3869            }
3870        };
3871
3872        /**
3873         *  Set the mouse drag support
3874         *
3875         * @private
3876         */
3877        Plugin.prototype._mouseDrag = function () {
3878            var that = this;
3879            var isTouchDevice = false;
3880            var isClicked = false;
3881            var mouseXposition = 0;
3882            var innerXposition = 0;
3883            var outerXposition = that.$inner.offset().left;
3884            var newPosition = 0;
3885            var isTouching = false;
3886            var isScrolling = false;
3887            var scrollTimer = null;
3888
3889            var updatePosition = function updatePosition(e) {
3890                if (!isTouchDevice) {
3891                    newPosition = innerXposition + (mouseXposition - e.pageX);
3892                    that.$inner.scrollLeft(newPosition);
3893                }
3894            };
3895
3896            // Touch events
3897
3898            that.$element.on({
3899                'touchstart': function touchstart(e) {
3900                    isTouchDevice = true;
3901                    isTouching = true;
3902                    isScrolling = true;
3903                    that.settings.onDragStart();
3904                }
3905            });
3906
3907            defaults.$document.on({
3908                'touchend': function touchend(e) {
3909                    if (isTouching) {
3910                        that._checkPosition();
3911                        that.settings.onDragEnd();
3912                        isTouching = false;
3913                    }
3914                }
3915            });
3916
3917            that.$inner.scroll(function () {
3918                clearTimeout(scrollTimer);
3919                scrollTimer = setTimeout(function () {
3920                    if (isScrolling) {
3921                        that._checkPosition();
3922                        that.settings.onDragEnd();
3923                        isScrolling = false;
3924                    }
3925                }, 250);
3926            });
3927
3928            // Mouse events
3929
3930            if (that.settings.mouseDrag && !isTouchDevice) {
3931                that.$element.addClass(defaults.mouseDragClass);
3932
3933                that.$element.on({
3934                    'mousedown': function mousedown(e) {
3935                        isClicked = true;
3936                        mouseXposition = e.pageX;
3937                        innerXposition = that.$inner.scrollLeft();
3938
3939                        if (e.target.tagName.toLowerCase() !== 'button') {
3940                            that.settings.onDragStart();
3941                        }
3942                    }
3943                });
3944
3945                defaults.$document.on({
3946                    'mousemove': function mousemove(e) {
3947                        isClicked && updatePosition(e);
3948                    },
3949                    'mouseup': function mouseup(e) {
3950                        if (isClicked) {
3951                            if (e.target.tagName.toLowerCase() !== 'button') {
3952                                that._checkPosition();
3953                                that.settings.onDragEnd();
3954                            }
3955                        }
3956                        isClicked = false;
3957                    }
3958                });
3959            }
3960        };
3961
3962        /**
3963         *  Check the scrolling position
3964         *
3965         * @private
3966         */
3967        Plugin.prototype._checkPosition = function () {
3968            var that = this;
3969            var innerOffset = that.$inner.scrollLeft();
3970
3971            that.settings.arrows && that._checkArrowState(innerOffset);
3972            that.settings.dots && that._checkActiveDots(innerOffset);
3973        };
3974
3975        /**
3976         * Check the active dots and set the active class
3977         *
3978         * @param innerOffset
3979         * @private
3980         */
3981        Plugin.prototype._checkActiveDots = function (innerOffset) {
3982            var that = this;
3983            var itemStart = 0;
3984            var itemEnd = 0;
3985            var range = [innerOffset, innerOffset + that.viewportSize];
3986
3987            for (var i = 0; i < that.$items.length; ++i) {
3988                var $item = $(that.$items[i]);
3989                var itemWidth = $item.outerWidth(true);
3990
3991                itemEnd += itemWidth;
3992
3993                if (itemStart + itemWidth / 2 >= range[0] && itemEnd - itemWidth / 2 <= range[1]) {
3994                    that.$dots.find('[data-horizon-target="' + i + '"]').addClass('active');
3995                } else {
3996                    that.$dots.find('[data-horizon-target="' + i + '"]').removeClass('active');
3997                }
3998
3999                itemStart += itemWidth;
4000            }
4001        };
4002
4003        /**
4004         * Check for the arrow start and end position
4005         *
4006         * @param innerOffset
4007         * @private
4008         */
4009        Plugin.prototype._checkArrowState = function (innerOffset) {
4010            var that = this;
4011            if (innerOffset + that.viewportSize >= that.innerContainerWidth - 10) {
4012                that.$element.addClass(defaults.lastItemClass);
4013                that.$arrowNext.attr('disabled', 'disabled');
4014                if (innerOffset != 0) {
4015                    that.$element.removeClass(defaults.firstItemClass);
4016                    that.$arrowPrev.removeAttr('disabled');
4017                }
4018            } else if (innerOffset <= 0) {
4019                that.$element.addClass(defaults.firstItemClass);
4020                that.$arrowPrev.attr('disabled', 'disabled');
4021                that.$element.removeClass(defaults.lastItemClass);
4022                that.$arrowNext.removeAttr('disabled');
4023            } else {
4024                that.$element.removeClass(defaults.lastItemClass).removeClass(defaults.firstItemClass);
4025                that.$arrowPrev.removeAttr('disabled');
4026                that.$arrowNext.removeAttr('disabled');
4027            }
4028        };
4029
4030        /**
4031         *  Returns the class
4032         */
4033        return Plugin;
4034    })();
4035
4036    $.fn[pluginName] = function (options) {
4037        this.each(function () {
4038            if (!$.data(this, pluginName)) {
4039                $.data(this, pluginName, new HorizonSwiper(this, options));
4040            }
4041        });
4042
4043        return this;
4044    };
4045});
4046
4047/*!
4048 * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)
4049 *
4050 * Copyright 2012 Stefan Petre
4051 * Improvements by Andrew Rowls
4052 * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
4053 */(function(factory){
4054    if (typeof define === "function" && define.amd) {
4055        define(["jquery"], factory);
4056    } else if (typeof exports === 'object') {
4057        factory(require('jquery'));
4058    } else {
4059        factory(jQuery);
4060    }
4061}(function($, undefined){
4062
4063	function UTCDate(){
4064		return new Date(Date.UTC.apply(Date, arguments));
4065	}
4066	function UTCToday(){
4067		var today = new Date();
4068		return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
4069	}
4070	function isUTCEquals(date1, date2) {
4071		return (
4072			date1.getUTCFullYear() === date2.getUTCFullYear() &&
4073			date1.getUTCMonth() === date2.getUTCMonth() &&
4074			date1.getUTCDate() === date2.getUTCDate()
4075		);
4076	}
4077	function alias(method){
4078		return function(){
4079			return this[method].apply(this, arguments);
4080		};
4081	}
4082	function isValidDate(d) {
4083		return d && !isNaN(d.getTime());
4084	}
4085
4086	var DateArray = (function(){
4087		var extras = {
4088			get: function(i){
4089				return this.slice(i)[0];
4090			},
4091			contains: function(d){
4092				// Array.indexOf is not cross-browser;
4093				// $.inArray doesn't work with Dates
4094				var val = d && d.valueOf();
4095				for (var i=0, l=this.length; i < l; i++)
4096					if (this[i].valueOf() === val)
4097						return i;
4098				return -1;
4099			},
4100			remove: function(i){
4101				this.splice(i,1);
4102			},
4103			replace: function(new_array){
4104				if (!new_array)
4105					return;
4106				if (!$.isArray(new_array))
4107					new_array = [new_array];
4108				this.clear();
4109				this.push.apply(this, new_array);
4110			},
4111			clear: function(){
4112				this.length = 0;
4113			},
4114			copy: function(){
4115				var a = new DateArray();
4116				a.replace(this);
4117				return a;
4118			}
4119		};
4120
4121		return function(){
4122			var a = [];
4123			a.push.apply(a, arguments);
4124			$.extend(a, extras);
4125			return a;
4126		};
4127	})();
4128
4129
4130	// Picker object
4131
4132	var Datepicker = function(element, options){
4133		$(element).data('datepicker', this);
4134		this._process_options(options);
4135
4136		this.dates = new DateArray();
4137		this.viewDate = this.o.defaultViewDate;
4138		this.focusDate = null;
4139
4140		this.element = $(element);
4141		this.isInput = this.element.is('input');
4142		this.inputField = this.isInput ? this.element : this.element.find('input');
4143		this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
4144		this.hasInput = this.component && this.inputField.length;
4145		if (this.component && this.component.length === 0)
4146			this.component = false;
4147		this.isInline = !this.component && this.element.is('div');
4148
4149		this.picker = $(DPGlobal.template);
4150
4151		// Checking templates and inserting
4152		if (this._check_template(this.o.templates.leftArrow)) {
4153			this.picker.find('.prev').html(this.o.templates.leftArrow);
4154		}
4155		if (this._check_template(this.o.templates.rightArrow)) {
4156			this.picker.find('.next').html(this.o.templates.rightArrow);
4157		}
4158
4159		this._buildEvents();
4160		this._attachEvents();
4161
4162		if (this.isInline){
4163			this.picker.addClass('datepicker-inline').appendTo(this.element);
4164		}
4165		else {
4166			this.picker.addClass('datepicker-dropdown dropdown-menu');
4167		}
4168
4169		if (this.o.rtl){
4170			this.picker.addClass('datepicker-rtl');
4171		}
4172
4173		this.viewMode = this.o.startView;
4174
4175		if (this.o.calendarWeeks)
4176			this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear')
4177						.attr('colspan', function(i, val){
4178							return parseInt(val) + 1;
4179						});
4180
4181		this._allow_update = false;
4182
4183		this.setStartDate(this._o.startDate);
4184		this.setEndDate(this._o.endDate);
4185		this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
4186		this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);
4187		this.setDatesDisabled(this.o.datesDisabled);
4188
4189		this.fillDow();
4190		this.fillMonths();
4191
4192		this._allow_update = true;
4193
4194		this.update();
4195		this.showMode();
4196
4197		if (this.isInline){
4198			this.show();
4199		}
4200	};
4201
4202	Datepicker.prototype = {
4203		constructor: Datepicker,
4204
4205		_resolveViewName: function(view, default_value){
4206			if (view === 0 || view === 'days' || view === 'month') {
4207				return 0;
4208			}
4209			if (view === 1 || view === 'months' || view === 'year') {
4210				return 1;
4211			}
4212			if (view === 2 || view === 'years' || view === 'decade') {
4213				return 2;
4214			}
4215			if (view === 3 || view === 'decades' || view === 'century') {
4216				return 3;
4217			}
4218			if (view === 4 || view === 'centuries' || view === 'millennium') {
4219				return 4;
4220			}
4221			return default_value === undefined ? false : default_value;
4222		},
4223
4224		_check_template: function(tmp){
4225			try {
4226				// If empty
4227				if (tmp === undefined || tmp === "") {
4228					return false;
4229				}
4230				// If no html, everything ok
4231				if ((tmp.match(/[<>]/g) || []).length <= 0) {
4232					return true;
4233				}
4234				// Checking if html is fine
4235				var jDom = $(tmp);
4236				return jDom.length > 0;
4237			}
4238			catch (ex) {
4239				return false;
4240			}
4241		},
4242
4243		_process_options: function(opts){
4244			// Store raw options for reference
4245			this._o = $.extend({}, this._o, opts);
4246			// Processed options
4247			var o = this.o = $.extend({}, this._o);
4248
4249			// Check if "de-DE" style date is available, if not language should
4250			// fallback to 2 letter code eg "de"
4251			var lang = o.language;
4252			if (!dates[lang]){
4253				lang = lang.split('-')[0];
4254				if (!dates[lang])
4255					lang = defaults.language;
4256			}
4257			o.language = lang;
4258
4259			// Retrieve view index from any aliases
4260			o.startView = this._resolveViewName(o.startView, 0);
4261			o.minViewMode = this._resolveViewName(o.minViewMode, 0);
4262			o.maxViewMode = this._resolveViewName(o.maxViewMode, 4);
4263
4264			// Check that the start view is between min and max
4265			o.startView = Math.min(o.startView, o.maxViewMode);
4266			o.startView = Math.max(o.startView, o.minViewMode);
4267
4268			// true, false, or Number > 0
4269			if (o.multidate !== true){
4270				o.multidate = Number(o.multidate) || false;
4271				if (o.multidate !== false)
4272					o.multidate = Math.max(0, o.multidate);
4273			}
4274			o.multidateSeparator = String(o.multidateSeparator);
4275
4276			o.weekStart %= 7;
4277			o.weekEnd = (o.weekStart + 6) % 7;
4278
4279			var format = DPGlobal.parseFormat(o.format);
4280			if (o.startDate !== -Infinity){
4281				if (!!o.startDate){
4282					if (o.startDate instanceof Date)
4283						o.startDate = this._local_to_utc(this._zero_time(o.startDate));
4284					else
4285						o.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear);
4286				}
4287				else {
4288					o.startDate = -Infinity;
4289				}
4290			}
4291			if (o.endDate !== Infinity){
4292				if (!!o.endDate){
4293					if (o.endDate instanceof Date)
4294						o.endDate = this._local_to_utc(this._zero_time(o.endDate));
4295					else
4296						o.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear);
4297				}
4298				else {
4299					o.endDate = Infinity;
4300				}
4301			}
4302
4303			o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
4304			if (!$.isArray(o.daysOfWeekDisabled))
4305				o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
4306			o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
4307				return parseInt(d, 10);
4308			});
4309
4310			o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];
4311			if (!$.isArray(o.daysOfWeekHighlighted))
4312				o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/);
4313			o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){
4314				return parseInt(d, 10);
4315			});
4316
4317			o.datesDisabled = o.datesDisabled||[];
4318			if (!$.isArray(o.datesDisabled)) {
4319				o.datesDisabled = [
4320					o.datesDisabled
4321				];
4322			}
4323			o.datesDisabled = $.map(o.datesDisabled,function(d){
4324				return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
4325			});
4326
4327			var plc = String(o.orientation).toLowerCase().split(/\s+/g),
4328				_plc = o.orientation.toLowerCase();
4329			plc = $.grep(plc, function(word){
4330				return /^auto|left|right|top|bottom$/.test(word);
4331			});
4332			o.orientation = {x: 'auto', y: 'auto'};
4333			if (!_plc || _plc === 'auto')
4334				; // no action
4335			else if (plc.length === 1){
4336				switch (plc[0]){
4337					case 'top':
4338					case 'bottom':
4339						o.orientation.y = plc[0];
4340						break;
4341					case 'left':
4342					case 'right':
4343						o.orientation.x = plc[0];
4344						break;
4345				}
4346			}
4347			else {
4348				_plc = $.grep(plc, function(word){
4349					return /^left|right$/.test(word);
4350				});
4351				o.orientation.x = _plc[0] || 'auto';
4352
4353				_plc = $.grep(plc, function(word){
4354					return /^top|bottom$/.test(word);
4355				});
4356				o.orientation.y = _plc[0] || 'auto';
4357			}
4358			if (o.defaultViewDate) {
4359				var year = o.defaultViewDate.year || new Date().getFullYear();
vendor: 14,021 bytes, lines 4360-4859
4360				var month = o.defaultViewDate.month || 0;
4361				var day = o.defaultViewDate.day || 1;
4362				o.defaultViewDate = UTCDate(year, month, day);
4363			} else {
4364				o.defaultViewDate = UTCToday();
4365			}
4366		},
4367		_events: [],
4368		_secondaryEvents: [],
4369		_applyEvents: function(evs){
4370			for (var i=0, el, ch, ev; i < evs.length; i++){
4371				el = evs[i][0];
4372				if (evs[i].length === 2){
4373					ch = undefined;
4374					ev = evs[i][1];
4375				}
4376				else if (evs[i].length === 3){
4377					ch = evs[i][1];
4378					ev = evs[i][2];
4379				}
4380				el.on(ev, ch);
4381			}
4382		},
4383		_unapplyEvents: function(evs){
4384			for (var i=0, el, ev, ch; i < evs.length; i++){
4385				el = evs[i][0];
4386				if (evs[i].length === 2){
4387					ch = undefined;
4388					ev = evs[i][1];
4389				}
4390				else if (evs[i].length === 3){
4391					ch = evs[i][1];
4392					ev = evs[i][2];
4393				}
4394				el.off(ev, ch);
4395			}
4396		},
4397		_buildEvents: function(){
4398            var events = {
4399                keyup: $.proxy(function(e){
4400                    if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
4401                        this.update();
4402                }, this),
4403                keydown: $.proxy(this.keydown, this),
4404                paste: $.proxy(this.paste, this)
4405            };
4406
4407            if (this.o.showOnFocus === true) {
4408                events.focus = $.proxy(this.show, this);
4409            }
4410
4411            if (this.isInput) { // single input
4412                this._events = [
4413                    [this.element, events]
4414                ];
4415            }
4416            else if (this.component && this.hasInput) { // component: input + button
4417                this._events = [
4418                    // For components that are not readonly, allow keyboard nav
4419                    [this.inputField, events],
4420                    [this.component, {
4421                        click: $.proxy(this.show, this)
4422                    }]
4423                ];
4424            }
4425			else {
4426				this._events = [
4427					[this.element, {
4428						click: $.proxy(this.show, this),
4429						keydown: $.proxy(this.keydown, this)
4430					}]
4431				];
4432			}
4433			this._events.push(
4434				// Component: listen for blur on element descendants
4435				[this.element, '*', {
4436					blur: $.proxy(function(e){
4437						this._focused_from = e.target;
4438					}, this)
4439				}],
4440				// Input: listen for blur on element
4441				[this.element, {
4442					blur: $.proxy(function(e){
4443						this._focused_from = e.target;
4444					}, this)
4445				}]
4446			);
4447
4448			if (this.o.immediateUpdates) {
4449				// Trigger input updates immediately on changed year/month
4450				this._events.push([this.element, {
4451					'changeYear changeMonth': $.proxy(function(e){
4452						this.update(e.date);
4453					}, this)
4454				}]);
4455			}
4456
4457			this._secondaryEvents = [
4458				[this.picker, {
4459					click: $.proxy(this.click, this)
4460				}],
4461				[$(window), {
4462					resize: $.proxy(this.place, this)
4463				}],
4464				[$(document), {
4465					mousedown: $.proxy(function(e){
4466						// Clicked outside the datepicker, hide it
4467						if (!(
4468							this.element.is(e.target) ||
4469							this.element.find(e.target).length ||
4470							this.picker.is(e.target) ||
4471							this.picker.find(e.target).length ||
4472							this.isInline
4473						)){
4474							this.hide();
4475						}
4476					}, this)
4477				}]
4478			];
4479		},
4480		_attachEvents: function(){
4481			this._detachEvents();
4482			this._applyEvents(this._events);
4483		},
4484		_detachEvents: function(){
4485			this._unapplyEvents(this._events);
4486		},
4487		_attachSecondaryEvents: function(){
4488			this._detachSecondaryEvents();
4489			this._applyEvents(this._secondaryEvents);
4490		},
4491		_detachSecondaryEvents: function(){
4492			this._unapplyEvents(this._secondaryEvents);
4493		},
4494		_trigger: function(event, altdate){
4495			var date = altdate || this.dates.get(-1),
4496				local_date = this._utc_to_local(date);
4497
4498			this.element.trigger({
4499				type: event,
4500				date: local_date,
4501				dates: $.map(this.dates, this._utc_to_local),
4502				format: $.proxy(function(ix, format){
4503					if (arguments.length === 0){
4504						ix = this.dates.length - 1;
4505						format = this.o.format;
4506					}
4507					else if (typeof ix === 'string'){
4508						format = ix;
4509						ix = this.dates.length - 1;
4510					}
4511					format = format || this.o.format;
4512					var date = this.dates.get(ix);
4513					return DPGlobal.formatDate(date, format, this.o.language);
4514				}, this)
4515			});
4516		},
4517
4518		show: function(){
4519			if (this.inputField.prop('disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false))
4520				return;
4521			if (!this.isInline)
4522				this.picker.appendTo(this.o.container);
4523			this.place();
4524			this.picker.show();
4525			this._attachSecondaryEvents();
4526			this._trigger('show');
4527			if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {
4528				$(this.element).blur();
4529			}
4530			return this;
4531		},
4532
4533		hide: function(){
4534			if (this.isInline || !this.picker.is(':visible'))
4535				return this;
4536			this.focusDate = null;
4537			this.picker.hide().detach();
4538			this._detachSecondaryEvents();
4539			this.viewMode = this.o.startView;
4540			this.showMode();
4541
4542			if (this.o.forceParse && this.inputField.val())
4543				this.setValue();
4544			this._trigger('hide');
4545			return this;
4546		},
4547
4548		destroy: function(){
4549			this.hide();
4550			this._detachEvents();
4551			this._detachSecondaryEvents();
4552			this.picker.remove();
4553			delete this.element.data().datepicker;
4554			if (!this.isInput){
4555				delete this.element.data().date;
4556			}
4557			return this;
4558		},
4559
4560		paste: function(evt){
4561			var dateString;
4562			if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types
4563				&& $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {
4564				dateString = evt.originalEvent.clipboardData.getData('text/plain');
4565			}
4566			else if (window.clipboardData) {
4567				dateString = window.clipboardData.getData('Text');
4568			}
4569			else {
4570				return;
4571			}
4572			this.setDate(dateString);
4573			this.update();
4574			evt.preventDefault();
4575		},
4576
4577		_utc_to_local: function(utc){
4578			return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
4579		},
4580		_local_to_utc: function(local){
4581			return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
4582		},
4583		_zero_time: function(local){
4584			return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
4585		},
4586		_zero_utc_time: function(utc){
4587			return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
4588		},
4589
4590		getDates: function(){
4591			return $.map(this.dates, this._utc_to_local);
4592		},
4593
4594		getUTCDates: function(){
4595			return $.map(this.dates, function(d){
4596				return new Date(d);
4597			});
4598		},
4599
4600		getDate: function(){
4601			return this._utc_to_local(this.getUTCDate());
4602		},
4603
4604		getUTCDate: function(){
4605			var selected_date = this.dates.get(-1);
4606			if (typeof selected_date !== 'undefined') {
4607				return new Date(selected_date);
4608			} else {
4609				return null;
4610			}
4611		},
4612
4613		clearDates: function(){
4614			if (this.inputField) {
4615				this.inputField.val('');
4616			}
4617
4618			this.update();
4619			this._trigger('changeDate');
4620
4621			if (this.o.autoclose) {
4622				this.hide();
4623			}
4624		},
4625		setDates: function(){
4626			var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
4627			this.update.apply(this, args);
4628			this._trigger('changeDate');
4629			this.setValue();
4630			return this;
4631		},
4632
4633		setUTCDates: function(){
4634			var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
4635			this.update.apply(this, $.map(args, this._utc_to_local));
4636			this._trigger('changeDate');
4637			this.setValue();
4638			return this;
4639		},
4640
4641		setDate: alias('setDates'),
4642		setUTCDate: alias('setUTCDates'),
4643		remove: alias('destroy'),
4644
4645		setValue: function(){
4646			var formatted = this.getFormattedDate();
4647			this.inputField.val(formatted);
4648			return this;
4649		},
4650
4651		getFormattedDate: function(format){
4652			if (format === undefined)
4653				format = this.o.format;
4654
4655			var lang = this.o.language;
4656			return $.map(this.dates, function(d){
4657				return DPGlobal.formatDate(d, format, lang);
4658			}).join(this.o.multidateSeparator);
4659		},
4660
4661		getStartDate: function(){
4662			return this.o.startDate;
4663		},
4664
4665		setStartDate: function(startDate){
4666			this._process_options({startDate: startDate});
4667			this.update();
4668			this.updateNavArrows();
4669			return this;
4670		},
4671
4672		getEndDate: function(){
4673			return this.o.endDate;
4674		},
4675
4676		setEndDate: function(endDate){
4677			this._process_options({endDate: endDate});
4678			this.update();
4679			this.updateNavArrows();
4680			return this;
4681		},
4682
4683		setDaysOfWeekDisabled: function(daysOfWeekDisabled){
4684			this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
4685			this.update();
4686			this.updateNavArrows();
4687			return this;
4688		},
4689
4690		setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){
4691			this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});
4692			this.update();
4693			return this;
4694		},
4695
4696		setDatesDisabled: function(datesDisabled){
4697			this._process_options({datesDisabled: datesDisabled});
4698			this.update();
4699			this.updateNavArrows();
4700		},
4701
4702		place: function(){
4703			if (this.isInline)
4704				return this;
4705			var calendarWidth = this.picker.outerWidth(),
4706				calendarHeight = this.picker.outerHeight(),
4707				visualPadding = 10,
4708				container = $(this.o.container),
4709				windowWidth = container.width(),
4710				scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
4711				appendOffset = container.offset();
4712
4713			var parentsZindex = [];
4714			this.element.parents().each(function(){
4715				var itemZIndex = $(this).css('z-index');
4716				if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
4717			});
4718			var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
4719			var offset = this.component ? this.component.parent().offset() : this.element.offset();
4720			var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
4721			var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
4722			var left = offset.left - appendOffset.left,
4723				top = offset.top - appendOffset.top;
4724
4725			if (this.o.container !== 'body') {
4726				top += scrollTop;
4727			}
4728
4729			this.picker.removeClass(
4730				'datepicker-orient-top datepicker-orient-bottom '+
4731				'datepicker-orient-right datepicker-orient-left'
4732			);
4733
4734			if (this.o.orientation.x !== 'auto'){
4735				this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
4736				if (this.o.orientation.x === 'right')
4737					left -= calendarWidth - width;
4738			}
4739			// auto x orientation is best-placement: if it crosses a window
4740			// edge, fudge it sideways
4741			else {
4742				if (offset.left < 0) {
4743					// component is outside the window on the left side. Move it into visible range
4744					this.picker.addClass('datepicker-orient-left');
4745					left -= offset.left - visualPadding;
4746				} else if (left + calendarWidth > windowWidth) {
4747					// the calendar passes the widow right edge. Align it to component right side
4748					this.picker.addClass('datepicker-orient-right');
4749					left += width - calendarWidth;
4750				} else {
4751					// Default to left
4752					this.picker.addClass('datepicker-orient-left');
4753				}
4754			}
4755
4756			// auto y orientation is best-situation: top or bottom, no fudging,
4757			// decision based on which shows more of the calendar
4758			var yorient = this.o.orientation.y,
4759				top_overflow;
4760			if (yorient === 'auto'){
4761				top_overflow = -scrollTop + top - calendarHeight;
4762				yorient = top_overflow < 0 ? 'bottom' : 'top';
4763			}
4764
4765			this.picker.addClass('datepicker-orient-' + yorient);
4766			if (yorient === 'top')
4767				top -= calendarHeight + parseInt(this.picker.css('padding-top'));
4768			else
4769				top += height;
4770
4771			if (this.o.rtl) {
4772				var right = windowWidth - (left + width);
4773				this.picker.css({
4774					top: top,
4775					right: right,
4776					zIndex: zIndex
4777				});
4778			} else {
4779				this.picker.css({
4780					top: top,
4781					left: left,
4782					zIndex: zIndex
4783				});
4784			}
4785			return this;
4786		},
4787
4788		_allow_update: true,
4789		update: function(){
4790			if (!this._allow_update)
4791				return this;
4792
4793			var oldDates = this.dates.copy(),
4794				dates = [],
4795				fromArgs = false;
4796			if (arguments.length){
4797				$.each(arguments, $.proxy(function(i, date){
4798					if (date instanceof Date)
4799						date = this._local_to_utc(date);
4800					dates.push(date);
4801				}, this));
4802				fromArgs = true;
4803			}
4804			else {
4805				dates = this.isInput
4806						? this.element.val()
4807						: this.element.data('date') || this.inputField.val();
4808				if (dates && this.o.multidate)
4809					dates = dates.split(this.o.multidateSeparator);
4810				else
4811					dates = [dates];
4812				delete this.element.data().date;
4813			}
4814
4815			dates = $.map(dates, $.proxy(function(date){
4816				return DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear);
4817			}, this));
4818			dates = $.grep(dates, $.proxy(function(date){
4819				return (
4820					!this.dateWithinRange(date) ||
4821					!date
4822				);
4823			}, this), true);
4824			this.dates.replace(dates);
4825
4826			if (this.dates.length)
4827				this.viewDate = new Date(this.dates.get(-1));
4828			else if (this.viewDate < this.o.startDate)
4829				this.viewDate = new Date(this.o.startDate);
4830			else if (this.viewDate > this.o.endDate)
4831				this.viewDate = new Date(this.o.endDate);
4832			else
4833				this.viewDate = this.o.defaultViewDate;
4834
4835			if (fromArgs){
4836				// setting date by clicking
4837				this.setValue();
4838			}
4839			else if (dates.length){
4840				// setting date by typing
4841				if (String(oldDates) !== String(this.dates))
4842					this._trigger('changeDate');
4843			}
4844			if (!this.dates.length && oldDates.length)
4845				this._trigger('clearDate');
4846
4847			this.fill();
4848			this.element.change();
4849			return this;
4850		},
4851
4852		fillDow: function(){
4853			var dowCnt = this.o.weekStart,
4854				html = '<tr>';
4855			if (this.o.calendarWeeks){
4856				this.picker.find('.datepicker-days .datepicker-switch')
4857					.attr('colspan', function(i, val){
4858						return parseInt(val) + 1;
4859					});
4860				html += '<th class="cw">&#160;</th>';
4861			}
4862			while (dowCnt < this.o.weekStart + 7){
4863				html += '<th class="dow';
4864        if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) > -1)
4865          html += ' disabled';
4866        html += '">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
4867			}
4868			html += '</tr>';
4869			this.picker.find('.datepicker-days thead').append(html);
4870		},
4871
4872		fillMonths: function(){
4873      var localDate = this._utc_to_local(this.viewDate);
4874			var html = '',
4875			i = 0;
4876			while (i < 12){
4877        var focused = localDate && localDate.getMonth() === i ? ' focused' : '';
4878				html += '<span class="month' + focused + '">' + dates[this.o.language].monthsShort[i++]+'</span>';
4879			}
4880			this.picker.find('.datepicker-months td').html(html);
4881		},
4882
4883		setRange: function(range){
4884			if (!range || !range.length)
4885				delete this.range;
4886			else
4887				this.range = $.map(range, function(d){
4888					return d.valueOf();
4889				});
4890			this.fill();
4891		},
4892
4893		getClassNames: function(date){
4894			var cls = [],
4895				year = this.viewDate.getUTCFullYear(),
4896				month = this.viewDate.getUTCMonth(),
4897				today = new Date();
4898			if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
4899				cls.push('old');
4900			}
4901			else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
4902				cls.push('new');
4903			}
4904			if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
4905				cls.push('focused');
4906			// Compare internal UTC date with local today, not UTC today
4907			if (this.o.todayHighlight &&
4908				date.getUTCFullYear() === today.getFullYear() &&
4909				date.getUTCMonth() === today.getMonth() &&
4910				date.getUTCDate() === today.getDate()){
4911				cls.push('today');
4912			}
4913			if (this.dates.contains(date) !== -1)
4914				cls.push('active');
4915			if (!this.dateWithinRange(date)){
4916				cls.push('disabled');
4917			}
4918			if (this.dateIsDisabled(date)){
4919				cls.push('disabled', 'disabled-date');	
4920			} 
4921			if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
4922				cls.push('highlighted');
4923			}
4924
4925			if (this.range){
4926				if (date > this.range[0] && date < this.range[this.range.length-1]){
4927					cls.push('range');
4928				}
4929				if ($.inArray(date.valueOf(), this.range) !== -1){
4930					cls.push('selected');
4931				}
4932				if (date.valueOf() === this.range[0]){
4933          cls.push('range-start');
4934        }
4935        if (date.valueOf() === this.range[this.range.length-1]){
4936          cls.push('range-end');
4937        }
4938			}
4939			return cls;
4940		},
4941
4942		_fill_yearsView: function(selector, cssClass, factor, step, currentYear, startYear, endYear, callback){
4943			var html, view, year, steps, startStep, endStep, thisYear, i, classes, tooltip, before;
4944
4945			html      = '';
4946			view      = this.picker.find(selector);
4947			year      = parseInt(currentYear / factor, 10) * factor;
4948			startStep = parseInt(startYear / step, 10) * step;
4949			endStep   = parseInt(endYear / step, 10) * step;
4950			steps     = $.map(this.dates, function(d){
4951				return parseInt(d.getUTCFullYear() / step, 10) * step;
4952			});
4953
4954			view.find('.datepicker-switch').text(year + '-' + (year + step * 9));
4955
4956			thisYear = year - step;
4957			for (i = -1; i < 11; i += 1) {
4958				classes = [cssClass];
4959				tooltip = null;
4960
4961				if (i === -1) {
4962					classes.push('old');
4963				} else if (i === 10) {
4964					classes.push('new');
4965				}
4966				if ($.inArray(thisYear, steps) !== -1) {
4967					classes.push('active');
4968				}
4969				if (thisYear < startStep || thisYear > endStep) {
4970					classes.push('disabled');
4971				}
4972        if (thisYear === this.viewDate.getFullYear()) {
4973				  classes.push('focused');
4974        }
4975
4976				if (callback !== $.noop) {
4977					before = callback(new Date(thisYear, 0, 1));
4978					if (before === undefined) {
4979						before = {};
4980					} else if (typeof(before) === 'boolean') {
4981						before = {enabled: before};
4982					} else if (typeof(before) === 'string') {
4983						before = {classes: before};
4984					}
4985					if (before.enabled === false) {
4986						classes.push('disabled');
4987					}
4988					if (before.classes) {
4989						classes = classes.concat(before.classes.split(/\s+/));
4990					}
4991					if (before.tooltip) {
4992						tooltip = before.tooltip;
4993					}
4994				}
4995
4996				html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>
4996' + thisYear + '</span>';
4997				thisYear += step;
4998			}
4999			view.find('td').html(html);
5000		},
5001
5002		fill: function(){
5003			var d = new Date(this.viewDate),
5004				year = d.getUTCFullYear(),
5005				month = d.getUTCMonth(),
5006				startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
5007				startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
5008				endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
5009				endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
5010				todaytxt = dates[this.o.language].today || dates['en'].today || '',
5011				cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
5012				titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,
5013				tooltip,
5014				before;
5015			if (isNaN(year) || isNaN(month))
5016				return;
5017			this.picker.find('.datepicker-days .datepicker-switch')
5018						.text(DPGlobal.formatDate(d, titleFormat, this.o.language));
5019			this.picker.find('tfoot .today')
5020						.text(todaytxt)
5021						.toggle(this.o.todayBtn !== false);
5022			this.picker.find('tfoot .clear')
5023						.text(cleartxt)
5024						.toggle(this.o.clearBtn !== false);
5025			this.picker.find('thead .datepicker-title')
5026						.text(this.o.title)
5027						.toggle(this.o.title !== '');
5028			this.updateNavArrows();
5029			this.fillMonths();
5030			var prevMonth = UTCDate(year, month-1, 28),
5031				day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
5032			prevMonth.setUTCDate(day);
5033			prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
5034			var nextMonth = new Date(prevMonth);
5035			if (prevMonth.getUTCFullYear() < 100){
5036        nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
5037      }
5038			nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
5039			nextMonth = nextMonth.valueOf();
5040			var html = [];
5041			var clsName;
5042			while (prevMonth.valueOf() < nextMonth){
5043				if (prevMonth.getUTCDay() === this.o.weekStart){
5044					html.push('<tr>');
5045					if (this.o.calendarWeeks){
5046						// ISO 8601: First week contains first thursday.
5047						// ISO also states week starts on Monday, but we can be more abstract here.
5048						var
5049							// Start of current week: based on weekstart/current date
5050							ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
5051							// Thursday of this week
5052							th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
5053							// First Thursday of year, year from thursday
5054							yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
5055							// Calendar week: ms between thursdays, div ms per day, div 7 days
5056							calWeek =  (th - yth) / 864e5 / 7 + 1;
5057						html.push('<td class="cw">'+ calWeek +'</td>');
5058					}
5059				}
5060				clsName = this.getClassNames(prevMonth);
5061				clsName.push('day');
5062
5063				if (this.o.beforeShowDay !== $.noop){
5064					before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
5065					if (before === undefined)
5066						before = {};
5067					else if (typeof(before) === 'boolean')
5068						before = {enabled: before};
5069					else if (typeof(before) === 'string')
5070						before = {classes: before};
5071					if (before.enabled === false)
5072						clsName.push('disabled');
5073					if (before.classes)
5074						clsName = clsName.concat(before.classes.split(/\s+/));
5075					if (before.tooltip)
5076						tooltip = before.tooltip;
5077				}
5078
5079				//Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)
5080				//Fallback to unique function for older jquery versions
5081				if ($.isFunction($.uniqueSort)) {
5082					clsName = $.uniqueSort(clsName);
5083				} else {
5084					clsName = $.unique(clsName);
5085				}
5086
5087				html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
5088				tooltip = null;
5089				if (prevMonth.getUTCDay() === this.o.weekEnd){
5090					html.push('</tr>');
5091				}
5092				prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
5093			}
5094			this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
5095
5096			var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
5097			var months = this.picker.find('.datepicker-months')
5098						.find('.datepicker-switch')
5099							.text(this.o.maxViewMode < 2 ? monthsTitle : year)
5100							.end()
5101						.find('span').removeClass('active');
5102
5103			$.each(this.dates, function(i, d){
5104				if (d.getUTCFullYear() === year)
5105					months.eq(d.getUTCMonth()).addClass('active');
5106			});
5107
5108			if (year < startYear || year > endYear){
5109				months.addClass('disabled');
5110			}
5111			if (year === startYear){
5112				months.slice(0, startMonth).addClass('disabled');
5113			}
5114			if (year === endYear){
5115				months.slice(endMonth+1).addClass('disabled');
5116			}
5117
5118			if (this.o.beforeShowMonth !== $.noop){
5119				var that = this;
5120				$.each(months, function(i, month){
5121          var moDate = new Date(year, i, 1);
5122          var before = that.o.beforeShowMonth(moDate);
5123					if (before === undefined)
5124						before = {};
5125					else if (typeof(before) === 'boolean')
5126						before = {enabled: before};
5127					else if (typeof(before) === 'string')
5128						before = {classes: before};
5129					if (before.enabled === false && !$(month).hasClass('disabled'))
5130					    $(month).addClass('disabled');
5131					if (before.classes)
5132					    $(month).addClass(before.classes);
5133					if (before.tooltip)
5134					    $(month).prop('title', before.tooltip);
5135				});
5136			}
5137
5138			// Generating decade/years picker
5139			this._fill_yearsView(
5140				'.datepicker-years',
5141				'year',
5142				10,
5143				1,
5144				year,
5145				startYear,
5146				endYear,
5147				this.o.beforeShowYear
5148			);
5149
5150			// Generating century/decades picker
5151			this._fill_yearsView(
5152				'.datepicker-decades',
5153				'decade',
5154				100,
5155				10,
5156				year,
5157				startYear,
5158				endYear,
5159				this.o.beforeShowDecade
5160			);
5161
5162			// Generating millennium/centuries picker
5163			this._fill_yearsView(
5164				'.datepicker-centuries',
5165				'century',
5166				1000,
5167				100,
5168				year,
5169				startYear,
5170				endYear,
5171				this.o.beforeShowCentury
5172			);
5173		},
5174
5175		updateNavArrows: function(){
5176			if (!this._allow_update)
5177				return;
5178
5179			var d = new Date(this.viewDate),
5180				year = d.getUTCFullYear(),
5181				month = d.getUTCMonth();
5182			switch (this.viewMode){
5183				case 0:
5184					if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
5185						this.picker.find('.prev').css({visibility: 'hidden'});
5186					}
5187					else {
5188						this.picker.find('.prev').css({visibility: 'visible'});
5189					}
5190					if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
5191						this.picker.find('.next').css({visibility: 'hidden'});
5192					}
5193					else {
5194						this.picker.find('.next').css({visibility: 'visible'});
5195					}
5196					break;
5197				case 1:
5198				case 2:
5199				case 3:
5200				case 4:
5201					if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){
5202						this.picker.find('.prev').css({visibility: 'hidden'});
5203					}
5204					else {
5205						this.picker.find('.prev').css({visibility: 'visible'});
5206					}
5207					if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){
5208						this.picker.find('.next').css({visibility: 'hidden'});
5209					}
5210					else {
5211						this.picker.find('.next').css({visibility: 'visible'});
5212					}
5213					break;
5214			}
5215		},
5216
5217		click: function(e){
5218			e.preventDefault();
5219			e.stopPropagation();
5220
5221			var target, dir, day, year, month, monthChanged, yearChanged;
5222			target = $(e.target);
5223
5224			// Clicked on the switch
5225			if (target.hasClass('datepicker-switch')){
5226				this.showMode(1);
5227			}
5228
5229			// Clicked on prev or next
5230			var navArrow = target.closest('.prev, .next');
5231			if (navArrow.length > 0) {
5232				dir = DPGlobal.modes[this.viewMode].navStep * (navArrow.hasClass('prev') ? -1 : 1);
5233				if (this.viewMode === 0){
5234					this.viewDate = this.moveMonth(this.viewDate, dir);
5235					this._trigger('changeMonth', this.viewDate);
5236				} else {
5237					this.viewDate = this.moveYear(this.viewDate, dir);
5238					if (this.viewMode === 1){
5239						this._trigger('changeYear', this.viewDate);
5240					}
5241				}
5242				this.fill();
5243			}
5244
5245			// Clicked on today button
5246			if (target.hasClass('today') && !target.hasClass('day')){
5247				this.showMode(-2);
5248				this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
5249			}
5250
5251			// Clicked on clear button
5252			if (target.hasClass('clear')){
5253				this.clearDates();
5254			}
5255
5256			if (!target.hasClass('disabled')){
5257				// Clicked on a day
5258				if (target.hasClass('day')){
5259					day = parseInt(target.text(), 10) || 1;
5260					year = this.viewDate.getUTCFullYear();
5261					month = this.viewDate.getUTCMonth();
5262
5263					// From last month
5264					if (target.hasClass('old')){
5265						if (month === 0) {
5266							month = 11;
5267							year = year - 1;
5268							monthChanged = true;
5269							yearChanged = true;
5270						} else {
5271							month = month - 1;
5272							monthChanged = true;
5273 						}
5274 					}
5275
5276					// From next month
5277					if (target.hasClass('new')) {
5278						if (month === 11){
5279							month = 0;
5280							year = year + 1;
5281							monthChanged = true;
5282							yearChanged = true;
5283 						} else {
5284							month = month + 1;
5285							monthChanged = true;
5286 						}
5287					}
5288					this._setDate(UTCDate(year, month, day));
5289					if (yearChanged) {
5290						this._trigger('changeYear', this.viewDate);
5291					}
5292					if (monthChanged) {
5293						this._trigger('changeMonth', this.viewDate);
5294					}
5295				}
5296
5297				// Clicked on a month
5298				if (target.hasClass('month')) {
5299					this.viewDate.setUTCDate(1);
5300					day = 1;
5301					month = target.parent().find('span').index(target);
5302					year = this.viewDate.getUTCFullYear();
5303					this.viewDate.setUTCMonth(month);
5304					this._trigger('changeMonth', this.viewDate);
5305					if (this.o.minViewMode === 1){
5306						this._setDate(UTCDate(year, month, day));
5307						this.showMode();
5308					} else {
5309						this.showMode(-1);
5310					}
5311					this.fill();
5312				}
5313
5314				// Clicked on a year
5315				if (target.hasClass('year')
5316						|| target.hasClass('decade')
5317						|| target.hasClass('century')) {
5318					this.viewDate.setUTCDate(1);
5319
5320					day = 1;
5321					month = 0;
5322					year = parseInt(target.text(), 10)||0;
5323					this.viewDate.setUTCFullYear(year);
5324
5325					if (target.hasClass('year')){
5326						this._trigger('changeYear', this.viewDate);
5327						if (this.o.minViewMode === 2){
5328							this._setDate(UTCDate(year, month, day));
5329						}
5330					}
5331					if (target.hasClass('decade')){
5332						this._trigger('changeDecade', this.viewDate);
5333						if (this.o.minViewMode === 3){
5334							this._setDate(UTCDate(year, month, day));
5335						}
5336					}
5337					if (target.hasClass('century')){
5338						this._trigger('changeCentury', this.viewDate);
5339						if (this.o.minViewMode === 4){
5340							this._setDate(UTCDate(year, month, day));
5341						}
5342					}
5343
5344					this.showMode(-1);
5345					this.fill();
5346				}
5347			}
5348
5349			if (this.picker.is(':visible') && this._focused_from){
5350				$(this._focused_from).focus();
5351			}
5352			delete this._focused_from;
5353		},
5354
5355		_toggle_multidate: function(date){
5356			var ix = this.dates.contains(date);
5357			if (!date){
5358				this.dates.clear();
5359			}
5360
5361			if (ix !== -1){
5362				if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){
5363					this.dates.remove(ix);
5364				}
5365			} else if (this.o.multidate === false) {
5366				this.dates.clear();
5367				this.dates.push(date);
5368			}
5369			else {
5370				this.dates.push(date);
5371			}
5372
5373			if (typeof this.o.multidate === 'number')
5374				while (this.dates.length > this.o.multidate)
5375					this.dates.remove(0);
5376		},
5377
5378		_setDate: function(date, which){
5379			if (!which || which === 'date')
5380				this._toggle_multidate(date && new Date(date));
5381			if (!which || which === 'view')
5382				this.viewDate = date && new Date(date);
5383
5384			this.fill();
5385			this.setValue();
5386			if (!which || which !== 'view') {
5387				this._trigger('changeDate');
5388			}
5389			if (this.inputField){
5390				this.inputField.change();
5391			}
5392			if (this.o.autoclose && (!which || which === 'date')){
5393				this.hide();
5394			}
5395		},
5396
5397		moveDay: function(date, dir){
5398			var newDate = new Date(date);
5399			newDate.setUTCDate(date.getUTCDate() + dir);
5400
5401			return newDate;
5402		},
5403
5404		moveWeek: function(date, dir){
5405			return this.moveDay(date, dir * 7);
5406		},
5407
5408		moveMonth: function(date, dir){
5409			if (!isValidDate(date))
5410				return this.o.defaultViewDate;
5411			if (!dir)
5412				return date;
5413			var new_date = new Date(date.valueOf()),
5414				day = new_date.getUTCDate(),
5415				month = new_date.getUTCMonth(),
5416				mag = Math.abs(dir),
5417				new_month, test;
5418			dir = dir > 0 ? 1 : -1;
5419			if (mag === 1){
5420				test = dir === -1
5421					// If going back one month, make sure month is not current month
5422					// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
5423					? function(){
5424						return new_date.getUTCMonth() === month;
5425					}
5426					// If going forward one month, make sure month is as expected
5427					// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
5428					: function(){
5429						return new_date.getUTCMonth() !== new_month;
5430					};
5431				new_month = month + dir;
5432				new_date.setUTCMonth(new_month);
5433				// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
5434				if (new_month < 0 || new_month > 11)
5435					new_month = (new_month + 12) % 12;
5436			}
5437			else {
5438				// For magnitudes >1, move one month at a time...
5439				for (var i=0; i < mag; i++)
5440					// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
5441					new_date = this.moveMonth(new_date, dir);
5442				// ...then reset the day, keeping it in the new month
5443				new_month = new_date.getUTCMonth();
5444				new_date.setUTCDate(day);
5445				test = function(){
5446					return new_month !== new_date.getUTCMonth();
5447				};
5448			}
5449			// Common date-resetting loop -- if date is beyond end of month, make it
5450			// end of month
5451			while (test()){
5452				new_date.setUTCDate(--day);
5453				new_date.setUTCMonth(new_month);
5454			}
5455			return new_date;
5456		},
5457
5458		moveYear: function(date, dir){
5459			return this.moveMonth(date, dir*12);
5460		},
5461
5462		moveAvailableDate: function(date, dir, fn){
5463			do {
5464				date = this[fn](date, dir);
5465
5466				if (!this.dateWithinRange(date))
5467					return false;
5468
5469				fn = 'moveDay';
5470			}
5471			while (this.dateIsDisabled(date));
5472
5473			return date;
5474		},
5475
5476		weekOfDateIsDisabled: function(date){
5477			return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;
5478		},
5479
5480		dateIsDisabled: function(date){
5481			return (
5482				this.weekOfDateIsDisabled(date) ||
5483				$.grep(this.o.datesDisabled, function(d){
5484					return isUTCEquals(date, d);
5485				}).length > 0
5486			);
5487		},
5488
5489		dateWithinRange: function(date){
5490			return date >= this.o.startDate && date <= this.o.endDate;
5491		},
5492
5493		keydown: function(e){
vendor: 9,292 bytes, lines 5494-5824
5494			if (!this.picker.is(':visible')){
5495				if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker
5496					this.show();
5497					e.stopPropagation();
5498        }
5499				return;
5500			}
5501			var dateChanged = false,
5502				dir, newViewDate,
5503				focusDate = this.focusDate || this.viewDate;
5504			switch (e.keyCode){
5505				case 27: // escape
5506					if (this.focusDate){
5507						this.focusDate = null;
5508						this.viewDate = this.dates.get(-1) || this.viewDate;
5509						this.fill();
5510					}
5511					else
5512						this.hide();
5513					e.preventDefault();
5514					e.stopPropagation();
5515					break;
5516				case 37: // left
5517				case 38: // up
5518				case 39: // right
5519				case 40: // down
5520					if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7)
5521						break;
5522					dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;
5523          if (this.viewMode === 0) {
5524  					if (e.ctrlKey){
5525  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
5526
5527  						if (newViewDate)
5528  							this._trigger('changeYear', this.viewDate);
5529  					}
5530  					else if (e.shiftKey){
5531  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
5532
5533  						if (newViewDate)
5534  							this._trigger('changeMonth', this.viewDate);
5535  					}
5536  					else if (e.keyCode === 37 || e.keyCode === 39){
5537  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
5538  					}
5539  					else if (!this.weekOfDateIsDisabled(focusDate)){
5540  						newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
5541  					}
5542          } else if (this.viewMode === 1) {
5543            if (e.keyCode === 38 || e.keyCode === 40) {
5544              dir = dir * 4;
5545            }
5546            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
5547          } else if (this.viewMode === 2) {
5548            if (e.keyCode === 38 || e.keyCode === 40) {
5549              dir = dir * 4;
5550            }
5551            newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
5552          }
5553					if (newViewDate){
5554						this.focusDate = this.viewDate = newViewDate;
5555						this.setValue();
5556						this.fill();
5557						e.preventDefault();
5558					}
5559					break;
5560				case 13: // enter
5561					if (!this.o.forceParse)
5562						break;
5563					focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
5564					if (this.o.keyboardNavigation) {
5565						this._toggle_multidate(focusDate);
5566						dateChanged = true;
5567					}
5568					this.focusDate = null;
5569					this.viewDate = this.dates.get(-1) || this.viewDate;
5570					this.setValue();
5571					this.fill();
5572					if (this.picker.is(':visible')){
5573						e.preventDefault();
5574						e.stopPropagation();
5575						if (this.o.autoclose)
5576							this.hide();
5577					}
5578					break;
5579				case 9: // tab
5580					this.focusDate = null;
5581					this.viewDate = this.dates.get(-1) || this.viewDate;
5582					this.fill();
5583					this.hide();
5584					break;
5585			}
5586			if (dateChanged){
5587				if (this.dates.length)
5588					this._trigger('changeDate');
5589				else
5590					this._trigger('clearDate');
5591				if (this.inputField){
5592					this.inputField.change();
5593				}
5594			}
5595		},
5596
5597		showMode: function(dir){
5598			if (dir){
5599				this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));
5600			}
5601			this.picker
5602				.children('div')
5603				.hide()
5604				.filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
5605					.show();
5606			this.updateNavArrows();
5607		}
5608	};
5609
5610	var DateRangePicker = function(element, options){
5611		$(element).data('datepicker', this);
5612		this.element = $(element);
5613		this.inputs = $.map(options.inputs, function(i){
5614			return i.jquery ? i[0] : i;
5615		});
5616		delete options.inputs;
5617
5618		datepickerPlugin.call($(this.inputs), options)
5619			.on('changeDate', $.proxy(this.dateUpdated, this));
5620
5621		this.pickers = $.map(this.inputs, function(i){
5622			return $(i).data('datepicker');
5623		});
5624		this.updateDates();
5625	};
5626	DateRangePicker.prototype = {
5627		updateDates: function(){
5628			this.dates = $.map(this.pickers, function(i){
5629				return i.getUTCDate();
5630			});
5631			this.updateRanges();
5632		},
5633		updateRanges: function(){
5634			var range = $.map(this.dates, function(d){
5635				return d.valueOf();
5636			});
5637			$.each(this.pickers, function(i, p){
5638				p.setRange(range);
5639			});
5640		},
5641		dateUpdated: function(e){
5642			// `this.updating` is a workaround for preventing infinite recursion
5643			// between `changeDate` triggering and `setUTCDate` calling.  Until
5644			// there is a better mechanism.
5645			if (this.updating)
5646				return;
5647			this.updating = true;
5648
5649			var dp = $(e.target).data('datepicker');
5650
5651			if (typeof(dp) === "undefined") {
5652				return;
5653			}
5654
5655			var new_date = dp.getUTCDate(),
5656				i = $.inArray(e.target, this.inputs),
5657				j = i - 1,
5658				k = i + 1,
5659				l = this.inputs.length;
5660			if (i === -1)
5661				return;
5662
5663			$.each(this.pickers, function(i, p){
5664				if (!p.getUTCDate())
5665					p.setUTCDate(new_date);
5666			});
5667
5668			if (new_date < this.dates[j]){
5669				// Date being moved earlier/left
5670				while (j >= 0 && new_date < this.dates[j]){
5671					this.pickers[j--].setUTCDate(new_date);
5672				}
5673			}
5674			else if (new_date > this.dates[k]){
5675				// Date being moved later/right
5676				while (k < l && new_date > this.dates[k]){
5677					this.pickers[k++].setUTCDate(new_date);
5678				}
5679			}
5680			this.updateDates();
5681
5682			delete this.updating;
5683		},
5684		remove: function(){
5685			$.map(this.pickers, function(p){ p.remove(); });
5686			delete this.element.data().datepicker;
5687		}
5688	};
5689
5690	function opts_from_el(el, prefix){
5691		// Derive options from element data-attrs
5692		var data = $(el).data(),
5693			out = {}, inkey,
5694			replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
5695		prefix = new RegExp('^' + prefix.toLowerCase());
5696		function re_lower(_,a){
5697			return a.toLowerCase();
5698		}
5699		for (var key in data)
5700			if (prefix.test(key)){
5701				inkey = key.replace(replace, re_lower);
5702				out[inkey] = data[key];
5703			}
5704		return out;
5705	}
5706
5707	function opts_from_locale(lang){
5708		// Derive options from locale plugins
5709		var out = {};
5710		// Check if "de-DE" style date is available, if not language should
5711		// fallback to 2 letter code eg "de"
5712		if (!dates[lang]){
5713			lang = lang.split('-')[0];
5714			if (!dates[lang])
5715				return;
5716		}
5717		var d = dates[lang];
5718		$.each(locale_opts, function(i,k){
5719			if (k in d)
5720				out[k] = d[k];
5721		});
5722		return out;
5723	}
5724
5725	var old = $.fn.datepicker;
5726	var datepickerPlugin = function(option){
5727		var args = Array.apply(null, arguments);
5728		args.shift();
5729		var internal_return;
5730		this.each(function(){
5731			var $this = $(this),
5732				data = $this.data('datepicker'),
5733				options = typeof option === 'object' && option;
5734			if (!data){
5735				var elopts = opts_from_el(this, 'date'),
5736					// Preliminary otions
5737					xopts = $.extend({}, defaults, elopts, options),
5738					locopts = opts_from_locale(xopts.language),
5739					// Options priority: js args, data-attrs, locales, defaults
5740					opts = $.extend({}, defaults, locopts, elopts, options);
5741				if ($this.hasClass('input-daterange') || opts.inputs){
5742					$.extend(opts, {
5743						inputs: opts.inputs || $this.find('input').toArray()
5744					});
5745					data = new DateRangePicker(this, opts);
5746				}
5747				else {
5748					data = new Datepicker(this, opts);
5749				}
5750				$this.data('datepicker', data);
5751			}
5752			if (typeof option === 'string' && typeof data[option] === 'function'){
5753				internal_return = data[option].apply(data, args);
5754			}
5755		});
5756
5757		if (
5758			internal_return === undefined ||
5759			internal_return instanceof Datepicker ||
5760			internal_return instanceof DateRangePicker
5761		)
5762			return this;
5763
5764		if (this.length > 1)
5765			throw new Error('Using only allowed for the collection of a single element (' + option + ' function)');
5766		else
5767			return internal_return;
5768	};
5769	$.fn.datepicker = datepickerPlugin;
5770
5771	var defaults = $.fn.datepicker.defaults = {
5772		assumeNearbyYear: false,
5773		autoclose: false,
5774		beforeShowDay: $.noop,
5775		beforeShowMonth: $.noop,
5776		beforeShowYear: $.noop,
5777		beforeShowDecade: $.noop,
5778		beforeShowCentury: $.noop,
5779		calendarWeeks: false,
5780		clearBtn: false,
5781		toggleActive: false,
5782		daysOfWeekDisabled: [],
5783		daysOfWeekHighlighted: [],
5784		datesDisabled: [],
5785		endDate: Infinity,
5786		forceParse: true,
5787		format: 'mm/dd/yyyy',
5788		keyboardNavigation: true,
5789		language: 'en',
5790		minViewMode: 0,
5791		maxViewMode: 4,
5792		multidate: false,
5793		multidateSeparator: ',',
5794		orientation: "auto",
5795		rtl: false,
5796		startDate: -Infinity,
5797		startView: 0,
5798		todayBtn: false,
5799		todayHighlight: false,
5800		weekStart: 0,
5801		disableTouchKeyboard: false,
5802		enableOnReadonly: true,
5803		showOnFocus: true,
5804		zIndexOffset: 10,
5805		container: 'body',
5806		immediateUpdates: false,
5807		title: '',
5808		templates: {
5809			leftArrow: '&laquo;',
5810			rightArrow: '&raquo;'
5811		}
5812	};
5813	var locale_opts = $.fn.datepicker.locale_opts = [
5814		'format',
5815		'rtl',
5816		'weekStart'
5817	];
5818	$.fn.datepicker.Constructor = Datepicker;
5819	var dates = $.fn.datepicker.dates = {
5820		en: {
5821			days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
5822			daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
5823			daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
5824			months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
5824November", "December"],
5825			monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
5826			today: "Today",
5827			clear: "Clear",
5828			titleFormat: "MM yyyy"
5829		}
5830	};
5831
5832	var DPGlobal = {
5833		modes: [
5834			{
5835				clsName: 'days',
5836				navFnc: 'Month',
5837				navStep: 1
5838			},
5839			{
5840				clsName: 'months',
5841				navFnc: 'FullYear',
5842				navStep: 1
5843			},
5844			{
5845				clsName: 'years',
5846				navFnc: 'FullYear',
5847				navStep: 10
5848			},
5849			{
5850				clsName: 'decades',
5851				navFnc: 'FullDecade',
5852				navStep: 100
5853			},
5854			{
5855				clsName: 'centuries',
5856				navFnc: 'FullCentury',
5857				navStep: 1000
5858		}],
5859		isLeapYear: function(year){
5860			return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
5861		},
5862		getDaysInMonth: function(year, month){
5863			return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
5864		},
5865		validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
5866		nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
5867		parseFormat: function(format){
5868			if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')
5869                return format;
5870            // IE treats \0 as a string end in inputs (truncating the value),
5871			// so it's a bad format delimiter, anyway
5872			var separators = format.replace(this.validParts, '\0').split('\0'),
5873				parts = format.match(this.validParts);
5874			if (!separators || !separators.length || !parts || parts.length === 0){
5875				throw new Error("Invalid date format.");
5876			}
5877			return {separators: separators, parts: parts};
5878		},
5879		parseDate: function(date, format, language, assumeNearby){
5880			if (!date)
5881				return undefined;
5882			if (date instanceof Date)
5883				return date;
5884			if (typeof format === 'string')
5885				format = DPGlobal.parseFormat(format);
5886			if (format.toValue)
5887                return format.toValue(date, format, language);
5888            var part_re = /([\-+]\d+)([dmwy])/,
5889				parts = date.match(/([\-+]\d+)([dmwy])/g),
5890				fn_map = {
5891					d: 'moveDay',
5892					m: 'moveMonth',
5893					w: 'moveWeek',
5894					y: 'moveYear'
5895				},
5896				dateAliases = {
5897					yesterday: '-1d',
5898					today: '+0d',
5899					tomorrow: '+1d'
5900				},
5901				part, dir, i, fn;
5902			if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
5903				date = new Date();
5904				for (i=0; i < parts.length; i++){
5905					part = part_re.exec(parts[i]);
5906					dir = parseInt(part[1]);
5907					fn = fn_map[part[2]];
5908					date = Datepicker.prototype[fn](date, dir);
5909				}
5910				return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
5911			}
5912
5913			if (typeof dateAliases[date] !== 'undefined') {
5914				date = dateAliases[date];
5915				parts = date.match(/([\-+]\d+)([dmwy])/g);
5916
5917				if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
5918					date = new Date();
5919				  	for (i=0; i < parts.length; i++){
5920						part = part_re.exec(parts[i]);
5921						dir = parseInt(part[1]);
5922						fn = fn_map[part[2]];
5923						date = Datepicker.prototype[fn](date, dir);
5924				  	}
5925
5926			  		return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
5927				}
5928			}
5929
5930			parts = date && date.match(this.nonpunctuation) || [];
5931			date = new Date();
5932
5933			function applyNearbyYear(year, threshold){
5934				if (threshold === true)
5935					threshold = 10;
5936
5937				// if year is 2 digits or less, than the user most likely is trying to get a recent century
5938				if (year < 100){
5939					year += 2000;
5940					// if the new year is more than threshold years in advance, use last century
5941					if (year > ((new Date()).getFullYear()+threshold)){
5942						year -= 100;
5943					}
5944				}
5945
5946				return year;
5947			}
5948
5949			var parsed = {},
5950				setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
5951				setters_map = {
5952					yyyy: function(d,v){
5953						return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
5954					},
5955					yy: function(d,v){
5956						return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
5957					},
5958					m: function(d,v){
5959						if (isNaN(d))
5960							return d;
5961						v -= 1;
5962						while (v < 0) v += 12;
5963						v %= 12;
5964						d.setUTCMonth(v);
5965						while (d.getUTCMonth() !== v)
5966							d.setUTCDate(d.getUTCDate()-1);
5967						return d;
5968					},
5969					d: function(d,v){
5970						return d.setUTCDate(v);
5971					}
5972				},
5973				val, filtered;
5974			setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
5975			setters_map['dd'] = setters_map['d'];
5976			date = UTCToday();
5977			var fparts = format.parts.slice();
5978			// Remove noop parts
5979			if (parts.length !== fparts.length){
5980				fparts = $(fparts).filter(function(i,p){
5981					return $.inArray(p, setters_order) !== -1;
5982				}).toArray();
5983			}
5984			// Process remainder
5985			function match_part(){
5986				var m = this.slice(0, parts[i].length),
5987					p = parts[i].slice(0, m.length);
5988				return m.toLowerCase() === p.toLowerCase();
5989			}
5990			if (parts.length === fparts.length){
5991				var cnt;
5992				for (i=0, cnt = fparts.length; i < cnt; i++){
5993					val = parseInt(parts[i], 10);
5994					part = fparts[i];
vendor: 5,162 bytes, lines 5995-6164
5995					if (isNaN(val)){
5996						switch (part){
5997							case 'MM':
5998								filtered = $(dates[language].months).filter(match_part);
5999								val = $.inArray(filtered[0], dates[language].months) + 1;
6000								break;
6001							case 'M':
6002								filtered = $(dates[language].monthsShort).filter(match_part);
6003								val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
6004								break;
6005						}
6006					}
6007					parsed[part] = val;
6008				}
6009				var _date, s;
6010				for (i=0; i < setters_order.length; i++){
6011					s = setters_order[i];
6012					if (s in parsed && !isNaN(parsed[s])){
6013						_date = new Date(date);
6014						setters_map[s](_date, parsed[s]);
6015						if (!isNaN(_date))
6016							date = _date;
6017					}
6018				}
6019			}
6020			return date;
6021		},
6022		formatDate: function(date, format, language){
6023			if (!date)
6024				return '';
6025			if (typeof format === 'string')
6026				format = DPGlobal.parseFormat(format);
6027			if (format.toDisplay)
6028                return format.toDisplay(date, format, language);
6029            var val = {
6030				d: date.getUTCDate(),
6031				D: dates[language].daysShort[date.getUTCDay()],
6032				DD: dates[language].days[date.getUTCDay()],
6033				m: date.getUTCMonth() + 1,
6034				M: dates[language].monthsShort[date.getUTCMonth()],
6035				MM: dates[language].months[date.getUTCMonth()],
6036				yy: date.getUTCFullYear().toString().substring(2),
6037				yyyy: date.getUTCFullYear()
6038			};
6039			val.dd = (val.d < 10 ? '0' : '') + val.d;
6040			val.mm = (val.m < 10 ? '0' : '') + val.m;
6041			date = [];
6042			var seps = $.extend([], format.separators);
6043			for (var i=0, cnt = format.parts.length; i <= cnt; i++){
6044				if (seps.length)
6045					date.push(seps.shift());
6046				date.push(val[format.parts[i]]);
6047			}
6048			return date.join('');
6049		},
6050		headTemplate: '<thead>'+
6051			              '<tr>'+
6052			                '<th colspan="7" class="datepicker-title"></th>'+
6053			              '</tr>'+
6054							'<tr>'+
6055								'<th class="prev">&laquo;</th>'+
6056								'<th colspan="5" class="datepicker-switch"></th>'+
6057								'<th class="next">&raquo;</th>'+
6058							'</tr>'+
6059						'</thead>',
6060		contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
6061		footTemplate: '<tfoot>'+
6062							'<tr>'+
6063								'<th colspan="7" class="today"></th>'+
6064							'</tr>'+
6065							'<tr>'+
6066								'<th colspan="7" class="clear"></th>'+
6067							'</tr>'+
6068						'</tfoot>'
6069	};
6070	DPGlobal.template = '<div class="datepicker">'+
6071							'<div class="datepicker-days">'+
6072								'<table class="table-condensed">'+
6073									DPGlobal.headTemplate+
6074									'<tbody></tbody>'+
6075									DPGlobal.footTemplate+
6076								'</table>'+
6077							'</div>'+
6078							'<div class="datepicker-months">'+
6079								'<table class="table-condensed">'+
6080									DPGlobal.headTemplate+
6081									DPGlobal.contTemplate+
6082									DPGlobal.footTemplate+
6083								'</table>'+
6084							'</div>'+
6085							'<div class="datepicker-years">'+
6086								'<table class="table-condensed">'+
6087									DPGlobal.headTemplate+
6088									DPGlobal.contTemplate+
6089									DPGlobal.footTemplate+
6090								'</table>'+
6091							'</div>'+
6092							'<div class="datepicker-decades">'+
6093								'<table class="table-condensed">'+
6094									DPGlobal.headTemplate+
6095									DPGlobal.contTemplate+
6096									DPGlobal.footTemplate+
6097								'</table>'+
6098							'</div>'+
6099							'<div class="datepicker-centuries">'+
6100								'<table class="table-condensed">'+
6101									DPGlobal.headTemplate+
6102									DPGlobal.contTemplate+
6103									DPGlobal.footTemplate+
6104								'</table>'+
6105							'</div>'+
6106						'</div>';
6107
6108	$.fn.datepicker.DPGlobal = DPGlobal;
6109
6110
6111	/* DATEPICKER NO CONFLICT
6112	* =================== */
6113
6114	$.fn.datepicker.noConflict = function(){
6115		$.fn.datepicker = old;
6116		return this;
6117	};
6118
6119	/* DATEPICKER VERSION
6120	 * =================== */
6121	$.fn.datepicker.version = '1.6.4';
6122
6123	/* DATEPICKER DATA-API
6124	* ================== */
6125
6126	$(document).on(
6127		'focus.datepicker.data-api click.datepicker.data-api',
6128		'[data-provide="datepicker"]',
6129		function(e){
6130			var $this = $(this);
6131			if ($this.data('datepicker'))
6132				return;
6133			e.preventDefault();
6134			// component click requires us to explicitly show it
6135			datepickerPlugin.call($this, 'show');
6136		}
6137	);
6138	$(function(){
6139		datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
6140	});
6141
6142	;(function($){
6143		$.fn.datepicker.dates['it'] = {
6144			days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"],
6145			daysShort: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
6146			daysMin: ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa"],
6147			months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
6148			monthsShort: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"],
6149			today: "Oggi",
6150			monthsTitle: "Mesi",
6151			clear: "Cancella",
6152			weekStart: 1,
6153			format: "dd/mm/yyyy"
6154		};
6155	}(jQueryV2));
6156
6157}));
6158
6159
6160// @codekit-prepend "waves.js";
6161// @codekit-prepend "slick-slider.js";
6162// @codekit-prepend "clamp.js";
6163// @codekit-prepend "horizon-swiper.js";
6164// @codekit-prepend "bootstrap-datepicker.js";

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.