vendor/assets/javascripts/furatto.js in furatto-0.0.1 vs vendor/assets/javascripts/furatto.js in furatto-0.0.2
- old
+ new
@@ -1,15 +1,5978 @@
-//= require dropdown
-//= require jpanel
-//= require jquery.avgrund
-//= require jquery.dropkick-1.0.0
-//= require jquery.icheck
-//= require jquery.tagsinput
-//= require jquery.toolbar
-//= require legacy
-//= require picker
-//= require picker.date
-//= require picker.time
-//= require rainbow-custom.min
-//= require responsive-tables
-//= require responsiveslides
-//= require tooltip
+/*
+ * Snap.js
+ *
+ * Copyright 2013, Jacob Kelley - http://jakiestfu.com/
+ * Released under the MIT Licence
+ * http://opensource.org/licenses/MIT
+ *
+ * Github: http://github.com/jakiestfu/Snap.js/
+ * Version: 1.9.2
+ */
+/*jslint browser: true*/
+/*global define, module, ender*/
+(function(win, doc) {
+ 'use strict';
+ var Snap = Snap || function(userOpts) {
+ var settings = {
+ element: null,
+ dragger: null,
+ disable: 'none',
+ addBodyClasses: true,
+ hyperextensible: true,
+ resistance: 0.5,
+ flickThreshold: 50,
+ transitionSpeed: 0.3,
+ easing: 'ease',
+ maxPosition: 266,
+ minPosition: -266,
+ tapToClose: true,
+ touchToDrag: true,
+ slideIntent: 40, // degrees
+ minDragDistance: 5
+ },
+ cache = {
+ simpleStates: {
+ opening: null,
+ towards: null,
+ hyperExtending: null,
+ halfway: null,
+ flick: null,
+ translation: {
+ absolute: 0,
+ relative: 0,
+ sinceDirectionChange: 0,
+ percentage: 0
+ }
+ }
+ },
+ eventList = {},
+ utils = {
+ hasTouch: (doc.ontouchstart === null),
+ eventType: function(action) {
+ var eventTypes = {
+ down: (utils.hasTouch ? 'touchstart' : 'mousedown'),
+ move: (utils.hasTouch ? 'touchmove' : 'mousemove'),
+ up: (utils.hasTouch ? 'touchend' : 'mouseup'),
+ out: (utils.hasTouch ? 'touchcancel' : 'mouseout')
+ };
+ return eventTypes[action];
+ },
+ page: function(t, e){
+ return (utils.hasTouch && e.touches.length && e.touches[0]) ? e.touches[0]['page'+t] : e['page'+t];
+ },
+ klass: {
+ has: function(el, name){
+ return (el.className).indexOf(name) !== -1;
+ },
+ add: function(el, name){
+ if(!utils.klass.has(el, name) && settings.addBodyClasses){
+ el.className += " "+name;
+ }
+ },
+ remove: function(el, name){
+ if(settings.addBodyClasses){
+ el.className = (el.className).replace(name, "").replace(/^\s+|\s+$/g, '');
+ }
+ }
+ },
+ dispatchEvent: function(type) {
+ if (typeof eventList[type] === 'function') {
+ return eventList[type].call();
+ }
+ },
+ vendor: function(){
+ var tmp = doc.createElement("div"),
+ prefixes = 'webkit Moz O ms'.split(' '),
+ i;
+ for (i in prefixes) {
+ if (typeof tmp.style[prefixes[i] + 'Transition'] !== 'undefined') {
+ return prefixes[i];
+ }
+ }
+ },
+ transitionCallback: function(){
+ return (cache.vendor==='Moz' || cache.vendor==='ms') ? 'transitionend' : cache.vendor+'TransitionEnd';
+ },
+ canTransform: function(){
+ return typeof settings.element.style[cache.vendor+'Transform'] !== 'undefined';
+ },
+ deepExtend: function(destination, source) {
+ var property;
+ for (property in source) {
+ if (source[property] && source[property].constructor && source[property].constructor === Object) {
+ destination[property] = destination[property] || {};
+ utils.deepExtend(destination[property], source[property]);
+ } else {
+ destination[property] = source[property];
+ }
+ }
+ return destination;
+ },
+ angleOfDrag: function(x, y) {
+ var degrees, theta;
+ // Calc Theta
+ theta = Math.atan2(-(cache.startDragY - y), (cache.startDragX - x));
+ if (theta < 0) {
+ theta += 2 * Math.PI;
+ }
+ // Calc Degrees
+ degrees = Math.floor(theta * (180 / Math.PI) - 180);
+ if (degrees < 0 && degrees > -180) {
+ degrees = 360 - Math.abs(degrees);
+ }
+ return Math.abs(degrees);
+ },
+ events: {
+ addEvent: function addEvent(element, eventName, func) {
+ if (element.addEventListener) {
+ return element.addEventListener(eventName, func, false);
+ } else if (element.attachEvent) {
+ return element.attachEvent("on" + eventName, func);
+ }
+ },
+ removeEvent: function addEvent(element, eventName, func) {
+ if (element.addEventListener) {
+ return element.removeEventListener(eventName, func, false);
+ } else if (element.attachEvent) {
+ return element.detachEvent("on" + eventName, func);
+ }
+ },
+ prevent: function(e) {
+ if (e.preventDefault) {
+ e.preventDefault();
+ } else {
+ e.returnValue = false;
+ }
+ }
+ },
+ parentUntil: function(el, attr) {
+ var isStr = typeof attr === 'string';
+ while (el.parentNode) {
+ if (isStr && el.getAttribute && el.getAttribute(attr)){
+ return el;
+ } else if(!isStr && el === attr){
+ return el;
+ }
+ el = el.parentNode;
+ }
+ return null;
+ }
+ },
+ action = {
+ translate: {
+ get: {
+ matrix: function(index) {
+
+ if( !utils.canTransform() ){
+ return parseInt(settings.element.style.left, 10);
+ } else {
+ var matrix = win.getComputedStyle(settings.element)[cache.vendor+'Transform'].match(/\((.*)\)/),
+ ieOffset = 8;
+ if (matrix) {
+ matrix = matrix[1].split(',');
+ if(matrix.length===16){
+ index+=ieOffset;
+ }
+ return parseInt(matrix[index], 10);
+ }
+ return 0;
+ }
+ }
+ },
+ easeCallback: function(){
+ settings.element.style[cache.vendor+'Transition'] = '';
+ cache.translation = action.translate.get.matrix(4);
+ cache.easing = false;
+ clearInterval(cache.animatingInterval);
+
+ if(cache.easingTo===0){
+ utils.klass.remove(doc.body, 'paneljs-right');
+ utils.klass.remove(doc.body, 'paneljs-left');
+ }
+
+ utils.dispatchEvent('animated');
+ utils.events.removeEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
+ },
+ easeTo: function(n) {
+
+ if( !utils.canTransform() ){
+ cache.translation = n;
+ action.translate.x(n);
+ } else {
+ cache.easing = true;
+ cache.easingTo = n;
+
+ settings.element.style[cache.vendor+'Transition'] = 'all ' + settings.transitionSpeed + 's ' + settings.easing;
+
+ cache.animatingInterval = setInterval(function() {
+ utils.dispatchEvent('animating');
+ }, 1);
+
+ utils.events.addEvent(settings.element, utils.transitionCallback(), action.translate.easeCallback);
+ action.translate.x(n);
+ }
+ if(n===0){
+ settings.element.style[cache.vendor+'Transform'] = '';
+ }
+ },
+ x: function(n) {
+ if( (settings.disable==='left' && n>0) ||
+ (settings.disable==='right' && n<0)
+ ){ return; }
+
+ if( !settings.hyperextensible ){
+ if( n===settings.maxPosition || n>settings.maxPosition ){
+ n=settings.maxPosition;
+ } else if( n===settings.minPosition || n<settings.minPosition ){
+ n=settings.minPosition;
+ }
+ }
+
+ n = parseInt(n, 10);
+ if(isNaN(n)){
+ n = 0;
+ }
+
+ if( utils.canTransform() ){
+ var theTranslate = 'translate3d(' + n + 'px, 0,0)';
+ settings.element.style[cache.vendor+'Transform'] = theTranslate;
+ } else {
+ settings.element.style.width = (win.innerWidth || doc.documentElement.clientWidth)+'px';
+
+ settings.element.style.left = n+'px';
+ settings.element.style.right = '';
+ }
+ }
+ },
+ drag: {
+ listen: function() {
+ cache.translation = 0;
+ cache.easing = false;
+ utils.events.addEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
+ utils.events.addEvent(settings.element, utils.eventType('move'), action.drag.dragging);
+ utils.events.addEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
+ },
+ stopListening: function() {
+ utils.events.removeEvent(settings.element, utils.eventType('down'), action.drag.startDrag);
+ utils.events.removeEvent(settings.element, utils.eventType('move'), action.drag.dragging);
+ utils.events.removeEvent(settings.element, utils.eventType('up'), action.drag.endDrag);
+ },
+ startDrag: function(e) {
+ // No drag on ignored elements
+ var target = e.target ? e.target : e.srcElement,
+ ignoreParent = utils.parentUntil(target, 'data-snap-ignore');
+
+ if (ignoreParent) {
+ utils.dispatchEvent('ignore');
+ return;
+ }
+
+
+ if(settings.dragger){
+ var dragParent = utils.parentUntil(target, settings.dragger);
+
+ // Only use dragger if we're in a closed state
+ if( !dragParent &&
+ (cache.translation !== settings.minPosition &&
+ cache.translation !== settings.maxPosition
+ )){
+ return;
+ }
+ }
+
+ utils.dispatchEvent('start');
+ settings.element.style[cache.vendor+'Transition'] = '';
+ cache.isDragging = true;
+ cache.hasIntent = null;
+ cache.intentChecked = false;
+ cache.startDragX = utils.page('X', e);
+ cache.startDragY = utils.page('Y', e);
+ cache.dragWatchers = {
+ current: 0,
+ last: 0,
+ hold: 0,
+ state: ''
+ };
+ cache.simpleStates = {
+ opening: null,
+ towards: null,
+ hyperExtending: null,
+ halfway: null,
+ flick: null,
+ translation: {
+ absolute: 0,
+ relative: 0,
+ sinceDirectionChange: 0,
+ percentage: 0
+ }
+ };
+ },
+ dragging: function(e) {
+ if (cache.isDragging && settings.touchToDrag) {
+
+ var thePageX = utils.page('X', e),
+ thePageY = utils.page('Y', e),
+ translated = cache.translation,
+ absoluteTranslation = action.translate.get.matrix(4),
+ whileDragX = thePageX - cache.startDragX,
+ openingLeft = absoluteTranslation > 0,
+ translateTo = whileDragX,
+ diff;
+
+ // Shown no intent already
+ if((cache.intentChecked && !cache.hasIntent)){
+ return;
+ }
+
+ if(settings.addBodyClasses){
+ if((absoluteTranslation)>0){
+ utils.klass.add(doc.body, 'paneljs-left');
+ utils.klass.remove(doc.body, 'paneljs-right');
+ } else if((absoluteTranslation)<0){
+ utils.klass.add(doc.body, 'paneljs-right');
+ utils.klass.remove(doc.body, 'paneljs-left');
+ }
+ }
+
+ if (cache.hasIntent === false || cache.hasIntent === null) {
+ var deg = utils.angleOfDrag(thePageX, thePageY),
+ inRightRange = (deg >= 0 && deg <= settings.slideIntent) || (deg <= 360 && deg > (360 - settings.slideIntent)),
+ inLeftRange = (deg >= 180 && deg <= (180 + settings.slideIntent)) || (deg <= 180 && deg >= (180 - settings.slideIntent));
+ if (!inLeftRange && !inRightRange) {
+ cache.hasIntent = false;
+ } else {
+ cache.hasIntent = true;
+ }
+ cache.intentChecked = true;
+ }
+
+ if (
+ (settings.minDragDistance>=Math.abs(thePageX-cache.startDragX)) || // Has user met minimum drag distance?
+ (cache.hasIntent === false)
+ ) {
+ return;
+ }
+
+ utils.events.prevent(e);
+ utils.dispatchEvent('drag');
+
+ cache.dragWatchers.current = thePageX;
+ // Determine which direction we are going
+ if (cache.dragWatchers.last > thePageX) {
+ if (cache.dragWatchers.state !== 'left') {
+ cache.dragWatchers.state = 'left';
+ cache.dragWatchers.hold = thePageX;
+ }
+ cache.dragWatchers.last = thePageX;
+ } else if (cache.dragWatchers.last < thePageX) {
+ if (cache.dragWatchers.state !== 'right') {
+ cache.dragWatchers.state = 'right';
+ cache.dragWatchers.hold = thePageX;
+ }
+ cache.dragWatchers.last = thePageX;
+ }
+ if (openingLeft) {
+ // Pulling too far to the right
+ if (settings.maxPosition < absoluteTranslation) {
+ diff = (absoluteTranslation - settings.maxPosition) * settings.resistance;
+ translateTo = whileDragX - diff;
+ }
+ cache.simpleStates = {
+ opening: 'left',
+ towards: cache.dragWatchers.state,
+ hyperExtending: settings.maxPosition < absoluteTranslation,
+ halfway: absoluteTranslation > (settings.maxPosition / 2),
+ flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
+ translation: {
+ absolute: absoluteTranslation,
+ relative: whileDragX,
+ sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
+ percentage: (absoluteTranslation/settings.maxPosition)*100
+ }
+ };
+ } else {
+ // Pulling too far to the left
+ if (settings.minPosition > absoluteTranslation) {
+ diff = (absoluteTranslation - settings.minPosition) * settings.resistance;
+ translateTo = whileDragX - diff;
+ }
+ cache.simpleStates = {
+ opening: 'right',
+ towards: cache.dragWatchers.state,
+ hyperExtending: settings.minPosition > absoluteTranslation,
+ halfway: absoluteTranslation < (settings.minPosition / 2),
+ flick: Math.abs(cache.dragWatchers.current - cache.dragWatchers.hold) > settings.flickThreshold,
+ translation: {
+ absolute: absoluteTranslation,
+ relative: whileDragX,
+ sinceDirectionChange: (cache.dragWatchers.current - cache.dragWatchers.hold),
+ percentage: (absoluteTranslation/settings.minPosition)*100
+ }
+ };
+ }
+ action.translate.x(translateTo + translated);
+ }
+ },
+ endDrag: function(e) {
+ if (cache.isDragging) {
+ utils.dispatchEvent('end');
+ var translated = action.translate.get.matrix(4);
+
+ // Tap Close
+ if (cache.dragWatchers.current === 0 && translated !== 0 && settings.tapToClose) {
+ utils.dispatchEvent('close');
+ utils.events.prevent(e);
+ action.translate.easeTo(0);
+ cache.isDragging = false;
+ cache.startDragX = 0;
+ return;
+ }
+
+ // Revealing Left
+ if (cache.simpleStates.opening === 'left') {
+ // Halfway, Flicking, or Too Far Out
+ if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
+ if (cache.simpleStates.flick && cache.simpleStates.towards === 'left') { // Flicking Closed
+ action.translate.easeTo(0);
+ } else if (
+ (cache.simpleStates.flick && cache.simpleStates.towards === 'right') || // Flicking Open OR
+ (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
+ ) {
+ action.translate.easeTo(settings.maxPosition); // Open Left
+ }
+ } else {
+ action.translate.easeTo(0); // Close Left
+ }
+ // Revealing Right
+ } else if (cache.simpleStates.opening === 'right') {
+ // Halfway, Flicking, or Too Far Out
+ if ((cache.simpleStates.halfway || cache.simpleStates.hyperExtending || cache.simpleStates.flick)) {
+ if (cache.simpleStates.flick && cache.simpleStates.towards === 'right') { // Flicking Closed
+ action.translate.easeTo(0);
+ } else if (
+ (cache.simpleStates.flick && cache.simpleStates.towards === 'left') || // Flicking Open OR
+ (cache.simpleStates.halfway || cache.simpleStates.hyperExtending) // At least halfway open OR hyperextending
+ ) {
+ action.translate.easeTo(settings.minPosition); // Open Right
+ }
+ } else {
+ action.translate.easeTo(0); // Close Right
+ }
+ }
+ cache.isDragging = false;
+ cache.startDragX = utils.page('X', e);
+ }
+ }
+ }
+ },
+ init = function(opts) {
+ if (opts.element) {
+ utils.deepExtend(settings, opts);
+ cache.vendor = utils.vendor();
+ action.drag.listen();
+ }
+ };
+ /*
+ * Public
+ */
+ this.open = function(side) {
+ utils.dispatchEvent('open');
+ utils.klass.remove(doc.body, 'paneljs-expand-left');
+ utils.klass.remove(doc.body, 'paneljs-expand-right');
+
+ if (side === 'left') {
+ cache.simpleStates.opening = 'left';
+ cache.simpleStates.towards = 'right';
+ utils.klass.add(doc.body, 'paneljs-left');
+ utils.klass.remove(doc.body, 'paneljs-right');
+ action.translate.easeTo(settings.maxPosition);
+ } else if (side === 'right') {
+ cache.simpleStates.opening = 'right';
+ cache.simpleStates.towards = 'left';
+ utils.klass.remove(doc.body, 'paneljs-left');
+ utils.klass.add(doc.body, 'paneljs-right');
+ action.translate.easeTo(settings.minPosition);
+ }
+ };
+ this.close = function() {
+ utils.dispatchEvent('close');
+ action.translate.easeTo(0);
+ };
+ this.expand = function(side){
+ var to = win.innerWidth || doc.documentElement.clientWidth;
+
+ if(side==='left'){
+ utils.dispatchEvent('expandLeft');
+ utils.klass.add(doc.body, 'paneljs-expand-left');
+ utils.klass.remove(doc.body, 'paneljs-expand-right');
+ } else {
+ utils.dispatchEvent('expandRight');
+ utils.klass.add(doc.body, 'paneljs-expand-right');
+ utils.klass.remove(doc.body, 'paneljs-expand-left');
+ to *= -1;
+ }
+ action.translate.easeTo(to);
+ };
+
+ this.on = function(evt, fn) {
+ eventList[evt] = fn;
+ return this;
+ };
+ this.off = function(evt) {
+ if (eventList[evt]) {
+ eventList[evt] = false;
+ }
+ };
+
+ this.enable = function() {
+ utils.dispatchEvent('enable');
+ action.drag.listen();
+ };
+ this.disable = function() {
+ utils.dispatchEvent('disable');
+ action.drag.stopListening();
+ };
+
+ this.settings = function(opts){
+ utils.deepExtend(settings, opts);
+ };
+
+ this.state = function() {
+ var state,
+ fromLeft = action.translate.get.matrix(4);
+ if (fromLeft === settings.maxPosition) {
+ state = 'left';
+ } else if (fromLeft === settings.minPosition) {
+ state = 'right';
+ } else {
+ state = 'closed';
+ }
+ return {
+ state: state,
+ info: cache.simpleStates
+ };
+ };
+ init(userOpts);
+ };
+ if ((typeof module !== 'undefined') && module.exports) {
+ module.exports = Snap;
+ }
+ if (typeof ender === 'undefined') {
+ this.Snap = Snap;
+ }
+ if ((typeof define === "function") && define.amd) {
+ define("snap", [], function() {
+ return Snap;
+ });
+ }
+}).call(this, window, document);
+// Generated by CoffeeScript 1.6.3
+(function($, window) {
+ "use strict";
+ var Panel;
+ Panel = (function() {
+ Panel.DEFAULTS = {
+ element: null,
+ dragger: null,
+ disable: 'right',
+ addBodyClasses: true,
+ hyperextensible: true,
+ resistance: 0.5,
+ flickThreshold: 50,
+ transitionSpeed: 0.3,
+ easing: 'ease',
+ maxPosition: 266,
+ minPosition: -266,
+ tapToClose: true,
+ touchToDrag: false,
+ slideIntent: 40,
+ minDragDistance: 5
+ };
+
+ function Panel(el, options) {
+ this.options = $.extend(options, {
+ element: el
+ });
+ this.menu = $($('[data-toggle="panel"]').data('target'));
+ this.append_menu_to_panel();
+ this.snapper = new Snap(this.options);
+ }
+
+ Panel.prototype.apply_ios_devices_fix = function() {
+ if (navigator.userAgent.match(/(iPad|iPhone|iPod)/g)) {
+ return $('.panel-content').css({
+ 'overflow': 'visible'
+ });
+ }
+ };
+
+ Panel.prototype.append_menu_to_panel = function() {
+ return $('.panel-left').html(this.menu.html());
+ };
+
+ Panel.prototype.toggle = function() {
+ $('.panel').css('display', 'block');
+ if (this.snapper.state().state === "left") {
+ return this.snapper.close();
+ } else {
+ return this.snapper.open('left');
+ }
+ };
+
+ return Panel;
+
+ })();
+ $.fn.panel = function(option) {
+ return this.each(function() {
+ var $this, data, options;
+ $this = $(this);
+ data = $this.data('Panel');
+ options = $.extend({}, Panel.DEFAULTS, $this.data(), typeof option === 'object' && option);
+ if (!data) {
+ $this.data('Panel', (data = new Panel(this, options)));
+ }
+ if (typeof option === 'string') {
+ return data[option]();
+ }
+ });
+ };
+ $(document).on('click', '[data-toggle="panel"]', function(e) {
+ e.preventDefault();
+ return $('.panel-content').panel('toggle');
+ });
+ return $(document).ready(function() {
+ return $('.panel-content').panel('apply_ios_devices_fix');
+ });
+})(window.jQuery, window);
+/**
+ * Toolbar.js
+ *
+ * @fileoverview jQuery plugin that creates tooltip style toolbars.
+ * @link http://paulkinzett.github.com/toolbar/
+ * @author Paul Kinzett (http://kinzett.co.nz/)
+ * @version 1.0.4
+ * @requires jQuery 1.7+
+ *
+ * @license jQuery Toolbar Plugin v1.0.4
+ * http://paulkinzett.github.com/toolbar/
+ * Copyright 2013 Paul Kinzett (http://kinzett.co.nz/)
+ * Released under the MIT license.
+ * <https://raw.github.com/paulkinzett/toolbar/master/LICENSE.txt>
+ */
+
+if ( typeof Object.create !== 'function' ) {
+ Object.create = function( obj ) {
+ function F() {}
+ F.prototype = obj;
+ return new F();
+ };
+}
+
+(function( $, window, document, undefined ) {
+
+ var ToolBar = {
+ init: function( options, elem ) {
+ var self = this;
+ self.elem = elem;
+ self.$elem = $( elem );
+ self.options = $.extend( {}, $.fn.toolbar.options, options );
+ self.toolbar = $('<div class="tool-container gradient" />')
+ .addClass('tool-'+self.options.position)
+ .addClass('tool-rounded')
+ .append('<div class="tool-items" />')
+ .append('<div class="arrow" />')
+ .appendTo('body')
+ .css('opacity', 0)
+ .hide();
+ self.toolbar_arrow = self.toolbar.find('.arrow');
+ self.initializeToolbar();
+ },
+
+ initializeToolbar: function() {
+ var self = this;
+ self.populateContent();
+ self.setTrigger();
+ self.toolbarWidth = self.toolbar.width();
+ },
+
+ setTrigger: function() {
+ var self = this;
+
+ self.$elem.on('click', function(event) {
+ event.preventDefault();
+ if(self.$elem.hasClass('pressed')) {
+ self.hide();
+ } else {
+ self.show();
+ }
+ });
+
+ if (self.options.hideOnClick) {
+ $('html').on("click.toolbar", function ( event ) {
+ if (event.target != self.elem &&
+ self.$elem.has(event.target).length === 0 &&
+ self.toolbar.has(event.target).length === 0 &&
+ self.toolbar.is(":visible")) {
+ self.hide();
+ }
+ });
+ }
+
+ $(window).resize(function( event ) {
+ event.stopPropagation();
+ if ( self.toolbar.is(":visible") ) {
+ self.toolbarCss = self.getCoordinates(self.options.position, 20);
+ self.collisionDetection();
+ self.toolbar.css( self.toolbarCss );
+ self.toolbar_arrow.css( self.arrowCss );
+ }
+ });
+ },
+
+ populateContent: function() {
+ var self = this;
+ var location = self.toolbar.find('.tool-items');
+ var content = $(self.options.content).clone( true ).find('a').addClass('tool-item gradient');
+ location.html(content);
+ location.find('.tool-item').on('click', function(event) {
+ event.preventDefault();
+ self.$elem.trigger('toolbarItemClick', this);
+ });
+ },
+
+ calculatePosition: function() {
+ var self = this;
+ self.arrowCss = {};
+ self.toolbarCss = self.getCoordinates(self.options.position, 0);
+ self.toolbarCss.position = 'absolute';
+ self.toolbarCss.zIndex = self.options.zIndex;
+ self.collisionDetection();
+ self.toolbar.css(self.toolbarCss);
+ self.toolbar_arrow.css(self.arrowCss);
+ },
+
+ getCoordinates: function( position, adjustment ) {
+ var self = this;
+ self.coordinates = self.$elem.offset();
+
+ if (self.options.adjustment && self.options.adjustment[self.options.position]) {
+ adjustment = self.options.adjustment[self.options.position];
+ }
+
+ switch(self.options.position) {
+ case 'top':
+ return {
+ left: self.coordinates.left-(self.toolbar.width()/2)+(self.$elem.outerWidth()/2),
+ top: self.coordinates.top-self.$elem.height()-adjustment,
+ right: 'auto'
+ };
+ case 'left':
+ return {
+ left: self.coordinates.left-(self.toolbar.width()/2)-(self.$elem.width()/2)-adjustment,
+ top: self.coordinates.top-(self.toolbar.height()/2)+(self.$elem.outerHeight()/2),
+ right: 'auto'
+ };
+ case 'right':
+ return {
+ left: self.coordinates.left+(self.toolbar.width()/2)+(self.$elem.width()/3)+adjustment,
+ top: self.coordinates.top-(self.toolbar.height()/2)+(self.$elem.outerHeight()/2),
+ right: 'auto'
+ };
+ case 'bottom':
+ return {
+ left: self.coordinates.left-(self.toolbar.width()/2)+(self.$elem.outerWidth()/2),
+ top: self.coordinates.top+self.$elem.height()+adjustment,
+ right: 'auto'
+ };
+ }
+ },
+
+ collisionDetection: function() {
+ var self = this;
+ var edgeOffset = 20;
+ if(self.options.position == 'top' || self.options.position == 'bottom') {
+ self.arrowCss = {left: '50%', right: '50%'};
+ if( self.toolbarCss.left < edgeOffset ) {
+ self.toolbarCss.left = edgeOffset;
+ self.arrowCss.left = self.$elem.offset().left + self.$elem.width()/2-(edgeOffset);
+ }
+ else if(($(window).width() - (self.toolbarCss.left + self.toolbarWidth)) < edgeOffset) {
+ self.toolbarCss.right = edgeOffset;
+ self.toolbarCss.left = 'auto';
+ self.arrowCss.left = 'auto';
+ self.arrowCss.right = ($(window).width()-self.$elem.offset().left)-(self.$elem.width()/2)-(edgeOffset)-5;
+ }
+ }
+ },
+
+ show: function() {
+ var self = this;
+ var animation = {'opacity': 1};
+
+ self.$elem.addClass('pressed');
+ self.calculatePosition();
+
+ switch(self.options.position) {
+ case 'top':
+ animation.top = '-=20';
+ break;
+ case 'left':
+ animation.left = '-=20';
+ break;
+ case 'right':
+ animation.left = '+=20';
+ break;
+ case 'bottom':
+ animation.top = '+=20';
+ break;
+ }
+
+ self.toolbar.show().animate(animation, 200 );
+ self.$elem.trigger('toolbarShown');
+ },
+
+ hide: function() {
+ var self = this;
+ var animation = {'opacity': 0};
+
+ self.$elem.removeClass('pressed');
+
+ switch(self.options.position) {
+ case 'top':
+ animation.top = '+=20';
+ break;
+ case 'left':
+ animation.left = '+=20';
+ break;
+ case 'right':
+ animation.left = '-=20';
+ break;
+ case 'bottom':
+ animation.top = '-=20';
+ break;
+ }
+
+ self.toolbar.animate(animation, 200, function() {
+ self.toolbar.hide();
+ });
+
+ self.$elem.trigger('toolbarHidden');
+ },
+
+ getToolbarElement: function () {
+ return this.toolbar.find('.tool-items');
+ }
+ };
+
+ $.fn.toolbar = function( options ) {
+ if ($.isPlainObject( options )) {
+ return this.each(function() {
+ var toolbarObj = Object.create( ToolBar );
+ toolbarObj.init( options, this );
+ $(this).data('toolbarObj', toolbarObj);
+ });
+ } else if ( typeof options === 'string' && options.indexOf('_') !== 0 ) {
+ var toolbarObj = $(this).data('toolbarObj');
+ var method = toolbarObj[options];
+ return method.apply(toolbarObj, $.makeArray(arguments).slice(1));
+ }
+ };
+
+ $.fn.toolbar.options = {
+ content: '#myContent',
+ position: 'top',
+ hideOnClick: false,
+ zIndex: 120
+ };
+
+}) ( jQuery, window, document );
+// Generated by CoffeeScript 1.6.3
+$(document).ready(function() {
+ return $('[data-furatto="toolbar"]').each(function() {
+ return $(this).toolbar({
+ content: $(this).data('content'),
+ position: $(this).data('position') || 'top',
+ hideOnClick: true
+ });
+ });
+});
+/* Rainbow v1.2 rainbowco.de | included languages: generic, shell, javascript, html, css */
+window.Rainbow=function(){function q(a){var b,c=a.getAttribute&&a.getAttribute("data-language")||0;if(!c){a=a.attributes;for(b=0;b<a.length;++b)if("data-language"===a[b].nodeName)return a[b].nodeValue}return c}function B(a){var b=q(a)||q(a.parentNode);if(!b){var c=/\blang(?:uage)?-(\w+)/;(a=a.className.match(c)||a.parentNode.className.match(c))&&(b=a[1])}return b}function C(a,b){for(var c in f[d]){c=parseInt(c,10);if(a==c&&b==f[d][c]?0:a<=c&&b>=f[d][c])delete f[d][c],delete j[d][c];if(a>=c&&a<f[d][c]||
+b>c&&b<f[d][c])return!0}return!1}function r(a,b){return'<span class="'+a.replace(/\./g," ")+(l?" "+l:"")+'">'+b+"</span>"}function s(a,b,c,i){var e=a.exec(c);if(e){++t;!b.name&&"string"==typeof b.matches[0]&&(b.name=b.matches[0],delete b.matches[0]);var k=e[0],g=e.index,u=e[0].length+g,h=function(){function e(){s(a,b,c,i)}t%100>0?e():setTimeout(e,0)};if(C(g,u))h();else{var m=v(b.matches),l=function(a,c,i){if(a>=c.length)i(k);else{var d=e[c[a]];if(d){var g=b.matches[c[a]],f=g.language,h=g.name&&g.matches?
+g.matches:g,j=function(b,d,g){var f;f=0;var h;for(h=1;h<c[a];++h)e[h]&&(f=f+e[h].length);d=g?r(g,d):d;k=k.substr(0,f)+k.substr(f).replace(b,d.replace("$'","$$$$'"));l(++a,c,i)};f?n(d,f,function(a){j(d,a)}):typeof g==="string"?j(d,d,g):w(d,h.length?h:[h],function(a){j(d,a,g.matches?g.name:0)})}else l(++a,c,i)}};l(0,m,function(a){b.name&&(a=r(b.name,a));if(!j[d]){j[d]={};f[d]={}}j[d][g]={replace:e[0],"with":a};f[d][g]=u;h()})}}else i()}function v(a){var b=[],c;for(c in a)a.hasOwnProperty(c)&&b.push(c);
+return b.sort(function(a,b){return b-a})}function w(a,b,c){function i(b,k){k<b.length?s(b[k].pattern,b[k],a,function(){i(b,++k)}):D(a,function(a){delete j[d];delete f[d];--d;c(a)})}++d;i(b,0)}function D(a,b){function c(a,b,i,f){if(i<b.length){++x;var h=b[i],l=j[d][h],a=a.substr(0,h)+a.substr(h).replace(l.replace,l["with"].replace("$'","$$$$'")),h=function(){c(a,b,++i,f)};0<x%250?h():setTimeout(h,0)}else f(a)}var i=v(j[d]);c(a,i,0,b)}function n(a,b,c){var d=m[b]||[],e=m[y]||[],b=z[b]?d:d.concat(e);
+w(a.replace(/</g,"<").replace(/>/g,">").replace(/&(?![\w\#]+;)/g,"&"),b,c)}function o(a,b,c){if(b<a.length){var d=a[b],e=B(d);return!(-1<(" "+d.className+" ").indexOf(" rainbow "))&&e?(e=e.toLowerCase(),d.className+=d.className?" rainbow":"rainbow",n(d.innerHTML,e,function(k){d.innerHTML=k;j={};f={};p&&p(d,e);setTimeout(function(){o(a,++b,c)},0)})):o(a,++b,c)}c&&c()}function A(a,b){var a=a&&"function"==typeof a.getElementsByTagName?a:document,c=a.getElementsByTagName("pre"),d=a.getElementsByTagName("code"),
+e,f=[],g=[];for(e=0;e<c.length;++e)c[e].getElementsByTagName("code").length?c[e].innerHTML=c[e].innerHTML.replace(/^\s+/,"").replace(/\s+$/,""):f.push(c[e]);for(e=0;e<d.length;++e)g.push(d[e]);o(g.concat(f),0,b)}var j={},f={},m={},z={},d=0,y=0,t=0,x=0,l,p;return{extend:function(a,b,c){1==arguments.length&&(b=a,a=y);z[a]=c;m[a]=b.concat(m[a]||[])},b:function(a){p=a},a:function(a){l=a},color:function(a,b,c){if("string"==typeof a)return n(a,b,c);if("function"==typeof a)return A(0,a);A(a,b)}}}();
+document.addEventListener?document.addEventListener("DOMContentLoaded",Rainbow.color,!1):window.attachEvent("onload",Rainbow.color);Rainbow.onHighlight=Rainbow.b;Rainbow.addClass=Rainbow.a;Rainbow.extend([{matches:{1:{name:"keyword.operator",pattern:/\=/g},2:{name:"string",matches:{name:"constant.character.escape",pattern:/\\('|"){1}/g}}},pattern:/(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm},{name:"comment",pattern:/\/\*[\s\S]*?\*\/|(\/\/|\#)[\s\S]*?$/gm},{name:"constant.numeric",pattern:/\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi},{matches:{1:"keyword"},pattern:/\b(and|array|as|b(ool(ean)?|reak)|c(ase|atch|har|lass|on(st|tinue))|d(ef|elete|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\(|\b)/gi},
+{name:"constant.language",pattern:/true|false|null/g},{name:"keyword.operator",pattern:/\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g},{matches:{1:"function.call"},pattern:/(\w+?)(?=\()/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(function)\s(.*?)(?=\()/g}]);Rainbow.extend("shell",[{name:"shell",matches:{1:{language:"shell"}},pattern:/\$\(([\s\S]*?)\)/gm},{matches:{2:"string"},pattern:/(\(|\s|\[|\=)(('|")[\s\S]*?(\3))/gm},{name:"keyword.operator",pattern:/<|>|&/g},{name:"comment",pattern:/\#[\s\S]*?$/gm},{name:"storage.function",pattern:/(.+?)(?=\(\)\s{0,}\{)/g},{name:"support.command",pattern:/\b(echo|rm|ls|(mk|rm)dir|cd|find|cp|exit|pwd|exec|trap|source|shift|unset)/g},{matches:{1:"keyword"},pattern:/\b(break|case|continue|do|done|elif|else|esac|eval|export|fi|for|function|if|in|local|return|set|then|unset|until|while)(?=\(|\b)/g}],
+!0);Rainbow.extend("javascript",[{name:"selector",pattern:/(\s|^)\$(?=\.|\()/g},{name:"support",pattern:/\b(window|document)\b/g},{matches:{1:"support.property"},pattern:/\.(length|node(Name|Value))\b/g},{matches:{1:"support.function"},pattern:/(setTimeout|setInterval)(?=\()/g},{matches:{1:"support.method"},pattern:/\.(getAttribute|push|getElementById|getElementsByClassName|log|setTimeout|setInterval)(?=\()/g},{name:"string.regexp",matches:{1:"string.regexp.open",2:{name:"constant.regexp.escape",pattern:/\\(.){1}/g},
+3:"string.regexp.close",4:"string.regexp.modifier"},pattern:/(\/)(?!\*)(.+)(\/)([igm]{0,3})/g},{matches:{1:"storage",3:"entity.function"},pattern:/(var)?(\s|^)(\S*)(?=\s?=\s?function\()/g},{matches:{1:"keyword",2:"entity.function"},pattern:/(new)\s+(.*)(?=\()/g},{name:"entity.function",pattern:/(\w+)(?=:\s{0,}function)/g}]);Rainbow.extend("html",[{name:"source.php.embedded",matches:{2:{language:"php"}},pattern:/<\?=?(?!xml)(php)?([\s\S]*?)(\?>)/gm},{name:"source.css.embedded",matches:{1:{matches:{1:"support.tag.style",2:[{name:"string",pattern:/('|")(.*?)(\1)/g},{name:"entity.tag.style",pattern:/(\w+)/g}],3:"support.tag.style"},pattern:/(<\/?)(style.*?)(>)/g},2:{language:"css"},3:"support.tag.style",4:"entity.tag.style",5:"support.tag.style"},pattern:/(<style.*?>)([\s\S]*?)(<\/)(style)(>)/gm},
+{name:"source.js.embedded",matches:{1:{matches:{1:"support.tag.script",2:[{name:"string",pattern:/('|")(.*?)(\1)/g},{name:"entity.tag.script",pattern:/(\w+)/g}],3:"support.tag.script"},pattern:/(<\/?)(script.*?)(>)/g},2:{language:"javascript"},3:"support.tag.script",4:"entity.tag.script",5:"support.tag.script"},pattern:/(<script(?! src).*?>)([\s\S]*?)(<\/)(script)(>)/gm},{name:"comment.html",pattern:/<\!--[\S\s]*?-->/g},{matches:{1:"support.tag.open",2:"support.tag.close"},
+pattern:/(<)|(\/?\??>)/g},{name:"support.tag",matches:{1:"support.tag",2:"support.tag.special",3:"support.tag-name"},pattern:/(<\??)(\/|\!?)(\w+)/g},{matches:{1:"support.attribute"},pattern:/([a-z-]+)(?=\=)/gi},{matches:{1:"support.operator",2:"string.quote",3:"string.value",4:"string.quote"},pattern:/(=)('|")(.*?)(\2)/g},{matches:{1:"support.operator",2:"support.value"},pattern:/(=)([a-zA-Z\-0-9]*)\b/g},{matches:{1:"support.attribute"},pattern:/\s(\w+)(?=\s|>)(?![\s\S]*<)/g}],!0);Rainbow.extend("css",[{name:"comment",pattern:/\/\*[\s\S]*?\*\//gm},{name:"constant.hex-color",pattern:/#([a-f0-9]{3}|[a-f0-9]{6})(?=;|\s|,|\))/gi},{matches:{1:"constant.numeric",2:"keyword.unit"},pattern:/(\d+)(px|em|cm|s|%)?/g},{name:"string",pattern:/('|")(.*?)\1/g},{name:"support.css-property",matches:{1:"support.vendor-prefix"},pattern:/(-o-|-moz-|-webkit-|-ms-)?[\w-]+(?=\s?:)(?!.*\{)/g},{matches:{1:[{name:"entity.name.sass",pattern:/&/g},{name:"direct-descendant",pattern:/>/g},{name:"entity.name.class",
+pattern:/\.[\w\-_]+/g},{name:"entity.name.id",pattern:/\#[\w\-_]+/g},{name:"entity.name.pseudo",pattern:/:[\w\-_]+/g},{name:"entity.name.tag",pattern:/\w+/g}]},pattern:/([\w\ ,\n:\.\#\&\;\-_]+)(?=.*\{)/g},{matches:{2:"support.vendor-prefix",3:"support.css-value"},pattern:/(:|,)\s*(-o-|-moz-|-webkit-|-ms-)?([a-zA-Z-]*)(?=\b)(?!.*\{)/g}],!0);
+/* ===========================================================
+ * bootstrap-tooltip.js v2.3.0
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ===========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* TOOLTIP PUBLIC CLASS DEFINITION
+ * =============================== */
+
+ var Tooltip = function (element, options) {
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.prototype = {
+
+ constructor: Tooltip
+
+ , init: function (type, element, options) {
+ var eventIn
+ , eventOut
+ , triggers
+ , trigger
+ , i
+
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.enabled = true
+
+ triggers = this.options.trigger.split(' ')
+
+ for (i = triggers.length; i--;) {
+ trigger = triggers[i]
+ if (trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (trigger != 'manual') {
+ eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
+ eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ , getOptions: function (options) {
+ options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay
+ , hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ , enter: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ clearTimeout(this.timeout)
+ self.hoverState = 'in'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ , leave: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (this.timeout) clearTimeout(this.timeout)
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.hoverState = 'out'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ , show: function () {
+ var $tip
+ , pos
+ , actualWidth
+ , actualHeight
+ , placement
+ , tp
+ , e = $.Event('show')
+
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+ $tip = this.tip()
+ this.setContent()
+
+ if (this.options.animation) {
+ $tip.addClass('fade')
+ }
+
+ placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+
+ pos = this.getPosition()
+
+ actualWidth = $tip[0].offsetWidth
+ actualHeight = $tip[0].offsetHeight
+
+ switch (placement) {
+ case 'bottom':
+ tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'top':
+ tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'left':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
+ break
+ case 'right':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
+ break
+ }
+
+ this.applyPlacement(tp, placement)
+ this.$element.trigger('shown')
+ }
+ }
+
+ , applyPlacement: function(offset, placement){
+ var $tip = this.tip()
+ , width = $tip[0].offsetWidth
+ , height = $tip[0].offsetHeight
+ , actualWidth
+ , actualHeight
+ , delta
+ , replace
+
+ $tip
+ .offset(offset)
+ .addClass(placement)
+ .addClass('in')
+
+ actualWidth = $tip[0].offsetWidth
+ actualHeight = $tip[0].offsetHeight
+
+ if (placement == 'top' && actualHeight != height) {
+ offset.top = offset.top + height - actualHeight
+ replace = true
+ }
+
+ if (placement == 'bottom' || placement == 'top') {
+ delta = 0
+
+ if (offset.left < 0){
+ delta = offset.left * -2
+ offset.left = 0
+ $tip.offset(offset)
+ actualWidth = $tip[0].offsetWidth
+ actualHeight = $tip[0].offsetHeight
+ }
+
+ this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
+ } else {
+ this.replaceArrow(actualHeight - height, actualHeight, 'top')
+ }
+
+ if (replace) $tip.offset(offset)
+ }
+
+ , replaceArrow: function(delta, dimension, position){
+ this
+ .arrow()
+ .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
+ }
+
+ , setContent: function () {
+ var $tip = this.tip()
+ , title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ , hide: function () {
+ var that = this
+ , $tip = this.tip()
+ , e = $.Event('hide')
+
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+
+ $tip.removeClass('in')
+
+ function removeWithAnimation() {
+ var timeout = setTimeout(function () {
+ $tip.off($.support.transition.end).detach()
+ }, 500)
+
+ $tip.one($.support.transition.end, function () {
+ clearTimeout(timeout)
+ $tip.detach()
+ })
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ removeWithAnimation() :
+ $tip.detach()
+
+ this.$element.trigger('hidden')
+
+ return this
+ }
+
+ , fixTitle: function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+ }
+ }
+
+ , hasContent: function () {
+ return this.getTitle()
+ }
+
+ , getPosition: function () {
+ var el = this.$element[0]
+ return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
+ width: el.offsetWidth
+ , height: el.offsetHeight
+ }, this.$element.offset())
+ }
+
+ , getTitle: function () {
+ var title
+ , $e = this.$element
+ , o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ , tip: function () {
+ return this.$tip = this.$tip || $(this.options.template)
+ }
+
+ , arrow: function(){
+ return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
+ }
+
+ , validate: function () {
+ if (!this.$element[0].parentNode) {
+ this.hide()
+ this.$element = null
+ this.options = null
+ }
+ }
+
+ , enable: function () {
+ this.enabled = true
+ }
+
+ , disable: function () {
+ this.enabled = false
+ }
+
+ , toggleEnabled: function () {
+ this.enabled = !this.enabled
+ }
+
+ , toggle: function (e) {
+ var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
+ self.tip().hasClass('in') ? self.hide() : self.show()
+ }
+
+ , destroy: function () {
+ this.hide().$element.off('.' + this.type).removeData(this.type)
+ }
+
+ }
+
+
+ /* TOOLTIP PLUGIN DEFINITION
+ * ========================= */
+
+ var old = $.fn.tooltip
+
+ $.fn.tooltip = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('tooltip')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.tooltip.Constructor = Tooltip
+
+ $.fn.tooltip.defaults = {
+ animation: true
+ , placement: 'top'
+ , selector: false
+ , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
+ , trigger: 'hover focus'
+ , title: ''
+ , delay: 0
+ , html: false
+ , container: false
+ }
+
+
+ /* TOOLTIP NO CONFLICT
+ * =================== */
+
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old
+ return this
+ }
+
+}(window.jQuery);
+
+/*!
+ * pickadate.js v3.1.1, 2013/06/28
+ * By Amsul, http://amsul.ca
+ * Hosted on http://amsul.github.io/pickadate.js
+ * Licensed under MIT
+ */
+
+/*jshint
+ debug: true,
+ devel: true,
+ browser: true,
+ asi: true,
+ unused: true,
+ boss: true,
+ eqnull: true
+ */
+
+
+// Create a global scope.
+window.Picker = (function( $, $document, undefined ) {
+
+
+/**
+ * The picker constructor that creates a blank picker.
+ */
+function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
+
+ // If there’s no element, return the picker constructor.
+ if ( !ELEMENT ) return PickerConstructor
+
+
+ var
+ // The state of the picker.
+ STATE = {
+ id: Math.abs( ~~( Math.random() * 1e9 ) )
+ },
+
+
+ // Merge the defaults and options passed.
+ SETTINGS = COMPONENT ? $.extend( true, {}, COMPONENT.defaults, OPTIONS ) : OPTIONS || {},
+
+
+ // Merge the default classes with the settings classes.
+ CLASSES = $.extend( {}, PickerConstructor.klasses(), SETTINGS.klass ),
+
+
+ // The element node wrapper into a jQuery object.
+ $ELEMENT = $( ELEMENT ),
+
+
+ // Pseudo picker constructor.
+ PickerInstance = function() {
+ return this.start()
+ },
+
+
+ // The picker prototype.
+ P = PickerInstance.prototype = {
+
+ constructor: PickerInstance,
+
+ $node: $ELEMENT,
+
+
+ /**
+ * Initialize everything
+ */
+ start: function() {
+
+ // If it’s already started, do nothing.
+ if ( STATE && STATE.start ) return P
+
+
+ // Update the picker states.
+ STATE.methods = {}
+ STATE.start = true
+ STATE.open = false
+ STATE.type = ELEMENT.type
+
+
+ // Confirm focus state, save original type, convert into text input
+ // to remove UA stylings, and set as readonly to prevent keyboard popup.
+ ELEMENT.autofocus = ELEMENT == document.activeElement
+ ELEMENT.type = 'text'
+ ELEMENT.readOnly = true
+
+
+ // Create a new picker component with the settings.
+ P.component = new COMPONENT( P, SETTINGS )
+
+
+ // Create the picker root with a new wrapped holder and bind the events.
+ P.$root = $( PickerConstructor._.node( 'div', createWrappedComponent(), CLASSES.picker ) ).on({
+
+ // When something within the root is focused, stop from bubbling
+ // to the doc and remove the “focused” state from the root.
+ focusin: function( event ) {
+ P.$root.removeClass( CLASSES.focused )
+ event.stopPropagation()
+ },
+
+ // If the event is not on the root holder, stop it from bubbling to the doc.
+ mousedown: function( event ) {
+ if ( event.target != P.$root.children()[ 0 ] ) {
+ event.stopPropagation()
+ }
+ },
+
+ // When something within the root holder is clicked, handle the various event.
+ click: function( event ) {
+
+ var target = event.target,
+ $target = target.attributes.length ? $( target ) : $( target ).closest( '[data-pick]' ),
+ targetData = $target.data()
+
+ // If the event is not on the root holder itself, handle the clicks within.
+ if ( target != P.$root.children()[ 0 ] ) {
+
+ // Stop it from propagating to the doc.
+ event.stopPropagation()
+
+ // If nothing inside is actively focused, re-focus the element.
+ if ( !P.$root.find( document.activeElement ).length ) {
+ ELEMENT.focus()
+ }
+
+ // If something is superficially changed, update the `highlight` based on the `nav`.
+ if ( targetData.nav && !$target.hasClass( CLASSES.navDisabled ) ) {
+ P.set( 'highlight', P.component.item.highlight, { nav: targetData.nav } )
+ }
+
+ // If something is picked, set `select` then close with focus.
+ else if ( PickerConstructor._.isInteger( targetData.pick ) && !$target.hasClass( CLASSES.disabled ) ) {
+ P.set( 'select', targetData.pick ).close( true )
+ }
+
+ // If a “clear” button is pressed, empty the values and close with focus.
+ else if ( targetData.clear ) {
+ P.clear().close( true )
+ }
+ }
+ }
+ }) //P.$root
+
+
+ // If there’s a format for the hidden input element, create the element
+ // using the name of the original input plus suffix. Otherwise set it to null.
+ // If the element has a value, use either the `data-value` or `value`.
+ P._hidden = SETTINGS.formatSubmit ? $( '<input type=hidden name=' + ELEMENT.name + ( SETTINGS.hiddenSuffix || '_submit' ) + ( $ELEMENT.data( 'value' ) ? ' value="' + PickerConstructor._.trigger( P.component.formats.toString, P.component, [ SETTINGS.formatSubmit, P.component.item.select ] ) + '"' : '' ) + '>' )[ 0 ] : undefined
+
+
+ // Add the class and bind the events on the element.
+ $ELEMENT.addClass( CLASSES.input ).
+
+ // On focus/click, open the picker and adjust the root “focused” state.
+ on( 'focus.P' + STATE.id + ' click.P' + STATE.id, focusToOpen ).
+
+ // If the value changes, update the hidden input with the correct format.
+ on( 'change.P' + STATE.id, function() {
+ if ( P._hidden ) {
+ P._hidden.value = ELEMENT.value ? PickerConstructor._.trigger( P.component.formats.toString, P.component, [ SETTINGS.formatSubmit, P.component.item.select ] ) : ''
+ }
+ }).
+
+ // Handle keyboard event based on the picker being opened or not.
+ on( 'keydown.P' + STATE.id, function( event ) {
+
+ var keycode = event.keyCode,
+
+ // Check if one of the delete keys was pressed.
+ isKeycodeDelete = /^(8|46)$/.test( keycode )
+
+ // For some reason IE clears the input value on “escape”.
+ if ( keycode == 27 ) {
+ P.close()
+ return false
+ }
+
+ // Check if `space` or `delete` was pressed or the picker is closed with a key movement.
+ if ( keycode == 32 || isKeycodeDelete || !STATE.open && P.component.key[ keycode ] ) {
+
+ // Prevent it from moving the page and bubbling to doc.
+ event.preventDefault()
+ event.stopPropagation()
+
+ // If `delete` was pressed, clear the values and close the picker.
+ // Otherwise open the picker.
+ if ( isKeycodeDelete ) { P.clear().close() }
+ else { P.open() }
+ }
+ }).
+
+ // If there’s a `data-value`, update the value of the element.
+ val( $ELEMENT.data( 'value' ) ? PickerConstructor._.trigger( P.component.formats.toString, P.component, [ SETTINGS.format, P.component.item.select ] ) : ELEMENT.value ).
+
+ // Insert the root and hidden input after the element.
+ after( P.$root, P._hidden ).
+
+ // Store the picker data by component name.
+ data( NAME, P )
+
+
+ // Bind the default component and settings events.
+ P.on({
+ start: P.component.onStart,
+ render: P.component.onRender,
+ stop: P.component.onStop,
+ open: P.component.onOpen,
+ close: P.component.onClose,
+ set: P.component.onSet
+ }).on({
+ start: SETTINGS.onStart,
+ render: SETTINGS.onRender,
+ stop: SETTINGS.onStop,
+ open: SETTINGS.onOpen,
+ close: SETTINGS.onClose,
+ set: SETTINGS.onSet
+ })
+
+
+ // If the element has autofocus, open the picker.
+ if ( ELEMENT.autofocus ) {
+ P.open()
+ }
+
+
+ // Trigger queued the “start” and “render” events.
+ return P.trigger( 'start' ).trigger( 'render' )
+ }, //start
+
+
+ /**
+ * Render a new picker within the root
+ */
+ render: function() {
+
+ // Insert a new component holder in the root.
+ P.$root.html( createWrappedComponent() )
+
+ // Trigger the queued “render” events.
+ return P.trigger( 'render' )
+ }, //render
+
+
+ /**
+ * Destroy everything
+ */
+ stop: function() {
+
+ // If it’s already stopped, do nothing.
+ if ( !STATE.start ) return P
+
+ // Then close the picker.
+ P.close()
+
+ // Remove the hidden field.
+ if ( P._hidden ) {
+ P._hidden.parentNode.removeChild( P._hidden )
+ }
+
+ // Remove the root.
+ P.$root.remove()
+
+ // Remove the input class, unbind the events, and remove the stored data.
+ $ELEMENT.removeClass( CLASSES.input ).off( '.P' + STATE.id ).removeData( NAME )
+
+ // Restore the element state
+ ELEMENT.type = STATE.type
+ ELEMENT.readOnly = false
+
+ // Trigger the queued “stop” events.
+ P.trigger( 'stop' )
+
+ // Reset the picker states.
+ STATE.methods = {}
+ STATE.start = false
+
+ return P
+ }, //stop
+
+
+ /*
+ * Open up the picker
+ */
+ open: function( dontGiveFocus ) {
+
+ // If it’s already open, do nothing.
+ if ( STATE.open ) return P
+
+ // Add the “active” class.
+ $ELEMENT.addClass( CLASSES.active )
+
+ // Add the “opened” class to the picker root.
+ P.$root.addClass( CLASSES.opened )
+
+ // If we have to give focus, bind the element and doc events.
+ if ( dontGiveFocus !== false ) {
+
+ // Set it as open.
+ STATE.open = true
+
+ // Pass focus to the element’s jQuery object.
+ $ELEMENT.focus()
+
+ // Bind the document events.
+ $document.on( 'click.P' + STATE.id + ' focusin.P' + STATE.id, function( event ) {
+
+ // If the target of the event is not the element, close the picker picker.
+ // * Don’t worry about clicks or focusins on the root because those don’t bubble up.
+ // Also, for Firefox, a click on an `option` element bubbles up directly
+ // to the doc. So make sure the target wasn't the doc.
+ if ( event.target != ELEMENT && event.target != document ) P.close()
+
+ }).on( 'keydown.P' + STATE.id, function( event ) {
+
+ var
+ // Get the keycode.
+ keycode = event.keyCode,
+
+ // Translate that to a selection change.
+ keycodeToMove = P.component.key[ keycode ],
+
+ // Grab the target.
+ target = event.target
+
+
+ // On escape, close the picker and give focus.
+ if ( keycode == 27 ) {
+ P.close( true )
+ }
+
+
+ // Check if there is a key movement or “enter” keypress on the element.
+ else if ( target == ELEMENT && ( keycodeToMove || keycode == 13 ) ) {
+
+ // Prevent the default action to stop page movement.
+ event.preventDefault()
+
+ // Trigger the key movement action.
+ if ( keycodeToMove ) {
+ PickerConstructor._.trigger( P.component.key.go, P, [ keycodeToMove ] )
+ }
+
+ // On “enter”, if the highlighted item isn’t disabled, set the value and close.
+ else if ( !P.$root.find( '.' + CLASSES.highlighted ).hasClass( CLASSES.disabled ) ) {
+ P.set( 'select', P.component.item.highlight ).close()
+ }
+ }
+
+
+ // If the target is within the root and “enter” is pressed,
+ // prevent the default action and trigger a click on the target instead.
+ else if ( P.$root.find( target ).length && keycode == 13 ) {
+ event.preventDefault()
+ target.click()
+ }
+ })
+ }
+
+ // Trigger the queued “open” events.
+ return P.trigger( 'open' )
+ }, //open
+
+
+ /**
+ * Close the picker
+ */
+ close: function( giveFocus ) {
+
+ // If we need to give focus, do it before changing states.
+ if ( giveFocus ) {
+ // ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
+ // The focus is triggered *after* the close has completed - causing it
+ // to open again. So unbind and rebind the event at the next tick.
+ $ELEMENT.off( 'focus.P' + STATE.id ).focus()
+ setTimeout( function() {
+ $ELEMENT.on( 'focus.P' + STATE.id, focusToOpen )
+ }, 0 )
+ }
+
+ // Remove the “active” class.
+ $ELEMENT.removeClass( CLASSES.active )
+
+ // Remove the “opened” and “focused” class from the picker root.
+ P.$root.removeClass( CLASSES.opened + ' ' + CLASSES.focused )
+
+ // If it’s open, update the state.
+ if ( STATE.open ) {
+
+ // Set it as closed.
+ STATE.open = false
+
+ // Unbind the document events.
+ $document.off( '.P' + STATE.id )
+ }
+
+ // Trigger the queued “close” events.
+ return P.trigger( 'close' )
+ }, //close
+
+
+ /**
+ * Clear the values
+ */
+ clear: function() {
+ return P.set( 'clear' )
+ }, //clear
+
+
+ /**
+ * Set something
+ */
+ set: function( thing, value, options ) {
+
+ var thingItem, thingValue,
+ thingIsObject = PickerConstructor._.isObject( thing ),
+ thingObject = thingIsObject ? thing : {}
+
+ if ( thing ) {
+
+ // If the thing isn’t an object, make it one.
+ if ( !thingIsObject ) {
+ thingObject[ thing ] = value
+ }
+
+ // Go through the things of items to set.
+ for ( thingItem in thingObject ) {
+
+ // Grab the value of the thing.
+ thingValue = thingObject[ thingItem ]
+
+ // First, if the item exists and there’s a value, set it.
+ if ( P.component.item[ thingItem ] ) {
+ P.component.set( thingItem, thingValue, options || {} )
+ }
+
+ // Then, check to update the element value and broadcast a change.
+ if ( thingItem == 'select' || thingItem == 'clear' ) {
+ $ELEMENT.val( thingItem == 'clear' ? '' :
+ PickerConstructor._.trigger( P.component.formats.toString, P.component, [ SETTINGS.format, P.component.get( thingItem ) ] )
+ ).trigger( 'change' )
+ }
+ }
+
+ // Render a new picker.
+ P.render()
+ }
+
+ // Trigger queued “set” events and pass the `thingObject`.
+ return P.trigger( 'set', thingObject )
+ }, //set
+
+
+ /**
+ * Get something
+ */
+ get: function( thing, format ) {
+
+ // Make sure there’s something to get.
+ thing = thing || 'value'
+
+ // If a picker state exists, return that.
+ if ( STATE[ thing ] != null ) {
+ return STATE[ thing ]
+ }
+
+ // Return the value, if that.
+ if ( thing == 'value' ) {
+ return ELEMENT.value
+ }
+
+ // Check if a component item exists, return that.
+ if ( P.component.item[ thing ] ) {
+ if ( typeof format == 'string' ) {
+ return PickerConstructor._.trigger( P.component.formats.toString, P.component, [ format, P.component.get( thing ) ] )
+ }
+ return P.component.get( thing )
+ }
+ }, //get
+
+
+
+ /**
+ * Bind events on the things.
+ */
+ on: function( thing, method ) {
+
+ var thingName, thingMethod,
+ thingIsObject = PickerConstructor._.isObject( thing ),
+ thingObject = thingIsObject ? thing : {}
+
+ if ( thing ) {
+
+ // If the thing isn’t an object, make it one.
+ if ( !thingIsObject ) {
+ thingObject[ thing ] = method
+ }
+
+ // Go through the things to bind to.
+ for ( thingName in thingObject ) {
+
+ // Grab the method of the thing.
+ thingMethod = thingObject[ thingName ]
+
+ // Make sure the thing methods collection exists.
+ STATE.methods[ thingName ] = STATE.methods[ thingName ] || []
+
+ // Add the method to the relative method collection.
+ STATE.methods[ thingName ].push( thingMethod )
+ }
+ }
+
+ return P
+ }, //on
+
+
+ /**
+ * Fire off method events.
+ */
+ trigger: function( name, data ) {
+ var methodList = STATE.methods[ name ]
+ if ( methodList ) {
+ methodList.map( function( method ) {
+ PickerConstructor._.trigger( method, P, [ data ] )
+ })
+ }
+ return P
+ } //trigger
+ } //PickerInstance.prototype
+
+
+ /**
+ * Wrap the picker holder components together.
+ */
+ function createWrappedComponent() {
+
+ // Create a picker wrapper holder
+ return PickerConstructor._.node( 'div',
+
+ // Create a picker wrapper node
+ PickerConstructor._.node( 'div',
+
+ // Create a picker frame
+ PickerConstructor._.node( 'div',
+
+ // Create a picker box node
+ PickerConstructor._.node( 'div',
+
+ // Create the components nodes.
+ P.component.nodes( STATE.open ),
+
+ // The picker box class
+ CLASSES.box
+ ),
+
+ // Picker wrap class
+ CLASSES.wrap
+ ),
+
+ // Picker frame class
+ CLASSES.frame
+ ),
+
+ // Picker holder class
+ CLASSES.holder
+ ) //endreturn
+ } //createWrappedComponent
+
+
+ // Separated for IE
+ function focusToOpen( event ) {
+
+ // Stop the event from propagating to the doc.
+ event.stopPropagation()
+
+ // If it’s a focus event, add the “focused” class to the root.
+ if ( event.type == 'focus' ) P.$root.addClass( CLASSES.focused )
+
+ // And then finally open the picker.
+ P.open()
+ }
+
+
+ // Return a new picker instance.
+ return new PickerInstance()
+} //PickerConstructor
+
+
+
+/**
+ * The default classes and prefix to use for the HTML classes.
+ */
+PickerConstructor.klasses = function( prefix ) {
+ prefix = prefix || 'picker'
+ return {
+
+ picker: prefix,
+ opened: prefix + '--opened',
+ focused: prefix + '--focused',
+
+ input: prefix + '__input',
+ active: prefix + '__input--active',
+
+ holder: prefix + '__holder',
+
+ frame: prefix + '__frame',
+ wrap: prefix + '__wrap',
+
+ box: prefix + '__box'
+ }
+} //PickerConstructor.klasses
+
+
+
+/**
+ * PickerConstructor helper methods.
+ */
+PickerConstructor._ = {
+
+ /**
+ * Create a group of nodes. Expects:
+ * `
+ {
+ min: {Integer},
+ max: {Integer},
+ i: {Integer},
+ node: {String},
+ item: {Function}
+ }
+ * `
+ */
+ group: function( groupObject ) {
+
+ var
+ // Scope for the looped object
+ loopObjectScope,
+
+ // Create the nodes list
+ nodesList = '',
+
+ // The counter starts from the `min`
+ counter = PickerConstructor._.trigger( groupObject.min, groupObject )
+
+
+ // Loop from the `min` to `max`, incrementing by `i`
+ for ( ; counter <= PickerConstructor._.trigger( groupObject.max, groupObject, [ counter ] ); counter += groupObject.i ) {
+
+ // Trigger the `item` function within scope of the object
+ loopObjectScope = PickerConstructor._.trigger( groupObject.item, groupObject, [ counter ] )
+
+ // Splice the subgroup and create nodes out of the sub nodes
+ nodesList += PickerConstructor._.node(
+ groupObject.node,
+ loopObjectScope[ 0 ], // the node
+ loopObjectScope[ 1 ], // the classes
+ loopObjectScope[ 2 ] // the attributes
+ )
+ }
+
+ // Return the list of nodes
+ return nodesList
+ }, //group
+
+
+ /**
+ * Create a dom node string
+ */
+ node: function( wrapper, item, klass, attribute ) {
+
+ // If the item is false-y, just return an empty string
+ if ( !item ) return ''
+
+ // If the item is an array, do a join
+ item = Array.isArray( item ) ? item.join( '' ) : item
+
+ // Check for the class
+ klass = klass ? ' class="' + klass + '"' : ''
+
+ // Check for any attributes
+ attribute = attribute ? ' ' + attribute : ''
+
+ // Return the wrapped item
+ return '<' + wrapper + klass + attribute + '>' + item + '</' + wrapper + '>'
+ }, //node
+
+
+ /**
+ * Lead numbers below 10 with a zero.
+ */
+ lead: function( number ) {
+ return ( number < 10 ? '0': '' ) + number
+ },
+
+
+ /**
+ * Trigger a function otherwise return the value.
+ */
+ trigger: function( callback, scope, args ) {
+ return typeof callback == 'function' ? callback.apply( scope, args || [] ) : callback
+ },
+
+
+ /**
+ * If the second character is a digit, length is 2 otherwise 1.
+ */
+ digits: function( string ) {
+ return ( /\d/ ).test( string[ 1 ] ) ? 2 : 1
+ },
+
+
+ /**
+ * Tell if something is an object.
+ */
+ isObject: function( value ) {
+ return {}.toString.call( value ).indexOf( 'Object' ) > -1
+ },
+
+
+ /**
+ * Tell if something is a date object.
+ */
+ isDate: function( value ) {
+ return {}.toString.call( value ).indexOf( 'Date' ) > -1 && this.isInteger( value.getDate() )
+ },
+
+
+ /**
+ * Tell if something is an integer.
+ */
+ isInteger: function( value ) {
+ return {}.toString.call( value ).indexOf( 'Number' ) > -1 && value % 1 === 0
+ }
+} //PickerConstructor._
+
+
+
+/**
+ * Extend the picker with a component and defaults.
+ */
+PickerConstructor.extend = function( name, Component ) {
+
+ // Extend jQuery.
+ $.fn[ name ] = function( options, action ) {
+
+ // Grab the component data.
+ var componentData = this.data( name )
+
+ // If the picker is requested, return the data object.
+ if ( options == 'picker' ) {
+ return componentData
+ }
+
+ // If the component data exists and `options` is a string, carry out the action.
+ if ( componentData && typeof options == 'string' ) {
+ PickerConstructor._.trigger( componentData[ options ], componentData, [ action ] )
+ return this
+ }
+
+ // Otherwise go through each matched element and if the component
+ // doesn’t exist, create a new picker using `this` element
+ // and merging the defaults and options with a deep copy.
+ return this.each( function() {
+ var $this = $( this )
+ if ( !$this.data( name ) ) {
+ new PickerConstructor( this, name, Component, options )
+ }
+ })
+ }
+
+ // Set the defaults.
+ $.fn[ name ].defaults = Component.defaults
+} //PickerConstructor.extend
+
+
+
+// Return the picker constructor.
+return PickerConstructor
+
+
+// Close the global scope.
+})( jQuery, jQuery( document ) );
+
+
+
+
+/*!
+ * Date picker for pickadate.js v3.1.1
+ * http://amsul.github.io/pickadate.js/date.htm
+ */
+
+/*jshint
+ debug: true,
+ devel: true,
+ browser: true,
+ asi: true,
+ unused: true,
+ boss: true
+ */
+
+
+// Create a new scope.
+(function() {
+
+
+/**
+ * Globals and constants
+ */
+var DAYS_IN_WEEK = 7,
+ WEEKS_IN_CALENDAR = 6
+
+
+
+/**
+ * The date picker constructor
+ */
+function DatePicker( picker, settings ) {
+
+ var calendar = this,
+ elementValue = picker.$node[ 0 ].value,
+ elementDataValue = picker.$node.data( 'value' ),
+ valueString = elementDataValue || elementValue,
+ formatString = elementDataValue ? settings.formatSubmit : settings.format
+
+ calendar.settings = settings
+
+ // The queue of methods that will be used to build item objects.
+ calendar.queue = {
+ min: 'measure create',
+ max: 'measure create',
+ now: 'now create',
+ select: 'parse create validate',
+ highlight: 'navigate create validate',
+ view: 'create validate viewset',
+ disable: 'flipItem',
+ enable: 'flipItem'
+ }
+
+ // The component's item object.
+ calendar.item = {}
+
+ calendar.item.disable = ( settings.disable || [] ).slice( 0 )
+ calendar.item.enable = -(function( collectionDisabled ) {
+ return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1
+ })( calendar.item.disable )
+
+ calendar.
+ set( 'min', settings.min ).
+ set( 'max', settings.max ).
+ set( 'now' ).
+
+ // Setting the `select` also sets the `highlight` and `view`.
+ set( 'select',
+
+ // Use the value provided or default to selecting “today”.
+ valueString || calendar.item.now,
+ {
+ // Use the appropriate format.
+ format: formatString,
+
+ // Set user-provided month data as true when there is a
+ // “mm” or “m” used in the relative format string.
+ data: (function( formatArray ) {
+ return valueString && ( formatArray.indexOf( 'mm' ) > -1 || formatArray.indexOf( 'm' ) > -1 )
+ })( calendar.formats.toArray( formatString ) )
+ }
+ )
+
+
+ // The keycode to movement mapping.
+ calendar.key = {
+ 40: 7, // Down
+ 38: -7, // Up
+ 39: 1, // Right
+ 37: -1, // Left
+ go: function( timeChange ) {
+ calendar.set( 'highlight', [ calendar.item.highlight.year, calendar.item.highlight.month, calendar.item.highlight.date + timeChange ], { interval: timeChange } )
+ this.render()
+ }
+ }
+
+
+ // Bind some picker events.
+ picker.
+ on( 'render', function() {
+ picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() {
+ picker.set( 'highlight', [ picker.get( 'view' ).year, this.value, picker.get( 'highlight' ).date ] )
+ picker.$root.find( '.' + settings.klass.selectMonth ).focus()
+ })
+ picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() {
+ picker.set( 'highlight', [ this.value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] )
+ picker.$root.find( '.' + settings.klass.selectYear ).focus()
+ })
+ }).
+ on( 'open', function() {
+ picker.$root.find( 'button, select' ).attr( 'disabled', false )
+ }).
+ on( 'close', function() {
+ picker.$root.find( 'button, select' ).attr( 'disabled', true )
+ })
+
+} //DatePicker
+
+
+/**
+ * Set a datepicker item object.
+ */
+DatePicker.prototype.set = function( type, value, options ) {
+
+ var calendar = this
+
+ // Go through the queue of methods, and invoke the function. Update this
+ // as the time unit, and set the final resultant as this item type.
+ // * In the case of `enable`, keep the queue but set `disable` instead.
+ // And in the case of `flip`, keep the queue but set `enable` instead.
+ calendar.item[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) {
+ return value = calendar[ method ]( type, value, options )
+ }).pop()
+
+ // Check if we need to cascade through more updates.
+ if ( type == 'select' ) {
+ calendar.set( 'highlight', calendar.item.select, options )
+ }
+ else if ( type == 'highlight' ) {
+ calendar.set( 'view', calendar.item.highlight, options )
+ }
+ else if ( ( type == 'flip' || type == 'min' || type == 'max' || type == 'disable' || type == 'enable' ) && calendar.item.select && calendar.item.highlight ) {
+ calendar.
+ set( 'select', calendar.item.select, options ).
+ set( 'highlight', calendar.item.highlight, options )
+ }
+
+ return calendar
+} //DatePicker.prototype.set
+
+
+/**
+ * Get a datepicker item object.
+ */
+DatePicker.prototype.get = function( type ) {
+ return this.item[ type ]
+} //DatePicker.prototype.get
+
+
+/**
+ * Create a picker date object.
+ */
+DatePicker.prototype.create = function( type, value, options ) {
+
+ var isInfiniteValue,
+ calendar = this
+
+ // If there’s no value, use the type as the value.
+ value = value === undefined ? type : value
+
+
+ // If it’s infinity, update the value.
+ if ( value == -Infinity || value == Infinity ) {
+ isInfiniteValue = value
+ }
+
+ // If it’s an object, use the native date object.
+ else if ( Picker._.isObject( value ) && Picker._.isInteger( value.pick ) ) {
+ value = value.obj
+ }
+
+ // If it’s an array, convert it into a date and make sure
+ // that it’s a valid date – otherwise default to today.
+ else if ( Array.isArray( value ) ) {
+ value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] )
+ value = Picker._.isDate( value ) ? value : calendar.create().obj
+ }
+
+ // If it’s a number or date object, make a normalized date.
+ else if ( Picker._.isInteger( value ) || Picker._.isDate( value ) ) {
+ value = calendar.normalize( new Date( value ), options )
+ }
+
+ // If it’s a literal true or any other case, set it to now.
+ else /*if ( value === true )*/ {
+ value = calendar.now( type, value, options )
+ }
+
+ // Return the compiled object.
+ return {
+ year: isInfiniteValue || value.getFullYear(),
+ month: isInfiniteValue || value.getMonth(),
+ date: isInfiniteValue || value.getDate(),
+ day: isInfiniteValue || value.getDay(),
+ obj: isInfiniteValue || value,
+ pick: isInfiniteValue || value.getTime()
+ }
+} //DatePicker.prototype.create
+
+
+/**
+ * Get the date today.
+ */
+DatePicker.prototype.now = function( type, value, options ) {
+ value = new Date()
+ if ( options && options.rel ) {
+ value.setDate( value.getDate() + options.rel )
+ }
+ return this.normalize( value, options )
+} //DatePicker.prototype.now
+
+
+/**
+ * Navigate to next/prev month.
+ */
+DatePicker.prototype.navigate = function( type, value, options ) {
+
+ if ( Picker._.isObject( value ) ) {
+
+ var targetDateObject = new Date( value.year, value.month + ( options && options.nav ? options.nav : 0 ), 1 ),
+ year = targetDateObject.getFullYear(),
+ month = targetDateObject.getMonth(),
+ date = value.date
+
+ // Make sure the date is valid and if the month we’re going to doesn’t have enough
+ // days, keep decreasing the date until we reach the month’s last date.
+ while ( Picker._.isDate( targetDateObject ) && new Date( year, month, date ).getMonth() !== month ) {
+ date -= 1
+ }
+
+ value = [ year, month, date ]
+ }
+
+ return value
+} //DatePicker.prototype.navigate
+
+
+/**
+ * Normalize a date by setting the hours to midnight.
+ */
+DatePicker.prototype.normalize = function( value/*, options*/ ) {
+ value.setHours( 0, 0, 0, 0 )
+ return value
+}
+
+
+/**
+ * Measure the range of dates.
+ */
+DatePicker.prototype.measure = function( type, value/*, options*/ ) {
+
+ var calendar = this
+
+ // If it's anything false-y, remove the limits.
+ if ( !value ) {
+ value = type == 'min' ? -Infinity : Infinity
+ }
+
+ // If it's an integer, get a date relative to today.
+ else if ( Picker._.isInteger( value ) ) {
+ value = calendar.now( type, value, { rel: value } )
+ }
+
+ return value
+} ///DatePicker.prototype.measure
+
+
+/**
+ * Create a viewset object based on navigation.
+ */
+DatePicker.prototype.viewset = function( type, dateObject/*, options*/ ) {
+ return this.create([ dateObject.year, dateObject.month, 1 ])
+}
+
+
+/**
+ * Validate a date as enabled and shift if needed.
+ */
+DatePicker.prototype.validate = function( type, dateObject, options ) {
+
+ var calendar = this,
+
+ // Keep a reference to the original date.
+ originalDateObject = dateObject,
+
+ // Make sure we have an interval.
+ interval = options && options.interval ? options.interval : 1,
+
+ // Check if the calendar enabled dates are inverted.
+ isInverted = calendar.item.enable === -1,
+
+ // Check if we have any enabled dates after/before now.
+ hasEnabledBeforeTarget, hasEnabledAfterTarget,
+
+ // The min & max limits.
+ minLimitObject = calendar.item.min,
+ maxLimitObject = calendar.item.max,
+
+ // Check if we’ve reached the limit during shifting.
+ reachedMin, reachedMax,
+
+ // Check if the calendar is inverted and at least one weekday is enabled.
+ hasEnabledWeekdays = isInverted && calendar.item.disable.filter( function( value ) {
+
+ // If there’s a date, check where it is relative to the target.
+ if ( Array.isArray( value ) ) {
+ var dateTime = calendar.create( value ).pick
+ if ( dateTime < dateObject.pick ) hasEnabledBeforeTarget = true
+ else if ( dateTime > dateObject.pick ) hasEnabledAfterTarget = true
+ }
+
+ // Return only integers for enabled weekdays.
+ return Picker._.isInteger( value )
+ }).length
+
+
+
+ // Cases to validate for:
+ // [1] Not inverted and date disabled.
+ // [2] Inverted and some dates enabled.
+ // [3] Out of range.
+ //
+ // Cases to **not** validate for:
+ // • Not inverted and date enabled.
+ // • Inverted and all dates disabled.
+ // • Navigating months.
+ // • ..and anything else.
+ if (
+ /* 1 */ ( !isInverted && calendar.disabled( dateObject ) ) ||
+ /* 2 */ ( isInverted && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) ||
+ /* 3 */ ( dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick )
+ ) {
+
+
+ // When inverted, flip the direction if there aren’t any enabled weekdays
+ // and there are no enabled dates in the direction of the interval.
+ if ( isInverted && !hasEnabledWeekdays && ( ( !hasEnabledAfterTarget && interval > 0 ) || ( !hasEnabledBeforeTarget && interval < 0 ) ) ) {
+ interval *= -1
+ }
+
+
+ // Keep looping until we reach an enabled date.
+ while ( calendar.disabled( dateObject ) ) {
+
+
+ // If we’ve looped into the next/prev month, return to the original date and flatten the interval.
+ if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) {
+ dateObject = originalDateObject
+ interval = Math.abs( interval ) / interval
+ }
+
+
+ // If we’ve reached the min/max limit, reverse the direction and flatten the interval.
+ if ( dateObject.pick <= minLimitObject.pick ) {
+ reachedMin = true
+ interval = 1
+ }
+ else if ( dateObject.pick >= maxLimitObject.pick ) {
+ reachedMax = true
+ interval = -1
+ }
+
+
+ // If we’ve reached both limits, just break out of the loop.
+ if ( reachedMin && reachedMax ) {
+ break
+ }
+
+
+ // Finally, create the shifted date using the interval and keep looping.
+ dateObject = calendar.create([ dateObject.year, dateObject.month, dateObject.date + interval ])
+ }
+
+ } //endif
+
+
+ // Return the date object settled on.
+ return dateObject
+} //DatePicker.prototype.validate
+
+
+/**
+ * Check if an object is disabled.
+ */
+DatePicker.prototype.disabled = function( dateObject ) {
+
+ var calendar = this,
+
+ // Filter through the disabled dates to check if this is one.
+ isDisabledDate = calendar.item.disable.filter( function( dateToDisable ) {
+
+ // If the date is a number, match the weekday with 0index and `firstDay` check.
+ if ( Picker._.isInteger( dateToDisable ) ) {
+ return dateObject.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7
+ }
+
+ // If it's an array, create the object and match the exact date.
+ if ( Array.isArray( dateToDisable ) ) {
+ return dateObject.pick === calendar.create( dateToDisable ).pick
+ }
+ }).length
+
+
+ // It’s disabled beyond the min/max limits. If within the limits, check the
+ // calendar “enabled” flag is flipped and respectively flip the condition.
+ return dateObject.pick < calendar.item.min.pick ||
+ dateObject.pick > calendar.item.max.pick ||
+ calendar.item.enable === -1 ? !isDisabledDate : isDisabledDate
+} //DatePicker.prototype.disabled
+
+
+/**
+ * Parse a string into a usable type.
+ */
+DatePicker.prototype.parse = function( type, value, options ) {
+
+ var calendar = this,
+ parsingObject = {}
+
+ if ( !value || Picker._.isInteger( value ) || Array.isArray( value ) || Picker._.isDate( value ) || Picker._.isObject( value ) && Picker._.isInteger( value.pick ) ) {
+ return value
+ }
+
+ // We need a `.format` to parse the value.
+ if ( !( options && options.format ) ) {
+ // should probably default to the default format.
+ throw "Need a formatting option to parse this.."
+ }
+
+ // Convert the format into an array and then map through it.
+ calendar.formats.toArray( options.format ).map( function( label ) {
+
+ var
+ // Grab the formatting label.
+ formattingLabel = calendar.formats[ label ],
+
+ // The format length is from the formatting label function or the
+ // label length without the escaping exclamation (!) mark.
+ formatLength = formattingLabel ? Picker._.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length
+
+ // If there's a format label, split the value up to the format length.
+ // Then add it to the parsing object with appropriate label.
+ if ( formattingLabel ) {
+ parsingObject[ label ] = value.substr( 0, formatLength )
+ }
+
+ // Update the value as the substring from format length to end.
+ value = value.substr( formatLength )
+ })
+
+ // If it’s parsing a user provided month value, compensate for month 0index.
+ return [ parsingObject.yyyy || parsingObject.yy, +( parsingObject.mm || parsingObject.m ) - ( options.data ? 1 : 0 ), parsingObject.dd || parsingObject.d ]
+} //DatePicker.prototype.parse
+
+
+/**
+ * Various formats to display the object in.
+ */
+DatePicker.prototype.formats = (function() {
+
+ // Return the length of the first word in a collection.
+ function getWordLengthFromCollection( string, collection, dateObject ) {
+
+ // Grab the first word from the string.
+ var word = string.match( /\w+/ )[ 0 ]
+
+ // If there's no month index, add it to the date object
+ if ( !dateObject.mm && !dateObject.m ) {
+ dateObject.m = collection.indexOf( word )
+ }
+
+ // Return the length of the word.
+ return word.length
+ }
+
+ // Get the length of the first word in a string.
+ function getFirstWordLength( string ) {
+ return string.match( /\w+/ )[ 0 ].length
+ }
+
+ return {
+
+ d: function( string, dateObject ) {
+
+ // If there's string, then get the digits length.
+ // Otherwise return the selected date.
+ return string ? Picker._.digits( string ) : dateObject.date
+ },
+ dd: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected date with a leading zero.
+ return string ? 2 : Picker._.lead( dateObject.date )
+ },
+ ddd: function( string, dateObject ) {
+
+ // If there's a string, then get the length of the first word.
+ // Otherwise return the short selected weekday.
+ return string ? getFirstWordLength( string ) : this.settings.weekdaysShort[ dateObject.day ]
+ },
+ dddd: function( string, dateObject ) {
+
+ // If there's a string, then get the length of the first word.
+ // Otherwise return the full selected weekday.
+ return string ? getFirstWordLength( string ) : this.settings.weekdaysFull[ dateObject.day ]
+ },
+ m: function( string, dateObject ) {
+
+ // If there's a string, then get the length of the digits
+ // Otherwise return the selected month with 0index compensation.
+ return string ? Picker._.digits( string ) : dateObject.month + 1
+ },
+ mm: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected month with 0index and leading zero.
+ return string ? 2 : Picker._.lead( dateObject.month + 1 )
+ },
+ mmm: function( string, dateObject ) {
+
+ var collection = this.settings.monthsShort
+
+ // If there's a string, get length of the relevant month from the short
+ // months collection. Otherwise return the selected month from that collection.
+ return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
+ },
+ mmmm: function( string, dateObject ) {
+
+ var collection = this.settings.monthsFull
+
+ // If there's a string, get length of the relevant month from the full
+ // months collection. Otherwise return the selected month from that collection.
+ return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
+ },
+ yy: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected year by slicing out the first 2 digits.
+ return string ? 2 : ( '' + dateObject.year ).slice( 2 )
+ },
+ yyyy: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 4.
+ // Otherwise return the selected year.
+ return string ? 4 : dateObject.year
+ },
+
+ // Create an array by splitting the formatting string passed.
+ toArray: function( formatString ) { return formatString.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) },
+
+ // Format an object into a string using the formatting options.
+ toString: function ( formatString, itemObject ) {
+ var calendar = this
+ return calendar.formats.toArray( formatString ).map( function( label ) {
+ return Picker._.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' )
+ }).join( '' )
+ }
+ }
+})() //DatePicker.prototype.formats
+
+
+/**
+ * Flip an item as enabled or disabled.
+ */
+DatePicker.prototype.flipItem = function( type, value/*, options*/ ) {
+
+ var calendar = this,
+ collection = calendar.item.disable,
+ isInverted = calendar.item.enable === -1
+
+ // Flip the enabled and disabled dates.
+ if ( value == 'flip' ) {
+ calendar.item.enable = isInverted ? 1 : -1
+ }
+
+ // Check if we have to add/remove from collection.
+ else if ( !isInverted && type == 'enable' || isInverted && type == 'disable' ) {
+ collection = calendar.removeDisabled( collection, value )
+ }
+ else if ( !isInverted && type == 'disable' || isInverted && type == 'enable' ) {
+ collection = calendar.addDisabled( collection, value )
+ }
+
+ return collection
+} //DatePicker.prototype.flipItem
+
+
+/**
+ * Add an item to the disabled collection.
+ */
+DatePicker.prototype.addDisabled = function( collection, item ) {
+ var calendar = this
+ item.map( function( timeUnit ) {
+ if ( !calendar.filterDisabled( collection, timeUnit ).length ) {
+ collection.push( timeUnit )
+ }
+ })
+ return collection
+} //DatePicker.prototype.addDisabled
+
+
+/**
+ * Remove an item from the disabled collection.
+ */
+DatePicker.prototype.removeDisabled = function( collection, item ) {
+ var calendar = this
+ item.map( function( timeUnit ) {
+ collection = calendar.filterDisabled( collection, timeUnit, 1 )
+ })
+ return collection
+} //DatePicker.prototype.removeDisabled
+
+
+/**
+ * Filter through the disabled collection to find a time unit.
+ */
+DatePicker.prototype.filterDisabled = function( collection, timeUnit, isRemoving ) {
+ var timeIsArray = Array.isArray( timeUnit )
+ return collection.filter( function( disabledTimeUnit ) {
+ var isMatch = !timeIsArray && timeUnit === disabledTimeUnit ||
+ timeIsArray && Array.isArray( disabledTimeUnit ) && timeUnit.toString() === disabledTimeUnit.toString()
+ return isRemoving ? !isMatch : isMatch
+ })
+} //DatePicker.prototype.filterDisabled
+
+
+/**
+ * Create a string for the nodes in the picker.
+ */
+DatePicker.prototype.nodes = function( isOpen ) {
+
+ var
+ calendar = this,
+ settings = calendar.settings,
+ nowObject = calendar.item.now,
+ selectedObject = calendar.item.select,
+ highlightedObject = calendar.item.highlight,
+ viewsetObject = calendar.item.view,
+ disabledCollection = calendar.item.disable,
+ minLimitObject = calendar.item.min,
+ maxLimitObject = calendar.item.max,
+
+
+ // Create the calendar table head using a copy of weekday labels collection.
+ // * We do a copy so we don't mutate the original array.
+ tableHead = (function( collection ) {
+
+ // If the first day should be Monday, move Sunday to the end.
+ if ( settings.firstDay ) {
+ collection.push( collection.shift() )
+ }
+
+ // Create and return the table head group.
+ return Picker._.node(
+ 'thead',
+ Picker._.group({
+ min: 0,
+ max: DAYS_IN_WEEK - 1,
+ i: 1,
+ node: 'th',
+ item: function( counter ) {
+ return [
+ collection[ counter ],
+ settings.klass.weekdays
+ ]
+ }
+ })
+ ) //endreturn
+ })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ) ), //tableHead
+
+
+ // Create the nav for next/prev month.
+ createMonthNav = function( next ) {
+
+ // Otherwise, return the created month tag.
+ return Picker._.node(
+ 'div',
+ ' ',
+ settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + (
+
+ // If the focused month is outside the range, disabled the button.
+ ( next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month ) ||
+ ( !next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month ) ?
+ ' ' + settings.klass.navDisabled : ''
+ ),
+ 'data-nav=' + ( next || -1 )
+ ) //endreturn
+ }, //createMonthNav
+
+
+ // Create the month label.
+ createMonthLabel = function( monthsCollection ) {
+
+ // If there are months to select, add a dropdown menu.
+ if ( settings.selectMonths ) {
+
+ return Picker._.node( 'select', Picker._.group({
+ min: 0,
+ max: 11,
+ i: 1,
+ node: 'option',
+ item: function( loopedMonth ) {
+
+ return [
+
+ // The looped month and no classes.
+ monthsCollection[ loopedMonth ], 0,
+
+ // Set the value and selected index.
+ 'value=' + loopedMonth +
+ ( viewsetObject.month == loopedMonth ? ' selected' : '' ) +
+ (
+ (
+ ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) ||
+ ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month )
+ ) ?
+ ' disabled' : ''
+ )
+ ]
+ }
+ }), settings.klass.selectMonth, isOpen ? '' : 'disabled' )
+ }
+
+ // If there's a need for a month selector
+ return Picker._.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month )
+ }, //createMonthLabel
+
+
+ // Create the year label.
+ createYearLabel = function() {
+
+ var focusedYear = viewsetObject.year,
+
+ // If years selector is set to a literal "true", set it to 5. Otherwise
+ // divide in half to get half before and half after focused year.
+ numberYears = settings.selectYears === true ? 5 : ~~( settings.selectYears / 2 )
+
+ // If there are years to select, add a dropdown menu.
+ if ( numberYears ) {
+
+ var
+ minYear = minLimitObject.year,
+ maxYear = maxLimitObject.year,
+ lowestYear = focusedYear - numberYears,
+ highestYear = focusedYear + numberYears
+
+ // If the min year is greater than the lowest year, increase the highest year
+ // by the difference and set the lowest year to the min year.
+ if ( minYear > lowestYear ) {
+ highestYear += minYear - lowestYear
+ lowestYear = minYear
+ }
+
+ // If the max year is less than the highest year, decrease the lowest year
+ // by the lower of the two: available and needed years. Then set the
+ // highest year to the max year.
+ if ( maxYear < highestYear ) {
+
+ var availableYears = lowestYear - minYear,
+ neededYears = highestYear - maxYear
+
+ lowestYear -= availableYears > neededYears ? neededYears : availableYears
+ highestYear = maxYear
+ }
+
+ return Picker._.node( 'select', Picker._.group({
+ min: lowestYear,
+ max: highestYear,
+ i: 1,
+ node: 'option',
+ item: function( loopedYear ) {
+ return [
+
+ // The looped year and no classes.
+ loopedYear, 0,
+
+ // Set the value and selected index.
+ 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' )
+ ]
+ }
+ }), settings.klass.selectYear, isOpen ? '' : 'disabled' )
+ }
+
+ // Otherwise just return the year focused
+ return Picker._.node( 'div', focusedYear, settings.klass.year )
+ } //createYearLabel
+
+
+ // Create and return the entire calendar.
+ return Picker._.node(
+ 'div',
+ createMonthNav() + createMonthNav( 1 ) +
+ createMonthLabel( settings.showMonthsShort ? settings.monthsShort : settings.monthsFull ) +
+ createYearLabel(),
+ settings.klass.header
+ ) + Picker._.node(
+ 'table',
+ tableHead +
+ Picker._.node(
+ 'tbody',
+ Picker._.group({
+ min: 0,
+ max: WEEKS_IN_CALENDAR - 1,
+ i: 1,
+ node: 'tr',
+ item: function( rowCounter ) {
+
+ // If Monday is the first day and the month starts on Sunday, shift the date back a week.
+ var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0
+
+ return [
+ Picker._.group({
+ min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index
+ max: function() {
+ return this.min + DAYS_IN_WEEK - 1
+ },
+ i: 1,
+ node: 'td',
+ item: function( targetDate ) {
+
+ // Convert the time date from a relative date to a target date.
+ targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ])
+
+ return [
+ Picker._.node(
+ 'div',
+ targetDate.date,
+ (function( klasses ) {
+
+ // Add the `infocus` or `outfocus` classes based on month in view.
+ klasses.push( viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus )
+
+ // Add the `today` class if needed.
+ if ( nowObject.pick == targetDate.pick ) {
+ klasses.push( settings.klass.now )
+ }
+
+ // Add the `selected` class if something's selected and the time matches.
+ if ( selectedObject && selectedObject.pick == targetDate.pick ) {
+ klasses.push( settings.klass.selected )
+ }
+
+ // Add the `highlighted` class if something's highlighted and the time matches.
+ if ( highlightedObject && highlightedObject.pick == targetDate.pick ) {
+ klasses.push( settings.klass.highlighted )
+ }
+
+ // Add the `disabled` class if something's disabled and the object matches.
+ if ( disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick ) {
+ klasses.push( settings.klass.disabled )
+ }
+
+ return klasses.join( ' ' )
+ })([ settings.klass.day ]),
+ 'data-pick=' + targetDate.pick
+ )
+ ] //endreturn
+ }
+ })
+ ] //endreturn
+ }
+ })
+ ),
+ settings.klass.table
+ ) +
+
+ Picker._.node(
+ 'div',
+ Picker._.node( 'button', settings.today, settings.klass.buttonToday, 'data-pick=' + nowObject.pick + ( isOpen ? '' : ' disabled' ) ) +
+ Picker._.node( 'button', settings.clear, settings.klass.buttonClear, 'data-clear=1' + ( isOpen ? '' : ' disabled' ) ),
+ settings.klass.footer
+ ) //endreturn
+} //DatePicker.prototype.nodes
+
+
+
+
+/**
+ * The date picker defaults.
+ */
+DatePicker.defaults = (function( prefix ) {
+
+ return {
+
+ // Months and weekdays
+ monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
+ monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
+ weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
+ weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
+
+ // Today and clear
+ today: 'Today',
+ clear: 'Clear',
+
+ // The format to show on the `input` element
+ format: 'd mmmm, yyyy',
+
+ // Classes
+ klass: {
+
+ table: prefix + 'table',
+
+ header: prefix + 'header',
+
+ navPrev: prefix + 'nav--prev',
+ navNext: prefix + 'nav--next',
+ navDisabled: prefix + 'nav--disabled',
+
+ month: prefix + 'month',
+ year: prefix + 'year',
+
+ selectMonth: prefix + 'select--month',
+ selectYear: prefix + 'select--year',
+
+ weekdays: prefix + 'weekday',
+
+ day: prefix + 'day',
+ disabled: prefix + 'day--disabled',
+ selected: prefix + 'day--selected',
+ highlighted: prefix + 'day--highlighted',
+ now: prefix + 'day--today',
+ infocus: prefix + 'day--infocus',
+ outfocus: prefix + 'day--outfocus',
+
+ footer: prefix + 'footer',
+
+ buttonClear: prefix + 'button--clear',
+ buttonToday: prefix + 'button--today'
+ }
+ }
+})( Picker.klasses().picker + '__' )
+
+
+
+
+
+/**
+ * Extend the picker to add the date picker.
+ */
+Picker.extend( 'pickadate', DatePicker )
+
+
+// Close the scope.
+})();
+
+
+
+
+/*jshint
+ asi: true,
+ unused: true,
+ boss: true,
+ loopfunc: true,
+ eqnull: true
+ */
+
+
+/*!
+ * Legacy browser support
+ */
+
+// isArray support
+if ( !Array.isArray ) {
+ Array.isArray = function( value ) {
+ return {}.toString.call( value ) == '[object Array]'
+ }
+}
+
+
+// Map array support
+if ( ![].map ) {
+ Array.prototype.map = function ( callback, self ) {
+ var array = this, len = array.length, newArray = new Array( len )
+ for ( var i = 0; i < len; i++ ) {
+ if ( i in array ) {
+ newArray[ i ] = callback.call( self, array[ i ], i, array )
+ }
+ }
+ return newArray
+ }
+}
+
+
+// Filter array support
+if ( ![].filter ) {
+ Array.prototype.filter = function( callback ) {
+ if ( this == null ) throw new TypeError()
+ var t = Object( this ), len = t.length >>> 0
+ if ( typeof callback != 'function' ) throw new TypeError()
+ var newArray = [], thisp = arguments[ 1 ]
+ for ( var i = 0; i < len; i++ ) {
+ if ( i in t ) {
+ var val = t[ i ]
+ if ( callback.call( thisp, val, i, t ) ) newArray.push( val )
+ }
+ }
+ return newArray
+ }
+}
+
+
+// Index of array support
+if ( ![].indexOf ) {
+ Array.prototype.indexOf = function( searchElement ) {
+ if ( this == null ) throw new TypeError()
+ var t = Object( this ), len = t.length >>> 0
+ if ( len === 0 ) return -1
+ var n = 0
+ if ( arguments.length > 1 ) {
+ n = Number( arguments[ 1 ] )
+ if ( n != n ) {
+ n = 0
+ }
+ else if ( n !== 0 && n != Infinity && n != -Infinity ) {
+ n = ( n > 0 || -1 ) * Math.floor( Math.abs( n ) )
+ }
+ }
+ if ( n >= len ) return -1
+ var k = n >= 0 ? n : Math.max( len - Math.abs( n ), 0 )
+ for ( ; k < len; k++ ) {
+ if ( k in t && t[ k ] === searchElement ) return k
+ }
+ return -1
+ }
+}
+
+
+/*!
+ * Cross-Browser Split 1.1.1
+ * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
+ * Available under the MIT License
+ * http://blog.stevenlevithan.com/archives/cross-browser-split
+ */
+var nativeSplit = String.prototype.split, compliantExecNpcg = /()??/.exec('')[1] === undefined
+String.prototype.split = function(separator, limit) {
+ var str = this
+ if (Object.prototype.toString.call(separator) !== '[object RegExp]') {
+ return nativeSplit.call(str, separator, limit)
+ }
+ var output = [],
+ flags = (separator.ignoreCase ? 'i' : '') +
+ (separator.multiline ? 'm' : '') +
+ (separator.extended ? 'x' : '') +
+ (separator.sticky ? 'y' : ''),
+ lastLastIndex = 0,
+ separator2, match, lastIndex, lastLength
+ separator = new RegExp(separator.source, flags + 'g')
+ str += ''
+ if (!compliantExecNpcg) {
+ separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags)
+ }
+ limit = limit === undefined ? -1 >>> 0 : limit >>> 0
+ while (match = separator.exec(str)) {
+ lastIndex = match.index + match[0].length
+ if (lastIndex > lastLastIndex) {
+ output.push(str.slice(lastLastIndex, match.index))
+ if (!compliantExecNpcg && match.length > 1) {
+ match[0].replace(separator2, function () {
+ for (var i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === undefined) {
+ match[i] = undefined
+ }
+ }
+ })
+ }
+ if (match.length > 1 && match.index < str.length) {
+ Array.prototype.push.apply(output, match.slice(1))
+ }
+ lastLength = match[0].length
+ lastLastIndex = lastIndex
+ if (output.length >= limit) {
+ break
+ }
+ }
+ if (separator.lastIndex === match.index) {
+ separator.lastIndex++
+ }
+ }
+ if (lastLastIndex === str.length) {
+ if (lastLength || !separator.test('')) {
+ output.push('')
+ }
+ } else {
+ output.push(str.slice(lastLastIndex))
+ }
+ return output.length > limit ? output.slice(0, limit) : output
+}
+$(document).ready(function() {
+ var switched = false;
+ var updateTables = function() {
+ if (($(window).width() <= 768) && !switched ){
+ console.log('entro');
+ switched = true;
+ $("table.responsive").each(function(i, element) {
+ splitTable($(element));
+ });
+ return true;
+ }
+ else if (switched && ($(window).width() > 768)) {
+ switched = false;
+ $("table.responsive").each(function(i, element) {
+ unsplitTable($(element));
+ });
+ }
+ };
+
+ $(window).load(updateTables);
+ $(window).on("redraw",function(){switched=false;updateTables();}); // An event to listen for
+ $(window).on("resize", updateTables);
+
+
+ function splitTable(original)
+ {
+ original.wrap("<div class='table-wrapper' />");
+
+ var copy = original.clone();
+ copy.find("td:not(:first-child), th:not(:first-child)").css("display", "none");
+ copy.removeClass("responsive");
+
+ original.closest(".table-wrapper").append(copy);
+ copy.wrap("<div class='pinned' />");
+ original.wrap("<div class='scrollable' />");
+
+ setCellHeights(original, copy);
+ }
+
+ function unsplitTable(original) {
+ original.closest(".table-wrapper").find(".pinned").remove();
+ original.unwrap();
+ original.unwrap();
+ }
+
+ function setCellHeights(original, copy) {
+ var tr = original.find('tr'),
+ tr_copy = copy.find('tr'),
+ heights = [];
+
+ tr.each(function (index) {
+ var self = $(this),
+ tx = self.find('th, td');
+
+ tx.each(function () {
+ var height = $(this).outerHeight(true);
+ heights[index] = heights[index] || 0;
+ if (height > heights[index]) heights[index] = height;
+ });
+
+ });
+
+ tr_copy.each(function (index) {
+ $(this).height(heights[index]);
+ });
+ }
+
+});
+/* ============================================================
+ * bootstrap-dropdown.js v2.3.2
+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns
+ * ============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* DROPDOWN CLASS DEFINITION
+ * ========================= */
+
+ var toggle = '[data-toggle=dropdown]'
+ , Dropdown = function (element) {
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
+ $('html').on('click.dropdown.data-api', function () {
+ $el.parent().removeClass('open')
+ })
+ }
+
+ Dropdown.prototype = {
+
+ constructor: Dropdown
+
+ , toggle: function (e) {
+ var $this = $(this)
+ , $parent
+ , isActive
+
+ if ($this.is('.disabled, :disabled')) return
+
+ $parent = getParent($this)
+
+ isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement) {
+ // if mobile we we use a backdrop because click events don't delegate
+ $('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
+ }
+ $parent.toggleClass('open')
+ }
+
+ $this.focus()
+
+ return false
+ }
+
+ , keydown: function (e) {
+ var $this
+ , $items
+ , $active
+ , $parent
+ , isActive
+ , index
+
+ if (!/(38|40|27)/.test(e.keyCode)) return
+
+ $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ $parent = getParent($this)
+
+ isActive = $parent.hasClass('open')
+
+ if (!isActive || (isActive && e.keyCode == 27)) {
+ if (e.which == 27) $parent.find(toggle).focus()
+ return $this.click()
+ }
+
+ $items = $('[role=menu] li:not(.divider):visible a', $parent)
+
+ if (!$items.length) return
+
+ index = $items.index($items.filter(':focus'))
+
+ if (e.keyCode == 38 && index > 0) index-- // up
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items
+ .eq(index)
+ .focus()
+ }
+
+ }
+
+ function clearMenus() {
+ $('.dropdown-backdrop').remove()
+ $(toggle).each(function () {
+ getParent($(this)).removeClass('open')
+ })
+ }
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+ , $parent
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ $parent = selector && $(selector)
+
+ if (!$parent || !$parent.length) $parent = $this.parent()
+
+ return $parent
+ }
+
+
+ /* DROPDOWN PLUGIN DEFINITION
+ * ========================== */
+
+ var old = $.fn.dropdown
+
+ $.fn.dropdown = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('dropdown')
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ /* DROPDOWN NO CONFLICT
+ * ==================== */
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
+
+
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
+ * =================================== */
+
+ $(document)
+ .on('click.dropdown.data-api', clearMenus)
+ .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
+ .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
+
+ $(document).ready(function() {
+ $('.dropdown-toggle').dropdown();
+
+ $('.dropdown input, .dropdown label').click(function(e){
+ e.stopPropagation();
+ });
+ })
+
+}(window.jQuery);
+// Generated by CoffeeScript 1.6.3
+var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+
+(function($, window) {
+ var Modal;
+ Modal = (function() {
+ function Modal(el, options) {
+ this.hideOnDocumentClick = __bind(this.hideOnDocumentClick, this);
+ this.hideOnEsc = __bind(this.hideOnEsc, this);
+ this.show = __bind(this.show, this);
+ this.init = __bind(this.init, this);
+ this.options = $.extend({}, options);
+ this.$el = $(el);
+ this.modal = $(this.$el.data('target'));
+ this.close = this.modal.find('.modal-close');
+ this.transition = this.$el.data('transition') || "1";
+ this.theme = this.$el.data('theme') || "default";
+ this.modal.addClass("modal-effect-" + this.transition);
+ this.modal.find('.modal-content').addClass("modal-content-" + this.theme);
+ }
+
+ Modal.prototype.init = function() {
+ var _this = this;
+ this.$el.click(this.show);
+ return this.close.click(function(ev) {
+ ev.stopPropagation();
+ return _this.hide();
+ });
+ };
+
+ Modal.prototype.show = function(ev) {
+ if (this.$el.is('div')) {
+ this.$el.addClass('modal-show');
+ } else {
+ this.modal.addClass('modal-show');
+ }
+ $('.modal-overlay').addClass('modal-show-overlay');
+ $('body').bind('keyup', this.hideOnEsc);
+ return $('body').bind('click', this.hideOnDocumentClick);
+ };
+
+ Modal.prototype.hideOnEsc = function(event) {
+ if (event.keyCode === 27) {
+ return this.hide();
+ }
+ };
+
+ Modal.prototype.hideOnDocumentClick = function(event) {
+ if ($(event.target).is('.modal-overlay')) {
+ return this.hide();
+ }
+ };
+
+ Modal.prototype.hide = function() {
+ $('.modal-overlay').removeClass('modal-show-overlay');
+ if (this.$el.is('div')) {
+ this.$el.removeClass('modal-show');
+ } else {
+ this.modal.removeClass('modal-show');
+ }
+ $('body').unbind('keyup', this.hideOnEsc);
+ return $('body').unbind('click', this.hideOnDocumentClick);
+ };
+
+ return Modal;
+
+ })();
+ $.fn.modal = function(option) {
+ return this.each(function() {
+ var $this, data, options;
+ $this = $(this);
+ data = $this.data('modal');
+ options = $.extend({}, $this.data(), typeof option === 'object' && option);
+ if (!data) {
+ $this.data('modal', (data = new Modal(this, options)));
+ }
+ if (typeof option === 'string') {
+ return data[option]();
+ }
+ });
+ };
+ $(document).ready(function() {
+ $('.panel-content').append('<div class="modal-overlay"></div>');
+ return $('[data-furatto="modal"]').each(function() {
+ var modal;
+ modal = $(this);
+ return modal.modal('init');
+ });
+ });
+ return $(document).on('click', '[data-furatto="modal"]', function(e) {
+ var $this;
+ $this = $(this);
+ return $this.modal('init');
+ });
+})(window.jQuery, window);
+/*
+ * Swiper 2.1 - Mobile Touch Slider
+ * http://www.idangero.us/sliders/swiper/
+ *
+ * Copyright 2012-2013, Vladimir Kharlampidi
+ * The iDangero.us
+ * http://www.idangero.us/
+ *
+ * Licensed under GPL & MIT
+ *
+ * Updated on: August 22, 2013
+*/
+var Swiper = function (selector, params) {
+ /*=========================
+ A little bit dirty but required part for IE8 and old FF support
+ ===========================*/
+ if (document.body.__defineGetter__) {
+ if (HTMLElement) {
+ var element = HTMLElement.prototype;
+ if (element.__defineGetter__) {
+ element.__defineGetter__("outerHTML", function () { return new XMLSerializer().serializeToString(this); } );
+ }
+ }
+ }
+
+ if (!window.getComputedStyle) {
+ window.getComputedStyle = function (el, pseudo) {
+ this.el = el;
+ this.getPropertyValue = function (prop) {
+ var re = /(\-([a-z]){1})/g;
+ if (prop === 'float') prop = 'styleFloat';
+ if (re.test(prop)) {
+ prop = prop.replace(re, function () {
+ return arguments[2].toUpperCase();
+ });
+ }
+ return el.currentStyle[prop] ? el.currentStyle[prop] : null;
+ }
+ return this;
+ }
+ }
+ if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function(obj, start) {
+ for (var i = (start || 0), j = this.length; i < j; i++) {
+ if (this[i] === obj) { return i; }
+ }
+ return -1;
+ }
+ }
+ if (!document.querySelectorAll) {
+ if (!window.jQuery) return;
+ }
+ function $$(s) {
+ if (document.querySelectorAll)
+ return document.querySelectorAll(s);
+ else
+ return jQuery(s);
+ }
+
+ /*=========================
+ Check for correct selector
+ ===========================*/
+ if(typeof selector === 'undefined') return;
+
+ if(!(selector.nodeType)){
+ if ($$(selector).length === 0) return;
+ }
+
+ /*=========================
+ _this
+ ===========================*/
+ var _this = this;
+
+ /*=========================
+ Default Flags and vars
+ ===========================*/
+ _this.touches = {
+ start:0,
+ startX:0,
+ startY:0,
+ current:0,
+ currentX:0,
+ currentY:0,
+ diff:0,
+ abs:0
+ };
+ _this.positions = {
+ start:0,
+ abs:0,
+ diff:0,
+ current:0
+ };
+ _this.times = {
+ start:0,
+ end:0
+ };
+
+ _this.id = (new Date()).getTime();
+ _this.container = (selector.nodeType) ? selector : $$(selector)[0];
+ _this.isTouched = false;
+ _this.isMoved = false;
+ _this.activeIndex = 0;
+ _this.activeLoaderIndex = 0;
+ _this.activeLoopIndex = 0;
+ _this.previousIndex = null;
+ _this.velocity = 0;
+ _this.snapGrid = [];
+ _this.slidesGrid = [];
+ _this.imagesToLoad = [];
+ _this.imagesLoaded = 0;
+ _this.wrapperLeft=0;
+ _this.wrapperRight=0;
+ _this.wrapperTop=0;
+ _this.wrapperBottom=0;
+ var wrapper, slideSize, wrapperSize, direction, isScrolling, containerSize;
+
+ /*=========================
+ Default Parameters
+ ===========================*/
+ var defaults = {
+ mode : 'horizontal', // or 'vertical'
+ touchRatio : 1,
+ speed : 300,
+ freeMode : false,
+ freeModeFluid : false,
+ momentumRatio: 1,
+ momentumBounce: true,
+ momentumBounceRatio: 1,
+ slidesPerView : 1,
+ slidesPerGroup : 1,
+ simulateTouch : true,
+ followFinger : true,
+ shortSwipes : true,
+ moveStartThreshold:false,
+ autoplay: false,
+ onlyExternal : false,
+ createPagination : true,
+ pagination : false,
+ paginationElement: 'span',
+ paginationClickable: false,
+ paginationAsRange: true,
+ resistance : true, // or false or 100%
+ scrollContainer : false,
+ preventLinks : true,
+ noSwiping : false, // or class
+ noSwipingClass : 'swiper-no-swiping', //:)
+ initialSlide: 0,
+ keyboardControl: false,
+ mousewheelControl : false,
+ mousewheelDebounce: 600,
+ useCSS3Transforms : true,
+ //Loop mode
+ loop:false,
+ loopAdditionalSlides:0,
+ //Auto Height
+ calculateHeight: false,
+ //Images Preloader
+ updateOnImagesReady : true,
+ //Form elements
+ releaseFormElements : true,
+ //Watch for active slide, useful when use effects on different slide states
+ watchActiveIndex: false,
+ //Slides Visibility Fit
+ visibilityFullFit : false,
+ //Slides Offset
+ offsetPxBefore : 0,
+ offsetPxAfter : 0,
+ offsetSlidesBefore : 0,
+ offsetSlidesAfter : 0,
+ centeredSlides: false,
+ //Queue callbacks
+ queueStartCallbacks : false,
+ queueEndCallbacks : false,
+ //Auto Resize
+ autoResize : true,
+ resizeReInit : false,
+ //DOMAnimation
+ DOMAnimation : true,
+ //Slides Loader
+ loader: {
+ slides:[], //array with slides
+ slidesHTMLType:'inner', // or 'outer'
+ surroundGroups: 1, //keep preloaded slides groups around view
+ logic: 'reload', //or 'change'
+ loadAllSlides: false
+ },
+ //Namespace
+ slideElement : 'div',
+ slideClass : 'swiper-slide',
+ slideActiveClass : 'swiper-slide-active',
+ slideVisibleClass : 'swiper-slide-visible',
+ wrapperClass : 'swiper-wrapper',
+ paginationElementClass: 'swiper-pagination-switch',
+ paginationActiveClass : 'swiper-active-switch',
+ paginationVisibleClass : 'swiper-visible-switch'
+ }
+ params = params || {};
+ for (var prop in defaults) {
+ if (prop in params && typeof params[prop]==='object') {
+ for (var subProp in defaults[prop]) {
+ if (! (subProp in params[prop])) {
+ params[prop][subProp] = defaults[prop][subProp];
+ }
+ }
+ }
+ else if (! (prop in params)) {
+ params[prop] = defaults[prop]
+ }
+ }
+ _this.params = params;
+ if (params.scrollContainer) {
+ params.freeMode = true;
+ params.freeModeFluid = true;
+ }
+ if (params.loop) {
+ params.resistance = '100%';
+ }
+ var isH = params.mode==='horizontal';
+
+ /*=========================
+ Define Touch Events
+ ===========================*/
+
+ _this.touchEvents = {
+ touchStart : _this.support.touch || !params.simulateTouch ? 'touchstart' : (_this.browser.ie10 ? 'MSPointerDown' : 'mousedown'),
+ touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : (_this.browser.ie10 ? 'MSPointerMove' : 'mousemove'),
+ touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : (_this.browser.ie10 ? 'MSPointerUp' : 'mouseup')
+ };
+
+ /*=========================
+ Wrapper
+ ===========================*/
+ for (var i = _this.container.childNodes.length - 1; i >= 0; i--) {
+ if (_this.container.childNodes[i].className) {
+ var _wrapperClasses = _this.container.childNodes[i].className.split(' ')
+ for (var j = 0; j < _wrapperClasses.length; j++) {
+ if (_wrapperClasses[j]===params.wrapperClass) {
+ wrapper = _this.container.childNodes[i];
+ }
+ };
+ }
+ };
+
+ _this.wrapper = wrapper;
+ /*=========================
+ Slide API
+ ===========================*/
+ _this._extendSwiperSlide = function (el) {
+ el.append = function () {
+ if (params.loop) {
+ el.insertAfter(_this.slides.length-_this.loopedSlides);
+ _this.removeLoopedSlides();
+ _this.calcSlides();
+ _this.createLoop();
+ }
+ else {
+ _this.wrapper.appendChild(el);
+ }
+
+ _this.reInit();
+ return el;
+ }
+ el.prepend = function () {
+ if (params.loop) {
+ _this.wrapper.insertBefore(el, _this.slides[_this.loopedSlides]);
+ _this.removeLoopedSlides();
+ _this.calcSlides();
+ _this.createLoop();
+ }
+ else {
+ _this.wrapper.insertBefore(el, _this.wrapper.firstChild);
+ }
+ _this.reInit();
+ return el;
+ }
+ el.insertAfter = function (index) {
+ if(typeof index === 'undefined') return false;
+ var beforeSlide;
+
+ if (params.loop) {
+ beforeSlide = _this.slides[index + 1 + _this.loopedSlides];
+ _this.wrapper.insertBefore(el, beforeSlide);
+ _this.removeLoopedSlides();
+ _this.calcSlides();
+ _this.createLoop();
+ }
+ else {
+ beforeSlide = _this.slides[index + 1];
+ _this.wrapper.insertBefore(el, beforeSlide)
+ }
+ _this.reInit();
+ return el;
+ }
+ el.clone = function () {
+ return _this._extendSwiperSlide(el.cloneNode(true))
+ }
+ el.remove = function () {
+ _this.wrapper.removeChild(el);
+ _this.reInit();
+ }
+ el.html = function (html) {
+ if (typeof html === 'undefined') {
+ return el.innerHTML;
+ }
+ else {
+ el.innerHTML = html;
+ return el;
+ }
+ }
+ el.index = function () {
+ var index;
+ for (var i = _this.slides.length - 1; i >= 0; i--) {
+ if(el === _this.slides[i]) index = i;
+ }
+ return index;
+ }
+ el.isActive = function () {
+ if (el.index() === _this.activeIndex) return true;
+ else return false;
+ }
+ if (!el.swiperSlideDataStorage) el.swiperSlideDataStorage={};
+ el.getData = function (name) {
+ return el.swiperSlideDataStorage[name];
+ }
+ el.setData = function (name, value) {
+ el.swiperSlideDataStorage[name] = value;
+ return el;
+ }
+ el.data = function (name, value) {
+ if (!value) {
+ return el.getAttribute('data-'+name);
+ }
+ else {
+ el.setAttribute('data-'+name,value);
+ return el;
+ }
+ }
+ el.getWidth = function (outer) {
+ return _this.h.getWidth(el, outer);
+ }
+ el.getHeight = function (outer) {
+ return _this.h.getHeight(el, outer);
+ }
+ el.getOffset = function() {
+ return _this.h.getOffset(el);
+ }
+ return el;
+ }
+
+ //Calculate information about number of slides
+ _this.calcSlides = function (forceCalcSlides) {
+ var oldNumber = _this.slides ? _this.slides.length : false;
+ _this.slides = [];
+ _this.displaySlides = [];
+ for (var i = 0; i < _this.wrapper.childNodes.length; i++) {
+ if (_this.wrapper.childNodes[i].className) {
+ var _className = _this.wrapper.childNodes[i].className;
+ var _slideClasses = _className.split(' ');
+ for (var j = 0; j < _slideClasses.length; j++) {
+ if(_slideClasses[j]===params.slideClass) {
+ _this.slides.push(_this.wrapper.childNodes[i]);
+ }
+ }
+ }
+ }
+ for (i = _this.slides.length - 1; i >= 0; i--) {
+ _this._extendSwiperSlide(_this.slides[i]);
+ }
+ if (!oldNumber) return;
+ if(oldNumber!==_this.slides.length || forceCalcSlides) {
+ // Number of slides has been changed
+ removeSlideEvents();
+ addSlideEvents();
+ _this.updateActiveSlide();
+ if (params.createPagination && _this.params.pagination) _this.createPagination();
+ _this.callPlugins('numberOfSlidesChanged');
+ }
+ }
+
+ //Create Slide
+ _this.createSlide = function (html, slideClassList, el) {
+ var slideClassList = slideClassList || _this.params.slideClass;
+ var el = el||params.slideElement;
+ var newSlide = document.createElement(el);
+ newSlide.innerHTML = html||'';
+ newSlide.className = slideClassList;
+ return _this._extendSwiperSlide(newSlide);
+ }
+
+ //Append Slide
+ _this.appendSlide = function (html, slideClassList, el) {
+ if (!html) return;
+ if (html.nodeType) {
+ return _this._extendSwiperSlide(html).append()
+ }
+ else {
+ return _this.createSlide(html, slideClassList, el).append()
+ }
+ }
+ _this.prependSlide = function (html, slideClassList, el) {
+ if (!html) return;
+ if (html.nodeType) {
+ return _this._extendSwiperSlide(html).prepend()
+ }
+ else {
+ return _this.createSlide(html, slideClassList, el).prepend()
+ }
+ }
+ _this.insertSlideAfter = function (index, html, slideClassList, el) {
+ if (typeof index === 'undefined') return false;
+ if (html.nodeType) {
+ return _this._extendSwiperSlide(html).insertAfter(index);
+ }
+ else {
+ return _this.createSlide(html, slideClassList, el).insertAfter(index);
+ }
+ }
+ _this.removeSlide = function (index) {
+ if (_this.slides[index]) {
+ if (params.loop) {
+ if (!_this.slides[index+_this.loopedSlides]) return false;
+ _this.slides[index+_this.loopedSlides].remove();
+ _this.removeLoopedSlides();
+ _this.calcSlides();
+ _this.createLoop();
+ }
+ else _this.slides[index].remove();
+ return true;
+ }
+ else return false;
+ }
+ _this.removeLastSlide = function () {
+ if (_this.slides.length>0) {
+ if (params.loop) {
+ _this.slides[_this.slides.length - 1 - _this.loopedSlides].remove();
+ _this.removeLoopedSlides();
+ _this.calcSlides();
+ _this.createLoop();
+ }
+ else _this.slides[ (_this.slides.length-1) ].remove();
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ _this.removeAllSlides = function () {
+ for (var i = _this.slides.length - 1; i >= 0; i--) {
+ _this.slides[i].remove()
+ }
+ }
+ _this.getSlide = function (index) {
+ return _this.slides[index]
+ }
+ _this.getLastSlide = function () {
+ return _this.slides[ _this.slides.length-1 ]
+ }
+ _this.getFirstSlide = function () {
+ return _this.slides[0]
+ }
+
+ //Currently Active Slide
+ _this.activeSlide = function () {
+ return _this.slides[_this.activeIndex]
+ }
+
+ /*=========================
+ Plugins API
+ ===========================*/
+ var _plugins = [];
+ for (var plugin in _this.plugins) {
+ if (params[plugin]) {
+ var p = _this.plugins[plugin](_this, params[plugin]);
+ if (p) _plugins.push( p );
+ }
+ }
+ _this.callPlugins = function(method, args) {
+ if (!args) args = {}
+ for (var i=0; i<_plugins.length; i++) {
+ if (method in _plugins[i]) {
+ _plugins[i][method](args);
+ }
+ }
+ }
+
+ /*=========================
+ WP8 Fix
+ ===========================*/
+ if (_this.browser.ie10 && !params.onlyExternal) {
+ if (isH) _this.wrapper.classList.add('swiper-wp8-horizontal');
+ else _this.wrapper.classList.add('swiper-wp8-vertical');
+ }
+
+ /*=========================
+ Free Mode Class
+ ===========================*/
+ if (params.freeMode) {
+ _this.container.className+=' swiper-free-mode';
+ }
+
+ /*==================================================
+ Init/Re-init/Resize Fix
+ ====================================================*/
+ _this.initialized = false;
+ _this.init = function(force, forceCalcSlides) {
+ var _width = _this.h.getWidth(_this.container);
+ var _height = _this.h.getHeight(_this.container);
+ if (_width===_this.width && _height===_this.height && !force) return;
+ _this.width = _width;
+ _this.height = _height;
+
+ containerSize = isH ? _width : _height;
+ var wrapper = _this.wrapper;
+
+ if (force) {
+ _this.calcSlides(forceCalcSlides);
+ }
+
+ if (params.slidesPerView==='auto') {
+ //Auto mode
+ var slidesWidth = 0;
+ var slidesHeight = 0;
+
+ //Unset Styles
+ if (params.slidesOffset>0) {
+ wrapper.style.paddingLeft = '';
+ wrapper.style.paddingRight = '';
+ wrapper.style.paddingTop = '';
+ wrapper.style.paddingBottom = '';
+ }
+ wrapper.style.width = '';
+ wrapper.style.height = '';
+ if (params.offsetPxBefore>0) {
+ if (isH) _this.wrapperLeft = params.offsetPxBefore;
+ else _this.wrapperTop = params.offsetPxBefore;
+ }
+ if (params.offsetPxAfter>0) {
+ if (isH) _this.wrapperRight = params.offsetPxAfter;
+ else _this.wrapperBottom = params.offsetPxAfter;
+ }
+
+ if (params.centeredSlides) {
+ if (isH) {
+ _this.wrapperLeft = (containerSize - this.slides[0].getWidth(true) )/2;
+ _this.wrapperRight = (containerSize - _this.slides[ _this.slides.length-1 ].getWidth(true))/2;
+ }
+ else {
+ _this.wrapperTop = (containerSize - _this.slides[0].getHeight(true))/2;
+ _this.wrapperBottom = (containerSize - _this.slides[ _this.slides.length-1 ].getHeight(true))/2;
+ }
+ }
+
+ if (isH) {
+ if (_this.wrapperLeft>=0) wrapper.style.paddingLeft = _this.wrapperLeft+'px';
+ if (_this.wrapperRight>=0) wrapper.style.paddingRight = _this.wrapperRight+'px';
+ }
+ else {
+ if (_this.wrapperTop>=0) wrapper.style.paddingTop = _this.wrapperTop+'px';
+ if (_this.wrapperBottom>=0) wrapper.style.paddingBottom = _this.wrapperBottom+'px';
+ }
+ var slideLeft = 0;
+ var centeredSlideLeft=0;
+ _this.snapGrid = [];
+ _this.slidesGrid = [];
+
+ var slideMaxHeight = 0;
+ for(var i = 0; i<_this.slides.length; i++) {
+ var slideWidth = _this.slides[i].getWidth(true);
+ var slideHeight = _this.slides[i].getHeight(true);
+ if (params.calculateHeight) {
+ slideMaxHeight = Math.max(slideMaxHeight, slideHeight)
+ }
+ var _slideSize = isH ? slideWidth : slideHeight;
+ if (params.centeredSlides) {
+ var nextSlideWidth = i === _this.slides.length-1 ? 0 : _this.slides[i+1].getWidth(true);
+ var nextSlideHeight = i === _this.slides.length-1 ? 0 : _this.slides[i+1].getHeight(true);
+ var nextSlideSize = isH ? nextSlideWidth : nextSlideHeight;
+ if (_slideSize>containerSize) {
+ for (var j=0; j<=Math.floor(_slideSize/(containerSize+_this.wrapperLeft)); j++) {
+ if (j === 0) _this.snapGrid.push(slideLeft+_this.wrapperLeft);
+ else _this.snapGrid.push(slideLeft+_this.wrapperLeft+containerSize*j);
+ }
+ _this.slidesGrid.push(slideLeft+_this.wrapperLeft);
+ }
+ else {
+ _this.snapGrid.push(centeredSlideLeft);
+ _this.slidesGrid.push(centeredSlideLeft);
+ }
+
+ centeredSlideLeft += _slideSize/2 + nextSlideSize/2;
+
+ }
+ else {
+ if (_slideSize>containerSize) {
+ for (var j=0; j<=Math.floor(_slideSize/containerSize); j++) {
+ _this.snapGrid.push(slideLeft+containerSize*j);
+ }
+ }
+ else {
+ _this.snapGrid.push(slideLeft);
+ }
+ _this.slidesGrid.push(slideLeft);
+ }
+
+ slideLeft += _slideSize;
+
+ slidesWidth += slideWidth;
+ slidesHeight += slideHeight;
+ }
+ if (params.calculateHeight) _this.height = slideMaxHeight;
+ if(isH) {
+ wrapperSize = slidesWidth + _this.wrapperRight + _this.wrapperLeft;
+ wrapper.style.width = (slidesWidth)+'px';
+ wrapper.style.height = (_this.height)+'px';
+ }
+ else {
+ wrapperSize = slidesHeight + _this.wrapperTop + _this.wrapperBottom;
+ wrapper.style.width = (_this.width)+'px';
+ wrapper.style.height = (slidesHeight)+'px';
+ }
+
+ }
+ else if (params.scrollContainer) {
+ //Scroll Container
+ wrapper.style.width = '';
+ wrapper.style.height = '';
+ var wrapperWidth = _this.slides[0].getWidth(true);
+ var wrapperHeight = _this.slides[0].getHeight(true);
+ wrapperSize = isH ? wrapperWidth : wrapperHeight;
+ wrapper.style.width = wrapperWidth+'px';
+ wrapper.style.height = wrapperHeight+'px';
+ slideSize = isH ? wrapperWidth : wrapperHeight;
+
+ }
+ else {
+ //For usual slides
+ if (params.calculateHeight) {
+ var slideMaxHeight = 0;
+ var wrapperHeight = 0;
+ //ResetWrapperSize
+ if (!isH) _this.container.style.height= '';
+ wrapper.style.height='';
+
+ for (var i=0; i<_this.slides.length; i++) {
+ //ResetSlideSize
+ _this.slides[i].style.height='';
+ slideMaxHeight = Math.max( _this.slides[i].getHeight(true), slideMaxHeight );
+ if (!isH) wrapperHeight+=_this.slides[i].getHeight(true);
+ }
+ var slideHeight = slideMaxHeight;
+ _this.height = slideHeight;
+
+ if (isH) wrapperHeight = slideHeight;
+ else containerSize = slideHeight, _this.container.style.height= containerSize+'px';
+ }
+ else {
+ var slideHeight = isH ? _this.height : _this.height/params.slidesPerView ;
+ var wrapperHeight = isH ? _this.height : _this.slides.length*slideHeight;
+ }
+ var slideWidth = isH ? _this.width/params.slidesPerView : _this.width;
+ var wrapperWidth = isH ? _this.slides.length*slideWidth : _this.width;
+ slideSize = isH ? slideWidth : slideHeight;
+
+ if (params.offsetSlidesBefore>0) {
+ if (isH) _this.wrapperLeft = slideSize*params.offsetSlidesBefore;
+ else _this.wrapperTop = slideSize*params.offsetSlidesBefore;
+ }
+ if (params.offsetSlidesAfter>0) {
+ if (isH) _this.wrapperRight = slideSize*params.offsetSlidesAfter;
+ else _this.wrapperBottom = slideSize*params.offsetSlidesAfter;
+ }
+ if (params.offsetPxBefore>0) {
+ if (isH) _this.wrapperLeft = params.offsetPxBefore;
+ else _this.wrapperTop = params.offsetPxBefore;
+ }
+ if (params.offsetPxAfter>0) {
+ if (isH) _this.wrapperRight = params.offsetPxAfter;
+ else _this.wrapperBottom = params.offsetPxAfter;
+ }
+ if (params.centeredSlides) {
+ if (isH) {
+ _this.wrapperLeft = (containerSize - slideSize)/2;
+ _this.wrapperRight = (containerSize - slideSize)/2;
+ }
+ else {
+ _this.wrapperTop = (containerSize - slideSize)/2;
+ _this.wrapperBottom = (containerSize - slideSize)/2;
+ }
+ }
+ if (isH) {
+ if (_this.wrapperLeft>0) wrapper.style.paddingLeft = _this.wrapperLeft+'px';
+ if (_this.wrapperRight>0) wrapper.style.paddingRight = _this.wrapperRight+'px';
+ }
+ else {
+ if (_this.wrapperTop>0) wrapper.style.paddingTop = _this.wrapperTop+'px';
+ if (_this.wrapperBottom>0) wrapper.style.paddingBottom = _this.wrapperBottom+'px';
+ }
+
+ wrapperSize = isH ? wrapperWidth + _this.wrapperRight + _this.wrapperLeft : wrapperHeight + _this.wrapperTop + _this.wrapperBottom;
+ wrapper.style.width = wrapperWidth+'px';
+ wrapper.style.height = wrapperHeight+'px';
+ var slideLeft = 0;
+ _this.snapGrid = [];
+ _this.slidesGrid = [];
+ for (var i=0; i<_this.slides.length; i++) {
+ _this.snapGrid.push(slideLeft);
+ _this.slidesGrid.push(slideLeft);
+ slideLeft+=slideSize;
+ _this.slides[i].style.width = slideWidth+'px';
+ _this.slides[i].style.height = slideHeight+'px';
+ }
+
+ }
+
+ if (!_this.initialized) {
+ _this.callPlugins('onFirstInit');
+ if (params.onFirstInit) params.onFirstInit(_this);
+ }
+ else {
+ _this.callPlugins('onInit');
+ if (params.onInit) params.onInit(_this);
+ }
+ _this.initialized = true;
+ }
+ _this.reInit = function (forceCalcSlides) {
+ _this.init(true, forceCalcSlides);
+ }
+ _this.resizeFix = function(reInit){
+ _this.callPlugins('beforeResizeFix');
+ _this.init(params.resizeReInit||reInit);
+ if (!params.freeMode) {
+ if (params.loop) _this.swipeTo(_this.activeLoopIndex, 0, false);
+ else _this.swipeTo(_this.activeIndex, 0, false);
+ }
+ else {
+ var pos = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+ if (pos < -maxWrapperPosition()) {
+ var x = isH ? -maxWrapperPosition() : 0;
+ var y = isH ? 0 : -maxWrapperPosition();
+ _this.setWrapperTransition(0);
+ _this.setWrapperTranslate(x,y,0);
+ }
+ }
+ _this.callPlugins('afterResizeFix');
+ }
+
+ /*==========================================
+ Max and Min Positions
+ ============================================*/
+ function maxWrapperPosition() {
+ var a = (wrapperSize - containerSize);
+ if (params.freeMode) {
+ a = wrapperSize - containerSize;
+ }
+ // if (params.loop) a -= containerSize;
+ if (params.slidesPerView > _this.slides.length) a = 0;
+ if (a<0) a = 0;
+ return a;
+ }
+ function minWrapperPosition() {
+ var a = 0;
+ // if (params.loop) a = containerSize;
+ return a;
+ }
+
+ /*==========================================
+ Event Listeners
+ ============================================*/
+ function initEvents() {
+ //Touch Events
+ if (!_this.browser.ie10) {
+ if (_this.support.touch) {
+ _this.h.addEventListener(_this.wrapper, 'touchstart', onTouchStart, false);
+ _this.h.addEventListener(_this.wrapper, 'touchmove', onTouchMove, false);
+ _this.h.addEventListener(_this.wrapper, 'touchend', onTouchEnd, false);
+ }
+ if (params.simulateTouch) {
+ _this.h.addEventListener(_this.wrapper, 'mousedown', onTouchStart, false);
+ _this.h.addEventListener(document, 'mousemove', onTouchMove, false);
+ _this.h.addEventListener(document, 'mouseup', onTouchEnd, false);
+ }
+ }
+ else {
+ _this.h.addEventListener(_this.wrapper, _this.touchEvents.touchStart, onTouchStart, false);
+ _this.h.addEventListener(document, _this.touchEvents.touchMove, onTouchMove, false);
+ _this.h.addEventListener(document, _this.touchEvents.touchEnd, onTouchEnd, false);
+ }
+ //Resize Event
+ if (params.autoResize) {
+ _this.h.addEventListener(window, 'resize', _this.resizeFix, false);
+ }
+ //Slide Events
+ addSlideEvents();
+ //Mousewheel
+ _this._wheelEvent = false;
+ if (params.mousewheelControl) {
+ if ( document.onmousewheel !== undefined ) {
+ _this._wheelEvent = "mousewheel";
+ }
+ try {
+ WheelEvent("wheel");
+ _this._wheelEvent = "wheel";
+ } catch (e) {}
+ if ( !_this._wheelEvent ) {
+ _this._wheelEvent = "DOMMouseScroll";
+ }
+
+ if (_this._wheelEvent) {
+ _this.h.addEventListener(_this.container, _this._wheelEvent, handleMousewheel, false);
+ }
+ }
+
+ //Keyboard
+ if (params.keyboardControl) {
+ _this.h.addEventListener(document, 'keydown', handleKeyboardKeys, false);
+ }
+ if (params.updateOnImagesReady) {
+ if (document.querySelectorAll) _this.imagesToLoad = _this.container.querySelectorAll('img');
+ else if (window.jQuery) _this.imagesToLoad = $$(_this.container).find('img');
+
+ for (var i=0; i<_this.imagesToLoad.length; i++) {
+ _loadImage(_this.imagesToLoad[i].getAttribute('src'))
+ }
+ }
+ function _loadImage(src) {
+ var image = new Image();
+ image.onload = function(){
+ _this.imagesLoaded++;
+ if (_this.imagesLoaded==_this.imagesToLoad.length) {
+ _this.reInit();
+ if (params.onImagesReady) params.onImagesReady(_this);
+ }
+ }
+ image.src = src;
+ }
+ }
+
+
+
+ //Remove Event Listeners
+ _this.destroy = function(removeResizeFix){
+ //Touch Events
+ if (!_this.browser.ie10) {
+ if (_this.support.touch) {
+ _this.h.removeEventListener(_this.wrapper, 'touchstart', onTouchStart, false);
+ _this.h.removeEventListener(_this.wrapper, 'touchmove', onTouchMove, false);
+ _this.h.removeEventListener(_this.wrapper, 'touchend', onTouchEnd, false);
+ }
+ if (params.simulateTouch) {
+ _this.h.removeEventListener(_this.wrapper, 'mousedown', onTouchStart, false);
+ _this.h.removeEventListener(document, 'mousemove', onTouchMove, false);
+ _this.h.removeEventListener(document, 'mouseup', onTouchEnd, false);
+ }
+ }
+ else {
+ _this.h.removeEventListener(_this.wrapper, _this.touchEvents.touchStart, onTouchStart, false);
+ _this.h.removeEventListener(document, _this.touchEvents.touchMove, onTouchMove, false);
+ _this.h.removeEventListener(document, _this.touchEvents.touchEnd, onTouchEnd, false);
+ }
+ //Resize Event
+ if (params.autoResize) {
+ _this.h.removeEventListener(window, 'resize', _this.resizeFix, false);
+ }
+ //Init Slide Events
+ removeSlideEvents();
+
+ //Pagination
+ if (params.paginationClickable) {
+ removePaginationEvents();
+ }
+
+ //Mousewheel
+ if (params.mousewheelControl && _this._wheelEvent) {
+ _this.h.removeEventListener(_this.container, _this._wheelEvent, handleMousewheel, false);
+ }
+
+ //Keyboard
+ if (params.keyboardControl) {
+ _this.h.removeEventListener(document, 'keydown', handleKeyboardKeys, false);
+ }
+
+ //Stop autoplay
+ if (params.autoplay) {
+ _this.stopAutoplay();
+ }
+ _this.callPlugins('onDestroy');
+
+ //Destroy variable
+ _this = null;
+ }
+ function addSlideEvents() {
+ //Prevent Links Events
+ if (params.preventLinks) {
+ var links = [];
+ if (document.querySelectorAll) {
+ links = _this.container.querySelectorAll('a');
+ }
+ else if (window.jQuery) {
+ links = $$(_this.container).find('a');
+ }
+ for (var i=0; i<links.length; i++) {
+ _this.h.addEventListener(links[i], 'click', preventClick, false);
+ }
+ }
+ //Release Form Elements
+ if (params.releaseFormElements) {
+ var formElements = document.querySelectorAll ? _this.container.querySelectorAll('input, textarea, select') : $$(_this.container).find('input, textarea, select');
+ for (var i=0; i<formElements.length; i++) {
+ _this.h.addEventListener(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
+ }
+ }
+
+ //Slide Clicks & Touches
+ if (params.onSlideClick) {
+ for (var i=0; i<_this.slides.length; i++) {
+ _this.h.addEventListener(_this.slides[i], 'click', slideClick, false);
+ }
+ }
+ if (params.onSlideTouch) {
+ for (var i=0; i<_this.slides.length; i++) {
+ _this.h.addEventListener(_this.slides[i], _this.touchEvents.touchStart, slideTouch, false);
+ }
+ }
+ }
+ function removeSlideEvents() {
+ //Slide Clicks & Touches
+ if (params.onSlideClick) {
+ for (var i=0; i<_this.slides.length; i++) {
+ _this.h.removeEventListener(_this.slides[i], 'click', slideClick, false);
+ }
+ }
+ if (params.onSlideTouch) {
+ for (var i=0; i<_this.slides.length; i++) {
+ _this.h.removeEventListener(_this.slides[i], _this.touchEvents.touchStart, slideTouch, false);
+ }
+ }
+ //Release Form Elements
+ if (params.releaseFormElements) {
+ var formElements = document.querySelectorAll ? _this.container.querySelectorAll('input, textarea, select') : $$(_this.container).find('input, textarea, select');
+ for (var i=0; i<formElements.length; i++) {
+ _this.h.removeEventListener(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
+ }
+ }
+ //Prevent Links Events
+ if (params.preventLinks) {
+ var links = [];
+ if (document.querySelectorAll) {
+ links = _this.container.querySelectorAll('a');
+ }
+ else if (window.jQuery) {
+ links = $$(_this.container).find('a');
+ }
+ for (var i=0; i<links.length; i++) {
+ _this.h.removeEventListener(links[i], 'click', preventClick, false);
+ }
+ }
+ }
+ /*==========================================
+ Keyboard Control
+ ============================================*/
+ function handleKeyboardKeys (e) {
+ var kc = e.keyCode || e.charCode;
+ if (kc==37 || kc==39 || kc==38 || kc==40) {
+ var inView = false;
+ //Check that swiper should be inside of visible area of window
+ var swiperOffset = _this.h.getOffset( _this.container );
+ var scrollLeft = _this.h.windowScroll().left;
+ var scrollTop = _this.h.windowScroll().top;
+ var windowWidth = _this.h.windowWidth();
+ var windowHeight = _this.h.windowHeight();
+ var swiperCoord = [
+ [swiperOffset.left, swiperOffset.top],
+ [swiperOffset.left + _this.width, swiperOffset.top],
+ [swiperOffset.left, swiperOffset.top + _this.height],
+ [swiperOffset.left + _this.width, swiperOffset.top + _this.height]
+ ]
+ for (var i=0; i<swiperCoord.length; i++) {
+ var point = swiperCoord[i];
+ if (
+ point[0]>=scrollLeft && point[0]<=scrollLeft+windowWidth &&
+ point[1]>=scrollTop && point[1]<=scrollTop+windowHeight
+ ) {
+ inView = true;
+ }
+
+ }
+ if (!inView) return;
+ }
+ if (isH) {
+ if (kc==37 || kc==39) {
+ if (e.preventDefault) e.preventDefault();
+ else e.returnValue = false;
+ }
+ if (kc == 39) _this.swipeNext();
+ if (kc == 37) _this.swipePrev();
+ }
+ else {
+ if (kc==38 || kc==40) {
+ if (e.preventDefault) e.preventDefault();
+ else e.returnValue = false;
+ }
+ if (kc == 40) _this.swipeNext();
+ if (kc == 38) _this.swipePrev();
+ }
+ }
+
+ /*==========================================
+ Mousewheel Control
+ ============================================*/
+ var allowScrollChange = true;
+ function handleMousewheel (e) {
+ var we = _this._wheelEvent;
+ var delta;
+ //Opera & IE
+ if (e.detail) delta = -e.detail;
+ //WebKits
+ else if (we == 'mousewheel') delta = e.wheelDelta;
+ //Old FireFox
+ else if (we == 'DOMMouseScroll') delta = -e.detail;
+ //New FireFox
+ else if (we == 'wheel') {
+ delta = Math.abs(e.deltaX)>Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
+ }
+ if (!params.freeMode) {
+ if(delta<0) _this.swipeNext();
+ else _this.swipePrev();
+ }
+ else {
+ //Freemode or scrollContainer:
+ var currentTransform =isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+ var x,y;
+ if (isH) {
+ x = _this.getWrapperTranslate('x') + delta;
+ y = _this.getWrapperTranslate('y');
+ if (x>0) x = 0;
+ if (x<-maxWrapperPosition()) x = -maxWrapperPosition();
+ }
+ else {
+ x = _this.getWrapperTranslate('x');
+ y = _this.getWrapperTranslate('y')+delta;
+ if (y>0) y = 0;
+ if (y<-maxWrapperPosition()) y = -maxWrapperPosition();
+ }
+ _this.setWrapperTransition(0);
+ _this.setWrapperTranslate(x,y,0);
+ if (isH) _this.updateActiveSlide(x);
+ else _this.updateActiveSlide(y);
+ }
+ if (params.autoplay) _this.stopAutoplay();
+
+ if(e.preventDefault) e.preventDefault();
+ else e.returnValue = false;
+ return false;
+ }
+
+ /*=========================
+ Grab Cursor
+ ===========================*/
+ if (params.grabCursor) {
+ _this.container.style.cursor = 'move';
+ _this.container.style.cursor = 'grab';
+ _this.container.style.cursor = '-moz-grab';
+ _this.container.style.cursor = '-webkit-grab';
+ }
+
+ /*=========================
+ Slides Events Handlers
+ ===========================*/
+ function findSlide(el) {
+ var found = false;
+ while(!found) {
+ if (el.className.indexOf(params.slideClass)>-1)
+ {
+ found = el;
+ }
+ el = el.parentElement;
+ }
+ return found;
+ }
+ _this.allowSlideClick = true;
+ function slideClick(e) {
+ if(_this.allowSlideClick) {
+ if (!e.target) {
+ _this.clickedSlide = findSlide(e.srcElement);
+ _this.clickedSlideIndex = _this.slides.indexOf(_this.clickedSlide);
+ }
+ else {
+ _this.clickedSlide = this;
+ _this.clickedSlideIndex = _this.slides.indexOf(this);
+ }
+ params.onSlideClick(_this);
+ }
+ }
+ function slideTouch(e) {
+ if (!e.target) _this.clickedSlide = findSlide(e.srcElement);
+ else _this.clickedSlide = this;
+ _this.clickedSlideIndex = _this.slides.indexOf(_this.clickedSlide);
+ params.onSlideTouch(_this);
+ }
+ _this.allowLinks = true;
+ function preventClick(e) {
+ if (!_this.allowLinks) {
+ if(e.preventDefault) e.preventDefault();
+ else e.returnValue = false;
+ return false;
+ }
+ }
+ function releaseForms(e) {
+ if (e.stopPropagation) e.stopPropagation();
+ else e.returnValue = false;
+ return false;
+ }
+
+ /*==================================================
+ Event Handlers
+ ====================================================*/
+ var isTouchEvent = false;
+ var allowThresholdMove;
+ var allowMomentumBounce = true;
+ function onTouchStart(event) {
+ if (params.preventLinks) _this.allowLinks = true;
+ //Exit if slider is already was touched
+ if (_this.isTouched || params.onlyExternal) {
+ return false;
+ }
+
+ if (params.noSwiping && (event.target || event.srcElement) && noSwipingSlide(event.target || event.srcElement)) return false;
+ allowMomentumBounce = false;
+
+ //Check For Nested Swipers
+ _this.isTouched = true;
+ isTouchEvent = event.type=='touchstart';
+
+ if (!isTouchEvent || event.targetTouches.length == 1 ) {
+ if (params.loop) _this.fixLoop();
+ _this.callPlugins('onTouchStartBegin');
+
+ if(!isTouchEvent) {
+ if(event.preventDefault) event.preventDefault();
+ else event.returnValue = false;
+ }
+
+ var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
+ var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
+
+ //Start Touches to check the scrolling
+ _this.touches.startX = _this.touches.currentX = pageX;
+ _this.touches.startY = _this.touches.currentY = pageY;
+
+ _this.touches.start = _this.touches.current = isH ? pageX : pageY ;
+
+ //Set Transition Time to 0
+ _this.setWrapperTransition(0);
+
+ //Get Start Translate Position
+ _this.positions.start = _this.positions.current = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+
+ //Set Transform
+ if (isH) {
+ _this.setWrapperTranslate( _this.positions.start, 0, 0);
+ }
+ else {
+ _this.setWrapperTranslate( 0, _this.positions.start, 0);
+ }
+
+ //TouchStartTime
+ _this.times.start = (new Date()).getTime();
+
+ //Unset Scrolling
+ isScrolling = undefined;
+
+ //Set Treshold
+ if (params.moveStartThreshold>0) allowThresholdMove = false;
+
+ //CallBack
+ if (params.onTouchStart) params.onTouchStart(_this);
+ _this.callPlugins('onTouchStartEnd');
+
+ }
+ }
+ var velocityPrevPosition, velocityPrevTime;
+ function onTouchMove(event) {
+ // If slider is not touched - exit
+ if (!_this.isTouched || params.onlyExternal) return;
+ if (isTouchEvent && event.type=='mousemove') return;
+
+ var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
+ var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
+
+ //check for scrolling
+ if ( typeof isScrolling === 'undefined' && isH) {
+ isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs( pageX - _this.touches.startX ) );
+ }
+ if ( typeof isScrolling === 'undefined' && !isH) {
+ isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) < Math.abs( pageX - _this.touches.startX ) );
+ }
+ if (isScrolling ) {
+ _this.isTouched = false;
+ return
+ }
+
+ //Check For Nested Swipers
+ if (event.assignedToSwiper) {
+ _this.isTouched = false;
+ return
+ }
+ event.assignedToSwiper = true;
+
+ //Moved Flag
+ _this.isMoved = true;
+
+ //Block inner links
+ if (params.preventLinks) {
+ _this.allowLinks = false;
+ }
+ if (params.onSlideClick) {
+ _this.allowSlideClick = false;
+ }
+
+ //Stop AutoPlay if exist
+ if (params.autoplay) {
+ _this.stopAutoplay();
+ }
+ if (!isTouchEvent || event.touches.length == 1) {
+
+ _this.callPlugins('onTouchMoveStart');
+ if(event.preventDefault) event.preventDefault();
+ else event.returnValue = false;
+
+ _this.touches.current = isH ? pageX : pageY ;
+
+ _this.positions.current = (_this.touches.current - _this.touches.start) * params.touchRatio + _this.positions.start;
+
+ //Resistance Callbacks
+ if(_this.positions.current > 0 && params.onResistanceBefore) {
+ params.onResistanceBefore(_this, _this.positions.current);
+ }
+ if(_this.positions.current < -maxWrapperPosition() && params.onResistanceAfter) {
+ params.onResistanceAfter(_this, Math.abs(_this.positions.current + maxWrapperPosition()));
+ }
+ //Resistance
+ if (params.resistance && params.resistance!='100%') {
+ //Resistance for Negative-Back sliding
+ if(_this.positions.current > 0) {
+ var resistance = 1 - _this.positions.current/containerSize/2;
+ if (resistance < 0.5)
+ _this.positions.current = (containerSize/2);
+ else
+ _this.positions.current = _this.positions.current * resistance;
+ }
+ //Resistance for After-End Sliding
+ if ( _this.positions.current < -maxWrapperPosition() ) {
+
+ var diff = (_this.touches.current - _this.touches.start)*params.touchRatio + (maxWrapperPosition()+_this.positions.start);
+ var resistance = (containerSize+diff)/(containerSize);
+ var newPos = _this.positions.current-diff*(1-resistance)/2;
+ var stopPos = -maxWrapperPosition() - containerSize/2;
+
+ if (newPos < stopPos || resistance<=0)
+ _this.positions.current = stopPos;
+ else
+ _this.positions.current = newPos;
+ }
+ }
+ if (params.resistance && params.resistance=='100%') {
+ //Resistance for Negative-Back sliding
+ if(_this.positions.current > 0 && !(params.freeMode&&!params.freeModeFluid)) {
+ _this.positions.current = 0;
+ }
+ //Resistance for After-End Sliding
+ if ( (_this.positions.current) < -maxWrapperPosition() && !(params.freeMode&&!params.freeModeFluid)) {
+ _this.positions.current = -maxWrapperPosition();
+ }
+ }
+ //Move Slides
+ if (!params.followFinger) return
+
+ if (!params.moveStartThreshold) {
+ if (isH) _this.setWrapperTranslate( _this.positions.current, 0, 0);
+ else _this.setWrapperTranslate( 0, _this.positions.current, 0);
+ }
+ else {
+ if ( Math.abs(_this.touches.current - _this.touches.start)>params.moveStartThreshold || allowThresholdMove) {
+ allowThresholdMove = true;
+ if (isH) _this.setWrapperTranslate( _this.positions.current, 0, 0);
+ else _this.setWrapperTranslate( 0, _this.positions.current, 0);
+ }
+ else {
+ _this.positions.current = _this.positions.start;
+ }
+ }
+
+ if (params.freeMode || params.watchActiveIndex) {
+ _this.updateActiveSlide(_this.positions.current);
+ }
+
+ //Grab Cursor
+ if (params.grabCursor) {
+ _this.container.style.cursor = 'move';
+ _this.container.style.cursor = 'grabbing';
+ _this.container.style.cursor = '-moz-grabbin';
+ _this.container.style.cursor = '-webkit-grabbing';
+ }
+ //Velocity
+ if (!velocityPrevPosition) velocityPrevPosition = _this.touches.current;
+ if (!velocityPrevTime) velocityPrevTime = (new Date).getTime();
+ _this.velocity = (_this.touches.current - velocityPrevPosition)/((new Date).getTime() - velocityPrevTime)/2;
+ if (Math.abs(_this.touches.current - velocityPrevPosition)<2) _this.velocity=0;
+ velocityPrevPosition = _this.touches.current;
+ velocityPrevTime = (new Date).getTime();
+ //Callbacks
+ _this.callPlugins('onTouchMoveEnd');
+ if (params.onTouchMove) params.onTouchMove(_this);
+
+ return false;
+ }
+ }
+ function onTouchEnd(event) {
+ //Check For scrolling
+ if (isScrolling) {
+ _this.swipeReset();
+ }
+ // If slider is not touched exit
+ if ( params.onlyExternal || !_this.isTouched ) return;
+ _this.isTouched = false
+
+ //Return Grab Cursor
+ if (params.grabCursor) {
+ _this.container.style.cursor = 'move';
+ _this.container.style.cursor = 'grab';
+ _this.container.style.cursor = '-moz-grab';
+ _this.container.style.cursor = '-webkit-grab';
+ }
+
+ //Check for Current Position
+ if (!_this.positions.current && _this.positions.current!==0) {
+ _this.positions.current = _this.positions.start
+ }
+
+ //For case if slider touched but not moved
+ if (params.followFinger) {
+ if (isH) _this.setWrapperTranslate( _this.positions.current, 0, 0)
+ else _this.setWrapperTranslate( 0, _this.positions.current, 0)
+ }
+ //--
+
+ // TouchEndTime
+ _this.times.end = (new Date()).getTime();
+
+ //Difference
+ _this.touches.diff = _this.touches.current - _this.touches.start
+ _this.touches.abs = Math.abs(_this.touches.diff)
+
+ _this.positions.diff = _this.positions.current - _this.positions.start
+ _this.positions.abs = Math.abs(_this.positions.diff)
+
+ var diff = _this.positions.diff ;
+ var diffAbs =_this.positions.abs ;
+ var timeDiff = _this.times.end - _this.times.start
+
+ if(diffAbs < 5 && (timeDiff) < 300 && _this.allowLinks == false) {
+ if (!params.freeMode && diffAbs!=0) _this.swipeReset()
+ //Release inner links
+ if (params.preventLinks) {
+ _this.allowLinks = true;
+ }
+ if (params.onSlideClick) {
+ _this.allowSlideClick = true;
+ }
+ }
+ setTimeout(function(){
+ //Release inner links
+ if (params.preventLinks) {
+ _this.allowLinks = true;
+ }
+ if (params.onSlideClick) {
+ _this.allowSlideClick = true;
+ }
+ },100)
+
+ //Exit if not moved
+ if (!_this.isMoved) {
+ _this.isMoved = false;
+ if (params.onTouchEnd) params.onTouchEnd(_this)
+ _this.callPlugins('onTouchEnd');
+ _this.swipeReset();
+ return;
+ }
+ _this.isMoved = false;
+
+ var maxPosition = maxWrapperPosition();
+
+ //Prevent Negative Back Sliding
+ if (_this.positions.current > 0) {
+ _this.swipeReset()
+ if (params.onTouchEnd) params.onTouchEnd(_this)
+ _this.callPlugins('onTouchEnd');
+ return;
+ }
+ //Prevent After-End Sliding
+ if (_this.positions.current < -maxPosition) {
+ _this.swipeReset()
+ if (params.onTouchEnd) params.onTouchEnd(_this)
+ _this.callPlugins('onTouchEnd');
+ return;
+ }
+
+ //Free Mode
+ if (params.freeMode) {
+ if ( params.freeModeFluid ) {
+ var momentumDuration = 1000*params.momentumRatio;
+ var momentumDistance = _this.velocity*momentumDuration;
+ var newPosition = _this.positions.current + momentumDistance
+ var doBounce = false;
+ var afterBouncePosition;
+ var bounceAmount = Math.abs( _this.velocity )*20*params.momentumBounceRatio;
+ if (newPosition < -maxPosition) {
+ if (params.momentumBounce && _this.support.transitions) {
+ if (newPosition + maxPosition < -bounceAmount) newPosition = -maxPosition-bounceAmount;
+ afterBouncePosition = -maxPosition;
+ doBounce=true;
+ allowMomentumBounce = true;
+ }
+ else newPosition = -maxPosition;
+ }
+ if (newPosition > 0) {
+ if (params.momentumBounce && _this.support.transitions) {
+ if (newPosition>bounceAmount) newPosition = bounceAmount;
+ afterBouncePosition = 0
+ doBounce = true;
+ allowMomentumBounce = true;
+ }
+ else newPosition = 0;
+ }
+ //Fix duration
+ if (_this.velocity!=0) momentumDuration = Math.abs((newPosition - _this.positions.current)/_this.velocity)
+
+ if (isH) _this.setWrapperTranslate( newPosition, 0, 0);
+ else _this.setWrapperTranslate( 0, newPosition, 0);
+
+ _this.setWrapperTransition( momentumDuration );
+
+ if (params.momentumBounce && doBounce) {
+ _this.wrapperTransitionEnd(function(){
+ if (!allowMomentumBounce) return;
+ if (params.onMomentumBounce) params.onMomentumBounce(_this);
+ if (isH) _this.setWrapperTranslate(afterBouncePosition, 0, 0);
+ else _this.setWrapperTranslate(0, afterBouncePosition, 0);
+ _this.setWrapperTransition(300);
+ })
+ }
+
+ _this.updateActiveSlide(newPosition)
+ }
+ if (!params.freeModeFluid || timeDiff >= 300) _this.updateActiveSlide(_this.positions.current)
+
+ if (params.onTouchEnd) params.onTouchEnd(_this)
+ _this.callPlugins('onTouchEnd');
+ return;
+ }
+
+ //Direction
+ direction = diff < 0 ? "toNext" : "toPrev"
+
+ //Short Touches
+ if (direction=="toNext" && ( timeDiff <= 300 ) ) {
+ if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset()
+ else _this.swipeNext(true);
+ }
+
+ if (direction=="toPrev" && ( timeDiff <= 300 ) ) {
+ if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset()
+ else _this.swipePrev(true);
+ }
+
+ //Long Touches
+ var targetSlideSize = 0;
+ if(params.slidesPerView == 'auto') {
+ //Define current slide's width
+ var currentPosition = Math.abs( isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y') );
+ var slidesOffset = 0;
+ var _slideSize;
+ for (var i=0; i<_this.slides.length; i++) {
+ _slideSize = isH ? _this.slides[i].getWidth(true) : _this.slides[i].getHeight(true);
+ slidesOffset+= _slideSize;
+ if (slidesOffset>currentPosition) {
+ targetSlideSize = _slideSize;
+ break;
+ }
+ }
+ if (targetSlideSize>containerSize) targetSlideSize = containerSize;
+ }
+ else {
+ targetSlideSize = slideSize * params.slidesPerView;
+ }
+ if (direction=="toNext" && ( timeDiff > 300 ) ) {
+ if (diffAbs >= targetSlideSize*0.5) {
+ _this.swipeNext(true)
+ }
+ else {
+ _this.swipeReset()
+ }
+ }
+ if (direction=="toPrev" && ( timeDiff > 300 ) ) {
+ if (diffAbs >= targetSlideSize*0.5) {
+ _this.swipePrev(true);
+ }
+ else {
+ _this.swipeReset()
+ }
+ }
+ if (params.onTouchEnd) params.onTouchEnd(_this)
+ _this.callPlugins('onTouchEnd');
+ }
+
+
+ /*==================================================
+ noSwiping Bubble Check by Isaac Strack
+ ====================================================*/
+ function noSwipingSlide(el){
+ /*This function is specifically designed to check the parent elements for the noSwiping class, up to the wrapper.
+ We need to check parents because while onTouchStart bubbles, _this.isTouched is checked in onTouchStart, which stops the bubbling.
+ So, if a text box, for example, is the initial target, and the parent slide container has the noSwiping class, the _this.isTouched
+ check will never find it, and what was supposed to be noSwiping is able to be swiped.
+ This function will iterate up and check for the noSwiping class in parents, up through the wrapperClass.*/
+
+ // First we create a truthy variable, which is that swiping is allowd (noSwiping = false)
+ var noSwiping = false;
+
+ // Now we iterate up (parentElements) until we reach the node with the wrapperClass.
+ do{
+
+ // Each time, we check to see if there's a 'swiper-no-swiping' class (noSwipingClass).
+ if (el.className.indexOf(params.noSwipingClass)>-1)
+ {
+ noSwiping = true; // If there is, we set noSwiping = true;
+ }
+
+ el = el.parentElement; // now we iterate up (parent node)
+
+ } while(!noSwiping && el.parentElement && el.className.indexOf(params.wrapperClass)==-1); // also include el.parentElement truthy, just in case.
+
+ // because we didn't check the wrapper itself, we do so now, if noSwiping is false:
+ if (!noSwiping && el.className.indexOf(params.wrapperClass)>-1 && el.className.indexOf(params.noSwipingClass)>-1)
+ noSwiping = true; // if the wrapper has the noSwipingClass, we set noSwiping = true;
+
+ return noSwiping;
+ }
+
+ /*==================================================
+ Swipe Functions
+ ====================================================*/
+ _this.swipeNext = function(internal){
+ if (!internal && params.loop) _this.fixLoop();
+ _this.callPlugins('onSwipeNext');
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+ var newPosition = currentPosition;
+ if (params.slidesPerView=='auto') {
+ for (var i=0; i<_this.snapGrid.length; i++) {
+ if (-currentPosition >= _this.snapGrid[i] && -currentPosition<_this.snapGrid[i+1]) {
+ newPosition = -_this.snapGrid[i+1]
+ break;
+ }
+ }
+ }
+ else {
+ var groupSize = slideSize * params.slidesPerGroup;
+ newPosition = -(Math.floor(Math.abs(currentPosition)/Math.floor(groupSize))*groupSize + groupSize);
+ }
+ if (newPosition < - maxWrapperPosition()) {
+ newPosition = - maxWrapperPosition()
+ };
+
+ if (newPosition == currentPosition) return false;
+
+ swipeToPosition(newPosition, 'next');
+ return true
+ }
+ _this.swipePrev = function(internal){
+ if (!internal && params.loop) _this.fixLoop();
+ if (!internal && params.autoplay) _this.stopAutoplay();
+ _this.callPlugins('onSwipePrev');
+
+ var currentPosition = Math.ceil( isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y') );
+ var newPosition;
+ if (params.slidesPerView=='auto') {
+ newPosition = 0;
+ for (var i=1; i<_this.snapGrid.length; i++) {
+ if (-currentPosition == _this.snapGrid[i]) {
+ newPosition = -_this.snapGrid[i-1]
+ break;
+ }
+ if (-currentPosition > _this.snapGrid[i] && -currentPosition<_this.snapGrid[i+1]) {
+ newPosition = -_this.snapGrid[i]
+ break;
+ }
+ }
+ }
+ else {
+ var groupSize = slideSize * params.slidesPerGroup;
+ newPosition = -(Math.ceil(-currentPosition/groupSize)-1)*groupSize;
+ }
+
+ if (newPosition > 0) newPosition = 0;
+
+ if (newPosition == currentPosition) return false;
+ swipeToPosition(newPosition, 'prev');
+ return true;
+
+ }
+ _this.swipeReset = function(){
+ _this.callPlugins('onSwipeReset');
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+ var groupSize = slideSize * params.slidesPerGroup;
+ var newPosition;
+ var maxPosition = -maxWrapperPosition();
+ if (params.slidesPerView=='auto') {
+ newPosition = 0;
+ for (var i=0; i<_this.snapGrid.length; i++) {
+ if (-currentPosition===_this.snapGrid[i]) return;
+ if (-currentPosition >= _this.snapGrid[i] && -currentPosition<_this.snapGrid[i+1]) {
+ if(_this.positions.diff>0) newPosition = -_this.snapGrid[i+1]
+ else newPosition = -_this.snapGrid[i]
+ break;
+ }
+ }
+ if (-currentPosition >= _this.snapGrid[_this.snapGrid.length-1]) newPosition = -_this.snapGrid[_this.snapGrid.length-1];
+ if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition()
+ }
+ else {
+ newPosition = currentPosition<0 ? Math.round(currentPosition/groupSize)*groupSize : 0
+ }
+ if (params.scrollContainer) {
+ newPosition = currentPosition<0 ? currentPosition : 0;
+ }
+ if (newPosition < -maxWrapperPosition()) {
+ newPosition = -maxWrapperPosition()
+ }
+ if (params.scrollContainer && (containerSize>slideSize)) {
+ newPosition = 0;
+ }
+
+ if (newPosition == currentPosition) return false;
+
+ swipeToPosition(newPosition, 'reset');
+ return true;
+ }
+ _this.swipeTo = function(index, speed, runCallbacks){
+ index = parseInt(index, 10);
+ _this.callPlugins('onSwipeTo', {index:index, speed:speed});
+ if (params.loop) index = index + _this.loopedSlides;
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+ if (index > (_this.slides.length-1)) return;
+ if (index<0) return;
+ var newPosition
+ if (params.slidesPerView=='auto') {
+ newPosition = -_this.slidesGrid[ index ];
+ }
+ else {
+ newPosition = -index*slideSize;
+ }
+ if (newPosition < - maxWrapperPosition()) {
+ newPosition = - maxWrapperPosition();
+ };
+
+ if (newPosition == currentPosition) return false;
+
+ runCallbacks = runCallbacks===false ? false : true;
+ swipeToPosition(newPosition, 'to', {index:index, speed:speed, runCallbacks:runCallbacks});
+ return true;
+ }
+ function swipeToPosition(newPosition, action, toOptions) {
+ if (_this.support.transitions || !params.DOMAnimation) {
+ if (isH) _this.setWrapperTranslate(newPosition,0,0);
+ else _this.setWrapperTranslate(0,newPosition,0);
+ var speed = (action=='to' && toOptions.speed>=0) ? toOptions.speed : params.speed;
+ _this.setWrapperTransition(speed);
+ }
+ else {
+ //Try the DOM animation
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+ var speed = (action=='to' && toOptions.speed>=0) ? toOptions.speed : params.speed;
+ var animationStep = Math.ceil( (newPosition - currentPosition)/speed*(1000/60) );
+ var direction = currentPosition > newPosition ? 'toNext' : 'toPrev';
+ var condition = direction=='toNext' ? currentPosition > newPosition : currentPosition < newPosition;
+ if (_this._DOMAnimating) return;
+
+ anim()
+ }
+ function anim(){
+ currentPosition += animationStep;
+ condition = direction=='toNext' ? currentPosition > newPosition : currentPosition < newPosition;
+ if (condition) {
+ if (isH) _this.setWrapperTranslate(Math.round(currentPosition),0)
+ else _this.setWrapperTranslate(0,Math.round(currentPosition))
+ _this._DOMAnimating = true
+ window.setTimeout(function(){
+ anim()
+ }, 1000 / 60)
+ }
+ else {
+ if (params.onSlideChangeEnd) params.onSlideChangeEnd(_this)
+ if (isH) _this.setWrapperTranslate(newPosition,0);
+ else _this.setWrapperTranslate(0, newPosition);
+ _this._DOMAnimating = false;
+ }
+ }
+
+ //Update Active Slide Index
+ _this.updateActiveSlide(newPosition);
+
+ //Callbacks
+ if (params.onSlideNext && action=='next') {
+ params.onSlideNext(_this, newPosition)
+ }
+ if (params.onSlidePrev && action=='prev') {
+ params.onSlidePrev(_this, newPosition)
+ }
+ //"Reset" Callback
+ if (params.onSlideReset && action=='reset') {
+ params.onSlideReset(_this, newPosition)
+ }
+
+ //"Next", "Prev" and "To" Callbacks
+ if (action=='next' || action=='prev' || (action=='to' && toOptions.runCallbacks==true))
+ slideChangeCallbacks()
+ }
+ /*==================================================
+ Transition Callbacks
+ ====================================================*/
+ //Prevent Multiple Callbacks
+ _this._queueStartCallbacks = false;
+ _this._queueEndCallbacks = false;
+ function slideChangeCallbacks() {
+ //Transition Start Callback
+ _this.callPlugins('onSlideChangeStart');
+ if (params.onSlideChangeStart) {
+ if (params.queueStartCallbacks && _this.support.transitions) {
+ if (_this._queueStartCallbacks) return;
+ _this._queueStartCallbacks = true;
+ params.onSlideChangeStart(_this)
+ _this.wrapperTransitionEnd(function(){
+ _this._queueStartCallbacks = false;
+ })
+ }
+ else params.onSlideChangeStart(_this)
+ }
+ //Transition End Callback
+ if (params.onSlideChangeEnd) {
+ if (_this.support.transitions) {
+ if (params.queueEndCallbacks) {
+ if (_this._queueEndCallbacks) return;
+ _this._queueEndCallbacks = true;
+ _this.wrapperTransitionEnd(params.onSlideChangeEnd)
+ }
+ else _this.wrapperTransitionEnd(params.onSlideChangeEnd)
+ }
+ else {
+ if (!params.DOMAnimation) {
+ setTimeout(function(){
+ params.onSlideChangeEnd(_this)
+ },10)
+ }
+ }
+ }
+ }
+ /*==================================================
+ Update Active Slide Index
+ ====================================================*/
+ _this.updateActiveSlide = function(position) {
+ if (!_this.initialized) return;
+ if (_this.slides.length==0) return;
+ _this.previousIndex = _this.activeIndex;
+ if (position>0) position=0;
+ if (typeof position=='undefined') position = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
+
+ if (params.slidesPerView == 'auto') {
+ var slidesOffset = 0;
+ _this.activeIndex = _this.slidesGrid.indexOf(-position);
+ if (_this.activeIndex<0) {
+ for (var i=0; i<_this.slidesGrid.length-1; i++) {
+ if (-position>_this.slidesGrid[i] && -position<_this.slidesGrid[i+1]) {
+ break;
+ }
+ }
+ var leftDistance = Math.abs( _this.slidesGrid[i] + position )
+ var rightDistance = Math.abs( _this.slidesGrid[i+1] + position )
+ if (leftDistance<=rightDistance) _this.activeIndex = i;
+ else _this.activeIndex = i+1;
+ }
+ }
+ else {
+ if (params.visibilityFullFit) _this.activeIndex = Math.ceil( -position/slideSize );
+ else _this.activeIndex = Math.round( -position/slideSize );
+ }
+ if (_this.activeIndex== _this.slides.length ) _this.activeIndex = _this.slides.length-1;
+ if (_this.activeIndex<0) _this.activeIndex = 0;
+ // Check for slide
+ if (!_this.slides[_this.activeIndex]) return;
+ // Calc Visible slides
+ _this.calcVisibleSlides(position);
+
+ // Mark visible and active slides with additonal classes
+ var activeClassRegexp = new RegExp( "\\s*" + params.slideActiveClass );
+ var inViewClassRegexp = new RegExp( "\\s*" + params.slideVisibleClass );
+
+ for (var i = 0; i < _this.slides.length; i++) {
+ _this.slides[ i ].className = _this.slides[ i ].className.replace( activeClassRegexp, '' ).replace( inViewClassRegexp, '' );
+ if ( _this.visibleSlides.indexOf( _this.slides[ i ] )>=0 ) {
+ _this.slides[ i ].className += ' ' + params.slideVisibleClass;
+ }
+
+ }
+ _this.slides[ _this.activeIndex ].className += ' ' + params.slideActiveClass;
+
+ //Update loop index
+ if (params.loop) {
+ var ls = _this.loopedSlides;
+ _this.activeLoopIndex = _this.activeIndex - ls;
+ if (_this.activeLoopIndex >= _this.slides.length - ls*2 ) {
+ _this.activeLoopIndex = _this.slides.length - ls*2 - _this.activeLoopIndex;
+ }
+ if (_this.activeLoopIndex<0) {
+ _this.activeLoopIndex = _this.slides.length - ls*2 + _this.activeLoopIndex;
+ }
+ }
+ else {
+ _this.activeLoopIndex = _this.activeIndex;
+ }
+ //Update Pagination
+ if (params.pagination) {
+ _this.updatePagination(position);
+ }
+ }
+ /*==================================================
+ Pagination
+ ====================================================*/
+ _this.createPagination = function (firstInit) {
+ if (params.paginationClickable && _this.paginationButtons) {
+ removePaginationEvents();
+ }
+ var paginationHTML = "";
+ var numOfSlides = _this.slides.length;
+ var numOfButtons = numOfSlides;
+ if (params.loop) numOfButtons -= _this.loopedSlides*2
+ for (var i = 0; i < numOfButtons; i++) {
+ paginationHTML += '<'+params.paginationElement+' class="'+params.paginationElementClass+'"></'+params.paginationElement+'>'
+ }
+ _this.paginationContainer = params.pagination.nodeType ? params.pagination : $$(params.pagination)[0];
+ _this.paginationContainer.innerHTML = paginationHTML;
+ _this.paginationButtons = []
+ if (document.querySelectorAll)
+ _this.paginationButtons = _this.paginationContainer.querySelectorAll('.'+params.paginationElementClass);
+ else if (window.jQuery)
+ _this.paginationButtons = $$(_this.paginationContainer).find('.'+params.paginationElementClass);
+ if (!firstInit) _this.updatePagination()
+ _this.callPlugins('onCreatePagination');
+ if (params.paginationClickable) {
+ addPaginationEvents();
+ }
+ }
+ function removePaginationEvents() {
+ var pagers = _this.paginationButtons;
+ for (var i=0; i<pagers.length; i++) {
+ _this.h.removeEventListener(pagers[i],'click', paginationClick, false)
+ }
+ }
+ function addPaginationEvents() {
+ var pagers = _this.paginationButtons;
+ for (var i=0; i<pagers.length; i++) {
+ _this.h.addEventListener(pagers[i],'click', paginationClick, false)
+ }
+ }
+ function paginationClick(e){
+ var index;
+ var target = e.target || e.srcElement;
+ var pagers = _this.paginationButtons;
+ for (var i=0; i<pagers.length; i++) {
+ if (target===pagers[i]) index = i;
+ }
+ _this.swipeTo(index)
+ }
+ _this.updatePagination = function(position) {
+ if (!params.pagination) return;
+ if (_this.slides.length<1) return;
+
+ if (document.querySelectorAll)
+ var activePagers = _this.paginationContainer.querySelectorAll('.'+params.paginationActiveClass)
+ else if (window.jQuery)
+ var activePagers = $$(_this.paginationContainer).find('.'+params.paginationActiveClass);
+ if(!activePagers) return;
+
+ //Reset all Buttons' class to not active
+ var pagers = _this.paginationButtons;
+ if (pagers.length==0) return;
+ for (var i=0; i < pagers.length; i++) {
+ pagers[i].className = params.paginationElementClass
+ }
+
+ var indexOffset = params.loop ? _this.loopedSlides : 0;
+ if (params.paginationAsRange) {
+ if (!_this.visibleSlides) _this.calcVisibleSlides(position)
+ //Get Visible Indexes
+ var visibleIndexes = [];
+ for (var i = 0; i < _this.visibleSlides.length; i++) {
+ var visIndex = _this.slides.indexOf( _this.visibleSlides[i] ) - indexOffset
+
+ if (params.loop && visIndex<0) {
+ visIndex = _this.slides.length - _this.loopedSlides*2 + visIndex;
+ }
+ if (params.loop && visIndex>=_this.slides.length-_this.loopedSlides*2) {
+ visIndex = _this.slides.length - _this.loopedSlides*2 - visIndex;
+ visIndex = Math.abs(visIndex)
+ }
+ visibleIndexes.push( visIndex )
+ }
+
+ for (i=0; i<visibleIndexes.length; i++) {
+ if (pagers[ visibleIndexes[i] ]) pagers[ visibleIndexes[i] ].className += ' ' + params.paginationVisibleClass;
+ }
+
+ if (params.loop) {
+ pagers[ _this.activeLoopIndex ].className += ' ' + params.paginationActiveClass;
+ }
+ else {
+ pagers[ _this.activeIndex ].className += ' ' + params.paginationActiveClass;
+ }
+
+ }
+ else {
+ if (params.loop) {
+ pagers[ _this.activeLoopIndex ].className+=' '+params.paginationActiveClass+' '+params.paginationVisibleClass;
+ }
+ else {
+ pagers[ _this.activeIndex ].className+=' '+params.paginationActiveClass+' '+params.paginationVisibleClass;
+ }
+
+ }
+
+ }
+ _this.calcVisibleSlides = function(position){
+ var visibleSlides = [];
+ var _slideLeft = 0, _slideSize = 0, _slideRight = 0;
+ if (isH && _this.wrapperLeft>0) position = position+_this.wrapperLeft;
+ if (!isH && _this.wrapperTop>0) position = position+_this.wrapperTop;
+
+ for (var i=0; i<_this.slides.length; i++) {
+ _slideLeft += _slideSize;
+ if (params.slidesPerView == 'auto')
+ _slideSize = isH ? _this.h.getWidth(_this.slides[i],true) : _this.h.getHeight(_this.slides[i],true);
+ else _slideSize = slideSize;
+
+ _slideRight = _slideLeft + _slideSize;
+ var isVisibile = false;
+ if (params.visibilityFullFit) {
+ if (_slideLeft >= -position && _slideRight <= -position+containerSize) isVisibile = true;
+ if (_slideLeft <= -position && _slideRight >= -position+containerSize) isVisibile = true;
+ }
+ else {
+
+ if (_slideRight > -position && _slideRight <= ((-position+containerSize))) isVisibile = true;
+ if (_slideLeft >= -position && _slideLeft < ((-position+containerSize))) isVisibile = true;
+ if (_slideLeft < -position && _slideRight > ((-position+containerSize))) isVisibile = true;
+ }
+
+ if (isVisibile) visibleSlides.push(_this.slides[i])
+
+ }
+ if (visibleSlides.length==0) visibleSlides = [ _this.slides[ _this.activeIndex ] ]
+
+ _this.visibleSlides = visibleSlides;
+ }
+
+ /*==========================================
+ Autoplay
+ ============================================*/
+ _this.autoPlayIntervalId = undefined;
+ _this.startAutoplay = function () {
+ if (typeof _this.autoPlayIntervalId !== 'undefined') return false;
+ if (params.autoplay && !params.loop) {
+ _this.autoPlayIntervalId = setInterval(function(){
+ if (!_this.swipeNext(true)) _this.swipeTo(0);
+ }, params.autoplay)
+ }
+ if (params.autoplay && params.loop) {
+ _this.autoPlayIntervalId = setInterval(function(){
+ _this.swipeNext();
+ }, params.autoplay)
+ }
+ _this.callPlugins('onAutoplayStart');
+ }
+ _this.stopAutoplay = function () {
+ if (_this.autoPlayIntervalId) clearInterval(_this.autoPlayIntervalId);
+ _this.autoPlayIntervalId = undefined;
+ _this.callPlugins('onAutoplayStop');
+ }
+ /*==================================================
+ Loop
+ ====================================================*/
+ _this.loopCreated = false;
+ _this.removeLoopedSlides = function(){
+ if (_this.loopCreated) {
+ for (var i=0; i<_this.slides.length; i++) {
+ if (_this.slides[i].getData('looped')===true) _this.wrapper.removeChild(_this.slides[i]);
+ }
+ }
+ }
+ _this.createLoop = function(){
+ if (_this.slides.length==0) return;
+ _this.loopedSlides = params.slidesPerView+params.loopAdditionalSlides;
+
+ var slideFirstHTML = '';
+ var slideLastHTML = '';
+
+ //Grab First Slides
+ for (var i=0; i<_this.loopedSlides; i++) {
+ slideFirstHTML+=_this.slides[i].outerHTML
+ }
+ //Grab Last Slides
+ for (i=_this.slides.length-_this.loopedSlides; i<_this.slides.length; i++) {
+ slideLastHTML+=_this.slides[i].outerHTML
+ }
+ wrapper.innerHTML = slideLastHTML + wrapper.innerHTML + slideFirstHTML;
+
+ _this.loopCreated = true;
+ _this.calcSlides();
+
+ //Update Looped Slides with special class
+ for (i=0; i<_this.slides.length; i++) {
+ if (i<_this.loopedSlides || i>=_this.slides.length-_this.loopedSlides) _this.slides[i].setData('looped', true);
+ }
+ _this.callPlugins('onCreateLoop');
+
+ }
+ _this.fixLoop = function(){
+ //Fix For Negative Oversliding
+ if (_this.activeIndex < _this.loopedSlides) {
+ var newIndex = _this.slides.length - _this.loopedSlides*3 + _this.activeIndex;
+ _this.swipeTo(newIndex, 0, false)
+ }
+ //Fix For Positive Oversliding
+ else if (_this.activeIndex > _this.slides.length - params.slidesPerView*2) {
+ var newIndex = -_this.slides.length + _this.activeIndex + _this.loopedSlides
+ _this.swipeTo(newIndex,0, false)
+ }
+ }
+ /*==================================================
+ Slides Loader
+ ====================================================*/
+ _this.loadSlides = function(){
+ var slidesHTML = '';
+ _this.activeLoaderIndex = 0;
+ var slides = params.loader.slides;
+ var slidesToLoad = params.loader.loadAllSlides ? slides.length : params.slidesPerView*(1+params.loader.surroundGroups);
+ for (var i=0; i< slidesToLoad; i++) {
+ if (params.loader.slidesHTMLType=='outer') slidesHTML+=slides[i];
+ else {
+ slidesHTML+='<'+params.slideElement+' class="'+params.slideClass+'" data-swiperindex="'+i+'">'+slides[i]+'</'+params.slideElement+'>';
+ }
+ }
+ _this.wrapper.innerHTML = slidesHTML;
+ _this.calcSlides(true);
+ //Add permanent transitionEnd callback
+ if (!params.loader.loadAllSlides) {
+ _this.wrapperTransitionEnd(_this.reloadSlides, true);
+ }
+ }
+ _this.reloadSlides = function(){
+ var slides = params.loader.slides;
+ var newActiveIndex = parseInt(_this.activeSlide().data('swiperindex'),10)
+ if (newActiveIndex<0 || newActiveIndex>slides.length-1) return //<-- Exit
+ _this.activeLoaderIndex = newActiveIndex;
+ var firstIndex = Math.max(0, newActiveIndex - params.slidesPerView*params.loader.surroundGroups)
+ var lastIndex = Math.min(newActiveIndex+params.slidesPerView*(1+params.loader.surroundGroups)-1, slides.length-1)
+ //Update Transforms
+ if (newActiveIndex>0) {
+ var newTransform = -slideSize*(newActiveIndex-firstIndex)
+ if (isH) _this.setWrapperTranslate(newTransform,0,0)
+ else _this.setWrapperTranslate(0,newTransform,0)
+ _this.setWrapperTransition(0)
+ }
+ //New Slides
+ if (params.loader.logic==='reload') {
+ _this.wrapper.innerHTML = '';
+ var slidesHTML = '';
+ for (var i = firstIndex; i<=lastIndex; i++) {
+ slidesHTML += params.loader.slidesHTMLType == 'outer' ? slides[i] : '<'+params.slideElement+' class="'+params.slideClass+'" data-swiperindex="'+i+'">'+slides[i]+'</'+params.slideElement+'>';
+ }
+ _this.wrapper.innerHTML = slidesHTML;
+ }
+ else {
+ var minExistIndex=1000;
+ var maxExistIndex=0;
+ for (var i=0; i<_this.slides.length; i++) {
+ var index = _this.slides[i].data('swiperindex');
+ if (index<firstIndex || index>lastIndex) {
+ _this.wrapper.removeChild(_this.slides[i]);
+ }
+ else {
+ minExistIndex = Math.min(index, minExistIndex)
+ maxExistIndex = Math.max(index, maxExistIndex)
+ }
+ }
+ for (var i=firstIndex; i<=lastIndex; i++) {
+ if (i<minExistIndex) {
+ var newSlide = document.createElement(params.slideElement);
+ newSlide.className = params.slideClass;
+ newSlide.setAttribute('data-swiperindex',i);
+ newSlide.innerHTML = slides[i];
+ _this.wrapper.insertBefore(newSlide, _this.wrapper.firstChild);
+ }
+ if (i>maxExistIndex) {
+ var newSlide = document.createElement(params.slideElement);
+ newSlide.className = params.slideClass;
+ newSlide.setAttribute('data-swiperindex',i);
+ newSlide.innerHTML = slides[i];
+ _this.wrapper.appendChild(newSlide);
+ }
+ }
+ }
+ //reInit
+ _this.reInit(true);
+ }
+ /*==================================================
+ Make Swiper
+ ====================================================*/
+ function makeSwiper(){
+ _this.calcSlides();
+ if (params.loader.slides.length>0 && _this.slides.length==0) {
+ _this.loadSlides();
+ }
+ if (params.loop) {
+ _this.createLoop();
+ }
+ _this.init();
+ initEvents();
+ if (params.pagination && params.createPagination) {
+ _this.createPagination(true);
+ }
+ if (params.loop || params.initialSlide>0) {
+ _this.swipeTo( params.initialSlide, 0, false );
+ }
+ else {
+ _this.updateActiveSlide(0);
+ }
+ if (params.autoplay) {
+ _this.startAutoplay();
+ }
+
+ }
+ makeSwiper();
+}
+
+Swiper.prototype = {
+ plugins : {},
+ /*==================================================
+ Wrapper Operations
+ ====================================================*/
+ wrapperTransitionEnd : function(callback, permanent) {
+ var a = this
+ var el = a.wrapper
+ var events = ['webkitTransitionEnd','transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
+ function fireCallBack() {
+ callback(a)
+ if (a.params.queueEndCallbacks) a._queueEndCallbacks = false
+ if (!permanent) {
+ for (var i=0; i<events.length; i++) {
+ a.h.removeEventListener(el,events[i], fireCallBack, false)
+ }
+ }
+ }
+ if (callback) {
+ for (var i=0; i<events.length; i++) {
+ a.h.addEventListener(el,events[i], fireCallBack, false)
+ }
+ }
+ },
+
+ getWrapperTranslate : function(axis){
+ var el = this.wrapper
+ var matrix;
+ var curTransform;
+ if (window.WebKitCSSMatrix) {
+ var transformMatrix = new WebKitCSSMatrix(window.getComputedStyle(el, null).webkitTransform)
+ matrix = transformMatrix.toString().split(',');
+ }
+ else {
+ var transformMatrix = window.getComputedStyle(el, null).MozTransform || window.getComputedStyle(el, null).OTransform || window.getComputedStyle(el, null).MsTransform || window.getComputedStyle(el, null).msTransform || window.getComputedStyle(el, null).transform|| window.getComputedStyle(el, null).getPropertyValue("transform").replace("translate(", "matrix(1, 0, 0, 1,");
+ matrix = transformMatrix.toString().split(',');
+
+ }
+ if (this.params.useCSS3Transforms) {
+ if (axis=='x') {
+ //Crazy IE10 Matrix
+ if (matrix.length==16)
+ curTransform = parseFloat( matrix[12] )
+ //Latest Chrome and webkits Fix
+ else if (window.WebKitCSSMatrix)
+ curTransform = transformMatrix.m41
+ //Normal Browsers
+ else
+ curTransform = parseFloat( matrix[4] )
+ }
+ if (axis=='y') {
+ //Crazy IE10 Matrix
+ if (matrix.length==16)
+ curTransform = parseFloat( matrix[13] )
+ //Latest Chrome and webkits Fix
+ else if (window.WebKitCSSMatrix)
+ curTransform = transformMatrix.m42
+ //Normal Browsers
+ else
+ curTransform = parseFloat( matrix[5] )
+ }
+ }
+ else {
+ if (axis=='x') curTransform = parseFloat(el.style.left,10) || 0
+ if (axis=='y') curTransform = parseFloat(el.style.top,10) || 0
+ }
+ return curTransform || 0;
+ },
+
+ setWrapperTranslate : function(x,y,z) {
+ var es = this.wrapper.style
+ x=x||0;
+ y=y||0;
+ z=z||0;
+ if (this.params.useCSS3Transforms) {
+ if (this.support.transforms3d) {
+ es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = 'translate3d('+x+'px, '+y+'px, '+z+'px)'
+ }
+ else {
+
+ es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = 'translate('+x+'px, '+y+'px)'
+ if (!this.support.transforms) {
+ es.left = x+'px'
+ es.top = y+'px'
+ }
+ }
+ }
+ else {
+ es.left = x+'px';
+ es.top = y+'px';
+ }
+ this.callPlugins('onSetWrapperTransform', {x:x, y:y, z:z})
+ },
+
+ setWrapperTransition : function(duration) {
+ var es = this.wrapper.style
+ es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration/1000+'s';
+ this.callPlugins('onSetWrapperTransition', {duration: duration})
+ },
+
+ /*==================================================
+ Helpers
+ ====================================================*/
+ h : {
+ getWidth: function (el, outer) {
+ var width = window.getComputedStyle(el, null).getPropertyValue('width')
+ var returnWidth = parseFloat(width);
+ //IE Fixes
+ if(isNaN(returnWidth) || width.indexOf('%')>0) {
+ returnWidth = el.offsetWidth - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
+ }
+ if (outer) returnWidth += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'))
+
+ return returnWidth;
+ },
+ getHeight: function(el, outer) {
+ if (outer) return el.offsetHeight;
+
+ var height = window.getComputedStyle(el, null).getPropertyValue('height')
+ var returnHeight = parseFloat(height);
+ //IE Fixes
+ if(isNaN(returnHeight) || height.indexOf('%')>0) {
+ returnHeight = el.offsetHeight - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
+ }
+ if (outer) returnHeight += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'))
+ return returnHeight;
+ },
+ getOffset: function(el) {
+ var box = el.getBoundingClientRect();
+ var body = document.body;
+ var clientTop = el.clientTop || body.clientTop || 0;
+ var clientLeft = el.clientLeft || body.clientLeft || 0;
+ var scrollTop = window.pageYOffset || el.scrollTop;
+ var scrollLeft = window.pageXOffset || el.scrollLeft;
+ if (document.documentElement && !window.pageYOffset) {
+ //IE7-8
+ scrollTop = document.documentElement.scrollTop;
+ scrollLeft = document.documentElement.scrollLeft;
+ }
+ return {
+ top: box.top + scrollTop - clientTop,
+ left: box.left + scrollLeft - clientLeft
+ };
+ },
+ windowWidth : function() {
+ if (window.innerWidth) return window.innerWidth
+ else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
+ },
+ windowHeight : function() {
+ if (window.innerHeight) return window.innerHeight
+ else if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight;
+ },
+ windowScroll : function() {
+ var left=0, top=0;
+ if (typeof pageYOffset != 'undefined') {
+ return {
+ left: window.pageXOffset,
+ top: window.pageYOffset
+ }
+ }
+ else if (document.documentElement) {
+ return {
+ left: document.documentElement.scrollLeft,
+ top: document.documentElement.scrollTop
+ }
+ }
+ },
+
+ addEventListener : function (el, event, listener, useCapture) {
+ if (el.addEventListener) {
+ el.addEventListener(event, listener, useCapture)
+ }
+ else if (el.attachEvent) {
+ el.attachEvent('on'+event, listener)
+ }
+ },
+ removeEventListener : function (el, event, listener, useCapture) {
+ if (el.removeEventListener) {
+ el.removeEventListener(event, listener, useCapture)
+ }
+ else if (el.detachEvent) {
+ el.detachEvent('on'+event, listener)
+ }
+ }
+ },
+ setTransform : function (el, transform) {
+ var es = el.style
+ es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transform
+ },
+ setTranslate : function (el, translate) {
+ var es = el.style
+ var pos = {
+ x : translate.x || 0,
+ y : translate.y || 0,
+ z : translate.z || 0
+ };
+ var transformString = this.support.transforms3d ? 'translate3d('+(pos.x)+'px,'+(pos.y)+'px,'+(pos.z)+'px)' : 'translate('+(pos.x)+'px,'+(pos.y)+'px)';
+ es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transformString;
+ if (!this.support.transforms) {
+ es.left = pos.x+'px'
+ es.top = pos.y+'px'
+ }
+ },
+ setTransition : function (el, duration) {
+ var es = el.style
+ es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration+'ms';
+ },
+ /*==================================================
+ Feature Detection
+ ====================================================*/
+ support: {
+
+ touch : (window.Modernizr && Modernizr.touch===true) || (function() {
+ return !!(("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch);
+ })(),
+
+ transforms3d : (window.Modernizr && Modernizr.csstransforms3d===true) || (function() {
+ var div = document.createElement('div');
+ return ( "webkitPerspective" in div.style || "MozPerspective" in div.style || "OPerspective" in div.style || "MsPerspective" in div.style || "perspective" in div.style );
+ })(),
+
+ transforms : (window.Modernizr && Modernizr.csstransforms===true) || (function(){
+ var div = document.createElement('div').style
+ return ('transform' in div) || ('WebkitTransform' in div) || ('MozTransform' in div) || ('msTransform' in div) || ('MsTransform' in div) || ('OTransform' in div);
+ })(),
+
+ transitions : (window.Modernizr && Modernizr.csstransitions===true) || (function(){
+ var div = document.createElement('div').style
+ return ('transition' in div) || ('WebkitTransition' in div) || ('MozTransition' in div) || ('msTransition' in div) || ('MsTransition' in div) || ('OTransition' in div);
+ })()
+ },
+
+ browser : {
+
+ ie8 : (function(){
+ var rv = -1; // Return value assumes failure.
+ if (navigator.appName == 'Microsoft Internet Explorer') {
+ var ua = navigator.userAgent;
+ var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
+ if (re.exec(ua) != null)
+ rv = parseFloat(RegExp.$1);
+ }
+ return rv != -1 && rv < 9;
+ })(),
+
+ ie10 : window.navigator.msPointerEnabled
+ }
+}
+
+/*=========================
+ jQuery & Zepto Plugins
+ ===========================*/
+if (window.jQuery||window.Zepto) {
+ (function($){
+ $.fn.swiper = function(params) {
+ var s = new Swiper($(this)[0], params)
+ $(this).data('swiper',s);
+ return s
+ }
+ })(window.jQuery||window.Zepto)
+}
+
+// component
+if ( typeof( module ) !== 'undefined' )
+{
+ module.exports = Swiper;
+}
+// Generated by CoffeeScript 1.6.3
+(function($, window) {
+ "use strict";
+ var Nav;
+ Nav = (function() {
+ function Nav(el, options) {
+ this.options = $.extend({}, options);
+ this.$el = $(el);
+ }
+
+ Nav.prototype.slide = function() {
+ return this.$el.next('ul').slideToggle();
+ };
+
+ return Nav;
+
+ })();
+ $.fn.nav = function(option) {
+ return this.each(function() {
+ var $this, data;
+ $this = $(this);
+ data = $this.data('Nav');
+ if (!data) {
+ $this.data('Nav', (data = new Nav(this, {})));
+ }
+ if (typeof option === 'string') {
+ return data[option]();
+ }
+ });
+ };
+ return $(document).on('click', '[data-toggle="nav"]', function(e) {
+ $(this).nav('slide');
+ return e.preventDefault();
+ });
+})(window.jQuery, window);
+// Generated by CoffeeScript 1.6.3
+jQuery(function() {
+ var swiper;
+ $('.close').each(function() {
+ return $(this).click(function(e) {
+ e.preventDefault();
+ return $(this).parent().fadeOut();
+ });
+ });
+ $("[data-toggle=tooltip]").tooltip();
+ $("[data-datepicker]").each(function() {
+ var input;
+ input = $(this);
+ return input.pickadate({
+ selectYears: input.data('select-years') || false,
+ selectMonths: input.data('select-months') || false
+ });
+ });
+ swiper = new Swiper('.swiper-container', {
+ pagination: '.swiper-pagination',
+ mode: 'horizontal',
+ loop: true,
+ calculateHeight: true,
+ grabCursor: true,
+ paginationClickable: true,
+ speed: 600
+ });
+ $('.swiper-control.left').on('click', function(e) {
+ e.preventDefault();
+ return swiper.swipePrev();
+ });
+ return $('.swiper-control.right').on('click', function(e) {
+ e.preventDefault();
+ return swiper.swipeNext();
+ });
+});