(function ($) {
//flexslider: object instance
$.flexslider = function(el, options) {
var slider = $(el);
// making variables public
slider.vars = $.extend({}, $.flexslider.defaults, options);
var namespace = slider.vars.namespace,
msgesture = window.navigator && window.navigator.mspointerenabled && window.msgesture,
touch = (( "ontouchstart" in window ) || msgesture || window.documenttouch && document instanceof documenttouch) && slider.vars.touch,
// depricating this idea, as devices are being released with both of these events
//eventtype = (touch) ? "touchend" : "click",
eventtype = "click touchend mspointerup keyup",
watchedevent = "",
watchedeventcleartimer,
vertical = slider.vars.direction === "vertical",
reverse = slider.vars.reverse,
carousel = (slider.vars.itemwidth > 0),
fade = slider.vars.animation === "fade",
asnav = slider.vars.asnavfor !== "",
methods = {},
focused = true;
// store a reference to the slider object
$.data(el, "flexslider", slider);
// private slider methods
methods = {
init: function() {
slider.animating = false;
// get current slide and make sure it is a number
slider.currentslide = parseint( ( slider.vars.startat ? slider.vars.startat : 0), 10 );
if ( isnan( slider.currentslide ) ) slider.currentslide = 0;
slider.animatingto = slider.currentslide;
slider.atend = (slider.currentslide === 0 || slider.currentslide === slider.last);
slider.containerselector = slider.vars.selector.substr(0,slider.vars.selector.search(' '));
slider.slides = $(slider.vars.selector, slider);
slider.container = $(slider.containerselector, slider);
slider.count = slider.slides.length;
// sync:
slider.syncexists = $(slider.vars.sync).length > 0;
// slide:
if (slider.vars.animation === "slide") slider.vars.animation = "swing";
slider.prop = (vertical) ? "top" : "marginleft";
slider.args = {};
// slideshow:
slider.manualpause = false;
slider.stopped = false;
//pause when invisible
slider.started = false;
slider.starttimeout = null;
// touch/usecss:
slider.transitions = !slider.vars.video && !fade && slider.vars.usecss && (function() {
var obj = document.createelement('div'),
props = ['perspectiveproperty', 'webkitperspective', 'mozperspective', 'operspective', 'msperspective'];
for (var i in props) {
if ( obj.style[ props[i] ] !== undefined ) {
slider.pfx = props[i].replace('perspective','').tolowercase();
slider.prop = "-" + slider.pfx + "-transform";
return true;
}
}
return false;
}());
slider.ensureanimationend = '';
// controlscontainer:
if (slider.vars.controlscontainer !== "") slider.controlscontainer = $(slider.vars.controlscontainer).length > 0 && $(slider.vars.controlscontainer);
// manual:
if (slider.vars.manualcontrols !== "") slider.manualcontrols = $(slider.vars.manualcontrols).length > 0 && $(slider.vars.manualcontrols);
// randomize:
if (slider.vars.randomize) {
slider.slides.sort(function() { return (math.round(math.random())-0.5); });
slider.container.empty().append(slider.slides);
}
slider.domath();
// init
slider.setup("init");
// controlnav:
if (slider.vars.controlnav) methods.controlnav.setup();
// directionnav:
if (slider.vars.directionnav) methods.directionnav.setup();
// keyboard:
if (slider.vars.keyboard && ($(slider.containerselector).length === 1 || slider.vars.multiplekeyboard)) {
$(document).bind('keyup', function(event) {
var keycode = event.keycode;
if (!slider.animating && (keycode === 39 || keycode === 37)) {
var target = (keycode === 39) ? slider.gettarget('next') :
(keycode === 37) ? slider.gettarget('prev') : false;
slider.flexanimate(target, slider.vars.pauseonaction);
}
});
}
// mousewheel:
if (slider.vars.mousewheel) {
slider.bind('mousewheel', function(event, delta, deltax, deltay) {
event.preventdefault();
var target = (delta < 0) ? slider.gettarget('next') : slider.gettarget('prev');
slider.flexanimate(target, slider.vars.pauseonaction);
});
}
// pauseplay
if (slider.vars.pauseplay) methods.pauseplay.setup();
//pause when invisible
if (slider.vars.slideshow && slider.vars.pauseinvisible) methods.pauseinvisible.init();
// slidseshow
if (slider.vars.slideshow) {
if (slider.vars.pauseonhover) {
slider.hover(function() {
if (!slider.manualplay && !slider.manualpause) slider.pause();
}, function() {
if (!slider.manualpause && !slider.manualplay && !slider.stopped) slider.play();
});
}
// initialize animation
//if we're visible, or we don't use pagevisibility api
if(!slider.vars.pauseinvisible || !methods.pauseinvisible.ishidden()) {
(slider.vars.initdelay > 0) ? slider.starttimeout = settimeout(slider.play, slider.vars.initdelay) : slider.play();
}
}
// asnav:
if (asnav) methods.asnav.setup();
// touch
if (touch && slider.vars.touch) methods.touch();
// fade&&smoothheight || slide:
if (!fade || (fade && slider.vars.smoothheight)) $(window).bind("resize orientationchange focus", methods.resize);
slider.find("img").attr("draggable", "false");
// api: start() callback
settimeout(function(){
slider.vars.start(slider);
}, 200);
},
asnav: {
setup: function() {
slider.asnav = true;
slider.animatingto = math.floor(slider.currentslide/slider.move);
slider.currentitem = slider.currentslide;
slider.slides.removeclass(namespace + "active-slide").eq(slider.currentitem).addclass(namespace + "active-slide");
if(!msgesture){
slider.slides.on(eventtype, function(e){
e.preventdefault();
var $slide = $(this),
target = $slide.index();
var posfromleft = $slide.offset().left - $(slider).scrollleft(); // find position of slide relative to left of slider container
if( posfromleft <= 0 && $slide.hasclass( namespace + 'active-slide' ) ) {
slider.flexanimate(slider.gettarget("prev"), true);
} else if (!$(slider.vars.asnavfor).data('flexslider').animating && !$slide.hasclass(namespace + "active-slide")) {
slider.direction = (slider.currentitem < target) ? "next" : "prev";
slider.flexanimate(target, slider.vars.pauseonaction, false, true, true);
}
});
}else{
el._slider = slider;
slider.slides.each(function (){
var that = this;
that._gesture = new msgesture();
that._gesture.target = that;
that.addeventlistener("mspointerdown", function (e){
e.preventdefault();
if(e.currenttarget._gesture)
e.currenttarget._gesture.addpointer(e.pointerid);
}, false);
that.addeventlistener("msgesturetap", function (e){
e.preventdefault();
var $slide = $(this),
target = $slide.index();
if (!$(slider.vars.asnavfor).data('flexslider').animating && !$slide.hasclass('active')) {
slider.direction = (slider.currentitem < target) ? "next" : "prev";
slider.flexanimate(target, slider.vars.pauseonaction, false, true, true);
}
});
});
}
}
},
controlnav: {
setup: function() {
if (!slider.manualcontrols) {
methods.controlnav.setuppaging();
} else { // manualcontrols:
methods.controlnav.setupmanual();
}
},
setuppaging: function() {
var type = (slider.vars.controlnav === "thumbnails") ? 'control-thumbs' : 'control-paging',
j = 1,
item,
slide;
slider.controlnavscaffold = $('
');
if (slider.pagingcount > 1) {
for (var i = 0; i < slider.pagingcount; i++) {
slide = slider.slides.eq(i);
item = (slider.vars.controlnav === "thumbnails") ? '' : '' + j + '';
if ( 'thumbnails' === slider.vars.controlnav && true === slider.vars.thumbcaptions ) {
var captn = slide.attr( 'data-thumbcaption' );
if ( '' != captn && undefined != captn ) item += '' + captn + '';
}
slider.controlnavscaffold.append('' + item + '');
j++;
}
}
// controlscontainer:
(slider.controlscontainer) ? $(slider.controlscontainer).append(slider.controlnavscaffold) : slider.append(slider.controlnavscaffold);
methods.controlnav.set();
methods.controlnav.active();
slider.controlnavscaffold.delegate('a, img', eventtype, function(event) {
event.preventdefault();
if (watchedevent === "" || watchedevent === event.type) {
var $this = $(this),
target = slider.controlnav.index($this);
if (!$this.hasclass(namespace + 'active')) {
slider.direction = (target > slider.currentslide) ? "next" : "prev";
slider.flexanimate(target, slider.vars.pauseonaction);
}
}
// setup flags to prevent event duplication
if (watchedevent === "") {
watchedevent = event.type;
}
methods.settoclearwatchedevent();
});
},
setupmanual: function() {
slider.controlnav = slider.manualcontrols;
methods.controlnav.active();
slider.controlnav.bind(eventtype, function(event) {
event.preventdefault();
if (watchedevent === "" || watchedevent === event.type) {
var $this = $(this),
target = slider.controlnav.index($this);
if (!$this.hasclass(namespace + 'active')) {
(target > slider.currentslide) ? slider.direction = "next" : slider.direction = "prev";
slider.flexanimate(target, slider.vars.pauseonaction);
}
}
// setup flags to prevent event duplication
if (watchedevent === "") {
watchedevent = event.type;
}
methods.settoclearwatchedevent();
});
},
set: function() {
var selector = (slider.vars.controlnav === "thumbnails") ? 'img' : 'a';
slider.controlnav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlscontainer) ? slider.controlscontainer : slider);
},
active: function() {
slider.controlnav.removeclass(namespace + "active").eq(slider.animatingto).addclass(namespace + "active");
},
update: function(action, pos) {
if (slider.pagingcount > 1 && action === "add") {
slider.controlnavscaffold.append($('' + slider.count + ''));
} else if (slider.pagingcount === 1) {
slider.controlnavscaffold.find('li').remove();
} else {
slider.controlnav.eq(pos).closest('li').remove();
}
methods.controlnav.set();
(slider.pagingcount > 1 && slider.pagingcount !== slider.controlnav.length) ? slider.update(pos, action) : methods.controlnav.active();
}
},
directionnav: {
setup: function() {
var directionnavscaffold = $('');
// controlscontainer:
if (slider.controlscontainer) {
$(slider.controlscontainer).append(directionnavscaffold);
slider.directionnav = $('.' + namespace + 'direction-nav li a', slider.controlscontainer);
} else {
slider.append(directionnavscaffold);
slider.directionnav = $('.' + namespace + 'direction-nav li a', slider);
}
methods.directionnav.update();
slider.directionnav.bind(eventtype, function(event) {
event.preventdefault();
var target;
if (watchedevent === "" || watchedevent === event.type) {
target = ($(this).hasclass(namespace + 'next')) ? slider.gettarget('next') : slider.gettarget('prev');
slider.flexanimate(target, slider.vars.pauseonaction);
}
// setup flags to prevent event duplication
if (watchedevent === "") {
watchedevent = event.type;
}
methods.settoclearwatchedevent();
});
},
update: function() {
var disabledclass = namespace + 'disabled';
if (slider.pagingcount === 1) {
slider.directionnav.addclass(disabledclass).attr('tabindex', '-1');
} else if (!slider.vars.animationloop) {
if (slider.animatingto === 0) {
slider.directionnav.removeclass(disabledclass).filter('.' + namespace + "prev").addclass(disabledclass).attr('tabindex', '-1');
} else if (slider.animatingto === slider.last) {
slider.directionnav.removeclass(disabledclass).filter('.' + namespace + "next").addclass(disabledclass).attr('tabindex', '-1');
} else {
slider.directionnav.removeclass(disabledclass).removeattr('tabindex');
}
} else {
slider.directionnav.removeclass(disabledclass).removeattr('tabindex');
}
}
},
pauseplay: {
setup: function() {
var pauseplayscaffold = $('');
// controlscontainer:
if (slider.controlscontainer) {
slider.controlscontainer.append(pauseplayscaffold);
slider.pauseplay = $('.' + namespace + 'pauseplay a', slider.controlscontainer);
} else {
slider.append(pauseplayscaffold);
slider.pauseplay = $('.' + namespace + 'pauseplay a', slider);
}
methods.pauseplay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play');
slider.pauseplay.bind(eventtype, function(event) {
event.preventdefault();
if (watchedevent === "" || watchedevent === event.type) {
if ($(this).hasclass(namespace + 'pause')) {
slider.manualpause = true;
slider.manualplay = false;
slider.pause();
} else {
slider.manualpause = false;
slider.manualplay = true;
slider.play();
}
}
// setup flags to prevent event duplication
if (watchedevent === "") {
watchedevent = event.type;
}
methods.settoclearwatchedevent();
});
},
update: function(state) {
(state === "play") ? slider.pauseplay.removeclass(namespace + 'pause').addclass(namespace + 'play').html(slider.vars.playtext) : slider.pauseplay.removeclass(namespace + 'play').addclass(namespace + 'pause').html(slider.vars.pausetext);
}
},
touch: function() {
var startx,
starty,
offset,
cwidth,
dx,
startt,
scrolling = false,
localx = 0,
localy = 0,
accdx = 0;
if(!msgesture){
el.addeventlistener('touchstart', ontouchstart, false);
function ontouchstart(e) {
if (slider.animating) {
e.preventdefault();
} else if ( ( window.navigator.mspointerenabled ) || e.touches.length === 1 ) {
slider.pause();
// carousel:
cwidth = (vertical) ? slider.h : slider. w;
startt = number(new date());
// carousel:
// local vars for x and y points.
localx = e.touches[0].pagex;
localy = e.touches[0].pagey;
offset = (carousel && reverse && slider.animatingto === slider.last) ? 0 :
(carousel && reverse) ? slider.limit - (((slider.itemw + slider.vars.itemmargin) * slider.move) * slider.animatingto) :
(carousel && slider.currentslide === slider.last) ? slider.limit :
(carousel) ? ((slider.itemw + slider.vars.itemmargin) * slider.move) * slider.currentslide :
(reverse) ? (slider.last - slider.currentslide + slider.cloneoffset) * cwidth : (slider.currentslide + slider.cloneoffset) * cwidth;
startx = (vertical) ? localy : localx;
starty = (vertical) ? localx : localy;
el.addeventlistener('touchmove', ontouchmove, false);
el.addeventlistener('touchend', ontouchend, false);
}
}
function ontouchmove(e) {
// local vars for x and y points.
localx = e.touches[0].pagex;
localy = e.touches[0].pagey;
dx = (vertical) ? startx - localy : startx - localx;
scrolling = (vertical) ? (math.abs(dx) < math.abs(localx - starty)) : (math.abs(dx) < math.abs(localy - starty));
var fxms = 500;
if ( ! scrolling || number( new date() ) - startt > fxms ) {
e.preventdefault();
if (!fade && slider.transitions) {
if (!slider.vars.animationloop) {
dx = dx/((slider.currentslide === 0 && dx < 0 || slider.currentslide === slider.last && dx > 0) ? (math.abs(dx)/cwidth+2) : 1);
}
slider.setprops(offset + dx, "settouch");
}
}
}
function ontouchend(e) {
// finish the touch by undoing the touch session
el.removeeventlistener('touchmove', ontouchmove, false);
if (slider.animatingto === slider.currentslide && !scrolling && !(dx === null)) {
var updatedx = (reverse) ? -dx : dx,
target = (updatedx > 0) ? slider.gettarget('next') : slider.gettarget('prev');
if (slider.canadvance(target) && (number(new date()) - startt < 550 && math.abs(updatedx) > 50 || math.abs(updatedx) > cwidth/2)) {
slider.flexanimate(target, slider.vars.pauseonaction);
} else {
if (!fade) slider.flexanimate(slider.currentslide, slider.vars.pauseonaction, true);
}
}
el.removeeventlistener('touchend', ontouchend, false);
startx = null;
starty = null;
dx = null;
offset = null;
}
}else{
el.style.mstouchaction = "none";
el._gesture = new msgesture();
el._gesture.target = el;
el.addeventlistener("mspointerdown", onmspointerdown, false);
el._slider = slider;
el.addeventlistener("msgesturechange", onmsgesturechange, false);
el.addeventlistener("msgestureend", onmsgestureend, false);
function onmspointerdown(e){
e.stoppropagation();
if (slider.animating) {
e.preventdefault();
}else{
slider.pause();
el._gesture.addpointer(e.pointerid);
accdx = 0;
cwidth = (vertical) ? slider.h : slider. w;
startt = number(new date());
// carousel:
offset = (carousel && reverse && slider.animatingto === slider.last) ? 0 :
(carousel && reverse) ? slider.limit - (((slider.itemw + slider.vars.itemmargin) * slider.move) * slider.animatingto) :
(carousel && slider.currentslide === slider.last) ? slider.limit :
(carousel) ? ((slider.itemw + slider.vars.itemmargin) * slider.move) * slider.currentslide :
(reverse) ? (slider.last - slider.currentslide + slider.cloneoffset) * cwidth : (slider.currentslide + slider.cloneoffset) * cwidth;
}
}
function onmsgesturechange(e) {
e.stoppropagation();
var slider = e.target._slider;
if(!slider){
return;
}
var transx = -e.translationx,
transy = -e.translationy;
//accumulate translations.
accdx = accdx + ((vertical) ? transy : transx);
dx = accdx;
scrolling = (vertical) ? (math.abs(accdx) < math.abs(-transx)) : (math.abs(accdx) < math.abs(-transy));
if(e.detail === e.msgesture_flag_inertia){
setimmediate(function (){
el._gesture.stop();
});
return;
}
if (!scrolling || number(new date()) - startt > 500) {
e.preventdefault();
if (!fade && slider.transitions) {
if (!slider.vars.animationloop) {
dx = accdx / ((slider.currentslide === 0 && accdx < 0 || slider.currentslide === slider.last && accdx > 0) ? (math.abs(accdx) / cwidth + 2) : 1);
}
slider.setprops(offset + dx, "settouch");
}
}
}
function onmsgestureend(e) {
e.stoppropagation();
var slider = e.target._slider;
if(!slider){
return;
}
if (slider.animatingto === slider.currentslide && !scrolling && !(dx === null)) {
var updatedx = (reverse) ? -dx : dx,
target = (updatedx > 0) ? slider.gettarget('next') : slider.gettarget('prev');
if (slider.canadvance(target) && (number(new date()) - startt < 550 && math.abs(updatedx) > 50 || math.abs(updatedx) > cwidth/2)) {
slider.flexanimate(target, slider.vars.pauseonaction);
} else {
if (!fade) slider.flexanimate(slider.currentslide, slider.vars.pauseonaction, true);
}
}
startx = null;
starty = null;
dx = null;
offset = null;
accdx = 0;
}
}
},
resize: function() {
if (!slider.animating && slider.is(':visible')) {
if (!carousel) slider.domath();
if (fade) {
// smooth height:
methods.smoothheight();
} else if (carousel) { //carousel:
slider.slides.width(slider.computedw);
slider.update(slider.pagingcount);
slider.setprops();
}
else if (vertical) { //vertical:
slider.viewport.height(slider.h);
slider.setprops(slider.h, "settotal");
} else {
// smooth height:
if (slider.vars.smoothheight) methods.smoothheight();
slider.newslides.width(slider.computedw);
slider.setprops(slider.computedw, "settotal");
}
}
},
smoothheight: function(dur) {
if (!vertical || fade) {
var $obj = (fade) ? slider : slider.viewport;
(dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingto).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingto).height());
}
},
sync: function(action) {
var $obj = $(slider.vars.sync).data("flexslider"),
target = slider.animatingto;
switch (action) {
case "animate": $obj.flexanimate(target, slider.vars.pauseonaction, false, true); break;
case "play": if (!$obj.playing && !$obj.asnav) { $obj.play(); } break;
case "pause": $obj.pause(); break;
}
},
uniqueid: function($clone) {
// append _clone to current level and children elements with id attributes
$clone.filter( '[id]' ).add($clone.find( '[id]' )).each(function() {
var $this = $(this);
$this.attr( 'id', $this.attr( 'id' ) + '_clone' );
});
return $clone;
},
pauseinvisible: {
visprop: null,
init: function() {
var prefixes = ['webkit','moz','ms','o'];
if ('hidden' in document) return 'hidden';
for (var i = 0; i < prefixes.length; i++) {
if ((prefixes[i] + 'hidden') in document)
methods.pauseinvisible.visprop = prefixes[i] + 'hidden';
}
if (methods.pauseinvisible.visprop) {
var evtname = methods.pauseinvisible.visprop.replace(/[h|h]idden/,'') + 'visibilitychange';
document.addeventlistener(evtname, function() {
if (methods.pauseinvisible.ishidden()) {
if(slider.starttimeout) cleartimeout(slider.starttimeout); //if clock is ticking, stop timer and prevent from starting while invisible
else slider.pause(); //or just pause
}
else {
if(slider.started) slider.play(); //initiated before, just play
else (slider.vars.initdelay > 0) ? settimeout(slider.play, slider.vars.initdelay) : slider.play(); //didn't init before: simply init or wait for it
}
});
}
},
ishidden: function() {
return document[methods.pauseinvisible.visprop] || false;
}
},
settoclearwatchedevent: function() {
cleartimeout(watchedeventcleartimer);
watchedeventcleartimer = settimeout(function() {
watchedevent = "";
}, 3000);
}
};
// public methods
slider.flexanimate = function(target, pause, override, withsync, fromnav) {
if (!slider.vars.animationloop && target !== slider.currentslide) {
slider.direction = (target > slider.currentslide) ? "next" : "prev";
}
if (asnav && slider.pagingcount === 1) slider.direction = (slider.currentitem < target) ? "next" : "prev";
if (!slider.animating && (slider.canadvance(target, fromnav) || override) && slider.is(":visible")) {
if (asnav && withsync) {
var master = $(slider.vars.asnavfor).data('flexslider');
slider.atend = target === 0 || target === slider.count - 1;
master.flexanimate(target, true, false, true, fromnav);
slider.direction = (slider.currentitem < target) ? "next" : "prev";
master.direction = slider.direction;
if (math.ceil((target + 1)/slider.visible) - 1 !== slider.currentslide && target !== 0) {
slider.currentitem = target;
slider.slides.removeclass(namespace + "active-slide").eq(target).addclass(namespace + "active-slide");
target = math.floor(target/slider.visible);
} else {
slider.currentitem = target;
slider.slides.removeclass(namespace + "active-slide").eq(target).addclass(namespace + "active-slide");
return false;
}
}
slider.animating = true;
slider.animatingto = target;
// slideshow:
if (pause) slider.pause();
// api: before() animation callback
slider.vars.before(slider);
// sync:
if (slider.syncexists && !fromnav) methods.sync("animate");
// controlnav
if (slider.vars.controlnav) methods.controlnav.active();
// !carousel:
// candidate: slide active class (for add/remove slide)
if (!carousel) slider.slides.removeclass(namespace + 'active-slide').eq(target).addclass(namespace + 'active-slide');
// infinite loop:
// candidate: atend
slider.atend = target === 0 || target === slider.last;
// directionnav:
if (slider.vars.directionnav) methods.directionnav.update();
if (target === slider.last) {
// api: end() of cycle callback
slider.vars.end(slider);
// slideshow && !infinite loop:
if (!slider.vars.animationloop) slider.pause();
}
// slide:
if (!fade) {
var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedw,
margin, slidestring, calcnext;
// infinite loop / reverse:
if (carousel) {
//margin = (slider.vars.itemwidth > slider.w) ? slider.vars.itemmargin * 2 : slider.vars.itemmargin;
margin = slider.vars.itemmargin;
calcnext = ((slider.itemw + margin) * slider.move) * slider.animatingto;
slidestring = (calcnext > slider.limit && slider.visible !== 1) ? slider.limit : calcnext;
} else if (slider.currentslide === 0 && target === slider.count - 1 && slider.vars.animationloop && slider.direction !== "next") {
slidestring = (reverse) ? (slider.count + slider.cloneoffset) * dimension : 0;
} else if (slider.currentslide === slider.last && target === 0 && slider.vars.animationloop && slider.direction !== "prev") {
slidestring = (reverse) ? 0 : (slider.count + 1) * dimension;
} else {
slidestring = (reverse) ? ((slider.count - 1) - target + slider.cloneoffset) * dimension : (target + slider.cloneoffset) * dimension;
}
slider.setprops(slidestring, "", slider.vars.animationspeed);
if (slider.transitions) {
if (!slider.vars.animationloop || !slider.atend) {
slider.animating = false;
slider.currentslide = slider.animatingto;
}
// unbind previous transitionend events and re-bind new transitionend event
slider.container.unbind("webkittransitionend transitionend");
slider.container.bind("webkittransitionend transitionend", function() {
cleartimeout(slider.ensureanimationend);
slider.wrapup(dimension);
});
// insurance for the ever-so-fickle transitionend event
cleartimeout(slider.ensureanimationend);
slider.ensureanimationend = settimeout(function() {
slider.wrapup(dimension);
}, slider.vars.animationspeed + 100);
} else {
slider.container.animate(slider.args, slider.vars.animationspeed, slider.vars.easing, function(){
slider.wrapup(dimension);
});
}
} else { // fade:
if (!touch) {
//slider.slides.eq(slider.currentslide).fadeout(slider.vars.animationspeed, slider.vars.easing);
//slider.slides.eq(target).fadein(slider.vars.animationspeed, slider.vars.easing, slider.wrapup);
slider.slides.eq(slider.currentslide).css({"zindex": 1}).animate({"opacity": 0}, slider.vars.animationspeed, slider.vars.easing);
slider.slides.eq(target).css({"zindex": 2}).animate({"opacity": 1}, slider.vars.animationspeed, slider.vars.easing, slider.wrapup);
} else {
slider.slides.eq(slider.currentslide).css({ "opacity": 0, "zindex": 1 });
slider.slides.eq(target).css({ "opacity": 1, "zindex": 2 });
slider.wrapup(dimension);
}
}
// smooth height:
if (slider.vars.smoothheight) methods.smoothheight(slider.vars.animationspeed);
}
};
slider.wrapup = function(dimension) {
// slide:
if (!fade && !carousel) {
if (slider.currentslide === 0 && slider.animatingto === slider.last && slider.vars.animationloop) {
slider.setprops(dimension, "jumpend");
} else if (slider.currentslide === slider.last && slider.animatingto === 0 && slider.vars.animationloop) {
slider.setprops(dimension, "jumpstart");
}
}
slider.animating = false;
slider.currentslide = slider.animatingto;
// api: after() animation callback
slider.vars.after(slider);
};
// slideshow:
slider.animateslides = function() {
if (!slider.animating && focused ) slider.flexanimate(slider.gettarget("next"));
};
// slideshow:
slider.pause = function() {
clearinterval(slider.animatedslides);
slider.animatedslides = null;
slider.playing = false;
// pauseplay:
if (slider.vars.pauseplay) methods.pauseplay.update("play");
// sync:
if (slider.syncexists) methods.sync("pause");
};
// slideshow:
slider.play = function() {
if (slider.playing) clearinterval(slider.animatedslides);
slider.animatedslides = slider.animatedslides || setinterval(slider.animateslides, slider.vars.slideshowspeed);
slider.started = slider.playing = true;
// pauseplay:
if (slider.vars.pauseplay) methods.pauseplay.update("pause");
// sync:
if (slider.syncexists) methods.sync("play");
};
// stop:
slider.stop = function () {
slider.pause();
slider.stopped = true;
};
slider.canadvance = function(target, fromnav) {
// asnav:
var last = (asnav) ? slider.pagingcount - 1 : slider.last;
return (fromnav) ? true :
(asnav && slider.currentitem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true :
(asnav && slider.currentitem === 0 && target === slider.pagingcount - 1 && slider.direction !== "next") ? false :
(target === slider.currentslide && !asnav) ? false :
(slider.vars.animationloop) ? true :
(slider.atend && slider.currentslide === 0 && target === last && slider.direction !== "next") ? false :
(slider.atend && slider.currentslide === last && target === 0 && slider.direction === "next") ? false :
true;
};
slider.gettarget = function(dir) {
slider.direction = dir;
if (dir === "next") {
return (slider.currentslide === slider.last) ? 0 : slider.currentslide + 1;
} else {
return (slider.currentslide === 0) ? slider.last : slider.currentslide - 1;
}
};
// slide:
slider.setprops = function(pos, special, dur) {
var target = (function() {
var poscheck = (pos) ? pos : ((slider.itemw + slider.vars.itemmargin) * slider.move) * slider.animatingto,
poscalc = (function() {
if (carousel) {
return (special === "settouch") ? pos :
(reverse && slider.animatingto === slider.last) ? 0 :
(reverse) ? slider.limit - (((slider.itemw + slider.vars.itemmargin) * slider.move) * slider.animatingto) :
(slider.animatingto === slider.last) ? slider.limit : poscheck;
} else {
switch (special) {
case "settotal": return (reverse) ? ((slider.count - 1) - slider.currentslide + slider.cloneoffset) * pos : (slider.currentslide + slider.cloneoffset) * pos;
case "settouch": return (reverse) ? pos : pos;
case "jumpend": return (reverse) ? pos : slider.count * pos;
case "jumpstart": return (reverse) ? slider.count * pos : pos;
default: return pos;
}
}
}());
return (poscalc * -1) + "px";
}());
if (slider.transitions) {
target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)";
dur = (dur !== undefined) ? (dur/1000) + "s" : "0s";
slider.container.css("-" + slider.pfx + "-transition-duration", dur);
slider.container.css("transition-duration", dur);
}
slider.args[slider.prop] = target;
if (slider.transitions || dur === undefined) slider.container.css(slider.args);
slider.container.css('transform',target);
};
slider.setup = function(type) {
// slide:
if (!fade) {
var slideroffset, arr;
if (type === "init") {
slider.viewport = $('').css({"overflow": "hidden", "position": "relative"}).appendto(slider).append(slider.container);
// infinite loop:
slider.clonecount = 0;
slider.cloneoffset = 0;
// reverse:
if (reverse) {
arr = $.makearray(slider.slides).reverse();
slider.slides = $(arr);
slider.container.empty().append(slider.slides);
}
}
// infinite loop && !carousel:
if (slider.vars.animationloop && !carousel) {
slider.clonecount = 2;
slider.cloneoffset = 1;
// clear out old clones
if (type !== "init") slider.container.find('.clone').remove();
slider.container.append(methods.uniqueid(slider.slides.first().clone().addclass('clone')).attr('aria-hidden', 'true'))
.prepend(methods.uniqueid(slider.slides.last().clone().addclass('clone')).attr('aria-hidden', 'true'));
}
slider.newslides = $(slider.vars.selector, slider);
slideroffset = (reverse) ? slider.count - 1 - slider.currentslide + slider.cloneoffset : slider.currentslide + slider.cloneoffset;
// vertical:
if (vertical && !carousel) {
slider.container.height((slider.count + slider.clonecount) * 200 + "%").css("position", "absolute").width("100%");
settimeout(function(){
slider.newslides.css({"display": "block"});
slider.domath();
slider.viewport.height(slider.h);
slider.setprops(slideroffset * slider.h, "init");
}, (type === "init") ? 100 : 0);
} else {
slider.container.width((slider.count + slider.clonecount) * 200 + "%");
slider.setprops(slideroffset * slider.computedw, "init");
settimeout(function(){
slider.domath();
slider.newslides.css({"width": slider.computedw, "float": "left", "display": "block"});
// smooth height:
if (slider.vars.smoothheight) methods.smoothheight();
}, (type === "init") ? 100 : 0);
}
} else { // fade:
slider.slides.css({"width": "100%", "float": "left", "marginright": "-100%", "position": "relative"});
if (type === "init") {
if (!touch) {
//slider.slides.eq(slider.currentslide).fadein(slider.vars.animationspeed, slider.vars.easing);
if (slider.vars.fadefirstslide == false) {
slider.slides.css({ "opacity": 0, "display": "block", "zindex": 1 }).eq(slider.currentslide).css({"zindex": 2}).css({"opacity": 1});
} else {
slider.slides.css({ "opacity": 0, "display": "block", "zindex": 1 }).eq(slider.currentslide).css({"zindex": 2}).animate({"opacity": 1},slider.vars.animationspeed,slider.vars.easing);
}
} else {
slider.slides.css({ "opacity": 0, "display": "block", "webkittransition": "opacity " + slider.vars.animationspeed / 1000 + "s ease", "zindex": 1 }).eq(slider.currentslide).css({ "opacity": 1, "zindex": 2});
}
}
// smooth height:
if (slider.vars.smoothheight) methods.smoothheight();
}
// !carousel:
// candidate: active slide
if (!carousel) slider.slides.removeclass(namespace + "active-slide").eq(slider.currentslide).addclass(namespace + "active-slide");
//flexslider: init() callback
slider.vars.init(slider);
};
slider.domath = function() {
var slide = slider.slides.first(),
slidemargin = slider.vars.itemmargin,
minitems = slider.vars.minitems,
maxitems = slider.vars.maxitems;
slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width();
slider.h = slide.height();
slider.boxpadding = slide.outerwidth() - slide.width();
// carousel:
if (carousel) {
slider.itemt = slider.vars.itemwidth + slidemargin;
slider.minw = (minitems) ? minitems * slider.itemt : slider.w;
slider.maxw = (maxitems) ? (maxitems * slider.itemt) - slidemargin : slider.w;
slider.itemw = (slider.minw > slider.w) ? (slider.w - (slidemargin * (minitems - 1)))/minitems :
(slider.maxw < slider.w) ? (slider.w - (slidemargin * (maxitems - 1)))/maxitems :
(slider.vars.itemwidth > slider.w) ? slider.w : slider.vars.itemwidth;
slider.visible = math.floor(slider.w/(slider.itemw));
slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible;
slider.pagingcount = math.ceil(((slider.count - slider.visible)/slider.move) + 1);
slider.last = slider.pagingcount - 1;
slider.limit = (slider.pagingcount === 1) ? 0 :
(slider.vars.itemwidth > slider.w) ? (slider.itemw * (slider.count - 1)) + (slidemargin * (slider.count - 1)) : ((slider.itemw + slidemargin) * slider.count) - slider.w - slidemargin;
} else {
slider.itemw = slider.w;
slider.pagingcount = slider.count;
slider.last = slider.count - 1;
}
slider.computedw = slider.itemw - slider.boxpadding;
};
slider.update = function(pos, action) {
slider.domath();
// update currentslide and slider.animatingto if necessary
if (!carousel) {
if (pos < slider.currentslide) {
slider.currentslide += 1;
} else if (pos <= slider.currentslide && pos !== 0) {
slider.currentslide -= 1;
}
slider.animatingto = slider.currentslide;
}
// update controlnav
if (slider.vars.controlnav && !slider.manualcontrols) {
if ((action === "add" && !carousel) || slider.pagingcount > slider.controlnav.length) {
methods.controlnav.update("add");
} else if ((action === "remove" && !carousel) || slider.pagingcount < slider.controlnav.length) {
if (carousel && slider.currentslide > slider.last) {
slider.currentslide -= 1;
slider.animatingto -= 1;
}
methods.controlnav.update("remove", slider.last);
}
}
// update directionnav
if (slider.vars.directionnav) methods.directionnav.update();
};
slider.addslide = function(obj, pos) {
var $obj = $(obj);
slider.count += 1;
slider.last = slider.count - 1;
// append new slide
if (vertical && reverse) {
(pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj);
} else {
(pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj);
}
// update currentslide, animatingto, controlnav, and directionnav
slider.update(pos, "add");
// update slider.slides
slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
// re-setup the slider to accomdate new slide
slider.setup();
//flexslider: added() callback
slider.vars.added(slider);
};
slider.removeslide = function(obj) {
var pos = (isnan(obj)) ? slider.slides.index($(obj)) : obj;
// update count
slider.count -= 1;
slider.last = slider.count - 1;
// remove slide
if (isnan(obj)) {
$(obj, slider.slides).remove();
} else {
(vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove();
}
// update currentslide, animatingto, controlnav, and directionnav
slider.domath();
slider.update(pos, "remove");
// update slider.slides
slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
// re-setup the slider to accomdate new slide
slider.setup();
// flexslider: removed() callback
slider.vars.removed(slider);
};
//flexslider: initialize
methods.init();
};
// ensure the slider isn't focussed if the window loses focus.
$( window ).blur( function ( e ) {
focused = false;
}).focus( function ( e ) {
focused = true;
});
//flexslider: default settings
$.flexslider.defaults = {
namespace: "flex-", //{new} string: prefix string attached to the class of every element generated by the plugin
selector: ".slides > li", //{new} selector: must match a simple pattern. '{container} > {slide}' -- ignore pattern at your own peril
animation: "fade", //string: select your animation type, "fade" or "slide"
easing: "swing", //{new} string: determines the easing method used in jquery transitions. jquery easing plugin is supported!
direction: "horizontal", //string: select the sliding direction, "horizontal" or "vertical"
reverse: false, //{new} boolean: reverse the animation direction
animationloop: true, //boolean: should the animation loop? if false, directionnav will received "disable" classes at either end
smoothheight: false, //{new} boolean: allow height of the slider to animate smoothly in horizontal mode
startat: 0, //integer: the slide that the slider should start on. array notation (0 = first slide)
slideshow: true, //boolean: animate slider automatically
slideshowspeed: 7000, //integer: set the speed of the slideshow cycling, in milliseconds
animationspeed: 600, //integer: set the speed of animations, in milliseconds
initdelay: 0, //{new} integer: set an initialization delay, in milliseconds
randomize: false, //boolean: randomize slide order
fadefirstslide: true, //boolean: fade in the first slide when animation type is "fade"
thumbcaptions: false, //boolean: whether or not to put captions on thumbnails when using the "thumbnails" controlnav.
// usability features
pauseonaction: true, //boolean: pause the slideshow when interacting with control elements, highly recommended.
pauseonhover: false, //boolean: pause the slideshow when hovering over slider, then resume when no longer hovering
pauseinvisible: true, //{new} boolean: pause the slideshow when tab is invisible, resume when visible. provides better ux, lower cpu usage.
usecss: true, //{new} boolean: slider will use css3 transitions if available
touch: true, //{new} boolean: allow touch swipe navigation of the slider on touch-enabled devices
video: false, //{new} boolean: if using video in the slider, will prevent css3 3d transforms to avoid graphical glitches
// primary controls
controlnav: true, //boolean: create navigation for paging control of each slide? note: leave true for manualcontrols usage
directionnav: true, //boolean: create navigation for previous/next navigation? (true/false)
prevtext: "previous", //string: set the text for the "previous" directionnav item
nexttext: "next", //string: set the text for the "next" directionnav item
// secondary navigation
keyboard: true, //boolean: allow slider navigating via keyboard left/right keys
multiplekeyboard: false, //{new} boolean: allow keyboard navigation to affect multiple sliders. default behavior cuts out keyboard navigation with more than one slider present.
mousewheel: false, //{updated} boolean: requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - allows slider navigating via mousewheel
pauseplay: false, //boolean: create pause/play dynamic element
pausetext: "pause", //string: set the text for the "pause" pauseplay item
playtext: "play", //string: set the text for the "play" pauseplay item
// special properties
controlscontainer: "", //{updated} jquery object/selector: declare which container the navigation elements should be appended too. default container is the flexslider element. example use would be $(".flexslider-container"). property is ignored if given element is not found.
manualcontrols: "", //{updated} jquery object/selector: declare custom control navigation. examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. the number of elements in your controlnav should match the number of slides/tabs.
sync: "", //{new} selector: mirror the actions performed on this slider with another slider. use with care.
asnavfor: "", //{new} selector: internal property exposed for turning the slider into a thumbnail navigation for another slider
// carousel options
itemwidth: 0, //{new} integer: box-model width of individual carousel items, including horizontal borders and padding.
itemmargin: 0, //{new} integer: margin between carousel items.
minitems: 1, //{new} integer: minimum number of carousel items that should be visible. items will resize fluidly when below this.
maxitems: 0, //{new} integer: maxmimum number of carousel items that should be visible. items will resize fluidly when above this limit.
move: 0, //{new} integer: number of carousel items that should move on animation. if 0, slider will move all visible items.
allowoneslide: true, //{new} boolean: whether or not to allow a slider comprised of a single slide
// callback api
start: function(){}, //callback: function(slider) - fires when the slider loads the first slide
before: function(){}, //callback: function(slider) - fires asynchronously with each slider animation
after: function(){}, //callback: function(slider) - fires after each slider animation completes
end: function(){}, //callback: function(slider) - fires when the slider reaches the last slide (asynchronous)
added: function(){}, //{new} callback: function(slider) - fires after a slide is added
removed: function(){}, //{new} callback: function(slider) - fires after a slide is removed
init: function() {} //{new} callback: function(slider) - fires after the slider is initially setup
};
//flexslider: plugin function
$.fn.flexslider = function(options) {
if (options === undefined) options = {};
if (typeof options === "object") {
return this.each(function() {
var $this = $(this),
selector = (options.selector) ? options.selector : ".slides > li",
$slides = $this.find(selector);
if ( ( $slides.length === 1 && options.allowoneslide === true ) || $slides.length === 0 ) {
$slides.fadein(400);
if (options.start) options.start($this);
} else if ($this.data('flexslider') === undefined) {
new $.flexslider(this, options);
}
});
} else {
// helper strings to quickly perform functions on the slider
var $slider = $(this).data('flexslider');
switch (options) {
case "play": $slider.play(); break;
case "pause": $slider.pause(); break;
case "stop": $slider.stop(); break;
case "next": $slider.flexanimate($slider.gettarget("next"), true); break;
case "prev":
case "previous": $slider.flexanimate($slider.gettarget("prev"), true); break;
default: if (typeof options === "number") $slider.flexanimate(options, true);
}
}
};
})(jquery);