changeset 5:c69a71b4f40f

Add slideshow module
author Chris Cannam
date Thu, 07 Dec 2017 14:46:23 +0000
parents 8948ab6c87d2
children 875880e46745
files libraries/jquery.cycle/jquery.cycle.all.js libraries/jquery.hoverIntent/jquery.hoverIntent.js libraries/jquery.pause/jquery.pause.js libraries/json2/json2.js modules/contrib/views_slideshow/LICENSE.txt modules/contrib/views_slideshow/README.txt modules/contrib/views_slideshow/composer.json modules/contrib/views_slideshow/config/schema/views.style.slideshow.schema.yml modules/contrib/views_slideshow/config/schema/views_slideshow.data_types.schema.yml modules/contrib/views_slideshow/css/controls_text.css modules/contrib/views_slideshow/css/views-slideshow-pager-bullets.css modules/contrib/views_slideshow/css/views_slideshow.css modules/contrib/views_slideshow/js/views_slideshow.js modules/contrib/views_slideshow/modules/views_slideshow_cycle/css/views_slideshow_cycle.css modules/contrib/views_slideshow/modules/views_slideshow_cycle/drush.services.yml modules/contrib/views_slideshow/modules/views_slideshow_cycle/js/formoptions.js modules/contrib/views_slideshow/modules/views_slideshow_cycle/js/views_slideshow_cycle.js modules/contrib/views_slideshow/modules/views_slideshow_cycle/src/Commands/ViewsSlideshowCycleCommands.php modules/contrib/views_slideshow/modules/views_slideshow_cycle/src/Plugin/ViewsSlideshowType/Cycle.php modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle-main-frame-row-item.html.twig modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle-main-frame-row.html.twig modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle-main-frame.html.twig modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle.html.twig modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.drush.inc modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.info.yml modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.libraries.yml modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.module modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.theme.inc modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowSkin.php modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowType.php modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowWidget.php modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowWidgetType.php modules/contrib/views_slideshow/src/FormatAddonsName.php modules/contrib/views_slideshow/src/FormatAddonsNameInterface.php modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowSkin/DefaultSkin.php modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidget/ControlsText.php modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidget/PagerBullets.php modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidget/PagerFields.php modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidgetType/Controls.php modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidgetType/Counter.php modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidgetType/Pager.php modules/contrib/views_slideshow/src/Plugin/views/style/Slideshow.php modules/contrib/views_slideshow/src/Tests/Plugin/StyleSlideshowTest.php modules/contrib/views_slideshow/src/ViewsSlideshowSkinBase.php modules/contrib/views_slideshow/src/ViewsSlideshowSkinInterface.php modules/contrib/views_slideshow/src/ViewsSlideshowSkinPluginManager.php modules/contrib/views_slideshow/src/ViewsSlideshowTypeBase.php modules/contrib/views_slideshow/src/ViewsSlideshowTypeInterface.php modules/contrib/views_slideshow/src/ViewsSlideshowTypePluginManager.php modules/contrib/views_slideshow/src/ViewsSlideshowWidgetBase.php modules/contrib/views_slideshow/src/ViewsSlideshowWidgetInterface.php modules/contrib/views_slideshow/src/ViewsSlideshowWidgetPluginManager.php modules/contrib/views_slideshow/src/ViewsSlideshowWidgetTypeBase.php modules/contrib/views_slideshow/src/ViewsSlideshowWidgetTypeInterface.php modules/contrib/views_slideshow/src/ViewsSlideshowWidgetTypePluginManager.php modules/contrib/views_slideshow/templates/views-slideshow-controls-text-next.html.twig modules/contrib/views_slideshow/templates/views-slideshow-controls-text-pause.html.twig modules/contrib/views_slideshow/templates/views-slideshow-controls-text-previous.html.twig modules/contrib/views_slideshow/templates/views-slideshow-controls-text.html.twig modules/contrib/views_slideshow/templates/views-slideshow-main-section.html.twig modules/contrib/views_slideshow/templates/views-slideshow-pager-bullets.html.twig modules/contrib/views_slideshow/templates/views-slideshow-pager-field-field.html.twig modules/contrib/views_slideshow/templates/views-slideshow-pager-field-item.html.twig modules/contrib/views_slideshow/templates/views-slideshow-pager-fields.html.twig modules/contrib/views_slideshow/templates/views-slideshow-slide-counter.html.twig modules/contrib/views_slideshow/templates/views-view-slideshow.html.twig modules/contrib/views_slideshow/tests/modules/views_slideshow_test/test_views/views.view.test_style_slideshow.yml modules/contrib/views_slideshow/tests/modules/views_slideshow_test/views_slideshow_test.info.yml modules/contrib/views_slideshow/views_slideshow.developer-documentation.php modules/contrib/views_slideshow/views_slideshow.info.yml modules/contrib/views_slideshow/views_slideshow.libraries.yml modules/contrib/views_slideshow/views_slideshow.module modules/contrib/views_slideshow/views_slideshow.services.yml modules/contrib/views_slideshow/views_slideshow.theme.inc sites/default/files/color/isobartik-e35cfd6a/colors.css sites/default/files/color/isobartik-e35cfd6a/logo.svg
diffstat 76 files changed, 8096 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/jquery.cycle/jquery.cycle.all.js	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,1543 @@
+/*!
+ * jQuery Cycle Plugin (with Transition Definitions)
+ * Examples and documentation at: http://jquery.malsup.com/cycle/
+ * Copyright (c) 2007-2013 M. Alsup
+ * Version: 3.0.3 (11-JUL-2013)
+ * Dual licensed under the MIT and GPL licenses.
+ * http://jquery.malsup.com/license.html
+ * Requires: jQuery v1.7.1 or later
+ */
+;(function($, undefined) {
+"use strict";
+
+var ver = '3.0.3';
+
+function debug(s) {
+	if ($.fn.cycle.debug)
+		log(s);
+}		
+function log() {
+	/*global console */
+	if (window.console && console.log)
+		console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
+}
+$.expr[':'].paused = function(el) {
+	return el.cyclePause;
+};
+
+
+// the options arg can be...
+//   a number  - indicates an immediate transition should occur to the given slide index
+//   a string  - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc)
+//   an object - properties to control the slideshow
+//
+// the arg2 arg can be...
+//   the name of an fx (only used in conjunction with a numeric value for 'options')
+//   the value true (only used in first arg == 'resume') and indicates
+//	 that the resume should occur immediately (not wait for next timeout)
+
+$.fn.cycle = function(options, arg2) {
+	var o = { s: this.selector, c: this.context };
+
+	// in 1.3+ we can fix mistakes with the ready state
+	if (this.length === 0 && options != 'stop') {
+		if (!$.isReady && o.s) {
+			log('DOM not ready, queuing slideshow');
+			$(function() {
+				$(o.s,o.c).cycle(options,arg2);
+			});
+			return this;
+		}
+		// is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
+		log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
+		return this;
+	}
+
+	// iterate the matched nodeset
+	return this.each(function() {
+		var opts = handleArguments(this, options, arg2);
+		if (opts === false)
+			return;
+
+		opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;
+		
+		// stop existing slideshow for this container (if there is one)
+		if (this.cycleTimeout)
+			clearTimeout(this.cycleTimeout);
+		this.cycleTimeout = this.cyclePause = 0;
+		this.cycleStop = 0; // issue #108
+
+		var $cont = $(this);
+		var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
+		var els = $slides.get();
+
+		if (els.length < 2) {
+			log('terminating; too few slides: ' + els.length);
+			return;
+		}
+
+		var opts2 = buildOptions($cont, $slides, els, opts, o);
+		if (opts2 === false)
+			return;
+
+		var startTime = opts2.continuous ? 10 : getTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards);
+
+		// if it's an auto slideshow, kick it off
+		if (startTime) {
+			startTime += (opts2.delay || 0);
+			if (startTime < 10)
+				startTime = 10;
+			debug('first timeout: ' + startTime);
+			this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts.backwards);}, startTime);
+		}
+	});
+};
+
+function triggerPause(cont, byHover, onPager) {
+	var opts = $(cont).data('cycle.opts');
+	if (!opts)
+		return;
+	var paused = !!cont.cyclePause;
+	if (paused && opts.paused)
+		opts.paused(cont, opts, byHover, onPager);
+	else if (!paused && opts.resumed)
+		opts.resumed(cont, opts, byHover, onPager);
+}
+
+// process the args that were passed to the plugin fn
+function handleArguments(cont, options, arg2) {
+	if (cont.cycleStop === undefined)
+		cont.cycleStop = 0;
+	if (options === undefined || options === null)
+		options = {};
+	if (options.constructor == String) {
+		switch(options) {
+		case 'destroy':
+		case 'stop':
+			var opts = $(cont).data('cycle.opts');
+			if (!opts)
+				return false;
+			cont.cycleStop++; // callbacks look for change
+			if (cont.cycleTimeout)
+				clearTimeout(cont.cycleTimeout);
+			cont.cycleTimeout = 0;
+			if (opts.elements)
+				$(opts.elements).stop();
+			$(cont).removeData('cycle.opts');
+			if (options == 'destroy')
+				destroy(cont, opts);
+			return false;
+		case 'toggle':
+			cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1;
+			checkInstantResume(cont.cyclePause, arg2, cont);
+			triggerPause(cont);
+			return false;
+		case 'pause':
+			cont.cyclePause = 1;
+			triggerPause(cont);
+			return false;
+		case 'resume':
+			cont.cyclePause = 0;
+			checkInstantResume(false, arg2, cont);
+			triggerPause(cont);
+			return false;
+		case 'prev':
+		case 'next':
+			opts = $(cont).data('cycle.opts');
+			if (!opts) {
+				log('options not found, "prev/next" ignored');
+				return false;
+			}
+			if (typeof arg2 == 'string') 
+				opts.oneTimeFx = arg2;
+			$.fn.cycle[options](opts);
+			return false;
+		default:
+			options = { fx: options };
+		}
+		return options;
+	}
+	else if (options.constructor == Number) {
+		// go to the requested slide
+		var num = options;
+		options = $(cont).data('cycle.opts');
+		if (!options) {
+			log('options not found, can not advance slide');
+			return false;
+		}
+		if (num < 0 || num >= options.elements.length) {
+			log('invalid slide index: ' + num);
+			return false;
+		}
+		options.nextSlide = num;
+		if (cont.cycleTimeout) {
+			clearTimeout(cont.cycleTimeout);
+			cont.cycleTimeout = 0;
+		}
+		if (typeof arg2 == 'string')
+			options.oneTimeFx = arg2;
+		go(options.elements, options, 1, num >= options.currSlide);
+		return false;
+	}
+	return options;
+	
+	function checkInstantResume(isPaused, arg2, cont) {
+		if (!isPaused && arg2 === true) { // resume now!
+			var options = $(cont).data('cycle.opts');
+			if (!options) {
+				log('options not found, can not resume');
+				return false;
+			}
+			if (cont.cycleTimeout) {
+				clearTimeout(cont.cycleTimeout);
+				cont.cycleTimeout = 0;
+			}
+			go(options.elements, options, 1, !options.backwards);
+		}
+	}
+}
+
+function removeFilter(el, opts) {
+	if (!$.support.opacity && opts.cleartype && el.style.filter) {
+		try { el.style.removeAttribute('filter'); }
+		catch(smother) {} // handle old opera versions
+	}
+}
+
+// unbind event handlers
+function destroy(cont, opts) {
+	if (opts.next)
+		$(opts.next).unbind(opts.prevNextEvent);
+	if (opts.prev)
+		$(opts.prev).unbind(opts.prevNextEvent);
+	
+	if (opts.pager || opts.pagerAnchorBuilder)
+		$.each(opts.pagerAnchors || [], function() {
+			this.unbind().remove();
+		});
+	opts.pagerAnchors = null;
+	$(cont).unbind('mouseenter.cycle mouseleave.cycle');
+	if (opts.destroy) // callback
+		opts.destroy(opts);
+}
+
+// one-time initialization
+function buildOptions($cont, $slides, els, options, o) {
+	var startingSlideSpecified;
+	// support metadata plugin (v1.0 and v2.0)
+	var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {});
+	var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null;
+	if (meta)
+		opts = $.extend(opts, meta);
+	if (opts.autostop)
+		opts.countdown = opts.autostopCount || els.length;
+
+	var cont = $cont[0];
+	$cont.data('cycle.opts', opts);
+	opts.$cont = $cont;
+	opts.stopCount = cont.cycleStop;
+	opts.elements = els;
+	opts.before = opts.before ? [opts.before] : [];
+	opts.after = opts.after ? [opts.after] : [];
+
+	// push some after callbacks
+	if (!$.support.opacity && opts.cleartype)
+		opts.after.push(function() { removeFilter(this, opts); });
+	if (opts.continuous)
+		opts.after.push(function() { go(els,opts,0,!opts.backwards); });
+
+	saveOriginalOpts(opts);
+
+	// clearType corrections
+	if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
+		clearTypeFix($slides);
+
+	// container requires non-static position so that slides can be position within
+	if ($cont.css('position') == 'static')
+		$cont.css('position', 'relative');
+	if (opts.width)
+		$cont.width(opts.width);
+	if (opts.height && opts.height != 'auto')
+		$cont.height(opts.height);
+
+	if (opts.startingSlide !== undefined) {
+		opts.startingSlide = parseInt(opts.startingSlide,10);
+		if (opts.startingSlide >= els.length || opts.startSlide < 0)
+			opts.startingSlide = 0; // catch bogus input
+		else 
+			startingSlideSpecified = true;
+	}
+	else if (opts.backwards)
+		opts.startingSlide = els.length - 1;
+	else
+		opts.startingSlide = 0;
+
+	// if random, mix up the slide array
+	if (opts.random) {
+		opts.randomMap = [];
+		for (var i = 0; i < els.length; i++)
+			opts.randomMap.push(i);
+		opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
+		if (startingSlideSpecified) {
+			// try to find the specified starting slide and if found set start slide index in the map accordingly
+			for ( var cnt = 0; cnt < els.length; cnt++ ) {
+				if ( opts.startingSlide == opts.randomMap[cnt] ) {
+					opts.randomIndex = cnt;
+				}
+			}
+		}
+		else {
+			opts.randomIndex = 1;
+			opts.startingSlide = opts.randomMap[1];
+		}
+	}
+	else if (opts.startingSlide >= els.length)
+		opts.startingSlide = 0; // catch bogus input
+	opts.currSlide = opts.startingSlide || 0;
+	var first = opts.startingSlide;
+
+	// set position and zIndex on all the slides
+	$slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
+		var z;
+		if (opts.backwards)
+			z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i;
+		else
+			z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
+		$(this).css('z-index', z);
+	});
+
+	// make sure first slide is visible
+	$(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case
+	removeFilter(els[first], opts);
+
+	// stretch slides
+	if (opts.fit) {
+		if (!opts.aspect) {
+	        if (opts.width)
+	            $slides.width(opts.width);
+	        if (opts.height && opts.height != 'auto')
+	            $slides.height(opts.height);
+		} else {
+			$slides.each(function(){
+				var $slide = $(this);
+				var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect;
+				if( opts.width && $slide.width() != opts.width ) {
+					$slide.width( opts.width );
+					$slide.height( opts.width / ratio );
+				}
+
+				if( opts.height && $slide.height() < opts.height ) {
+					$slide.height( opts.height );
+					$slide.width( opts.height * ratio );
+				}
+			});
+		}
+	}
+
+	if (opts.center && ((!opts.fit) || opts.aspect)) {
+		$slides.each(function(){
+			var $slide = $(this);
+			$slide.css({
+				"margin-left": opts.width ?
+					((opts.width - $slide.width()) / 2) + "px" :
+					0,
+				"margin-top": opts.height ?
+					((opts.height - $slide.height()) / 2) + "px" :
+					0
+			});
+		});
+	}
+
+	if (opts.center && !opts.fit && !opts.slideResize) {
+		$slides.each(function(){
+			var $slide = $(this);
+			$slide.css({
+				"margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0,
+				"margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0
+			});
+		});
+	}
+		
+	// stretch container
+	var reshape = (opts.containerResize || opts.containerResizeHeight) && $cont.innerHeight() < 1;
+	if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
+		var maxw = 0, maxh = 0;
+		for(var j=0; j < els.length; j++) {
+			var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight();
+			if (!w) w = e.offsetWidth || e.width || $e.attr('width');
+			if (!h) h = e.offsetHeight || e.height || $e.attr('height');
+			maxw = w > maxw ? w : maxw;
+			maxh = h > maxh ? h : maxh;
+		}
+		if (opts.containerResize && maxw > 0 && maxh > 0)
+			$cont.css({width:maxw+'px',height:maxh+'px'});
+		if (opts.containerResizeHeight && maxh > 0)
+			$cont.css({height:maxh+'px'});
+	}
+
+	var pauseFlag = false;  // https://github.com/malsup/cycle/issues/44
+	if (opts.pause)
+		$cont.bind('mouseenter.cycle', function(){
+			pauseFlag = true;
+			this.cyclePause++;
+			triggerPause(cont, true);
+		}).bind('mouseleave.cycle', function(){
+				if (pauseFlag)
+					this.cyclePause--;
+				triggerPause(cont, true);
+		});
+
+	if (supportMultiTransitions(opts) === false)
+		return false;
+
+	// apparently a lot of people use image slideshows without height/width attributes on the images.
+	// Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that.
+	var requeue = false;
+	options.requeueAttempts = options.requeueAttempts || 0;
+	$slides.each(function() {
+		// try to get height/width of each slide
+		var $el = $(this);
+		this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0);
+		this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0);
+
+		if ( $el.is('img') ) {
+			var loading = (this.cycleH === 0 && this.cycleW === 0 && !this.complete);
+			// don't requeue for images that are still loading but have a valid size
+			if (loading) {
+				if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever
+					log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH);
+					setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout);
+					requeue = true;
+					return false; // break each loop
+				}
+				else {
+					log('could not determine size of image: '+this.src, this.cycleW, this.cycleH);
+				}
+			}
+		}
+		return true;
+	});
+
+	if (requeue)
+		return false;
+
+	opts.cssBefore = opts.cssBefore || {};
+	opts.cssAfter = opts.cssAfter || {};
+	opts.cssFirst = opts.cssFirst || {};
+	opts.animIn = opts.animIn || {};
+	opts.animOut = opts.animOut || {};
+
+	$slides.not(':eq('+first+')').css(opts.cssBefore);
+	$($slides[first]).css(opts.cssFirst);
+
+	if (opts.timeout) {
+		opts.timeout = parseInt(opts.timeout,10);
+		// ensure that timeout and speed settings are sane
+		if (opts.speed.constructor == String)
+			opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10);
+		if (!opts.sync)
+			opts.speed = opts.speed / 2;
+		
+		var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250;
+		while((opts.timeout - opts.speed) < buffer) // sanitize timeout
+			opts.timeout += opts.speed;
+	}
+	if (opts.easing)
+		opts.easeIn = opts.easeOut = opts.easing;
+	if (!opts.speedIn)
+		opts.speedIn = opts.speed;
+	if (!opts.speedOut)
+		opts.speedOut = opts.speed;
+
+	opts.slideCount = els.length;
+	opts.currSlide = opts.lastSlide = first;
+	if (opts.random) {
+		if (++opts.randomIndex == els.length)
+			opts.randomIndex = 0;
+		opts.nextSlide = opts.randomMap[opts.randomIndex];
+	}
+	else if (opts.backwards)
+		opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1;
+	else
+		opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1;
+
+	// run transition init fn
+	if (!opts.multiFx) {
+		var init = $.fn.cycle.transitions[opts.fx];
+		if ($.isFunction(init))
+			init($cont, $slides, opts);
+		else if (opts.fx != 'custom' && !opts.multiFx) {
+			log('unknown transition: ' + opts.fx,'; slideshow terminating');
+			return false;
+		}
+	}
+
+	// fire artificial events
+	var e0 = $slides[first];
+	if (!opts.skipInitializationCallbacks) {
+		if (opts.before.length)
+			opts.before[0].apply(e0, [e0, e0, opts, true]);
+		if (opts.after.length)
+			opts.after[0].apply(e0, [e0, e0, opts, true]);
+	}
+	if (opts.next)
+		$(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);});
+	if (opts.prev)
+		$(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);});
+	if (opts.pager || opts.pagerAnchorBuilder)
+		buildPager(els,opts);
+
+	exposeAddSlide(opts, els);
+
+	return opts;
+}
+
+// save off original opts so we can restore after clearing state
+function saveOriginalOpts(opts) {
+	opts.original = { before: [], after: [] };
+	opts.original.cssBefore = $.extend({}, opts.cssBefore);
+	opts.original.cssAfter  = $.extend({}, opts.cssAfter);
+	opts.original.animIn	= $.extend({}, opts.animIn);
+	opts.original.animOut   = $.extend({}, opts.animOut);
+	$.each(opts.before, function() { opts.original.before.push(this); });
+	$.each(opts.after,  function() { opts.original.after.push(this); });
+}
+
+function supportMultiTransitions(opts) {
+	var i, tx, txs = $.fn.cycle.transitions;
+	// look for multiple effects
+	if (opts.fx.indexOf(',') > 0) {
+		opts.multiFx = true;
+		opts.fxs = opts.fx.replace(/\s*/g,'').split(',');
+		// discard any bogus effect names
+		for (i=0; i < opts.fxs.length; i++) {
+			var fx = opts.fxs[i];
+			tx = txs[fx];
+			if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) {
+				log('discarding unknown transition: ',fx);
+				opts.fxs.splice(i,1);
+				i--;
+			}
+		}
+		// if we have an empty list then we threw everything away!
+		if (!opts.fxs.length) {
+			log('No valid transitions named; slideshow terminating.');
+			return false;
+		}
+	}
+	else if (opts.fx == 'all') {  // auto-gen the list of transitions
+		opts.multiFx = true;
+		opts.fxs = [];
+		for (var p in txs) {
+			if (txs.hasOwnProperty(p)) {
+				tx = txs[p];
+				if (txs.hasOwnProperty(p) && $.isFunction(tx))
+					opts.fxs.push(p);
+			}
+		}
+	}
+	if (opts.multiFx && opts.randomizeEffects) {
+		// munge the fxs array to make effect selection random
+		var r1 = Math.floor(Math.random() * 20) + 30;
+		for (i = 0; i < r1; i++) {
+			var r2 = Math.floor(Math.random() * opts.fxs.length);
+			opts.fxs.push(opts.fxs.splice(r2,1)[0]);
+		}
+		debug('randomized fx sequence: ',opts.fxs);
+	}
+	return true;
+}
+
+// provide a mechanism for adding slides after the slideshow has started
+function exposeAddSlide(opts, els) {
+	opts.addSlide = function(newSlide, prepend) {
+		var $s = $(newSlide), s = $s[0];
+		if (!opts.autostopCount)
+			opts.countdown++;
+		els[prepend?'unshift':'push'](s);
+		if (opts.els)
+			opts.els[prepend?'unshift':'push'](s); // shuffle needs this
+		opts.slideCount = els.length;
+
+		// add the slide to the random map and resort
+		if (opts.random) {
+			opts.randomMap.push(opts.slideCount-1);
+			opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
+		}
+
+		$s.css('position','absolute');
+		$s[prepend?'prependTo':'appendTo'](opts.$cont);
+
+		if (prepend) {
+			opts.currSlide++;
+			opts.nextSlide++;
+		}
+
+		if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
+			clearTypeFix($s);
+
+		if (opts.fit && opts.width)
+			$s.width(opts.width);
+		if (opts.fit && opts.height && opts.height != 'auto')
+			$s.height(opts.height);
+		s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height();
+		s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();
+
+		$s.css(opts.cssBefore);
+
+		if (opts.pager || opts.pagerAnchorBuilder)
+			$.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts);
+
+		if ($.isFunction(opts.onAddSlide))
+			opts.onAddSlide($s);
+		else
+			$s.hide(); // default behavior
+	};
+}
+
+// reset internal state; we do this on every pass in order to support multiple effects
+$.fn.cycle.resetState = function(opts, fx) {
+	fx = fx || opts.fx;
+	opts.before = []; opts.after = [];
+	opts.cssBefore = $.extend({}, opts.original.cssBefore);
+	opts.cssAfter  = $.extend({}, opts.original.cssAfter);
+	opts.animIn	= $.extend({}, opts.original.animIn);
+	opts.animOut   = $.extend({}, opts.original.animOut);
+	opts.fxFn = null;
+	$.each(opts.original.before, function() { opts.before.push(this); });
+	$.each(opts.original.after,  function() { opts.after.push(this); });
+
+	// re-init
+	var init = $.fn.cycle.transitions[fx];
+	if ($.isFunction(init))
+		init(opts.$cont, $(opts.elements), opts);
+};
+
+// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt
+function go(els, opts, manual, fwd) {
+	var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide];
+
+	// opts.busy is true if we're in the middle of an animation
+	if (manual && opts.busy && opts.manualTrump) {
+		// let manual transitions requests trump active ones
+		debug('manualTrump in go(), stopping active transition');
+		$(els).stop(true,true);
+		opts.busy = 0;
+		clearTimeout(p.cycleTimeout);
+	}
+
+	// don't begin another timeout-based transition if there is one active
+	if (opts.busy) {
+		debug('transition active, ignoring new tx request');
+		return;
+	}
+
+
+	// stop cycling if we have an outstanding stop request
+	if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual)
+		return;
+
+	// check to see if we should stop cycling based on autostop options
+	if (!manual && !p.cyclePause && !opts.bounce &&
+		((opts.autostop && (--opts.countdown <= 0)) ||
+		(opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) {
+		if (opts.end)
+			opts.end(opts);
+		return;
+	}
+
+	// if slideshow is paused, only transition on a manual trigger
+	var changed = false;
+	if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) {
+		changed = true;
+		var fx = opts.fx;
+		// keep trying to get the slide size if we don't have it yet
+		curr.cycleH = curr.cycleH || $(curr).height();
+		curr.cycleW = curr.cycleW || $(curr).width();
+		next.cycleH = next.cycleH || $(next).height();
+		next.cycleW = next.cycleW || $(next).width();
+
+		// support multiple transition types
+		if (opts.multiFx) {
+			if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length))
+				opts.lastFx = 0;
+			else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0))
+				opts.lastFx = opts.fxs.length - 1;
+			fx = opts.fxs[opts.lastFx];
+		}
+
+		// one-time fx overrides apply to:  $('div').cycle(3,'zoom');
+		if (opts.oneTimeFx) {
+			fx = opts.oneTimeFx;
+			opts.oneTimeFx = null;
+		}
+
+		$.fn.cycle.resetState(opts, fx);
+
+		// run the before callbacks
+		if (opts.before.length)
+			$.each(opts.before, function(i,o) {
+				if (p.cycleStop != opts.stopCount) return;
+				o.apply(next, [curr, next, opts, fwd]);
+			});
+
+		// stage the after callacks
+		var after = function() {
+			opts.busy = 0;
+			$.each(opts.after, function(i,o) {
+				if (p.cycleStop != opts.stopCount) return;
+				o.apply(next, [curr, next, opts, fwd]);
+			});
+			if (!p.cycleStop) {
+				// queue next transition
+				queueNext();
+			}
+		};
+
+		debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);
+		
+		// get ready to perform the transition
+		opts.busy = 1;
+		if (opts.fxFn) // fx function provided?
+			opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
+		else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ?
+			$.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent);
+		else
+			$.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
+	}
+	else {
+		queueNext();
+	}
+
+	if (changed || opts.nextSlide == opts.currSlide) {
+		// calculate the next slide
+		var roll;
+		opts.lastSlide = opts.currSlide;
+		if (opts.random) {
+			opts.currSlide = opts.nextSlide;
+			if (++opts.randomIndex == els.length) {
+				opts.randomIndex = 0;
+				opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
+			}
+			opts.nextSlide = opts.randomMap[opts.randomIndex];
+			if (opts.nextSlide == opts.currSlide)
+				opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1;
+		}
+		else if (opts.backwards) {
+			roll = (opts.nextSlide - 1) < 0;
+			if (roll && opts.bounce) {
+				opts.backwards = !opts.backwards;
+				opts.nextSlide = 1;
+				opts.currSlide = 0;
+			}
+			else {
+				opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1;
+				opts.currSlide = roll ? 0 : opts.nextSlide+1;
+			}
+		}
+		else { // sequence
+			roll = (opts.nextSlide + 1) == els.length;
+			if (roll && opts.bounce) {
+				opts.backwards = !opts.backwards;
+				opts.nextSlide = els.length-2;
+				opts.currSlide = els.length-1;
+			}
+			else {
+				opts.nextSlide = roll ? 0 : opts.nextSlide+1;
+				opts.currSlide = roll ? els.length-1 : opts.nextSlide-1;
+			}
+		}
+	}
+	if (changed && opts.pager)
+		opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);
+	
+	function queueNext() {
+		// stage the next transition
+		var ms = 0, timeout = opts.timeout;
+		if (opts.timeout && !opts.continuous) {
+			ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd);
+         if (opts.fx == 'shuffle')
+            ms -= opts.speedOut;
+      }
+		else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic
+			ms = 10;
+		if (ms > 0)
+			p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms);
+	}
+}
+
+// invoked after transition
+$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
+   $(pager).each(function() {
+       $(this).children().removeClass(clsName).eq(currSlide).addClass(clsName);
+   });
+};
+
+// calculate timeout value for current transition
+function getTimeout(curr, next, opts, fwd) {
+	if (opts.timeoutFn) {
+		// call user provided calc fn
+		var t = opts.timeoutFn.call(curr,curr,next,opts,fwd);
+		while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout
+			t += opts.speed;
+		debug('calculated timeout: ' + t + '; speed: ' + opts.speed);
+		if (t !== false)
+			return t;
+	}
+	return opts.timeout;
+}
+
+// expose next/prev function, caller must pass in state
+$.fn.cycle.next = function(opts) { advance(opts,1); };
+$.fn.cycle.prev = function(opts) { advance(opts,0);};
+
+// advance slide forward or back
+function advance(opts, moveForward) {
+	var val = moveForward ? 1 : -1;
+	var els = opts.elements;
+	var p = opts.$cont[0], timeout = p.cycleTimeout;
+	if (timeout) {
+		clearTimeout(timeout);
+		p.cycleTimeout = 0;
+	}
+	if (opts.random && val < 0) {
+		// move back to the previously display slide
+		opts.randomIndex--;
+		if (--opts.randomIndex == -2)
+			opts.randomIndex = els.length-2;
+		else if (opts.randomIndex == -1)
+			opts.randomIndex = els.length-1;
+		opts.nextSlide = opts.randomMap[opts.randomIndex];
+	}
+	else if (opts.random) {
+		opts.nextSlide = opts.randomMap[opts.randomIndex];
+	}
+	else {
+		opts.nextSlide = opts.currSlide + val;
+		if (opts.nextSlide < 0) {
+			if (opts.nowrap) return false;
+			opts.nextSlide = els.length - 1;
+		}
+		else if (opts.nextSlide >= els.length) {
+			if (opts.nowrap) return false;
+			opts.nextSlide = 0;
+		}
+	}
+
+	var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated
+	if ($.isFunction(cb))
+		cb(val > 0, opts.nextSlide, els[opts.nextSlide]);
+	go(els, opts, 1, moveForward);
+	return false;
+}
+
+function buildPager(els, opts) {
+	var $p = $(opts.pager);
+	$.each(els, function(i,o) {
+		$.fn.cycle.createPagerAnchor(i,o,$p,els,opts);
+	});
+	opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass);
+}
+
+$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
+	var a;
+	if ($.isFunction(opts.pagerAnchorBuilder)) {
+		a = opts.pagerAnchorBuilder(i,el);
+		debug('pagerAnchorBuilder('+i+', el) returned: ' + a);
+	}
+	else
+		a = '<a href="#">'+(i+1)+'</a>';
+		
+	if (!a)
+		return;
+	var $a = $(a);
+	// don't reparent if anchor is in the dom
+	if ($a.parents('body').length === 0) {
+		var arr = [];
+		if ($p.length > 1) {
+			$p.each(function() {
+				var $clone = $a.clone(true);
+				$(this).append($clone);
+				arr.push($clone[0]);
+			});
+			$a = $(arr);
+		}
+		else {
+			$a.appendTo($p);
+		}
+	}
+
+	opts.pagerAnchors =  opts.pagerAnchors || [];
+	opts.pagerAnchors.push($a);
+	
+	var pagerFn = function(e) {
+		e.preventDefault();
+		opts.nextSlide = i;
+		var p = opts.$cont[0], timeout = p.cycleTimeout;
+		if (timeout) {
+			clearTimeout(timeout);
+			p.cycleTimeout = 0;
+		}
+		var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated
+		if ($.isFunction(cb))
+			cb(opts.nextSlide, els[opts.nextSlide]);
+		go(els,opts,1,opts.currSlide < i); // trigger the trans
+//		return false; // <== allow bubble
+	};
+	
+	if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) {
+		$a.hover(pagerFn, function(){/* no-op */} );
+	}
+	else {
+		$a.bind(opts.pagerEvent, pagerFn);
+	}
+	
+	if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
+		$a.bind('click.cycle', function(){return false;}); // suppress click
+	
+	var cont = opts.$cont[0];
+	var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
+	if (opts.pauseOnPagerHover) {
+		$a.hover(
+			function() { 
+				pauseFlag = true;
+				cont.cyclePause++; 
+				triggerPause(cont,true,true);
+			}, function() { 
+				if (pauseFlag)
+					cont.cyclePause--; 
+				triggerPause(cont,true,true);
+			} 
+		);
+	}
+};
+
+// helper fn to calculate the number of slides between the current and the next
+$.fn.cycle.hopsFromLast = function(opts, fwd) {
+	var hops, l = opts.lastSlide, c = opts.currSlide;
+	if (fwd)
+		hops = c > l ? c - l : opts.slideCount - l;
+	else
+		hops = c < l ? l - c : l + opts.slideCount - c;
+	return hops;
+};
+
+// fix clearType problems in ie6 by setting an explicit bg color
+// (otherwise text slides look horrible during a fade transition)
+function clearTypeFix($slides) {
+	debug('applying clearType background-color hack');
+	function hex(s) {
+		s = parseInt(s,10).toString(16);
+		return s.length < 2 ? '0'+s : s;
+	}
+	function getBg(e) {
+		for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) {
+			var v = $.css(e,'background-color');
+			if (v && v.indexOf('rgb') >= 0 ) {
+				var rgb = v.match(/\d+/g);
+				return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
+			}
+			if (v && v != 'transparent')
+				return v;
+		}
+		return '#ffffff';
+	}
+	$slides.each(function() { $(this).css('background-color', getBg(this)); });
+}
+
+// reset common props before the next transition
+$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) {
+	$(opts.elements).not(curr).hide();
+	if (typeof opts.cssBefore.opacity == 'undefined')
+		opts.cssBefore.opacity = 1;
+	opts.cssBefore.display = 'block';
+	if (opts.slideResize && w !== false && next.cycleW > 0)
+		opts.cssBefore.width = next.cycleW;
+	if (opts.slideResize && h !== false && next.cycleH > 0)
+		opts.cssBefore.height = next.cycleH;
+	opts.cssAfter = opts.cssAfter || {};
+	opts.cssAfter.display = 'none';
+	$(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0));
+	$(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1));
+};
+
+// the actual fn for effecting a transition
+$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
+	var $l = $(curr), $n = $(next);
+	var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut, animInDelay = opts.animInDelay, animOutDelay = opts.animOutDelay;
+	$n.css(opts.cssBefore);
+	if (speedOverride) {
+		if (typeof speedOverride == 'number')
+			speedIn = speedOut = speedOverride;
+		else
+			speedIn = speedOut = 1;
+		easeIn = easeOut = null;
+	}
+	var fn = function() {
+		$n.delay(animInDelay).animate(opts.animIn, speedIn, easeIn, function() {
+			cb();
+		});
+	};
+	$l.delay(animOutDelay).animate(opts.animOut, speedOut, easeOut, function() {
+		$l.css(opts.cssAfter);
+		if (!opts.sync) 
+			fn();
+	});
+	if (opts.sync) fn();
+};
+
+// transition definitions - only fade is defined here, transition pack defines the rest
+$.fn.cycle.transitions = {
+	fade: function($cont, $slides, opts) {
+		$slides.not(':eq('+opts.currSlide+')').css('opacity',0);
+		opts.before.push(function(curr,next,opts) {
+			$.fn.cycle.commonReset(curr,next,opts);
+			opts.cssBefore.opacity = 0;
+		});
+		opts.animIn	   = { opacity: 1 };
+		opts.animOut   = { opacity: 0 };
+		opts.cssBefore = { top: 0, left: 0 };
+	}
+};
+
+$.fn.cycle.ver = function() { return ver; };
+
+// override these globally if you like (they are all optional)
+$.fn.cycle.defaults = {
+    activePagerClass: 'activeSlide', // class name used for the active pager link
+    after:            null,     // transition callback (scope set to element that was shown):  function(currSlideElement, nextSlideElement, options, forwardFlag)
+    allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling
+    animIn:           null,     // properties that define how the slide animates in
+    animInDelay:      0,        // allows delay before next slide transitions in	
+    animOut:          null,     // properties that define how the slide animates out
+    animOutDelay:     0,        // allows delay before current slide transitions out
+    aspect:           false,    // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option)
+    autostop:         0,        // true to end slideshow after X transitions (where X == slide count)
+    autostopCount:    0,        // number of transitions (optionally used with autostop to define X)
+    backwards:        false,    // true to start slideshow at last slide and move backwards through the stack
+    before:           null,     // transition callback (scope set to element to be shown):     function(currSlideElement, nextSlideElement, options, forwardFlag)
+    center:           null,     // set to true to have cycle add top/left margin to each slide (use with width and height options)
+    cleartype:        !$.support.opacity,  // true if clearType corrections should be applied (for IE)
+    cleartypeNoBg:    false,    // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)
+    containerResize:  1,        // resize container to fit largest slide
+    containerResizeHeight:  0,  // resize containers height to fit the largest slide but leave the width dynamic
+    continuous:       0,        // true to start next transition immediately after current one completes
+    cssAfter:         null,     // properties that defined the state of the slide after transitioning out
+    cssBefore:        null,     // properties that define the initial state of the slide before transitioning in
+    delay:            0,        // additional delay (in ms) for first transition (hint: can be negative)
+    easeIn:           null,     // easing for "in" transition
+    easeOut:          null,     // easing for "out" transition
+    easing:           null,     // easing method for both in and out transitions
+    end:              null,     // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
+    fastOnEvent:      0,        // force fast transitions when triggered manually (via pager or prev/next); value == time in ms
+    fit:              0,        // force slides to fit container
+    fx:               'fade',   // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle')
+    fxFn:             null,     // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
+    height:           'auto',   // container height (if the 'fit' option is true, the slides will be set to this height as well)
+    manualTrump:      true,     // causes manual transition to stop an active transition instead of being ignored
+    metaAttr:         'cycle',  // data- attribute that holds the option data for the slideshow
+    next:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide
+    nowrap:           0,        // true to prevent slideshow from wrapping
+    onPagerEvent:     null,     // callback fn for pager events: function(zeroBasedSlideIndex, slideElement)
+    onPrevNextEvent:  null,     // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement)
+    pager:            null,     // element, jQuery object, or jQuery selector string for the element to use as pager container
+    pagerAnchorBuilder: null,   // callback fn for building anchor links:  function(index, DOMelement)
+    pagerEvent:       'click.cycle', // name of event which drives the pager navigation
+    pause:            0,        // true to enable "pause on hover"
+    pauseOnPagerHover: 0,       // true to pause when hovering over pager link
+    prev:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide
+    prevNextEvent:    'click.cycle',// event which drives the manual transition to the previous or next slide
+    random:           0,        // true for random, false for sequence (not applicable to shuffle fx)
+    randomizeEffects: 1,        // valid when multiple effects are used; true to make the effect sequence random
+    requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded
+    requeueTimeout:   250,      // ms delay for requeue
+    rev:              0,        // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle)
+    shuffle:          null,     // coords for shuffle animation, ex: { top:15, left: 200 }
+    skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition
+    slideExpr:        null,     // expression for selecting slides (if something other than all children is required)
+    slideResize:      1,        // force slide width/height to fixed size before every transition
+    speed:            1000,     // speed of the transition (any valid fx speed value)
+    speedIn:          null,     // speed of the 'in' transition
+    speedOut:         null,     // speed of the 'out' transition
+    startingSlide:    undefined,// zero-based index of the first slide to be displayed
+    sync:             1,        // true if in/out transitions should occur simultaneously
+    timeout:          4000,     // milliseconds between slide transitions (0 to disable auto advance)
+    timeoutFn:        null,     // callback for determining per-slide timeout value:  function(currSlideElement, nextSlideElement, options, forwardFlag)
+    updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style)
+    width:            null      // container width (if the 'fit' option is true, the slides will be set to this width as well)
+};
+
+})(jQuery);
+
+
+/*!
+ * jQuery Cycle Plugin Transition Definitions
+ * This script is a plugin for the jQuery Cycle Plugin
+ * Examples and documentation at: http://malsup.com/jquery/cycle/
+ * Copyright (c) 2007-2010 M. Alsup
+ * Version:	 2.73
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+(function($) {
+"use strict";
+
+//
+// These functions define slide initialization and properties for the named
+// transitions. To save file size feel free to remove any of these that you
+// don't need.
+//
+$.fn.cycle.transitions.none = function($cont, $slides, opts) {
+	opts.fxFn = function(curr,next,opts,after){
+		$(next).show();
+		$(curr).hide();
+		after();
+	};
+};
+
+// not a cross-fade, fadeout only fades out the top slide
+$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) {
+	$slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 });
+	opts.before.push(function(curr,next,opts,w,h,rev) {
+		$(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0));
+		$(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1));
+	});
+	opts.animIn.opacity = 1;
+	opts.animOut.opacity = 0;
+	opts.cssBefore.opacity = 1;
+	opts.cssBefore.display = 'block';
+	opts.cssAfter.zIndex = 0;
+};
+
+// scrollUp/Down/Left/Right
+$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) {
+	$cont.css('overflow','hidden');
+	opts.before.push($.fn.cycle.commonReset);
+	var h = $cont.height();
+	opts.cssBefore.top = h;
+	opts.cssBefore.left = 0;
+	opts.cssFirst.top = 0;
+	opts.animIn.top = 0;
+	opts.animOut.top = -h;
+};
+$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) {
+	$cont.css('overflow','hidden');
+	opts.before.push($.fn.cycle.commonReset);
+	var h = $cont.height();
+	opts.cssFirst.top = 0;
+	opts.cssBefore.top = -h;
+	opts.cssBefore.left = 0;
+	opts.animIn.top = 0;
+	opts.animOut.top = h;
+};
+$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) {
+	$cont.css('overflow','hidden');
+	opts.before.push($.fn.cycle.commonReset);
+	var w = $cont.width();
+	opts.cssFirst.left = 0;
+	opts.cssBefore.left = w;
+	opts.cssBefore.top = 0;
+	opts.animIn.left = 0;
+	opts.animOut.left = 0-w;
+};
+$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) {
+	$cont.css('overflow','hidden');
+	opts.before.push($.fn.cycle.commonReset);
+	var w = $cont.width();
+	opts.cssFirst.left = 0;
+	opts.cssBefore.left = -w;
+	opts.cssBefore.top = 0;
+	opts.animIn.left = 0;
+	opts.animOut.left = w;
+};
+$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) {
+	$cont.css('overflow','hidden').width();
+	opts.before.push(function(curr, next, opts, fwd) {
+		if (opts.rev)
+			fwd = !fwd;
+		$.fn.cycle.commonReset(curr,next,opts);
+		opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW);
+		opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW;
+	});
+	opts.cssFirst.left = 0;
+	opts.cssBefore.top = 0;
+	opts.animIn.left = 0;
+	opts.animOut.top = 0;
+};
+$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) {
+	$cont.css('overflow','hidden');
+	opts.before.push(function(curr, next, opts, fwd) {
+		if (opts.rev)
+			fwd = !fwd;
+		$.fn.cycle.commonReset(curr,next,opts);
+		opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1);
+		opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH;
+	});
+	opts.cssFirst.top = 0;
+	opts.cssBefore.left = 0;
+	opts.animIn.top = 0;
+	opts.animOut.left = 0;
+};
+
+// slideX/slideY
+$.fn.cycle.transitions.slideX = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$(opts.elements).not(curr).hide();
+		$.fn.cycle.commonReset(curr,next,opts,false,true);
+		opts.animIn.width = next.cycleW;
+	});
+	opts.cssBefore.left = 0;
+	opts.cssBefore.top = 0;
+	opts.cssBefore.width = 0;
+	opts.animIn.width = 'show';
+	opts.animOut.width = 0;
+};
+$.fn.cycle.transitions.slideY = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$(opts.elements).not(curr).hide();
+		$.fn.cycle.commonReset(curr,next,opts,true,false);
+		opts.animIn.height = next.cycleH;
+	});
+	opts.cssBefore.left = 0;
+	opts.cssBefore.top = 0;
+	opts.cssBefore.height = 0;
+	opts.animIn.height = 'show';
+	opts.animOut.height = 0;
+};
+
+// shuffle
+$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) {
+	var i, w = $cont.css('overflow', 'visible').width();
+	$slides.css({left: 0, top: 0});
+	opts.before.push(function(curr,next,opts) {
+		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
+	});
+	// only adjust speed once!
+	if (!opts.speedAdjusted) {
+		opts.speed = opts.speed / 2; // shuffle has 2 transitions
+		opts.speedAdjusted = true;
+	}
+	opts.random = 0;
+	opts.shuffle = opts.shuffle || {left:-w, top:15};
+	opts.els = [];
+	for (i=0; i < $slides.length; i++)
+		opts.els.push($slides[i]);
+
+	for (i=0; i < opts.currSlide; i++)
+		opts.els.push(opts.els.shift());
+
+	// custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!)
+	opts.fxFn = function(curr, next, opts, cb, fwd) {
+		if (opts.rev)
+			fwd = !fwd;
+		var $el = fwd ? $(curr) : $(next);
+		$(next).css(opts.cssBefore);
+		var count = opts.slideCount;
+		$el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() {
+			var hops = $.fn.cycle.hopsFromLast(opts, fwd);
+			for (var k=0; k < hops; k++) {
+				if (fwd)
+					opts.els.push(opts.els.shift());
+				else
+					opts.els.unshift(opts.els.pop());
+			}
+			if (fwd) {
+				for (var i=0, len=opts.els.length; i < len; i++)
+					$(opts.els[i]).css('z-index', len-i+count);
+			}
+			else {
+				var z = $(curr).css('z-index');
+				$el.css('z-index', parseInt(z,10)+1+count);
+			}
+			$el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() {
+				$(fwd ? this : curr).hide();
+				if (cb) cb();
+			});
+		});
+	};
+	$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
+};
+
+// turnUp/Down/Left/Right
+$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,true,false);
+		opts.cssBefore.top = next.cycleH;
+		opts.animIn.height = next.cycleH;
+		opts.animOut.width = next.cycleW;
+	});
+	opts.cssFirst.top = 0;
+	opts.cssBefore.left = 0;
+	opts.cssBefore.height = 0;
+	opts.animIn.top = 0;
+	opts.animOut.height = 0;
+};
+$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,true,false);
+		opts.animIn.height = next.cycleH;
+		opts.animOut.top   = curr.cycleH;
+	});
+	opts.cssFirst.top = 0;
+	opts.cssBefore.left = 0;
+	opts.cssBefore.top = 0;
+	opts.cssBefore.height = 0;
+	opts.animOut.height = 0;
+};
+$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,false,true);
+		opts.cssBefore.left = next.cycleW;
+		opts.animIn.width = next.cycleW;
+	});
+	opts.cssBefore.top = 0;
+	opts.cssBefore.width = 0;
+	opts.animIn.left = 0;
+	opts.animOut.width = 0;
+};
+$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,false,true);
+		opts.animIn.width = next.cycleW;
+		opts.animOut.left = curr.cycleW;
+	});
+	$.extend(opts.cssBefore, { top: 0, left: 0, width: 0 });
+	opts.animIn.left = 0;
+	opts.animOut.width = 0;
+};
+
+// zoom
+$.fn.cycle.transitions.zoom = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,false,false,true);
+		opts.cssBefore.top = next.cycleH/2;
+		opts.cssBefore.left = next.cycleW/2;
+		$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
+		$.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 });
+	});
+	opts.cssFirst.top = 0;
+	opts.cssFirst.left = 0;
+	opts.cssBefore.width = 0;
+	opts.cssBefore.height = 0;
+};
+
+// fadeZoom
+$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,false,false);
+		opts.cssBefore.left = next.cycleW/2;
+		opts.cssBefore.top = next.cycleH/2;
+		$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
+	});
+	opts.cssBefore.width = 0;
+	opts.cssBefore.height = 0;
+	opts.animOut.opacity = 0;
+};
+
+// blindX
+$.fn.cycle.transitions.blindX = function($cont, $slides, opts) {
+	var w = $cont.css('overflow','hidden').width();
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts);
+		opts.animIn.width = next.cycleW;
+		opts.animOut.left   = curr.cycleW;
+	});
+	opts.cssBefore.left = w;
+	opts.cssBefore.top = 0;
+	opts.animIn.left = 0;
+	opts.animOut.left = w;
+};
+// blindY
+$.fn.cycle.transitions.blindY = function($cont, $slides, opts) {
+	var h = $cont.css('overflow','hidden').height();
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts);
+		opts.animIn.height = next.cycleH;
+		opts.animOut.top   = curr.cycleH;
+	});
+	opts.cssBefore.top = h;
+	opts.cssBefore.left = 0;
+	opts.animIn.top = 0;
+	opts.animOut.top = h;
+};
+// blindZ
+$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) {
+	var h = $cont.css('overflow','hidden').height();
+	var w = $cont.width();
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts);
+		opts.animIn.height = next.cycleH;
+		opts.animOut.top   = curr.cycleH;
+	});
+	opts.cssBefore.top = h;
+	opts.cssBefore.left = w;
+	opts.animIn.top = 0;
+	opts.animIn.left = 0;
+	opts.animOut.top = h;
+	opts.animOut.left = w;
+};
+
+// growX - grow horizontally from centered 0 width
+$.fn.cycle.transitions.growX = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,false,true);
+		opts.cssBefore.left = this.cycleW/2;
+		opts.animIn.left = 0;
+		opts.animIn.width = this.cycleW;
+		opts.animOut.left = 0;
+	});
+	opts.cssBefore.top = 0;
+	opts.cssBefore.width = 0;
+};
+// growY - grow vertically from centered 0 height
+$.fn.cycle.transitions.growY = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,true,false);
+		opts.cssBefore.top = this.cycleH/2;
+		opts.animIn.top = 0;
+		opts.animIn.height = this.cycleH;
+		opts.animOut.top = 0;
+	});
+	opts.cssBefore.height = 0;
+	opts.cssBefore.left = 0;
+};
+
+// curtainX - squeeze in both edges horizontally
+$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,false,true,true);
+		opts.cssBefore.left = next.cycleW/2;
+		opts.animIn.left = 0;
+		opts.animIn.width = this.cycleW;
+		opts.animOut.left = curr.cycleW/2;
+		opts.animOut.width = 0;
+	});
+	opts.cssBefore.top = 0;
+	opts.cssBefore.width = 0;
+};
+// curtainY - squeeze in both edges vertically
+$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) {
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,true,false,true);
+		opts.cssBefore.top = next.cycleH/2;
+		opts.animIn.top = 0;
+		opts.animIn.height = next.cycleH;
+		opts.animOut.top = curr.cycleH/2;
+		opts.animOut.height = 0;
+	});
+	opts.cssBefore.height = 0;
+	opts.cssBefore.left = 0;
+};
+
+// cover - curr slide covered by next slide
+$.fn.cycle.transitions.cover = function($cont, $slides, opts) {
+	var d = opts.direction || 'left';
+	var w = $cont.css('overflow','hidden').width();
+	var h = $cont.height();
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts);
+		opts.cssAfter.display = '';
+		if (d == 'right')
+			opts.cssBefore.left = -w;
+		else if (d == 'up')
+			opts.cssBefore.top = h;
+		else if (d == 'down')
+			opts.cssBefore.top = -h;
+		else
+			opts.cssBefore.left = w;
+	});
+	opts.animIn.left = 0;
+	opts.animIn.top = 0;
+	opts.cssBefore.top = 0;
+	opts.cssBefore.left = 0;
+};
+
+// uncover - curr slide moves off next slide
+$.fn.cycle.transitions.uncover = function($cont, $slides, opts) {
+	var d = opts.direction || 'left';
+	var w = $cont.css('overflow','hidden').width();
+	var h = $cont.height();
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
+		if (d == 'right')
+			opts.animOut.left = w;
+		else if (d == 'up')
+			opts.animOut.top = -h;
+		else if (d == 'down')
+			opts.animOut.top = h;
+		else
+			opts.animOut.left = -w;
+	});
+	opts.animIn.left = 0;
+	opts.animIn.top = 0;
+	opts.cssBefore.top = 0;
+	opts.cssBefore.left = 0;
+};
+
+// toss - move top slide and fade away
+$.fn.cycle.transitions.toss = function($cont, $slides, opts) {
+	var w = $cont.css('overflow','visible').width();
+	var h = $cont.height();
+	opts.before.push(function(curr, next, opts) {
+		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
+		// provide default toss settings if animOut not provided
+		if (!opts.animOut.left && !opts.animOut.top)
+			$.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 });
+		else
+			opts.animOut.opacity = 0;
+	});
+	opts.cssBefore.left = 0;
+	opts.cssBefore.top = 0;
+	opts.animIn.left = 0;
+};
+
+// wipe - clip animation
+$.fn.cycle.transitions.wipe = function($cont, $slides, opts) {
+	var w = $cont.css('overflow','hidden').width();
+	var h = $cont.height();
+	opts.cssBefore = opts.cssBefore || {};
+	var clip;
+	if (opts.clip) {
+		if (/l2r/.test(opts.clip))
+			clip = 'rect(0px 0px '+h+'px 0px)';
+		else if (/r2l/.test(opts.clip))
+			clip = 'rect(0px '+w+'px '+h+'px '+w+'px)';
+		else if (/t2b/.test(opts.clip))
+			clip = 'rect(0px '+w+'px 0px 0px)';
+		else if (/b2t/.test(opts.clip))
+			clip = 'rect('+h+'px '+w+'px '+h+'px 0px)';
+		else if (/zoom/.test(opts.clip)) {
+			var top = parseInt(h/2,10);
+			var left = parseInt(w/2,10);
+			clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)';
+		}
+	}
+
+	opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)';
+
+	var d = opts.cssBefore.clip.match(/(\d+)/g);
+	var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10);
+
+	opts.before.push(function(curr, next, opts) {
+		if (curr == next) return;
+		var $curr = $(curr), $next = $(next);
+		$.fn.cycle.commonReset(curr,next,opts,true,true,false);
+		opts.cssAfter.display = 'block';
+
+		var step = 1, count = parseInt((opts.speedIn / 13),10) - 1;
+		(function f() {
+			var tt = t ? t - parseInt(step * (t/count),10) : 0;
+			var ll = l ? l - parseInt(step * (l/count),10) : 0;
+			var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h;
+			var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w;
+			$next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' });
+			(step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none');
+		})();
+	});
+	$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
+	opts.animIn	   = { left: 0 };
+	opts.animOut   = { left: 0 };
+};
+
+})(jQuery);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/jquery.hoverIntent/jquery.hoverIntent.js	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,158 @@
+/*!
+ * hoverIntent v1.9.0 // 2017.09.01 // jQuery v1.7.0+
+ * http://briancherne.github.io/jquery-hoverIntent/
+ *
+ * You may use hoverIntent under the terms of the MIT license. Basically that
+ * means you are free to use hoverIntent as long as this header is left intact.
+ * Copyright 2007-2017 Brian Cherne
+ */
+
+/* hoverIntent is similar to jQuery's built-in "hover" method except that
+ * instead of firing the handlerIn function immediately, hoverIntent checks
+ * to see if the user's mouse has slowed down (beneath the sensitivity
+ * threshold) before firing the event. The handlerOut function is only
+ * called after a matching handlerIn.
+ *
+ * // basic usage ... just like .hover()
+ * .hoverIntent( handlerIn, handlerOut )
+ * .hoverIntent( handlerInOut )
+ *
+ * // basic usage ... with event delegation!
+ * .hoverIntent( handlerIn, handlerOut, selector )
+ * .hoverIntent( handlerInOut, selector )
+ *
+ * // using a basic configuration object
+ * .hoverIntent( config )
+ *
+ * @param  handlerIn   function OR configuration object
+ * @param  handlerOut  function OR selector for delegation OR undefined
+ * @param  selector    selector OR undefined
+ * @author Brian Cherne <brian(at)cherne(dot)net>
+ */
+
+;(function(factory) {
+    'use strict';
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery'], factory);
+    } else if (jQuery && !jQuery.fn.hoverIntent) {
+        factory(jQuery);
+    }
+})(function($) {
+    'use strict';
+
+    // default configuration values
+    var _cfg = {
+        interval: 100,
+        sensitivity: 6,
+        timeout: 0
+    };
+
+    // counter used to generate an ID for each instance
+    var INSTANCE_COUNT = 0;
+
+    // current X and Y position of mouse, updated during mousemove tracking (shared across instances)
+    var cX, cY;
+
+    // saves the current pointer position coordinates based on the given mousemove event
+    var track = function(ev) {
+        cX = ev.pageX;
+        cY = ev.pageY;
+    };
+
+    // compares current and previous mouse positions
+    var compare = function(ev,$el,s,cfg) {
+        // compare mouse positions to see if pointer has slowed enough to trigger `over` function
+        if ( Math.sqrt( (s.pX-cX)*(s.pX-cX) + (s.pY-cY)*(s.pY-cY) ) < cfg.sensitivity ) {
+            $el.off(s.event,track);
+            delete s.timeoutId;
+            // set hoverIntent state as active for this element (permits `out` handler to trigger)
+            s.isActive = true;
+            // overwrite old mouseenter event coordinates with most recent pointer position
+            ev.pageX = cX; ev.pageY = cY;
+            // clear coordinate data from state object
+            delete s.pX; delete s.pY;
+            return cfg.over.apply($el[0],[ev]);
+        } else {
+            // set previous coordinates for next comparison
+            s.pX = cX; s.pY = cY;
+            // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
+            s.timeoutId = setTimeout( function(){compare(ev, $el, s, cfg);} , cfg.interval );
+        }
+    };
+
+    // triggers given `out` function at configured `timeout` after a mouseleave and clears state
+    var delay = function(ev,$el,s,out) {
+        delete $el.data('hoverIntent')[s.id];
+        return out.apply($el[0],[ev]);
+    };
+
+    $.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
+        // instance ID, used as a key to store and retrieve state information on an element
+        var instanceId = INSTANCE_COUNT++;
+
+        // extend the default configuration and parse parameters
+        var cfg = $.extend({}, _cfg);
+        if ( $.isPlainObject(handlerIn) ) {
+            cfg = $.extend(cfg, handlerIn);
+            if ( !$.isFunction(cfg.out) ) {
+                cfg.out = cfg.over;
+            }
+        } else if ( $.isFunction(handlerOut) ) {
+            cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
+        } else {
+            cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
+        }
+
+        // A private function for handling mouse 'hovering'
+        var handleHover = function(e) {
+            // cloned event to pass to handlers (copy required for event object to be passed in IE)
+            var ev = $.extend({},e);
+
+            // the current target of the mouse event, wrapped in a jQuery object
+            var $el = $(this);
+
+            // read hoverIntent data from element (or initialize if not present)
+            var hoverIntentData = $el.data('hoverIntent');
+            if (!hoverIntentData) { $el.data('hoverIntent', (hoverIntentData = {})); }
+
+            // read per-instance state from element (or initialize if not present)
+            var state = hoverIntentData[instanceId];
+            if (!state) { hoverIntentData[instanceId] = state = { id: instanceId }; }
+
+            // state properties:
+            // id = instance ID, used to clean up data
+            // timeoutId = timeout ID, reused for tracking mouse position and delaying "out" handler
+            // isActive = plugin state, true after `over` is called just until `out` is called
+            // pX, pY = previously-measured pointer coordinates, updated at each polling interval
+            // event = string representing the namespaced event used for mouse tracking
+
+            // clear any existing timeout
+            if (state.timeoutId) { state.timeoutId = clearTimeout(state.timeoutId); }
+
+            // namespaced event used to register and unregister mousemove tracking
+            var mousemove = state.event = 'mousemove.hoverIntent.hoverIntent'+instanceId;
+
+            // handle the event, based on its type
+            if (e.type === 'mouseenter') {
+                // do nothing if already active
+                if (state.isActive) { return; }
+                // set "previous" X and Y position based on initial entry point
+                state.pX = ev.pageX; state.pY = ev.pageY;
+                // update "current" X and Y position based on mousemove
+                $el.off(mousemove,track).on(mousemove,track);
+                // start polling interval (self-calling timeout) to compare mouse coordinates over time
+                state.timeoutId = setTimeout( function(){compare(ev,$el,state,cfg);} , cfg.interval );
+            } else { // "mouseleave"
+                // do nothing if not already active
+                if (!state.isActive) { return; }
+                // unbind expensive mousemove event
+                $el.off(mousemove,track);
+                // if hoverIntent state is true, then call the mouseOut function after the specified delay
+                state.timeoutId = setTimeout( function(){delay(ev,$el,state,cfg.out);} , cfg.timeout );
+            }
+        };
+
+        // listen for mouseenter and mouseleave
+        return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
+    };
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/jquery.pause/jquery.pause.js	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,94 @@
+/*!
+ * Pause jQuery plugin v0.1
+ *
+ * Copyright 2010 by Tobia Conforto <tobia.conforto@gmail.com>
+ *
+ * Based on Pause-resume-animation jQuery plugin by Joe Weitzel
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or(at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/* Changelog:
+ *
+ * 0.1    2010-06-13  Initial release
+ */
+(function() {
+	var $ = jQuery,
+		pauseId = 'jQuery.pause',
+		uuid = 1,
+		oldAnimate = $.fn.animate,
+		anims = {};
+
+	function now() { return new Date().getTime(); }
+
+	$.fn.animate = function(prop, speed, easing, callback) {
+		var optall = $.speed(speed, easing, callback);
+		optall.complete = optall.old; // unwrap callback
+		return this.each(function() {
+			// check pauseId
+			if (! this[pauseId])
+				this[pauseId] = uuid++;
+			// start animation
+			var opt = $.extend({}, optall);
+			oldAnimate.apply($(this), [prop, $.extend({}, opt)]);
+			// store data
+			anims[this[pauseId]] = {
+				run: true,
+				prop: prop,
+				opt: opt,
+				start: now(),
+				done: 0
+			};
+		});
+	};
+
+	$.fn.pause = function() {
+		return this.each(function() {
+			// check pauseId
+			if (! this[pauseId])
+				this[pauseId] = uuid++;
+			// fetch data
+			var data = anims[this[pauseId]];
+			if (data && data.run) {
+				data.done += now() - data.start;
+				if (data.done > data.opt.duration) {
+					// remove stale entry
+					delete anims[this[pauseId]];
+				} else {
+					// pause animation
+					$(this).stop();
+					data.run = false;
+				}
+			}
+		});
+	};
+
+	$.fn.resume = function() {
+		return this.each(function() {
+			// check pauseId
+			if (! this[pauseId])
+				this[pauseId] = uuid++;
+			// fetch data
+			var data = anims[this[pauseId]];
+			if (data && ! data.run) {
+				// resume animation
+				data.opt.duration -= data.done;
+				data.done = 0;
+				data.run = true;
+				data.start = now();
+				oldAnimate.apply($(this), [data.prop, $.extend({}, data.opt)]);
+			}
+		});
+	};
+})();
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/json2/json2.js	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,506 @@
+//  json2.js
+//  2016-10-28
+//  Public Domain.
+//  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+//  See http://www.JSON.org/js.html
+//  This code should be minified before deployment.
+//  See http://javascript.crockford.com/jsmin.html
+
+//  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+//  NOT CONTROL.
+
+//  This file creates a global JSON object containing two methods: stringify
+//  and parse. This file provides the ES5 JSON capability to ES3 systems.
+//  If a project might run on IE8 or earlier, then this file should be included.
+//  This file does nothing on ES5 systems.
+
+//      JSON.stringify(value, replacer, space)
+//          value       any JavaScript value, usually an object or array.
+//          replacer    an optional parameter that determines how object
+//                      values are stringified for objects. It can be a
+//                      function or an array of strings.
+//          space       an optional parameter that specifies the indentation
+//                      of nested structures. If it is omitted, the text will
+//                      be packed without extra whitespace. If it is a number,
+//                      it will specify the number of spaces to indent at each
+//                      level. If it is a string (such as "\t" or "&nbsp;"),
+//                      it contains the characters used to indent at each level.
+//          This method produces a JSON text from a JavaScript value.
+//          When an object value is found, if the object contains a toJSON
+//          method, its toJSON method will be called and the result will be
+//          stringified. A toJSON method does not serialize: it returns the
+//          value represented by the name/value pair that should be serialized,
+//          or undefined if nothing should be serialized. The toJSON method
+//          will be passed the key associated with the value, and this will be
+//          bound to the value.
+
+//          For example, this would serialize Dates as ISO strings.
+
+//              Date.prototype.toJSON = function (key) {
+//                  function f(n) {
+//                      // Format integers to have at least two digits.
+//                      return (n < 10)
+//                          ? "0" + n
+//                          : n;
+//                  }
+//                  return this.getUTCFullYear()   + "-" +
+//                       f(this.getUTCMonth() + 1) + "-" +
+//                       f(this.getUTCDate())      + "T" +
+//                       f(this.getUTCHours())     + ":" +
+//                       f(this.getUTCMinutes())   + ":" +
+//                       f(this.getUTCSeconds())   + "Z";
+//              };
+
+//          You can provide an optional replacer method. It will be passed the
+//          key and value of each member, with this bound to the containing
+//          object. The value that is returned from your method will be
+//          serialized. If your method returns undefined, then the member will
+//          be excluded from the serialization.
+
+//          If the replacer parameter is an array of strings, then it will be
+//          used to select the members to be serialized. It filters the results
+//          such that only members with keys listed in the replacer array are
+//          stringified.
+
+//          Values that do not have JSON representations, such as undefined or
+//          functions, will not be serialized. Such values in objects will be
+//          dropped; in arrays they will be replaced with null. You can use
+//          a replacer function to replace those with JSON values.
+
+//          JSON.stringify(undefined) returns undefined.
+
+//          The optional space parameter produces a stringification of the
+//          value that is filled with line breaks and indentation to make it
+//          easier to read.
+
+//          If the space parameter is a non-empty string, then that string will
+//          be used for indentation. If the space parameter is a number, then
+//          the indentation will be that many spaces.
+
+//          Example:
+
+//          text = JSON.stringify(["e", {pluribus: "unum"}]);
+//          // text is '["e",{"pluribus":"unum"}]'
+
+//          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
+//          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+//          text = JSON.stringify([new Date()], function (key, value) {
+//              return this[key] instanceof Date
+//                  ? "Date(" + this[key] + ")"
+//                  : value;
+//          });
+//          // text is '["Date(---current time---)"]'
+
+//      JSON.parse(text, reviver)
+//          This method parses a JSON text to produce an object or array.
+//          It can throw a SyntaxError exception.
+
+//          The optional reviver parameter is a function that can filter and
+//          transform the results. It receives each of the keys and values,
+//          and its return value is used instead of the original value.
+//          If it returns what it received, then the structure is not modified.
+//          If it returns undefined then the member is deleted.
+
+//          Example:
+
+//          // Parse the text. Values that look like ISO date strings will
+//          // be converted to Date objects.
+
+//          myData = JSON.parse(text, function (key, value) {
+//              var a;
+//              if (typeof value === "string") {
+//                  a =
+//   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+//                  if (a) {
+//                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+//                          +a[5], +a[6]));
+//                  }
+//              }
+//              return value;
+//          });
+
+//          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+//              var d;
+//              if (typeof value === "string" &&
+//                      value.slice(0, 5) === "Date(" &&
+//                      value.slice(-1) === ")") {
+//                  d = new Date(value.slice(5, -1));
+//                  if (d) {
+//                      return d;
+//                  }
+//              }
+//              return value;
+//          });
+
+//  This is a reference implementation. You are free to copy, modify, or
+//  redistribute.
+
+/*jslint
+    eval, for, this
+*/
+
+/*property
+    JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (typeof JSON !== "object") {
+    JSON = {};
+}
+
+(function () {
+    "use strict";
+
+    var rx_one = /^[\],:{}\s]*$/;
+    var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
+    var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
+    var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
+    var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+    var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10
+            ? "0" + n
+            : n;
+    }
+
+    function this_value() {
+        return this.valueOf();
+    }
+
+    if (typeof Date.prototype.toJSON !== "function") {
+
+        Date.prototype.toJSON = function () {
+
+            return isFinite(this.valueOf())
+                ? this.getUTCFullYear() + "-" +
+                        f(this.getUTCMonth() + 1) + "-" +
+                        f(this.getUTCDate()) + "T" +
+                        f(this.getUTCHours()) + ":" +
+                        f(this.getUTCMinutes()) + ":" +
+                        f(this.getUTCSeconds()) + "Z"
+                : null;
+        };
+
+        Boolean.prototype.toJSON = this_value;
+        Number.prototype.toJSON = this_value;
+        String.prototype.toJSON = this_value;
+    }
+
+    var gap;
+    var indent;
+    var meta;
+    var rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        rx_escapable.lastIndex = 0;
+        return rx_escapable.test(string)
+            ? "\"" + string.replace(rx_escapable, function (a) {
+                var c = meta[a];
+                return typeof c === "string"
+                    ? c
+                    : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + "\""
+            : "\"" + string + "\"";
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i;          // The loop counter.
+        var k;          // The member key.
+        var v;          // The member value.
+        var length;
+        var mind = gap;
+        var partial;
+        var value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === "object" &&
+                typeof value.toJSON === "function") {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === "function") {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case "string":
+            return quote(value);
+
+        case "number":
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value)
+                ? String(value)
+                : "null";
+
+        case "boolean":
+        case "null":
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce "null". The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is "object", we might be dealing with an object or an array or
+// null.
+
+        case "object":
+
+// Due to a specification blunder in ECMAScript, typeof null is "object",
+// so watch out for that case.
+
+            if (!value) {
+                return "null";
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === "[object Array]") {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || "null";
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0
+                    ? "[]"
+                    : gap
+                        ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
+                        : "[" + partial.join(",") + "]";
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === "object") {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    if (typeof rep[i] === "string") {
+                        k = rep[i];
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (
+                                gap
+                                    ? ": "
+                                    : ":"
+                            ) + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.prototype.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (
+                                gap
+                                    ? ": "
+                                    : ":"
+                            ) + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0
+                ? "{}"
+                : gap
+                    ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
+                    : "{" + partial.join(",") + "}";
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== "function") {
+        meta = {    // table of character substitutions
+            "\b": "\\b",
+            "\t": "\\t",
+            "\n": "\\n",
+            "\f": "\\f",
+            "\r": "\\r",
+            "\"": "\\\"",
+            "\\": "\\\\"
+        };
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = "";
+            indent = "";
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === "number") {
+                for (i = 0; i < space; i += 1) {
+                    indent += " ";
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === "string") {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== "function" &&
+                    (typeof replacer !== "object" ||
+                    typeof replacer.length !== "number")) {
+                throw new Error("JSON.stringify");
+            }
+
+// Make a fake root object containing our value under the key of "".
+// Return the result of stringifying the value.
+
+            return str("", {"": value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== "function") {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k;
+                var v;
+                var value = holder[key];
+                if (value && typeof value === "object") {
+                    for (k in value) {
+                        if (Object.prototype.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            rx_dangerous.lastIndex = 0;
+            if (rx_dangerous.test(text)) {
+                text = text.replace(rx_dangerous, function (a) {
+                    return "\\u" +
+                            ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with "()" and "new"
+// because they can cause invocation, and "=" because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
+// replace all simple value tokens with "]" characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or "]" or
+// "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
+
+            if (
+                rx_one.test(
+                    text
+                        .replace(rx_two, "@")
+                        .replace(rx_three, "]")
+                        .replace(rx_four, "")
+                )
+            ) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The "{" operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval("(" + text + ")");
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return (typeof reviver === "function")
+                    ? walk({"": j}, "")
+                    : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError("JSON.parse");
+        };
+    }
+}());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/LICENSE.txt	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/README.txt	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,68 @@
+INTRODUCTION
+------------
+
+  * Views Slideshow can be used to create a slideshow of any content (not just
+    images) that can appear in a View. Powered by jQuery, it is heavily
+    customizable: you may choose slideshow settings for each View you create.
+
+
+REQUIREMENTS
+------------
+
+  * Views Slideshow 8.x-4.x requires Drupal 8 & the core views module enabled.
+
+  * There is no upgrade path from views slideshow for Drupal 7.
+
+
+INSTALLATION
+------------
+  * Install as you would normally install a contributed Drupal module. See the
+  <a href='http://drupal.org/documentation/install/modules-themes/modules-8'>
+  Drupal 8 instructions</a> if required in the Drupal documentation for further
+  information. Note there are two modules included in this project; "Views
+  Slideshow" & "Views Slideshow Cycle". In most cases you will need/want to
+  enable both of them.
+
+  * You will also need to download some JavaScript libraries. You can do this
+  semi-automatically via drush using `drush dl-cycle-lib` or if preferred,
+  manually from the sources.
+
+  * Required libraries
+    * https://malsup.github.io/jquery.cycle.all.js
+    * https://raw.githubusercontent.com/briancherne/jquery-hoverIntent/master/jquery.hoverIntent.js
+    * https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js
+
+  * an example of code you could run in your Drupal root directory to download
+    to the right place:
+
+    ```
+    mkdir -p libraries/jquery.cycle && cd $_ && wget https://malsup.github.io/jquery.cycle.all.js \
+    && mkdir -p ../../libraries/jquery.hoverIntent && cd $_ && wget https://raw.githubusercontent.com/briancherne/jquery-hoverIntent/master/jquery.hoverIntent.js \
+    && mkdir -p ../../libraries/json2 && cd $_ && wget https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js
+    ```
+
+CONFIGURATION
+-------------
+
+  * Configuration is on a per view/display basis. Select 'Slideshow' as the
+    display format and then configure settings as desired under Format
+    Settings.
+
+  * See also:
+        https://www.ostraining.com/blog/drupal/drupal-8-slideshows
+
+
+MAINTAINERS
+-----------
+
+Current maintainers:
+
+  * vbouchet (https://www.drupal.org/u/vbouchet) (Initial port & primary 8.x-4.x maintainer)
+
+  * NickWilde (https://www.drupal.org/u/nickwilde) (Secondary 8.x-4.x maintainer)
+
+  * aaron (https://www.drupal.org/u/aaron)
+
+  * xiukun.zhou (https://www.drupal.org/u/xiukun.zhou)
+
+  * wangqizhong (https://www.drupal.org/u/wangqizhong)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/composer.json	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,19 @@
+{
+  "name": "drupal/views_slideshow",
+  "description": "Describes relationships between entities.",
+  "type": "drupal-module",
+  "license": "GPL-2.0+",
+  "homepage": "https://www.drupal.org/project/views_slideshow",
+  "authors": [
+    {
+      "name": "See contributors",
+      "homepage":"https://www.drupal.org/node/160350/committers"
+    }
+  ],
+  "support": {
+    "issues": "https://www.drupal.org/project/issues/views_slideshow",
+    "irc": "irc://irc.freenode.org/drupal-contribute",
+    "source": "https://cgit.drupalcode.org/views_slideshow"
+  },
+  "require": {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/config/schema/views.style.slideshow.schema.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,20 @@
+views.style.slideshow:
+  type: views_style
+  label: 'Slideshow'
+  mapping:
+    slideshow_skin:
+      type:  string
+      label: 'Skin to apply to the slideshow'
+    slideshow_type:
+      type: string
+      label: 'Main frame plugin to use to render the slideshow'
+    widgets:
+      type: mapping
+      label: 'Control widgets for the slideshow'
+      mapping:
+        top:
+          type: views_slideshow_control_group
+          label: 'Widget configuration for above the slideshow'
+        bottom:
+          type: views_slideshow_control_group
+          label: 'Widget configuration for below the slideshow'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/config/schema/views_slideshow.data_types.schema.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,55 @@
+# Basic data types for views slideshows.
+
+views_slideshow_widget:
+  type: mapping
+  label: 'widget'
+  mapping:
+    enable:
+      type: boolean
+      label: 'Show widget'
+    weight:
+      type: string
+      label: 'Sort order'
+    hide_on_single_slide:
+      type: string
+      label: 'Hide if only one slide'
+
+views_slideshow_control_group:
+  type: mapping
+  label: 'Group of widget settings for slideshow region'
+  mapping:
+    views_slideshow_controls:
+      type: views_slideshow_widget
+      label: 'Slideshow controls'
+      mapping:
+        enable:
+          type: boolean
+          label: 'Show widget'
+        weight:
+          type: string
+          label: 'Sort order'
+        hide_on_single_slide:
+          type: string
+          label: 'Hide if only one slide'
+        type:
+          type: string
+          label: 'The control type'
+    views_slideshow_slide_counter:
+      type: views_slideshow_widget
+      label: 'Slide Counter'
+    views_slideshow_pager:
+      type: views_slideshow_widget
+      label: 'Slideshow pager'
+      mapping:
+        enable:
+          type: boolean
+          label: 'Show widget'
+        weight:
+          type: string
+          label: 'Sort order'
+        hide_on_single_slide:
+          type: string
+          label: 'Hide if only one slide'
+        type:
+          type: string
+          label: 'The control type'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/css/controls_text.css	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,4 @@
+.views_slideshow_controls_text span:hover {
+  text-decoration: underline;
+  cursor: pointer;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/css/views-slideshow-pager-bullets.css	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,23 @@
+.views-slideshow-controls-bottom .views-slideshow-pager-bullets {
+  text-align: center;
+}
+
+.views-slideshow-controls-bottom .views-slideshow-pager-bullets li {
+  text-indent: -9999px;
+  cursor: pointer;
+  display: inline-block;
+  border-radius: 6px;
+  padding: 0 6px;
+  background: #222;
+  margin: 0.4em;
+  line-height: 12px;
+}
+
+.views-slideshow-controls-bottom .views-slideshow-pager-bullets li.active {
+  background: #AAA;
+  cursor: default;
+}
+
+.views-slideshow-controls-bottom .views-slideshow-pager-bullets li:hover {
+  background: #555;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/css/views_slideshow.css	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,7 @@
+#views-slideshow-form-wrapper .form-item.dependent-options {
+  padding-left: 5px;
+}
+
+#views-slideshow-form-wrapper .vs-dependent {
+  padding-left: 30px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/js/views_slideshow.js	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,484 @@
+(function ($, Drupal, drupalSettings) {
+  'use strict';
+  Drupal.viewsSlideshow = Drupal.viewsSlideshow || {};
+  var pagerLocation;
+  var slideNum;
+  var error;
+  var excludeMethods;
+  /**
+   * Views Slideshow Controls
+   */
+  Drupal.viewsSlideshowControls = Drupal.viewsSlideshowControls || {};
+
+  /**
+   * Implement the play hook for controls.
+   */
+  Drupal.viewsSlideshowControls.play = function (options) {
+    // Route the control call to the correct control type.
+    // Need to use try catch so we don't have to check to make sure every part
+    // of the object is defined.
+    try {
+      if (typeof drupalSettings.viewsSlideshowControls[options.slideshowID].top.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].top.type].play == 'function') {
+        Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].top.type].play(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+
+    try {
+      if (typeof drupalSettings.viewsSlideshowControls[options.slideshowID].bottom.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].bottom.type].play == 'function') {
+        Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].bottom.type].play(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+  };
+
+  /**
+   * Implement the pause hook for controls.
+   */
+  Drupal.viewsSlideshowControls.pause = function (options) {
+    // Route the control call to the correct control type.
+    // Need to use try catch so we don't have to check to make sure every part
+    // of the object is defined.
+    try {
+      if (typeof drupalSettings.viewsSlideshowControls[options.slideshowID].top.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].top.type].pause == 'function') {
+        Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].top.type].pause(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+
+    try {
+      if (typeof drupalSettings.viewsSlideshowControls[options.slideshowID].bottom.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].bottom.type].pause == 'function') {
+        Drupal[drupalSettings.viewsSlideshowControls[options.slideshowID].bottom.type].pause(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+  };
+
+
+  /**
+   * Views Slideshow Text Controls
+   */
+
+  // Add views slieshow api calls for views slideshow text controls.
+  Drupal.behaviors.viewsSlideshowControlsText = {
+    attach: function (context) {
+
+      // Process previous link
+      $('.views_slideshow_controls_text_previous:not(.views-slideshow-controls-text-previous-processed)', context).addClass('views-slideshow-controls-text-previous-processed').each(function () {
+        var uniqueID = $(this).attr('id').replace('views_slideshow_controls_text_previous_', '');
+        $(this).click(function () {
+          Drupal.viewsSlideshow.action({"action": 'previousSlide', "slideshowID": uniqueID});
+          return false;
+        });
+      });
+
+      // Process next link
+      $('.views_slideshow_controls_text_next:not(.views-slideshow-controls-text-next-processed)', context).addClass('views-slideshow-controls-text-next-processed').each(function () {
+        var uniqueID = $(this).attr('id').replace('views_slideshow_controls_text_next_', '');
+        $(this).click(function () {
+          Drupal.viewsSlideshow.action({"action": 'nextSlide', "slideshowID": uniqueID});
+          return false;
+        });
+      });
+
+      // Process pause link
+      $('.views_slideshow_controls_text_pause:not(.views-slideshow-controls-text-pause-processed)', context).addClass('views-slideshow-controls-text-pause-processed').each(function () {
+        var uniqueID = $(this).attr('id').replace('views_slideshow_controls_text_pause_', '');
+        $(this).click(function () {
+          if (drupalSettings.viewsSlideshow[uniqueID].paused) {
+            Drupal.viewsSlideshow.action({"action": 'play', "slideshowID": uniqueID, "force": true});
+          }
+          else {
+            Drupal.viewsSlideshow.action({"action": 'pause', "slideshowID": uniqueID, "force": true});
+          }
+          return false;
+        });
+      });
+    }
+  };
+
+  Drupal.viewsSlideshowControlsText = Drupal.viewsSlideshowControlsText || {};
+
+  /**
+   * Implement the pause hook for text controls.
+   */
+  Drupal.viewsSlideshowControlsText.pause = function (options) {
+    var pauseText = Drupal.theme.viewsSlideshowControlsPause ? Drupal.theme('viewsSlideshowControlsPause') : '';
+    var $element = $('#views_slideshow_controls_text_pause_' + options.slideshowID);
+    $element.find('a').text(pauseText);
+    $element.removeClass('views-slideshow-controls-text-status-play');
+    $element.addClass('views-slideshow-controls-text-status-pause');
+  };
+
+  /**
+   * Implement the play hook for text controls.
+   */
+  Drupal.viewsSlideshowControlsText.play = function (options) {
+    var playText = Drupal.theme.viewsSlideshowControlsPlay ? Drupal.theme('viewsSlideshowControlsPlay') : '';
+    var $element = $('#views_slideshow_controls_text_pause_' + options.slideshowID);
+    $element.find('a').text(playText);
+    $element.removeClass('views-slideshow-controls-text-status-pause');
+    $element.addClass('views-slideshow-controls-text-status-play');
+  };
+
+  // Theme the resume control.
+  Drupal.theme.viewsSlideshowControlsPause = function () {
+    return Drupal.t('Resume');
+  };
+
+  // Theme the pause control.
+  Drupal.theme.viewsSlideshowControlsPlay = function () {
+    return Drupal.t('Pause');
+  };
+
+  /**
+   * Views Slideshow Pager
+   */
+  Drupal.viewsSlideshowPager = Drupal.viewsSlideshowPager || {};
+
+  /**
+   * Implement the transitionBegin hook for pagers.
+   */
+  Drupal.viewsSlideshowPager.transitionBegin = function (options) {
+    // Route the pager call to the correct pager type.
+    // Need to use try catch so we don't have to check to make sure every part
+    // of the object is defined.
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager != "undefined" && typeof drupalSettings.viewsSlideshowPager[options.slideshowID].top.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].transitionBegin == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].transitionBegin(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager != "undefined" && typeof drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].transitionBegin == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].transitionBegin(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+  };
+
+  /**
+   * Implement the goToSlide hook for pagers.
+   */
+  Drupal.viewsSlideshowPager.goToSlide = function (options) {
+    // Route the pager call to the correct pager type.
+    // Need to use try catch so we don't have to check to make sure every part
+    // of the object is defined.
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager[options.slideshowID].top.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].goToSlide == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].goToSlide(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].goToSlide == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].goToSlide(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+  };
+
+  /**
+   * Implement the previousSlide hook for pagers.
+   */
+  Drupal.viewsSlideshowPager.previousSlide = function (options) {
+    // Route the pager call to the correct pager type.
+    // Need to use try catch so we don't have to check to make sure every part
+    // of the object is defined.
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager[options.slideshowID].top.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].previousSlide == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].previousSlide(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].previousSlide == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].previousSlide(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+  };
+
+  /**
+   * Implement the nextSlide hook for pagers.
+   */
+  Drupal.viewsSlideshowPager.nextSlide = function (options) {
+    // Route the pager call to the correct pager type.
+    // Need to use try catch so we don't have to check to make sure every part
+    // of the object is defined.
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager[options.slideshowID].top.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].nextSlide == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].top.type].nextSlide(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+
+    try {
+      if (typeof drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type != "undefined" && typeof Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].nextSlide == 'function') {
+        Drupal[drupalSettings.viewsSlideshowPager[options.slideshowID].bottom.type].nextSlide(options);
+      }
+    }
+    catch(err) {
+      // Don't need to do anything on error.
+    }
+  };
+
+
+  /**
+   * Views Slideshow Pager Fields
+   */
+
+  // Add views slieshow api calls for views slideshow pager fields.
+  Drupal.behaviors.viewsSlideshowPagerFields = {
+    attach: function (context) {
+      // Process pause on hover.
+      $('.views_slideshow_pager_field:not(.views-slideshow-pager-field-processed)', context).addClass('views-slideshow-pager-field-processed').each(function () {
+        // Parse out the location and unique id from the full id.
+        var pagerInfo = $(this).attr('id').split('_');
+        var location = pagerInfo[2];
+        pagerInfo.splice(0, 3);
+        var uniqueID = pagerInfo.join('_');
+
+        // Add the activate and pause on pager hover event to each pager item.
+        if (drupalSettings.viewsSlideshowPagerFields[uniqueID][location].activatePauseOnHover) {
+          $(this).children().each(function (index, pagerItem) {
+            var mouseIn = function () {
+              Drupal.viewsSlideshow.action({"action": 'goToSlide', "slideshowID": uniqueID, "slideNum": index});
+              Drupal.viewsSlideshow.action({"action": 'pause', "slideshowID": uniqueID});
+            };
+
+            var mouseOut = function () {
+              Drupal.viewsSlideshow.action({"action": 'play', "slideshowID": uniqueID});
+            };
+
+            if (jQuery.fn.hoverIntent) {
+              $(pagerItem).hoverIntent(mouseIn, mouseOut);
+            }
+            else {
+              $(pagerItem).hover(mouseIn, mouseOut);
+            }
+          });
+        }
+        else {
+          $(this).children().each(function (index, pagerItem) {
+            $(pagerItem).click(function () {
+              Drupal.viewsSlideshow.action({"action": 'goToSlide', "slideshowID": uniqueID, "slideNum": index});
+            });
+          });
+        }
+      });
+    }
+  };
+
+  Drupal.viewsSlideshowPagerFields = Drupal.viewsSlideshowPagerFields || {};
+
+  /**
+   * Implement the transitionBegin hook for pager fields pager.
+   */
+  Drupal.viewsSlideshowPagerFields.transitionBegin = function (options) {
+    for (pagerLocation in drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+      if (drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+        // Remove active class from pagers
+        $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"]').removeClass('active');
+
+        // Add active class to active pager.
+        $('#views_slideshow_pager_field_item_'+ pagerLocation + '_' + options.slideshowID + '_' + options.slideNum).addClass('active');
+      }
+    }
+  };
+
+  /**
+   * Implement the goToSlide hook for pager fields pager.
+   */
+  Drupal.viewsSlideshowPagerFields.goToSlide = function (options) {
+    for (pagerLocation in drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+      if (drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+        // Remove active class from pagers
+        $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"]').removeClass('active');
+
+        // Add active class to active pager.
+        $('#views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '_' + options.slideNum).addClass('active');
+      }
+    }
+  };
+
+  /**
+   * Implement the previousSlide hook for pager fields pager.
+   */
+  Drupal.viewsSlideshowPagerFields.previousSlide = function (options) {
+    for (pagerLocation in drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+      if (drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+        // Get the current active pager.
+        var pagerNum = $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"].active').attr('id').replace('views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '_', '');
+
+        // If we are on the first pager then activate the last pager.
+        // Otherwise activate the previous pager.
+        if (pagerNum === 0) {
+          pagerNum = $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"]').length() - 1;
+        }
+        else {
+          pagerNum--;
+        }
+
+        // Remove active class from pagers
+        $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"]').removeClass('active');
+
+        // Add active class to active pager.
+        $('#views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '_' + pagerNum).addClass('active');
+      }
+    }
+  };
+
+  /**
+   * Implement the nextSlide hook for pager fields pager.
+   */
+  Drupal.viewsSlideshowPagerFields.nextSlide = function (options) {
+    for (pagerLocation in drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+      if (drupalSettings.viewsSlideshowPager[options.slideshowID]) {
+        // Get the current active pager.
+        var pagerNum = $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"].active').attr('id').replace('views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '_', '');
+        var totalPagers = $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"]').length();
+
+        // If we are on the last pager then activate the first pager.
+        // Otherwise activate the next pager.
+        pagerNum++;
+        if (pagerNum === totalPagers) {
+          pagerNum = 0;
+        }
+
+        // Remove active class from pagers
+        $('[id^="views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '"]').removeClass('active');
+
+        // Add active class to active pager.
+        $('#views_slideshow_pager_field_item_' + pagerLocation + '_' + options.slideshowID + '_' + slideNum).addClass('active');
+      }
+    }
+  };
+
+  // Copy the pager hooks from fields pager to the bullets one.
+  Drupal.viewsSlideshowPagerBullets = Drupal.viewsSlideshowPagerFields || {};
+
+  /**
+   * Views Slideshow Slide Counter
+   */
+
+  Drupal.viewsSlideshowSlideCounter = Drupal.viewsSlideshowSlideCounter || {};
+
+  /**
+   * Implement the transitionBegin for the slide counter.
+   */
+  Drupal.viewsSlideshowSlideCounter.transitionBegin = function (options) {
+    $('#views_slideshow_slide_counter_' + options.slideshowID + ' .num').text(options.slideNum + 1);
+  };
+
+  /**
+   * This is used as a router to process actions for the slideshow.
+   */
+  Drupal.viewsSlideshow.action = function (options) {
+    // Set default values for our return status.
+    var status = {
+      'value': true,
+      'text': ''
+    };
+
+    // If an action isn't specified return false.
+    if (typeof options.action == 'undefined' || options.action === '') {
+      status.value = false;
+      status.text =  Drupal.t('There was no action specified.');
+      return error;
+    }
+
+    // If we are using pause or play switch paused state accordingly.
+    if (options.action === 'pause') {
+      drupalSettings.viewsSlideshow[options.slideshowID].paused = 1;
+      // If the calling method is forcing a pause then mark it as such.
+      if (options.force) {
+        drupalSettings.viewsSlideshow[options.slideshowID].pausedForce = 1;
+      }
+    }
+    else if (options.action === 'play') {
+      // If the slideshow isn't forced pause or we are forcing a play then play
+      // the slideshow.
+      // Otherwise return telling the calling method that it was forced paused.
+      if (!drupalSettings.viewsSlideshow[options.slideshowID].pausedForce || options.force) {
+        drupalSettings.viewsSlideshow[options.slideshowID].paused = 0;
+        drupalSettings.viewsSlideshow[options.slideshowID].pausedForce = 0;
+      }
+      else {
+        status.value = false;
+        status.text += ' ' + Drupal.t('This slideshow is forced paused.');
+        return status;
+      }
+    }
+
+    // We use a switch statement here mainly just to limit the type of actions
+    // that are available.
+    switch (options.action) {
+      case "goToSlide":
+      case "transitionBegin":
+      case "transitionEnd":
+        // The three methods above require a slide number. Checking if it is
+        // defined and it is a number that is an integer.
+        if (typeof options.slideNum == 'undefined' || typeof options.slideNum !== 'number' || parseInt(options.slideNum) !== (options.slideNum - 0)) {
+          status.value = false;
+          status.text = Drupal.t('An invalid integer was specified for slideNum.');
+        }
+      case "pause":
+      case "play":
+      case "nextSlide":
+      case "previousSlide":
+        // Grab our list of methods.
+        var methods = drupalSettings.viewsSlideshow[options.slideshowID]['methods'];
+
+        // if the calling method specified methods that shouldn't be called then
+        // exclude calling them.
+        var excludeMethodsObj = {};
+        if (typeof options.excludeMethods !== 'undefined') {
+          // We need to turn the excludeMethods array into an object so we can use the in
+          // function.
+          for (var i=0; i < excludeMethods.length; i++) {
+            excludeMethodsObj[excludeMethods[i]] = '';
+          }
+        }
+
+        // Call every registered method and don't call excluded ones.
+        for (var i = 0; i < methods[options.action].length; i++) {
+          if (Drupal[methods[options.action][i]] !== 'undefined' && typeof Drupal[methods[options.action][i]][options.action] == 'function' && !(methods[options.action][i] in excludeMethodsObj)) {
+            Drupal[methods[options.action][i]][options.action](options);
+          }
+        }
+        break;
+
+      // If it gets here it's because it's an invalid action.
+      default:
+        status.value = false;
+        status.text = Drupal.t('An invalid action "@action" was specified.', {"@action": options.action});
+    }
+    return status;
+  };
+})(jQuery, Drupal, drupalSettings);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/css/views_slideshow_cycle.css	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,27 @@
+.views_slideshow_cycle_no_display,
+.views_slideshow_cycle_hidden,
+.views_slideshow_cycle_controls,
+.views_slideshow_cycle_image_count {
+  display: none;
+}
+
+/* Pager Settings */
+
+.views_slideshow_cycle_pager div a img {
+  width: 75px;
+  height: 75px;
+}
+
+.views_slideshow_pager_numbered div,
+.views_slideshow_pager_thumbnails div {
+  display: inline;
+  padding-left: 10px;
+}
+
+.views_slideshow_cycle_pager.thumbnails a.activeSlide img {
+  border: 3px solid #000;
+}
+
+.views_slideshow_cycle_pager.numbered a.activeSlide {
+  text-decoration: underline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/drush.services.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,5 @@
+services:
+  views_slideshow_cycle.commands:
+    class: \Drupal\views_slideshow_cycle\Commands\ViewsSlideshowCycleCommands
+    tags:
+      - { name: drush.command }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/js/formoptions.js	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,141 @@
+
+/**
+ *  @file
+ *  Javascript to enhance the views slideshow cycle form options.
+ */
+
+/**
+ * This will set our initial behavior, by starting up each individual slideshow.
+ */
+(function ($) {
+  
+  // Since Drupal 7 doesn't support having a field based on one of 3 values of
+  // a select box we need to add our own JavaScript handling.
+  Drupal.behaviors.viewsSlideshowCycleAmountAllowedVisible = {
+    attach: function (context) {
+      
+      // If necessary at start hide the amount allowed visible box.
+      var type = $(":input[name='style_options[views_slideshow_cycle][pause_when_hidden_type]']").val();
+      if (type == 'full') {
+        $(":input[name='style_options[views_slideshow_cycle][amount_allowed_visible]']").parent().hide();
+      }
+      
+      // Handle dependency on action advanced checkbox.
+      $(":input[name='style_options[views_slideshow_cycle][action_advanced]']").change(function() {
+        processValues('action_advanced');
+      });
+      
+      // Handle dependency on pause when hidden checkbox.
+      $(':input[name="style_options[views_slideshow_cycle][pause_when_hidden]"]').change(function() {
+        processValues('pause_when_hidden');
+      });
+      
+      // Handle dependency on pause when hidden type select box.
+      $(":input[name='style_options[views_slideshow_cycle][pause_when_hidden_type]']").change(function() {
+        processValues('pause_when_hidden_type');
+      });
+      
+      // Process our dependencies.
+      function processValues(field) {
+        switch (field) {
+          case 'action_advanced':
+            if (!$(':input[name="style_options[views_slideshow_cycle][action_advanced]"]').is(':checked')) {
+              $(":input[name='style_options[views_slideshow_cycle][amount_allowed_visible]']").parent().hide();
+              break;
+            }
+          case 'pause_when_hidden':
+            if (!$(':input[name="style_options[views_slideshow_cycle][pause_when_hidden]"]').is(':checked')) {
+              $(":input[name='style_options[views_slideshow_cycle][amount_allowed_visible]']").parent().hide();
+              break;
+            }
+          case 'pause_when_hidden_type':
+            if ($(":input[name='style_options[views_slideshow_cycle][pause_when_hidden_type]']").val() == 'full') {
+              $(":input[name='style_options[views_slideshow_cycle][amount_allowed_visible]']").parent().hide();
+            }
+            else {
+              $(":input[name='style_options[views_slideshow_cycle][amount_allowed_visible]']").parent().show();
+            }
+        }
+      }
+    }
+  }
+  
+  // Manage advanced options 
+  Drupal.behaviors.viewsSlideshowCycleOptions = {
+    attach: function (context) {
+      if ($(":input[name='style_options[views_slideshow_cycle][advanced_options]']").length) {
+        $(":input[name='style_options[views_slideshow_cycle][advanced_options]']").parent().hide();
+        
+        $(":input[name='style_options[views_slideshow_cycle][advanced_options_entry]']").parent().after(
+          '<div style="margin-left: 10px; padding: 10px 0;">' + 
+            '<a id="edit-style-options-views-slideshow-cycle-advanced-options-update-link" href="#">' + Drupal.t('Update Advanced Option') + '</a>' +
+          '</div>'
+        );
+        
+        $("#edit-style-options-views-slideshow-cycle-advanced-options-table").append('<tr><th colspan="2">' + Drupal.t('Applied Options') + '</th><tr>')
+        
+        var initialValue = $(":input[name='style_options[views_slideshow_cycle][advanced_options]']").val();
+        var advancedOptions = JSON.parse(initialValue);
+        for (var option in advancedOptions) {
+          viewsSlideshowCycleAdvancedOptionsAddRow(option);
+        }
+        
+        // Add the remove event to the advanced items.
+        viewsSlideshowCycleAdvancedOptionsRemoveEvent();
+        
+        $(":input[name='style_options[views_slideshow_cycle][advanced_options_choices]']").change(function() {
+          var selectedValue = $(":input[name='style_options[views_slideshow_cycle][advanced_options_choices]'] option:selected").val();
+          if (typeof advancedOptions[selectedValue] !== 'undefined') {
+            $(":input[name='style_options[views_slideshow_cycle][advanced_options_entry]']").val(advancedOptions[selectedValue]);
+          }
+          else {
+            $(":input[name='style_options[views_slideshow_cycle][advanced_options_entry]']").val('');
+          }
+        });
+    
+        $('#edit-style-options-views-slideshow-cycle-advanced-options-update-link').click(function() {
+          var option = $(":input[name='style_options[views_slideshow_cycle][advanced_options_choices]']").val();
+          if (option) {
+            var value = $(":input[name='style_options[views_slideshow_cycle][advanced_options_entry]']").val();
+          
+            if (typeof advancedOptions[option] == 'undefined') {
+              viewsSlideshowCycleAdvancedOptionsAddRow(option);
+              viewsSlideshowCycleAdvancedOptionsRemoveEvent()
+            }
+            advancedOptions[option] = value;
+            viewsSlideshowCycleAdvancedOptionsSave();
+          }
+          
+          return false;
+        });
+      }
+      
+      function viewsSlideshowCycleAdvancedOptionsAddRow(option) {
+        $("#edit-style-options-views-slideshow-cycle-advanced-options-table").append(
+          '<tr id="views-slideshow-cycle-advanced-options-table-row-' + option + '">' +
+            '<td>' + option + '</td>' +
+            '<td style="width: 20px;">' +
+              '<a style="margin-top: 6px" title="Remove ' + option + '" alt="Remove ' + option + '" class="views-hidden views-button-remove views-slideshow-cycle-advanced-options-table-remove" id="views-slideshow-cycle-advanced-options-table-remove-' + option + '" href="#"><span>Remove</span></a>' +
+            '</td>' +
+          '</tr>'
+        );
+      }
+      
+      function viewsSlideshowCycleAdvancedOptionsRemoveEvent() {
+        $('.views-slideshow-cycle-advanced-options-table-remove').unbind().click(function() {
+          var itemID = $(this).attr('id');
+          var uniqueID = itemID.replace('views-slideshow-cycle-advanced-options-table-remove-', '');
+          delete advancedOptions[uniqueID];
+          $('#views-slideshow-cycle-advanced-options-table-row-' + uniqueID).remove();
+          viewsSlideshowCycleAdvancedOptionsSave();
+          return false;
+        });
+      }
+      
+      function viewsSlideshowCycleAdvancedOptionsSave() {
+        var advancedOptionsString = JSON.stringify(advancedOptions);
+        $(":input[name='style_options[views_slideshow_cycle][advanced_options]']").val(advancedOptionsString);
+      }
+    }
+  }
+})(jQuery, Drupal);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/js/views_slideshow_cycle.js	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,602 @@
+
+/**
+ *  @file
+ *  A simple jQuery Cycle Div Slideshow Rotator.
+ */
+
+/**
+ * This will set our initial behavior, by starting up each individual slideshow.
+ */
+(function ($, Drupal, drupalSettings) {
+    Drupal.behaviors.viewsSlideshowCycle = {
+        attach: function (context) {
+            $('.views_slideshow_cycle_main:not(.viewsSlideshowCycle-processed)', context).addClass('viewsSlideshowCycle-processed').each(function() {
+                var fullId = '#' + $(this).attr('id');
+                var settings = drupalSettings.viewsSlideshowCycle[fullId];
+                settings.targetId = '#' + $(fullId + " :first").attr('id');
+
+                settings.slideshowId = settings.targetId.replace('#views_slideshow_cycle_teaser_section_', '');
+                // Pager after function.
+                var pager_after_fn = function(curr, next, opts) {
+                    // Need to do some special handling on first load.
+                    var slideNum = opts.currSlide;
+                    if (typeof settings.processedAfter == 'undefined' || !settings.processedAfter) {
+                        settings.processedAfter = 1;
+                        slideNum = (typeof settings.opts.startingSlide == 'undefined') ? 0 : settings.opts.startingSlide;
+                    }
+                    Drupal.viewsSlideshow.action({ "action": 'transitionEnd', "slideshowID": settings.slideshowId, "slideNum": slideNum });
+                }
+                // Pager before function.
+                var pager_before_fn = function(curr, next, opts) {
+                    var slideNum = opts.nextSlide;
+
+                    // Remember last slide.
+                    if (settings.remember_slide) {
+                        createCookie(settings.vss_id, slideNum, settings.remember_slide_days);
+                    }
+
+                    // Make variable height.
+                    if (!settings.fixed_height) {
+                        //get the height of the current slide
+                        var $ht = $(next).height();
+                        //set the container's height to that of the current slide
+                        $(next).parent().animate({height: $ht});
+                    }
+
+                    // Need to do some special handling on first load.
+                    if (typeof settings.processedBefore == 'undefined' || !settings.processedBefore) {
+                        settings.processedBefore = 1;
+                        slideNum = (typeof opts.startingSlide == 'undefined') ? 0 : opts.startingSlide;
+                    }
+
+                    Drupal.viewsSlideshow.action({ "action": 'transitionBegin', "slideshowID": settings.slideshowId, "slideNum": slideNum });
+                }
+                settings.loaded = false;
+
+                settings.opts = {
+                    speed:settings.speed,
+                    timeout:settings.timeout,
+                    delay:settings.delay,
+                    sync:settings.sync,
+                    random:settings.random,
+                    nowrap:settings.nowrap,
+                    after:pager_after_fn,
+                    before:pager_before_fn,
+                    cleartype:(settings.cleartype)? true : false,
+                    cleartypeNoBg:(settings.cleartypenobg)? true : false
+                }
+
+                // Set the starting slide if we are supposed to remember the slide
+                if (settings.remember_slide) {
+                    var startSlide = readCookie(settings.vss_id);
+                    if (startSlide == null) {
+                        startSlide = 0;
+                    }
+                    settings.opts.startingSlide = parseInt(startSlide);
+                }
+
+                if (settings.effect == 'none') {
+                    settings.opts.speed = 1;
+                }
+                else {
+                    settings.opts.fx = settings.effect;
+                }
+
+                // Take starting item from fragment.
+                var hash = location.hash;
+                if (hash) {
+                    var hash = hash.replace('#', '');
+                    var aHash = hash.split(';');
+                    var aHashLen = aHash.length;
+
+                    // Loop through all the possible starting points.
+                    for (var i = 0; i < aHashLen; i++) {
+                        // Split the hash into two parts. One part is the slideshow id the
+                        // other is the slide number.
+                        var initialInfo = aHash[i].split(':');
+                        // The id in the hash should match our slideshow.
+                        // The slide number chosen shouldn't be larger than the number of
+                        // slides we have.
+                        if (settings.slideshowId == initialInfo[0] && settings.num_divs > initialInfo[1]) {
+                            settings.opts.startingSlide = parseInt(initialInfo[1]);
+                        }
+                    }
+                }
+
+                // Pause on hover.
+                if (settings.pause) {
+                    var mouseIn = function() {
+                        Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId });
+                    }
+
+                    var mouseOut = function() {
+                        Drupal.viewsSlideshow.action({ "action": 'play', "slideshowID": settings.slideshowId });
+                    }
+
+                    if (jQuery.fn.hoverIntent) {
+                        $('#views_slideshow_cycle_teaser_section_' + settings.vss_id).hoverIntent(mouseIn, mouseOut);
+                    }
+                    else {
+                        $('#views_slideshow_cycle_teaser_section_' + settings.vss_id).hover(mouseIn, mouseOut);
+                    }
+                }
+
+                // Pause on clicking of the slide.
+                if (settings.pause_on_click) {
+                    $('#views_slideshow_cycle_teaser_section_' + settings.vss_id).click(function() {
+                        Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId, "force": true });
+                    });
+                }
+
+                if (typeof JSON != 'undefined' && typeof settings.advanced_options != 'undefined') {
+                    var advancedOptions = JSON.parse(settings.advanced_options);
+                    for (var option in advancedOptions) {
+                        switch(option) {
+
+                            // Standard Options
+                            case "activePagerClass":
+                            case "allowPagerClickBubble":
+                            case "autostop":
+                            case "autostopCount":
+                            case "backwards":
+                            case "bounce":
+                            case "cleartype":
+                            case "cleartypeNoBg":
+                            case "containerResize":
+                            case "continuous":
+                            case "delay":
+                            case "easeIn":
+                            case "easeOut":
+                            case "easing":
+                            case "fastOnEvent":
+                            case "fit":
+                            case "fx":
+                            case "height":
+                            case "manualTrump":
+                            case "metaAttr":
+                            case "next":
+                            case "nowrap":
+                            case "pager":
+                            case "pagerEvent":
+                            case "pause":
+                            case "pauseOnPagerHover":
+                            case "prev":
+                            case "prevNextEvent":
+                            case "random":
+                            case "randomizeEffects":
+                            case "requeueOnImageNotLoaded":
+                            case "requeueTimeout":
+                            case "rev":
+                            case "slideExpr":
+                            case "slideResize":
+                            case "speed":
+                            case "speedIn":
+                            case "speedOut":
+                            case "startingSlide":
+                            case "sync":
+                            case "timeout":
+                            case "width":
+                                var optionValue = advancedOptions[option];
+                                optionValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(optionValue);
+                                settings.opts[option] = optionValue;
+                                break;
+
+                            // These process options that look like {top:50, bottom:20}
+                            case "animIn":
+                            case "animOut":
+                            case "cssBefore":
+                            case "cssAfter":
+                            case "shuffle":
+                                var cssValue = advancedOptions[option];
+                                cssValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(cssValue);
+                                settings.opts[option] = eval('(' + cssValue + ')');
+                                break;
+
+                            // These options have their own functions.
+                            case "after":
+                                var afterValue = advancedOptions[option];
+                                afterValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(afterValue);
+                                // transition callback (scope set to element that was shown): function(currSlideElement, nextSlideElement, options, forwardFlag)
+                                settings.opts[option] = function(currSlideElement, nextSlideElement, options, forwardFlag) {
+                                    pager_after_fn(currSlideElement, nextSlideElement, options);
+                                    eval(afterValue);
+                                }
+                                break;
+
+                            case "before":
+                                var beforeValue = advancedOptions[option];
+                                beforeValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(beforeValue);
+                                // transition callback (scope set to element to be shown):     function(currSlideElement, nextSlideElement, options, forwardFlag)
+                                settings.opts[option] = function(currSlideElement, nextSlideElement, options, forwardFlag) {
+                                    pager_before_fn(currSlideElement, nextSlideElement, options);
+                                    eval(beforeValue);
+                                }
+                                break;
+
+                            case "end":
+                                var endValue = advancedOptions[option];
+                                endValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(endValue);
+                                // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
+                                settings.opts[option] = function(options) {
+                                    eval(endValue);
+                                }
+                                break;
+
+                            case "fxFn":
+                                var fxFnValue = advancedOptions[option];
+                                fxFnValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(fxFnValue);
+                                // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
+                                settings.opts[option] = function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag) {
+                                    eval(fxFnValue);
+                                }
+                                break;
+
+                            case "onPagerEvent":
+                                var onPagerEventValue = advancedOptions[option];
+                                onPagerEventValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(onPagerEventValue);
+                                settings.opts[option] = function(zeroBasedSlideIndex, slideElement) {
+                                    eval(onPagerEventValue);
+                                }
+                                break;
+
+                            case "onPrevNextEvent":
+                                var onPrevNextEventValue = advancedOptions[option];
+                                onPrevNextEventValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(onPrevNextEventValue);
+                                settings.opts[option] = function(isNext, zeroBasedSlideIndex, slideElement) {
+                                    eval(onPrevNextEventValue);
+                                }
+                                break;
+
+                            case "pagerAnchorBuilder":
+                                var pagerAnchorBuilderValue = advancedOptions[option];
+                                pagerAnchorBuilderValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(pagerAnchorBuilderValue);
+                                // callback fn for building anchor links:  function(index, DOMelement)
+                                settings.opts[option] = function(index, DOMelement) {
+                                    var returnVal = '';
+                                    eval(pagerAnchorBuilderValue);
+                                    return returnVal;
+                                }
+                                break;
+
+                            case "pagerClick":
+                                var pagerClickValue = advancedOptions[option];
+                                pagerClickValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(pagerClickValue);
+                                // callback fn for pager clicks:    function(zeroBasedSlideIndex, slideElement)
+                                settings.opts[option] = function(zeroBasedSlideIndex, slideElement) {
+                                    eval(pagerClickValue);
+                                }
+                                break;
+
+                            case "paused":
+                                var pausedValue = advancedOptions[option];
+                                pausedValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(pausedValue);
+                                // undocumented callback when slideshow is paused:    function(cont, opts, byHover)
+                                settings.opts[option] = function(cont, opts, byHover) {
+                                    eval(pausedValue);
+                                }
+                                break;
+
+                            case "resumed":
+                                var resumedValue = advancedOptions[option];
+                                resumedValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(resumedValue);
+                                // undocumented callback when slideshow is resumed:    function(cont, opts, byHover)
+                                settings.opts[option] = function(cont, opts, byHover) {
+                                    eval(resumedValue);
+                                }
+                                break;
+
+                            case "timeoutFn":
+                                var timeoutFnValue = advancedOptions[option];
+                                timeoutFnValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(timeoutFnValue);
+                                settings.opts[option] = function(currSlideElement, nextSlideElement, options, forwardFlag) {
+                                    eval(timeoutFnValue);
+                                }
+                                break;
+
+                            case "updateActivePagerLink":
+                                var updateActivePagerLinkValue = advancedOptions[option];
+                                updateActivePagerLinkValue = Drupal.viewsSlideshowCycle.advancedOptionCleanup(updateActivePagerLinkValue);
+                                // callback fn invoked to update the active pager link (adds/removes activePagerClass style)
+                                settings.opts[option] = function(pager, currSlideIndex) {
+                                    eval(updateActivePagerLinkValue);
+                                }
+                                break;
+                        }
+                    }
+                }
+
+                // If selected wait for the images to be loaded.
+                // otherwise just load the slideshow.
+                if (settings.wait_for_image_load) {
+                    // For IE/Chrome/Opera we if there are images then we need to make
+                    // sure the images are loaded before starting the slideshow.
+                    settings.totalImages = $(settings.targetId + ' img').length;
+                    if (settings.totalImages) {
+                        settings.loadedImages = 0;
+
+                        // Add a load event for each image.
+                        $(settings.targetId + ' img').each(function() {
+                            var $imageElement = $(this);
+                            $imageElement.bind('load', function () {
+                                Drupal.viewsSlideshowCycle.imageWait(fullId);
+                            });
+
+                            // Removing the source and adding it again will fire the load event.
+                            var imgSrc = $imageElement.attr('src');
+                            $imageElement.attr('src', '');
+                            $imageElement.attr('src', imgSrc);
+                        });
+
+                        // We need to set a timeout so that the slideshow doesn't wait
+                        // indefinitely for all images to load.
+                        setTimeout("Drupal.viewsSlideshowCycle.load('" + fullId + "')", settings.wait_for_image_load_timeout);
+                    }
+                    else {
+                        Drupal.viewsSlideshowCycle.load(fullId);
+                    }
+                }
+                else {
+                    Drupal.viewsSlideshowCycle.load(fullId);
+                }
+            });
+        }
+    };
+
+    Drupal.viewsSlideshowCycle = Drupal.viewsSlideshowCycle || {};
+
+    // Cleanup the values of advanced options.
+    Drupal.viewsSlideshowCycle.advancedOptionCleanup = function(value) {
+        value = $.trim(value);
+        value = value.replace(/\n/g, '');
+        if (!isNaN(parseInt(value))) {
+            value = parseInt(value);
+        }
+        else if (value.toLowerCase() == 'true') {
+            value = true;
+        }
+        else if (value.toLowerCase() == 'false') {
+            value = false;
+        }
+
+        return value;
+    }
+
+    // This checks to see if all the images have been loaded.
+    // If they have then it starts the slideshow.
+    Drupal.viewsSlideshowCycle.imageWait = function(fullId) {
+        if (++drupalSettings.viewsSlideshowCycle[fullId].loadedImages == drupalSettings.viewsSlideshowCycle[fullId].totalImages) {
+            Drupal.viewsSlideshowCycle.load(fullId);
+        }
+    };
+
+    // Start the slideshow.
+    Drupal.viewsSlideshowCycle.load = function (fullId) {
+        var settings = drupalSettings.viewsSlideshowCycle[fullId];
+
+        // Make sure the slideshow isn't already loaded.
+        if (!settings.loaded) {
+            $(settings.targetId).cycle(settings.opts);
+            settings.loaded = true;
+
+            // Start Paused
+            if (settings.start_paused) {
+                Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId, "force": true });
+            }
+
+            // Pause if hidden.
+            if (settings.pause_when_hidden) {
+                var checkPause = function(settings) {
+                    // If the slideshow is visible and it is paused then resume.
+                    // otherwise if the slideshow is not visible and it is not paused then
+                    // pause it.
+                    var visible = viewsSlideshowCycleIsVisible(settings.targetId, settings.pause_when_hidden_type, settings.amount_allowed_visible);
+                    if (visible) {
+                        Drupal.viewsSlideshow.action({ "action": 'play', "slideshowID": settings.slideshowId });
+                    }
+                    else {
+                        Drupal.viewsSlideshow.action({ "action": 'pause', "slideshowID": settings.slideshowId });
+                    }
+                }
+
+                // Check when scrolled.
+                $(window).scroll(function() {
+                    checkPause(settings);
+                });
+
+                // Check when the window is resized.
+                $(window).resize(function() {
+                    checkPause(settings);
+                });
+            }
+        }
+    };
+
+    Drupal.viewsSlideshowCycle.pause = function (options) {
+        //Eat TypeError, cycle doesn't handle pause well if options isn't defined.
+        try{
+            if (options.pause_in_middle && $.fn.pause) {
+                $('#views_slideshow_cycle_teaser_section_' + options.slideshowID).pause();
+            }
+            else {
+                $('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('pause');
+            }
+        }
+        catch(e){
+            if(!e instanceof TypeError){
+                throw e;
+            }
+        }
+    };
+
+    Drupal.viewsSlideshowCycle.play = function (options) {
+        drupalSettings.viewsSlideshowCycle['#views_slideshow_cycle_main_' + options.slideshowID].paused = false;
+        if (options.pause_in_middle && $.fn.resume) {
+            $('#views_slideshow_cycle_teaser_section_' + options.slideshowID).resume();
+        }
+        else {
+            $('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('resume');
+        }
+    };
+
+    Drupal.viewsSlideshowCycle.previousSlide = function (options) {
+        $('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('prev');
+    };
+
+    Drupal.viewsSlideshowCycle.nextSlide = function (options) {
+        $('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle('next');
+    };
+
+    Drupal.viewsSlideshowCycle.goToSlide = function (options) {
+        $('#views_slideshow_cycle_teaser_section_' + options.slideshowID).cycle(options.slideNum);
+    };
+
+    // Verify that the value is a number.
+    function IsNumeric(sText) {
+        var ValidChars = "0123456789";
+        var IsNumber=true;
+        var Char;
+
+        for (var i=0; i < sText.length && IsNumber == true; i++) {
+            Char = sText.charAt(i);
+            if (ValidChars.indexOf(Char) == -1) {
+                IsNumber = false;
+            }
+        }
+        return IsNumber;
+    }
+
+    /**
+     * Cookie Handling Functions
+     */
+    function createCookie(name,value,days) {
+        if (days) {
+            var date = new Date();
+            date.setTime(date.getTime()+(days*24*60*60*1000));
+            var expires = "; expires="+date.toGMTString();
+        }
+        else {
+            var expires = "";
+        }
+        document.cookie = name+"="+value+expires+"; path=/";
+    }
+
+    function readCookie(name) {
+        var nameEQ = name + "=";
+        var ca = document.cookie.split(';');
+        for(var i=0;i < ca.length;i++) {
+            var c = ca[i];
+            while (c.charAt(0)==' ') c = c.substring(1,c.length);
+            if (c.indexOf(nameEQ) == 0) {
+                return c.substring(nameEQ.length,c.length);
+            }
+        }
+        return null;
+    }
+
+    function eraseCookie(name) {
+        createCookie(name,"",-1);
+    }
+
+    /**
+     * Checks to see if the slide is visible enough.
+     * elem = element to check.
+     * type = The way to calculate how much is visible.
+     * amountVisible = amount that should be visible. Either in percent or px. If
+     *                it's not defined then all of the slide must be visible.
+     *
+     * Returns true or false
+     */
+    function viewsSlideshowCycleIsVisible(elem, type, amountVisible) {
+        // Get the top and bottom of the window;
+        var docViewTop = $(window).scrollTop();
+        var docViewBottom = docViewTop + $(window).height();
+        var docViewLeft = $(window).scrollLeft();
+        var docViewRight = docViewLeft + $(window).width();
+
+        // Get the top, bottom, and height of the slide;
+        var elemTop = $(elem).offset().top;
+        var elemHeight = $(elem).height();
+        var elemBottom = elemTop + elemHeight;
+        var elemLeft = $(elem).offset().left;
+        var elemWidth = $(elem).width();
+        var elemRight = elemLeft + elemWidth;
+        var elemArea = elemHeight * elemWidth;
+
+        // Calculate what's hiding in the slide.
+        var missingLeft = 0;
+        var missingRight = 0;
+        var missingTop = 0;
+        var missingBottom = 0;
+
+        // Find out how much of the slide is missing from the left.
+        if (elemLeft < docViewLeft) {
+            missingLeft = docViewLeft - elemLeft;
+        }
+
+        // Find out how much of the slide is missing from the right.
+        if (elemRight > docViewRight) {
+            missingRight = elemRight - docViewRight;
+        }
+
+        // Find out how much of the slide is missing from the top.
+        if (elemTop < docViewTop) {
+            missingTop = docViewTop - elemTop;
+        }
+
+        // Find out how much of the slide is missing from the bottom.
+        if (elemBottom > docViewBottom) {
+            missingBottom = elemBottom - docViewBottom;
+        }
+
+        // If there is no amountVisible defined then check to see if the whole slide
+        // is visible.
+        if (type == 'full') {
+            return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
+            && (elemBottom <= docViewBottom) &&  (elemTop >= docViewTop)
+            && (elemLeft >= docViewLeft) && (elemRight <= docViewRight)
+            && (elemLeft <= docViewRight) && (elemRight >= docViewLeft));
+        }
+        else if(type == 'vertical') {
+            var verticalShowing = elemHeight - missingTop - missingBottom;
+
+            // If user specified a percentage then find out if the current shown percent
+            // is larger than the allowed percent.
+            // Otherwise check to see if the amount of px shown is larger than the
+            // allotted amount.
+            if (amountVisible.indexOf('%')) {
+                return (((verticalShowing/elemHeight)*100) >= parseInt(amountVisible));
+            }
+            else {
+                return (verticalShowing >= parseInt(amountVisible));
+            }
+        }
+        else if(type == 'horizontal') {
+            var horizontalShowing = elemWidth - missingLeft - missingRight;
+
+            // If user specified a percentage then find out if the current shown percent
+            // is larger than the allowed percent.
+            // Otherwise check to see if the amount of px shown is larger than the
+            // allotted amount.
+            if (amountVisible.indexOf('%')) {
+                return (((horizontalShowing/elemWidth)*100) >= parseInt(amountVisible));
+            }
+            else {
+                return (horizontalShowing >= parseInt(amountVisible));
+            }
+        }
+        else if(type == 'area') {
+            var areaShowing = (elemWidth - missingLeft - missingRight) * (elemHeight - missingTop - missingBottom);
+
+            // If user specified a percentage then find out if the current shown percent
+            // is larger than the allowed percent.
+            // Otherwise check to see if the amount of px shown is larger than the
+            // allotted amount.
+            if (amountVisible.indexOf('%')) {
+                return (((areaShowing/elemArea)*100) >= parseInt(amountVisible));
+            }
+            else {
+                return (areaShowing >= parseInt(amountVisible));
+            }
+        }
+    }
+})(jQuery, Drupal, drupalSettings);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/src/Commands/ViewsSlideshowCycleCommands.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,132 @@
+<?php
+namespace Drupal\views_slideshow_cycle\Commands;
+
+use Drush\Commands\DrushCommands;
+
+/**
+ * Drush commands for Views Slideshow Cycle.
+ */
+class ViewsSlideshowCycleCommands extends DrushCommands {
+
+  /**
+   * Download and install the jQuery Cycle library.
+   *
+   * @command views:slideshow:cycle
+   * @aliases dl-cycle,views-slideshow-cycle-cycle
+   */
+  public function downloadCycle() {
+    $this->installLibrary(
+      'jQuery Cycle',
+      'libraries/jquery.cycle',
+      'jquery.cycle.all.js',
+      'https://raw.githubusercontent.com/malsup/cycle/3.0.3/jquery.cycle.all.js'
+    );
+  }
+
+  /**
+   * Download and install the JSON2 library.
+   *
+   * @command views:slideshow:json2
+   * @aliases dl-json2,views-slideshow-cycle-json2
+   */
+  public function downloadJson2() {
+    $this->installLibrary(
+      'JSON2',
+      'libraries/json2',
+      'json2.js',
+      'https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js'
+    );
+  }
+
+  /**
+   * Download and install the jquery.hoverIntent library.
+   *
+   * @command views:slideshow:hoverintent
+   * @aliases dl-hoverintent,views-slideshow-cycle-hoverintent
+   */
+  public function downloadHoverIntent() {
+    $this->installLibrary(
+      'jQuery HoverIntent',
+      'libraries/jquery.hoverIntent',
+      'jquery.hoverIntent.js',
+      'https://raw.githubusercontent.com/briancherne/jquery-hoverIntent/master/jquery.hoverIntent.js'
+    );
+  }
+
+  /**
+   * Download and install the jQuery.pause library.
+   *
+   * @command views:slideshow:pause
+   * @aliases dl-pause,views-slideshow-cycle-pause
+   */
+  public function downloadPause() {
+    $this->installLibrary(
+      'jQuery Pause',
+      'libraries/jquery.pause',
+      'jquery.pause.js',
+      'https://raw.githubusercontent.com/tobia/Pause/master/jquery.pause.js'
+    );
+  }
+
+  /**
+   * Download and install the jQuery Cycle, jQuery hoverIntent, JSON2 and Pause libraries.
+   *
+   * @command views:slideshow:lib
+   * @aliases dl-cycle-lib,views-slideshow-cycle-lib
+   */
+  public function downloadLib() {
+    $this->downloadCycle();
+    $this->downloadHoverIntent();
+    $this->downloadJson2();
+    $this->downloadPause();
+  }
+
+  /**
+   * Helper function to download a library in the given directory.
+   */
+  protected function installLibrary($name, $path, $filename, $url) {
+    // Create the path if it does not exist.
+    if (!is_dir($path)) {
+      drush_op('mkdir', $path, 0755, TRUE);
+      $this->logger()->info(dt('Directory @path was created', ['@path' => $path]));
+    }
+
+    // Be sure we can write in the directory.
+    $perms = substr(sprintf('%o', fileperms($path)), -4);
+    if ($perms !== '0755') {
+      drush_shell_exec('chmod 755 ' . $path);
+    }
+    else {
+      $perms = NULL;
+    }
+
+    $dir = getcwd();
+
+    // Download the JavaScript file.
+    if (is_file($path . '/' . $filename)) {
+      $this->logger()->notice(dt('@name appears to be already installed.', [
+        '@name' => $name,
+      ]));
+    }
+    elseif (drush_op('chdir', $path) && drush_shell_exec('wget ' . $url)) {
+      $this->logger()->success(dt('The latest version of @name has been downloaded to @path', [
+        '@name' => $name,
+        '@path' => $path,
+      ]));
+    }
+    else {
+      $this->logger()->warning(dt('Drush was unable to download the @name library to @path', [
+        '@name' => $name,
+        '@path' => $path,
+      ]));
+    }
+
+    chdir($dir);
+
+    // Restore the previous permissions.
+    if ($perms) {
+      drush_shell_exec('chmod ' . $perms . ' ' . $path);
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/src/Plugin/ViewsSlideshowType/Cycle.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,569 @@
+<?php
+
+namespace Drupal\views_slideshow_cycle\Plugin\ViewsSlideshowType;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
+use Drupal\views_slideshow\ViewsSlideshowTypeBase;
+use Drupal\Core\Link;
+
+/**
+ * Provides a slideshow type based on jquery cycle.
+ *
+ * @ViewsSlideshowType(
+ *   id = "views_slideshow_cycle",
+ *   label = @Translation("Cycle"),
+ *   accepts = {
+ *     "goToSlide",
+ *     "nextSlide",
+ *     "pause",
+ *     "play",
+ *     "previousSlide"
+ *   },
+ *   calls = {
+ *     "transitionBegin",
+ *     "transitionEnd",
+ *     "goToSlide",
+ *     "pause",
+ *     "play",
+ *     "nextSlide",
+ *     "previousSlide"
+ *   }
+ * )
+ */
+class Cycle extends ViewsSlideshowTypeBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'contains' => [
+        // Transition.
+        'effect' => ['default' => 'fade'],
+        'transition_advanced' => ['default' => 0],
+        'timeout' => ['default' => 5000],
+        'speed' => ['default' => 700],
+        'delay' => ['default' => 0],
+        'sync' => ['default' => 1],
+        'random' => ['default' => 0],
+        // Action.
+        'pause' => ['default' => 1],
+        'pause_on_click' => ['default' => 0],
+        'action_advanced' => ['default' => 0],
+        'start_paused' => ['default' => 0],
+        'remember_slide' => ['default' => 0],
+        'remember_slide_days' => ['default' => 1],
+        'pause_in_middle' => ['default' => 0],
+        'pause_when_hidden' => ['default' => 0],
+        'pause_when_hidden_type' => ['default' => 'full'],
+        'amount_allowed_visible' => ['default' => ''],
+        'nowrap' => ['default' => 0],
+        'fixed_height' => ['default' => 1],
+        'items_per_slide' => ['default' => 1],
+        'items_per_slide_first' => array('default' => FALSE),
+        'items_per_slide_first_number' => array('default' => 1),
+        'wait_for_image_load' => ['default' => 1],
+        'wait_for_image_load_timeout' => ['default' => 3000],
+
+        // Internet Explorer Tweaks.
+        'cleartype' => ['default' => 'true'],
+        'cleartypenobg' => ['default' => 'false'],
+
+        // Advanced.
+        'advanced_options' => ['default' => '{}'],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $cycle = \Drupal::service('library.discovery')->getLibraryByName('views_slideshow_cycle', 'jquery_cycle');
+    if (!isset($cycle['js'][0]['data']) || !file_exists($cycle['js'][0]['data'])) {
+      $form['views_slideshow_cycle']['no_cycle_js'] = [
+        '#markup' => '<div style="color: red">' . $this->t('You need to install the jQuery cycle plugin. Create a directory in libraries (which should be in your Drupal root folder, if not create the same) called jquery.cycle, and then copy jquery.cycle.all.js into it. You can find the plugin at @url.',
+          [
+            '@url' => Link::fromTextAndUrl('http://malsup.com/jquery/cycle', Url::FromUri('http://malsup.com/jquery/cycle'), [
+              'attributes' => ['target' => '_blank'],
+            ])->toString(),
+          ]) . '</div>',
+      ];
+    }
+
+    // Transition.
+    $form['views_slideshow_cycle']['transition'] = [
+      '#markup' => '<h2>' . $this->t('Transition') . '</h2>',
+    ];
+
+    $effects = [
+      'none' => 'none',
+      'blindX' => 'blindX',
+      'blindY' => 'blindY',
+      'blindZ' => 'blindZ',
+      'cover' => 'cover',
+      'curtainX' => 'curtainX',
+      'curtainY' => 'curtainY',
+      'fade' => 'fade',
+      'fadeZoom' => 'fadeZoom',
+      'growX' => 'growX',
+      'growY' => 'growY',
+      'scrollUp' => 'scrollUp',
+      'scrollDown' => 'scrollDown',
+      'scrollLeft' => 'scrollLeft',
+      'scrollRight' => 'scrollRight',
+      'scrollHorz' => 'scrollHorz',
+      'scrollVert' => 'scrollVert',
+      'shuffle' => 'shuffle',
+      'slideX' => 'slideX',
+      'slideY' => 'slideY',
+      'toss' => 'toss',
+      'turnUp' => 'turnUp',
+      'turnDown' => 'turnDown',
+      'turnLeft' => 'turnLeft',
+      'turnRight' => 'turnRight',
+      'uncover' => 'uncover',
+      'wipe' => 'wipe',
+      'zoom' => 'zoom',
+    ];
+    $form['views_slideshow_cycle']['effect'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Effect'),
+      '#options' => $effects,
+      '#default_value' => $this->getConfiguration()['effect'],
+      '#description' => $this->t('The transition effect that will be used to change between images. Not all options below may be relevant depending on the effect. <a href="http://jquery.malsup.com/cycle/browser.html" target="_black">Follow this link to see examples of each effect.</a>'),
+    ];
+
+    // Transition advanced options.
+    $form['views_slideshow_cycle']['transition_advanced'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('View Transition Advanced Options'),
+      '#default_value' => $this->getConfiguration()['transition_advanced'],
+    ];
+
+    // Need to wrap this so it indents correctly.
+    $form['views_slideshow_cycle']['transition_advanced_wrapper'] = [
+      '#markup' => '<div class="vs-dependent">',
+    ];
+
+    $form['views_slideshow_cycle']['timeout'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Timer delay'),
+      '#default_value' => $this->getConfiguration()['timeout'],
+      '#description' => $this->t('Amount of time in milliseconds between transitions. Set the value to 0 to not rotate the slideshow automatically.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][transition_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['speed'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Speed'),
+      '#default_value' => $this->getConfiguration()['speed'],
+      '#description' => $this->t('Time in milliseconds that each transition lasts. Numeric only!'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][transition_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['delay'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Initial slide delay offset'),
+      '#default_value' => $this->getConfiguration()['delay'],
+      '#description' => $this->t('Amount of time in milliseconds for the first slide to transition. This number will be added to Timer delay to create the initial delay.  For example if Timer delay is 4000 and Initial delay is 2000 then the first slide will change at 6000ms (6 seconds).  If Initial delay is -2000 then the first slide will change at 2000ms (2 seconds).'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][transition_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['sync'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Sync'),
+      '#default_value' => $this->getConfiguration()['sync'],
+      '#description' => $this->t('The sync option controls whether the slide transitions occur simultaneously. The default is selected which means that the current slide transitions out as the next slide transitions in. By unselecting this option you can get some interesting twists on your transitions.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][transition_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['random'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Random'),
+      '#description' => $this->t('This option controls the order items are displayed. The default setting, unselected, uses the views ordering. Selected will cause the images to display in a random order.'),
+      '#default_value' => $this->getConfiguration()['random'],
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][transition_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+
+    $form['views_slideshow_cycle']['transition_advanced_wrapper_close'] = [
+      '#markup' => '</div>',
+    ];
+
+    // Action.
+    $form['views_slideshow_cycle']['action'] = [
+      '#markup' => '<h2>' . $this->t('Action') . '</h2>',
+    ];
+    $form['views_slideshow_cycle']['pause'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Pause on hover'),
+      '#default_value' => $this->getConfiguration()['pause'],
+      '#description' => $this->t('Pause when hovering on the slideshow image.'),
+    ];
+    $form['views_slideshow_cycle']['pause_on_click'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Pause On Click'),
+      '#default_value' => $this->getConfiguration()['pause_on_click'],
+      '#description' => $this->t('Pause when the slide is clicked.'),
+    ];
+
+    // Action Advanced Options.
+    $form['views_slideshow_cycle']['action_advanced'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('View Action Advanced Options'),
+      '#default_value' => $this->getConfiguration()['action_advanced'],
+    ];
+
+    // Need to wrap this so it indents correctly.
+    $form['views_slideshow_cycle']['action_advanced_wrapper'] = [
+      '#markup' => '<div class="vs-dependent">',
+    ];
+
+    $form['views_slideshow_cycle']['start_paused'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Start Slideshow Paused'),
+      '#default_value' => $this->getConfiguration()['start_paused'],
+      '#description' => $this->t('Start the slideshow in the paused state.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['remember_slide'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Start On Last Slide Viewed'),
+      '#default_value' => $this->getConfiguration()['remember_slide'],
+      '#description' => $this->t('When the user leaves a page with a slideshow and comes back start them on the last slide viewed.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['remember_slide_days'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Length of Time to Remember Last Slide'),
+      '#default_value' => $this->getConfiguration()['remember_slide_days'],
+      '#description' => $this->t('The number of days to have the site remember the last slide. Default is 1'),
+      '#prefix' => '<div class="vs-dependent">',
+      '#suffix' => '</div>',
+      '#size' => 4,
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+          ':input[name="style_options[views_slideshow_cycle][remember_slide]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+
+    // @todo Check if there is a better way to detect optional libraries.
+    $pause = \Drupal::service('library.discovery')->getLibraryByName('views_slideshow_cycle', 'jquery_pause');
+    if (isset($pause['js'][0]['data']) && file_exists($pause['js'][0]['data'])) {
+      $form['views_slideshow_cycle']['pause_in_middle'] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Pause The Slideshow In The Middle of the Transition'),
+        '#default_value' => $this->getConfiguration()['pause_in_middle'],
+        '#description' => $this->t('When pausing the slideshow allow it to pause in the middle of tranistioning and not finish the transition until unpaused.'),
+        '#states' => [
+          'visible' => [
+            ':input[name="style_options[views_slideshow_cycle][transition_advanced]"]' => ['checked' => TRUE],
+          ],
+        ],
+      ];
+    }
+
+    $form['views_slideshow_cycle']['pause_when_hidden'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Pause When the Slideshow is Not Visible'),
+      '#default_value' => $this->getConfiguration()['pause_when_hidden'],
+      '#description' => $this->t('When the slideshow is scrolled out of view or when a window is resized that hides the slideshow, this will pause the slideshow.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['pause_when_hidden_type'] = [
+      '#type' => 'select',
+      '#title' => $this->t('How to Calculate Amount of Slide that Needs to be Shown'),
+      '#options' => [
+        'full' => $this->t('Entire slide'),
+        'vertical' => $this->t('Set amount of vertical'),
+        'horizontal' => $this->t('Set amount of horizontal'),
+        'area' => $this->t('Set total area of the slide'),
+      ],
+      '#default_value' => $this->getConfiguration()['pause_when_hidden_type'],
+      '#description' => $this->t('Choose how to calculate how much of the slide has to be shown. Entire Slide: All the slide has to be shown. Vertical: Set amount of height that has to be shown. Horizontal: Set amount of width that has to be shown. Area: Set total area that has to be shown.'),
+      '#prefix' => '<div class="vs-dependent">',
+      '#suffix' => '</div>',
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+          ':input[name="style_options[views_slideshow_cycle][pause_when_hidden]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['amount_allowed_visible'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Amount of Slide Needed to be Shown'),
+      '#default_value' => $this->getConfiguration()['amount_allowed_visible'],
+      '#description' => $this->t("The amount of the slide that needs to be shown to have it rotate. You can set the value in percentage (ex: 50%) or in pixels (ex: 250). The slidehsow will not rotate until it's height/width/total area, depending on the calculation method you have chosen above, is less than the value you have entered in this field."),
+      '#size' => 4,
+    ];
+    $form['views_slideshow_cycle']['#attached']['library'][] = 'views_slideshow_cycle/formoptions';
+    $form['views_slideshow_cycle']['nowrap'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('End slideshow after last slide'),
+      '#default_value' => $this->getConfiguration()['nowrap'],
+      '#description' => $this->t('If selected the slideshow will end when it gets to the last slide.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['fixed_height'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Make the slide window height fit the largest slide'),
+      '#default_value' => $this->getConfiguration()['fixed_height'],
+      '#description' => $this->t('If unselected then if the slides are different sizes the height of the slide area will change as the slides change.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['items_per_slide'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Items per slide'),
+      '#default_value' => $this->getConfiguration()['items_per_slide'],
+      '#description' => $this->t('The number of items per slide'),
+      '#size' => 4,
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['items_per_slide_first'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Different first slide'),
+      '#default_value' => $this->getConfiguration()['items_per_slide_first'],
+      '#description' => $this->t('Different number of items for the first slide'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['items_per_slide_first_number'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Items for first slide'),
+      '#default_value' => $this->getConfiguration()['items_per_slide_first_number'],
+      '#description' => $this->t('The number of items for the first slide'),
+      '#size' => 4,
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+          ':input[name="style_options[views_slideshow_cycle][items_per_slide_first]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['wait_for_image_load'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Wait for all the slide images to load'),
+      '#default_value' => $this->getConfiguration()['wait_for_image_load'],
+      '#description' => $this->t('If selected the slideshow will not start unless all the slide images are loaded.  This will fix some issues on IE7/IE8/Chrome/Opera.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['views_slideshow_cycle']['wait_for_image_load_timeout'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Timeout'),
+      '#default_value' => $this->getConfiguration()['wait_for_image_load_timeout'],
+      '#description' => $this->t('How long should it wait until it starts the slideshow anyway. Time is in milliseconds.'),
+      '#prefix' => '<div class="vs-dependent">',
+      '#suffix' => '</div>',
+      '#states' => [
+        'visible' => [
+          ':input[name="style_options[views_slideshow_cycle][action_advanced]"]' => ['checked' => TRUE],
+          ':input[name="style_options[views_slideshow_cycle][wait_for_image_load]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+
+    // Need to wrap this so it indents correctly.
+    $form['views_slideshow_cycle']['action_advanced_wrapper_close'] = [
+      '#markup' => '</div>',
+    ];
+
+    // Internet Explorer Tweaks.
+    $form['views_slideshow_cycle']['ie_tweaks'] = [
+      '#markup' => '<h2>' . $this->t('Internet Explorer Tweaks') . '</h2>',
+    ];
+    $form['views_slideshow_cycle']['cleartype'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('ClearType'),
+      '#default_value' => $this->getConfiguration()['cleartype'],
+      '#description' => $this->t('Select if clearType corrections should be applied (for IE).  Some background issues could be fixed by unselecting this option.'),
+    ];
+    $form['views_slideshow_cycle']['cleartypenobg'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('ClearType Background'),
+      '#default_value' => $this->getConfiguration()['cleartypenobg'],
+      '#description' => $this->t('Select to disable extra cleartype fixing.  Unselect to force background color setting on slides)'),
+    ];
+
+    // Advanced Options.
+    $form['views_slideshow_cycle']['advanced_options_header'] = [
+      '#markup' => '<h2>' . $this->t('jQuery Cycle Custom Options') . '</h2>',
+    ];
+
+    // @todo Check if there is a better way to detect optional libraries.
+    $json2 = \Drupal::service('library.discovery')->getLibraryByName('views_slideshow_cycle', 'json2');
+    if (!isset($json2['js'][0]['data']) || !file_exists($json2['js'][0]['data'])) {
+      // @todo Check if there is a better way to create this target _blank link.
+      $form['views_slideshow_cycle']['no_json_js'] = [
+        '#markup' => '<div>' . $this->t('To use the advanced options you need to download json2.js. You can do this by clicking the download button at <a href="https://github.com/douglascrockford/JSON-js" target="_black">https://github.com/douglascrockford/JSON-js</a> and extract json2.js to libraries/json2') . '</div>',
+      ];
+    }
+    else {
+      // @todo Check if there is a better way to create this target _blank link.
+      $form['views_slideshow_cycle']['advanced_options_info'] = [
+        '#markup' => '<p>' . $this->t('You can find a list of all the available options at <a href="http://malsup.com/jquery/cycle/options.html" target="_blank">http://malsup.com/jquery/cycle/options.html</a>. If one of the options you add uses a function, example fxFn, then you need to only enter what goes inside the function call. The variables that are in the documentation on the jquery cycle site will be available to you.') . '</p>',
+      ];
+
+      // All the jquery cycle options according to
+      // http://malsup.com/jquery/cycle/options.html
+      $cycle_options = [
+        0 => 'Select One',
+        'activePagerClass' => 'activePagerClass',
+        'after' => 'after',
+        'allowPagerClickBubble' => 'allowPagerClickBubble',
+        'animIn' => 'animIn',
+        'animOut' => 'animOut',
+        'autostop' => 'autostop',
+        'autostopCount' => 'autostopCount',
+        'backwards' => 'backwards',
+        'before' => 'before',
+        'bounce' => 'bounce',
+        'cleartype' => 'cleartype',
+        'cleartypeNoBg' => 'cleartypeNoBg',
+        'containerResize' => 'containerResize',
+        'continuous' => 'continuous',
+        'cssAfter' => 'cssAfter',
+        'cssBefore' => 'cssBefore',
+        'delay' => 'delay',
+        'easeIn' => 'easeIn',
+        'easeOut' => 'easeOut',
+        'easing' => 'easing',
+        'end' => 'end',
+        'fastOnEvent' => 'fastOnEvent',
+        'fit' => 'fit',
+        'fx' => 'fx',
+        'fxFn' => 'fxFn',
+        'height' => 'height',
+        'manualTrump' => 'manualTrump',
+        'metaAttr' => 'metaAttr',
+        'next' => 'next',
+        'nowrap' => 'nowrap',
+        'onPagerEvent' => 'onPagerEvent',
+        'onPrevNextEvent' => 'onPrevNextEvent',
+        'pager' => 'pager',
+        'pagerAnchorBuilder' => 'pagerAnchorBuilder',
+        'pagerEvent' => 'pagerEvent',
+        'pause' => 'pause',
+        'paused' => 'paused',
+        'pauseOnPagerHover' => 'pauseOnPagerHover',
+        'prev' => 'prev',
+        'prevNextEvent' => 'prevNextEvent',
+        'random' => 'random',
+        'randomizeEffects' => 'randomizeEffects',
+        'requeueOnImageNotLoaded' => 'requeueOnImageNotLoaded',
+        'requeueTimeout' => 'requeueTimeout',
+        'resumed' => 'resumed',
+        'rev' => 'rev',
+        'shuffle' => 'shuffle',
+        'slideExpr' => 'slideExpr',
+        'slideResize' => 'slideResize',
+        'speed' => 'speed',
+        'speedIn' => 'speedIn',
+        'speedOut' => 'speedOut',
+        'startingSlide' => 'startingSlide',
+        'sync' => 'sync',
+        'timeout' => 'timeout',
+        'timeoutFn' => 'timeoutFn',
+        'updateActivePagerLink' => 'updateActivePagerLink',
+        'width' => 'width',
+      ];
+
+      $form['views_slideshow_cycle']['advanced_options_choices'] = [
+        '#type' => 'select',
+        '#title' => $this->t('Advanced Options'),
+        '#options' => $cycle_options,
+      ];
+
+      $form['views_slideshow_cycle']['advanced_options_entry'] = [
+        '#type' => 'textarea',
+        '#title' => $this->t('Advanced Option Value'),
+        '#description' => $this->t('It is important that you click the Update link when you make any changes to the options or those changes will not be saved when you save the form.'),
+      ];
+
+      $form['views_slideshow_cycle']['advanced_options'] = [
+        '#type' => 'textarea',
+        '#default_value' => $this->getConfiguration()['advanced_options'],
+      ];
+
+      // @todo: Review how to create this table.
+      $form['views_slideshow_cycle']['advanced_options_table'] = [
+        '#markup' => '<table style="width: 400px; margin-left: 10px;" id="edit-style-options-views-slideshow-cycle-advanced-options-table"></table>',
+      ];
+    }
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $values = $form_state->getValue(['style_options', 'views_slideshow_cycle']);
+    if (!is_numeric($values['timeout'])) {
+      $form_state->setErrorByName('style_options][views_slideshow_cycle][timeout', $this->t('@setting must be numeric!',
+        ['@setting' => $this->t('Timeout')]
+      ));
+    }
+    if (!is_numeric($values['speed'])) {
+      $form_state->setErrorByName('style_options][views_slideshow_cycle][speed', $this->t('@setting must be numeric!',
+        ['@setting' => $this->t('Speed')]
+      ));
+    }
+    if (!is_numeric($values['remember_slide_days'])) {
+      $form_state->setErrorByName('style_options][views_slideshow_cycle][remember_slide_days', $this->t('@setting must be numeric!',
+        ['@setting' => $this->t('Slide days')]
+      ));
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle-main-frame-row-item.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,21 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an item on a views slideshow cycle slide.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the element.
+ * - count: The slide number.
+ * - item: Rendeder field(s) making up item.
+ * - item_count: nth item on slide.
+ * - length: Total number of slides.
+ * - view: The view.
+ *
+ * @see template_preprocess_views_slideshow_cycle_main_frame_row_item()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div {{ attributes.addClass(classes) }}>
+  {{ item }}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle-main-frame-row.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,21 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an individual views slideshow cycle slide.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the element.
+ * - count: The slide number.
+ * - rendered_items: Rendered items for slide.
+ * - vss_id: The slideshow's id.
+ *
+ * @see template_preprocess_views_slideshow_()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div id="views_slideshow_cycle_div_{{ vss_id }}_{{ count }}" {{ attributes.addClass(classes) }}>
+  {% for rendered_item in rendered_items %}
+    {{ rendered_item }}
+  {% endfor %}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle-main-frame.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an views slideshow cycle main frame.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the element.
+ * - rendered_rows: The slides.
+ * - vss_id: The slideshow id.
+ *
+ * @see template_preprocess_views_slideshow_cycle_main_frame()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div id="views_slideshow_cycle_teaser_section_{{ vss_id }}" {{ attributes.addClass(classes) }}>
+  {% for rendered_row in rendered_rows %}
+   {{ rendered_row }}
+  {% endfor %}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/templates/views-slideshow-cycle.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,31 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow with cycle main plugin.
+ *
+ * Available variables:
+ * - bottom_widget_rendered: Widget under the slideshow with controls/data.
+ * - skin: The skin being applied to the slideshow.
+ * - slideshow: The slideshow.
+ * - top_widget_rendered: Widget above the slideshow with controls/data.
+ *
+ * @see _views_slideshow_preprocess_views_view_slideshow()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div class="skin-{{ skin }}">
+  {% if top_widget_rendered %}
+    <div class="views-slideshow-controls-top clearfix">
+      {{ top_widget_rendered }}
+    </div>
+  {% endif %}
+
+  {{ slideshow }}
+
+  {% if bottom_widget_rendered %}
+    <div class="views-slideshow-controls-bottom clearfix">
+      {{ bottom_widget_rendered }}
+    </div>
+  {% endif %}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.drush.inc	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,197 @@
+<?php
+
+/**
+ * @file
+ * Drush integration for Views Slideshow.
+ *
+ * Specifically downloading of required and optional JavaScript libraries.
+ */
+
+/**
+ * Implements hook_drush_command().
+ */
+function views_slideshow_cycle_drush_command() {
+  $items = [];
+
+  // The key in the $items array is the name of the command.
+  $items['views-slideshow-cycle-cycle'] = [
+    'description' => dt('Download and install the jQuery Cycle library.'),
+    'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
+    'arguments' => [
+      'path' => dt('Optional. The path to install the jQuery Cycle library in. If omitted Drush will use the default location.'),
+    ],
+    'aliases' => ['dl-cycle'],
+  ];
+  $items['views-slideshow-cycle-json2'] = [
+    'description' => dt('Download and install the JSON2 library.'),
+    'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
+    'arguments' => [
+      'path' => dt('Optional. The path to install the JSON2 library in. If omitted Drush will use the default location.'),
+    ],
+    'aliases' => ['dl-json2'],
+  ];
+  $items['views-slideshow-cycle-hoverintent'] = [
+    'description' => dt('Download and install the jquery.hoverIntent library.'),
+    'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
+    'arguments' => [
+      'path' => dt('Optional. The path to install the jquery.hoverIntent library in. If omitted Drush will use the default location.'),
+    ],
+    'aliases' => ['dl-hoverintent'],
+  ];
+  $items['views-slideshow-cycle-pause'] = [
+    'description' => dt('Download and install the jQuery.pause library.'),
+    'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
+    'arguments' => [
+      'path' => dt('Optional. The path to install the jQuery.pause library in. If omitted Drush will use the default location.'),
+    ],
+    'aliases' => ['dl-pause'],
+  ];
+  $items['views-slideshow-cycle-lib'] = [
+    'description' => dt('Download and install the jQuery Cycle, jQuery hoverIntent and JSON2 libraries.'),
+    'bootstrap' => DRUSH_BOOTSTRAP_DRUSH,
+    'aliases' => ['dl-cycle-lib'],
+  ];
+  return $items;
+}
+
+/**
+ * Implements hook_drush_help().
+ */
+function views_slideshow_cycle_drush_help($section) {
+  switch ($section) {
+    case 'drush:views-slideshow-cycle-cycle':
+      return dt('Download and install the jQuery Cycle library from http://malsup.github.com/jquery.cycle.all.js, default location is libraries/jquery.cycle.');
+
+    case 'drush:views-slideshow-cycle-hoverintent':
+      return dt('Download and install the jQuery hoverIntent library from https://raw.githubusercontent.com/briancherne/jquery-hoverIntent/master/jquery.hoverIntent.js, default location is libraries/jquery.cycle.');
+
+    case 'drush:views-slideshow-cycle-pause':
+      return dt('Download and install the jQuery pause library from https://raw.githubusercontent.com/tobia/Pause/master/jquery.pause.js, default location is libraries/jquery.pause.');
+
+    case 'drush:views-slideshow-cycle-json2':
+      return dt('Download and install the JSON2 library from https://github.com/douglascrockford/JSON-js/, default location is libraries/json2.');
+
+    case 'drush:views-slideshow-cycle-lib':
+      return dt('Download and install the jQuery Cycle, jQuery hoverIntent and JSON2 libraries.');
+  }
+}
+
+/**
+ * Command to download the jQuery Cycle library.
+ */
+function drush_views_slideshow_cycle_cycle() {
+  _drush_views_slideshow_cycle_install_library(
+    'jQuery Cycle',
+    'libraries/jquery.cycle',
+    'jquery.cycle.all.js',
+    'https://raw.githubusercontent.com/malsup/cycle/3.0.3/jquery.cycle.all.js',
+    func_get_args()
+  );
+}
+
+/**
+ * Command to download the JSON2 library.
+ */
+function drush_views_slideshow_cycle_json2() {
+  _drush_views_slideshow_cycle_install_library(
+    'JSON2',
+    'libraries/json2',
+    'json2.js',
+    'https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js',
+    func_get_args()
+  );
+}
+
+/**
+ * Command to download the jQuery.hoverIntent library.
+ */
+function drush_views_slideshow_cycle_hoverintent() {
+  _drush_views_slideshow_cycle_install_library(
+    'jQuery HoverIntent',
+    'libraries/jquery.hoverIntent',
+    'jquery.hoverIntent.js',
+    'https://raw.githubusercontent.com/briancherne/jquery-hoverIntent/master/jquery.hoverIntent.js',
+    func_get_args()
+  );
+}
+
+/**
+ * Command to download the jQuery.pause library.
+ */
+function drush_views_slideshow_cycle_pause() {
+  _drush_views_slideshow_cycle_install_library(
+    'jQuery Pause',
+    'libraries/jquery.pause',
+    'jquery.pause.js',
+    'https://raw.githubusercontent.com/tobia/Pause/master/jquery.pause.js',
+    func_get_args()
+  );
+}
+
+/**
+ * Command to download all libraries.
+ */
+function drush_views_slideshow_cycle_lib() {
+  drush_views_slideshow_cycle_cycle();
+  drush_views_slideshow_cycle_json2();
+  drush_views_slideshow_cycle_hoverintent();
+  drush_views_slideshow_cycle_pause();
+}
+
+/**
+ * Implements drush_MODULE_pre_pm_enable().
+ */
+function drush_views_slideshow_cycle_pre_pm_enable() {
+  $modules = drush_get_context('PM_ENABLE_MODULES');
+  if (in_array('views_slideshow_cycle', $modules) && !drush_get_option('skip')) {
+    drush_views_slideshow_cycle_lib();
+  }
+}
+
+/**
+ * Helper function to download a library in the given directory.
+ */
+function _drush_views_slideshow_cycle_install_library($name, $path, $filename, $url, $args) {
+  // Check if path provided as an arg and use that instead of default if so.
+  if (!empty($args[0])) {
+    $path = $args[0];
+  }
+
+  // Create the path if it does not exist.
+  if (!is_dir($path)) {
+    drush_op('mkdir', $path, 0755, TRUE);
+    drush_log(dt('Directory @path was created', ['@path' => $path]), 'success');
+  }
+
+  // Be sure we can write in the directory.
+  $perms = substr(sprintf('%o', fileperms($path)), -4);
+  if ($perms !== '0755') {
+    drush_shell_exec('chmod 755 ' . $path);
+  }
+
+  $dir = getcwd();
+
+  // Download the JavaScript file.
+  if (is_file($path . '/' . $filename)) {
+    drush_log(dt('@name appears to be already installed.', [
+      '@name' => $name,
+    ]), 'ok');
+  }
+  elseif (drush_op('chdir', $path) && drush_shell_exec('wget --no-check-certificate ' . $url)) {
+    drush_log(dt('The latest version of @name has been downloaded to @path', [
+      '@name' => $name,
+      '@path' => $path,
+    ]), 'success');
+  }
+  else {
+    drush_log(dt('Drush was unable to download the @name library to @path', [
+      '@name' => $name,
+      '@path' => $path,
+    ]), 'error');
+  }
+
+  chdir($dir);
+
+  // Restore the previous permissions.
+  drush_shell_exec('chmod ' . $perms . ' ' . $path);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.info.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,13 @@
+name: Views Slideshow Cycle
+type: module
+description: 'Adds a Rotating slideshow mode to Views Slideshow.'
+package: Views
+# core: 8.x
+dependencies:
+  - views_slideshow:views_slideshow
+
+# Information added by Drupal.org packaging script on 2017-11-18
+version: '8.x-4.6'
+core: '8.x'
+project: 'views_slideshow'
+datestamp: 1510987088
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.libraries.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,51 @@
+formoptions:
+  js:
+    js/formoptions.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+
+views_slideshow_cycle:
+  css:
+    component:
+      css/views_slideshow_cycle.css: {}
+  js:
+    js/views_slideshow_cycle.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/drupalSettings
+
+jquery_cycle:
+  remote: http://malsup.github.io/jquery.cycle.all.js
+  version: 3.0.3
+  license:
+    name: MIT
+    url: http://jquery.malsup.com/license.html
+    gpl-compatible: true
+  js:
+    /libraries/jquery.cycle/jquery.cycle.all.js: {}
+  dependencies:
+    - core/jquery
+
+json2:
+  remote: https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js
+  version: 2.0
+  license:
+    name: MIT
+    url: https://github.com/douglascrockford/JSON-js/blob/master/README
+    gpl-compatible: true
+  js:
+    /libraries/json2/json2.js: {}
+
+jquery_pause:
+  remote: https://github.com/tobia/Pause
+  version: 3.0.3
+  license:
+    name: GNU
+    url: https://raw.githubusercontent.com/tobia/Pause/master/LICENSE.txt
+    gpl-compatible: true
+  js:
+    /libraries/jquery.pause/jquery.pause.js: {}
+  dependencies:
+    - core/jquery
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.module	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,95 @@
+<?php
+
+/**
+ * @file
+ * Views Slideshow: cycle is typically used for field views.
+ */
+
+use Drupal\Core\Url;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Link;
+
+/**
+ * Implements hook_help().
+ */
+function views_slideshow_cycle_help($route_name, RouteMatchInterface $route_match) {
+  switch ($route_name) {
+    case 'help.page.views_slideshow_cycle':
+      if (\Drupal::moduleHandler()->moduleExists('advanced_help')) {
+        $output = '<p>' . Link::fromTextAndUrl(t('Click here to view the documentation for Views Slideshow Cycle.'), Url::fromRoute('advanced_help.module_index', ['module' => 'views_slideshow_cycle'])->toString()) . '</p>';
+      }
+      else {
+        $output = '<p>' . t('Views Slideshow Cycle help can be found by installing and enabling the @advanced_help', ['@advanced_help' => Link::fromTextAndUrl(t('Advanced Help module'), Url::fromUri('http://drupal.org/project/advanced_help'))->toString()]) . '</p>';
+      }
+      return $output;
+  }
+}
+
+/**
+ * Implements hook_theme().
+ */
+function views_slideshow_cycle_theme($existing, $type, $theme, $path) {
+  return [
+    'views_slideshow_cycle' => [
+      'variables' => [
+        'view' => NULL,
+        'settings' => [],
+        'rows' => [],
+        'title' => '',
+      ],
+      'template' => 'views-slideshow-cycle',
+      'file' => 'views_slideshow_cycle.theme.inc',
+    ],
+    'views_slideshow_cycle_main_frame' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => NULL,
+        'rows' => NULL,
+      ],
+      'template' => 'views-slideshow-cycle-main-frame',
+      'file' => 'views_slideshow_cycle.theme.inc',
+    ],
+    'views_slideshow_cycle_main_frame_row' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'items' => NULL,
+        'count' => NULL,
+        'view' => NULL,
+      ],
+      'template' => 'views-slideshow-cycle-main-frame-row',
+      'file' => 'views_slideshow_cycle.theme.inc',
+    ],
+    'views_slideshow_cycle_main_frame_row_item' => [
+      'variables' => [
+        'item' => NULL,
+        'item_count' => NULL,
+        'count' => NULL,
+        'view' => NULL,
+        'length' => NULL,
+      ],
+      'template' => 'views-slideshow-cycle-main-frame-row-item',
+      'file' => 'views_slideshow_cycle.theme.inc',
+    ],
+  ];
+}
+
+/**
+ * Implements hook_preprocess_views_slideshow_pager_fields().
+ *
+ * As it is a preprocess function, store it with other functions in theme.inc.
+ */
+function views_slideshow_cycle_preprocess_views_slideshow_pager_fields(&$vars) {
+  \Drupal::moduleHandler()->loadInclude('views_slideshow_cycle', 'inc', 'views_slideshow_cycle.theme');
+  _views_slideshow_cycle_preprocess_views_slideshow_pager_fields($vars);
+}
+
+/**
+ * Implements hook_preprocess_views_slideshow_slide_counter().
+ *
+ * As it is a preprocess function, store it with other functions in theme.inc.
+ */
+function views_slideshow_cycle_preprocess_views_slideshow_slide_counter(&$vars) {
+  \Drupal::moduleHandler()->loadInclude('views_slideshow_cycle', 'inc', 'views_slideshow_cycle.theme');
+  _views_slideshow_cycle_preprocess_views_slideshow_slide_counter($vars);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/modules/views_slideshow_cycle/views_slideshow_cycle.theme.inc	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,255 @@
+<?php
+
+/**
+ * @file
+ * Theme & preprocess functions for the Views Slideshow: cycle module.
+ */
+
+use Drupal\Component\Utility\Html;
+
+/**
+ * Views Slideshow: Theme the main frame wrapper.
+ *
+ * @ingroup vss_theme
+ */
+function template_preprocess_views_slideshow_cycle_main_frame(&$vars) {
+  $settings = $vars['settings'];
+  $rows = $vars['rows'];
+  $vss_id = $vars['vss_id'];
+
+  // Cast the strings into int or bool as necessary.
+  $new_settings = [];
+  foreach ($settings as $key => $value) {
+    if (is_string($value)) {
+      $value = str_replace("\n", ' ', $value);
+
+      $value = trim($value);
+
+      if (is_numeric($value)) {
+        $value = (int) $value;
+      }
+      elseif (strtolower($value) == 'true') {
+        $value = TRUE;
+      }
+      elseif (strtolower($value) == 'false') {
+        $value = FALSE;
+      }
+    }
+
+    $new_settings[$key] = $value;
+  }
+
+  $num_divs = count($rows);
+  if ($settings['items_per_slide_first']) {
+    $num_divs -= $settings['items_per_slide_first_number'];
+    $num_divs = $num_divs / $settings['items_per_slide'];
+    $num_divs += 1;
+  }
+  else {
+    $num_divs = $num_divs / $settings['items_per_slide'];
+  }
+
+  $settings = array_merge(
+    [
+      'num_divs' => ceil($num_divs),
+      'id_prefix' => '#views_slideshow_cycle_main_',
+      'div_prefix' => '#views_slideshow_cycle_div_',
+      'vss_id' => $vss_id,
+    ],
+    $new_settings
+  );
+
+  // We need to go through the current js setting values to make sure the one we
+  // want to add is not already there. If it is already there then append -[num]
+  // to the id to make it unique.
+  $slideshow_count = 1;
+  global $_views_slideshow_processedCycles;
+  if (is_array($_views_slideshow_processedCycles)) {
+    foreach ($_views_slideshow_processedCycles as $processedCycle) {
+      if (stristr($processedCycle, '#views_slideshow_cycle_main_' . $vss_id)) {
+        $slideshow_count++;
+      }
+    }
+  }
+
+  if ($slideshow_count > 1) {
+    $vss_id .= '-' . $slideshow_count;
+    $settings['vss_id'] = $vss_id;
+  }
+
+  // Load the json2 library.
+  if (!empty($settings['advanced_options'])) {
+    $vars['#attached']['library'][] = 'views_slideshow_cycle/json2';
+  }
+
+  // Load the pause library.
+  if (!empty($settings['pause_in_middle'])) {
+    $vars['#attached']['library'][] = 'views_slideshow_cycle/jquery_pause';
+  }
+
+  // Load jQuery Cycle library.
+  $vars['#attached']['library'][] = 'views_slideshow_cycle/jquery_cycle';
+
+  // Load our custom cycle library.
+  $vars['#attached']['library'][] = 'views_slideshow_cycle/views_slideshow_cycle';
+  $vars['#attached']['drupalSettings']['viewsSlideshowCycle']['#views_slideshow_cycle_main_' . $vss_id] = $settings;
+
+  $_views_slideshow_processedCycles['#views_slideshow_cycle_main_' . $vss_id] = '#views_slideshow_cycle_main_' . $vss_id;
+
+  // Add hover intent library.
+  if ($settings['pause']) {
+    $vars['#attached']['library'][] = 'views_slideshow/jquery_hoverIntent';
+  }
+
+  // Add the slideshow elements.
+  $vars['attributes']['class'][] = 'views_slideshow_cycle_teaser_section';
+
+  $vars['items_per_slide'] = $settings['items_per_slide'];
+
+  $items = [];
+  $index = 0;
+  $vars['rendered_rows'] = [];
+  foreach ($rows as $count => $item) {
+    $items[] = $item;
+    if ($settings['items_per_slide_first'] && empty($vars['rendered_rows'])) {
+      if (count($items) == $settings['items_per_slide_first_number'] || $count == (count($rows) - 1)) {
+        $vars['rendered_rows'][] = [
+          '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_cycle_main_frame_row'),
+          '#vss_id' => $vss_id,
+          '#items' => $items,
+          '#count' => $index,
+          '#view' => $vars['view'],
+        ];
+
+        $items = [];
+        $index++;
+      }
+    }
+    elseif (count($items) == $settings['items_per_slide'] || $count == (count($rows) - 1)) {
+      $vars['rendered_rows'][] = [
+        '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_cycle_main_frame_row'),
+        '#vss_id' => $vss_id,
+        '#items' => $items,
+        '#count' => $index,
+        '#view' => $vars['view'],
+      ];
+
+      $items = [];
+      $index++;
+    }
+  }
+}
+
+/**
+ * Views Slideshow slideshow rows.
+ *
+ * @ingroup vss_theme
+ */
+function template_preprocess_views_slideshow_cycle_main_frame_row(&$vars) {
+  $current = $vars['count'] + 1;
+  $vars['attributes']['class'][] = 'views_slideshow_cycle_slide';
+  $vars['attributes']['class'][] = 'views_slideshow_slide views-row-' . $current;
+
+  if ($vars['count']) {
+    $vars['attributes']['class'][] = 'views_slideshow_cycle_hidden';
+  }
+  $vars['attributes']['class'][] = ($vars['count'] % 2) ? 'views-row-even' : 'views-row-odd';
+
+  $vars['rendered_items'] = [];
+  foreach ($vars['items'] as $item_count => $item) {
+    $vars['rendered_items'][] = [
+      '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_cycle_main_frame_row_item'),
+      '#item' => $item,
+      '#item_count' => $item_count,
+      '#count' => $vars['count'],
+      '#view' => $vars['view'],
+      '#length' => count($vars['view']->result),
+    ];
+  }
+}
+
+/**
+ * Views Slideshow slideshow row items.
+ *
+ * @ingroup vss_theme
+ */
+function template_preprocess_views_slideshow_cycle_main_frame_row_item(&$vars) {
+  $vars['attributes']['class'][] = 'views-row views-row-' . $vars['count'];
+  $vars['attributes']['class'][] = ($vars['count'] % 2) ? 'views-row-even' : 'views-row-odd';
+  if ($vars['count'] == 0) {
+    $vars['attributes']['class'][] = 'views-row-first';
+  }
+  elseif ($vars['count'] == $vars['length'] - 1) {
+    $vars['attributes']['class'][] = 'views-row-last';
+  }
+
+  // Support custom row classes.
+  if ($row_class = $vars['view']->style_plugin->getRowClass($vars['count'])) {
+    $vars['attributes']['class'][] = $row_class;
+  }
+}
+
+/**
+ * Implements hook_preprocess_views_slideshow_pager_fields().
+ *
+ * @ingroup vss_theme
+ */
+function _views_slideshow_cycle_preprocess_views_slideshow_pager_fields(&$vars) {
+  $slide_count = count($vars['view']->result);
+  $options = $vars['view']->style_plugin->options['views_slideshow_cycle'];
+  $items_per_slide = $options['items_per_slide'];
+
+  if ($vars['settings']['hide_on_single_slide'] && $slide_count == 1) {
+    return;
+  }
+
+  $vars['rendered_field_items'] = [];
+  for ($slide = 0, $count = 0; $slide < $slide_count; $count++) {
+    $rendered_fields = [];
+    foreach ($vars['settings']['views_slideshow_pager_fields']['views_slideshow_pager_fields_fields'] as $field => $use) {
+      if ($use !== 0 && is_object($vars['view']->field[$field])) {
+        $rendered_fields[] = [
+          '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_pager_field_field'),
+          '#view' => $vars['view'],
+          '#label' => $vars['view']->field[$field]->options['label'],
+          '#output' => $vars['view']->style_plugin->getField($slide, $field),
+          '#css_identifier' => Html::cleanCssIdentifier($vars['view']->field[$field]->field),
+        ];
+      }
+    }
+    if (empty($vars['rendered_field_items']) && $options['items_per_slide_first']) {
+      $slide += $options['items_per_slide_first_number'];
+    }
+    elseif ($options['items_per_slide']) {
+      $slide += $options['items_per_slide'];
+    }
+    else {
+      $slide += 1;
+    }
+    $vars['rendered_field_items'][] = [
+      '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_pager_field_item'),
+      '#vss_id' => $vars['vss_id'],
+      '#item' => $rendered_fields,
+      '#count' => $count,
+      '#location' => $vars['location'],
+    ];
+  }
+}
+
+/**
+ * Implements hook_preprocess_views_slideshow_slide_counter().
+ *
+ * @ingroup vss_theme
+ */
+function _views_slideshow_cycle_preprocess_views_slideshow_slide_counter(&$vars) {
+  $options = $vars['view']->style_plugin->options['views_slideshow_cycle'];
+  if ($options['items_per_slide_first']) {
+    $slide_count = $vars['slide_count'] - $options['items_per_slide_first_number'];
+    $slide_count = $slide_count / $options['items_per_slide'];
+    $slide_count += 1;
+  }
+  else {
+    $slide_count = $vars['slide_count'] / $options['items_per_slide'];
+  }
+  $vars['slide_count'] = ceil($slide_count);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowSkin.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\views_slideshow\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a slideshow skin annotation object.
+ *
+ * @Annotation
+ */
+class ViewsSlideshowSkin extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The human-readable name of the slideshow skin.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $label;
+
+  /**
+   * A list of libraries this slideshow skin needs to attach.
+   *
+   * @var string[]
+   */
+  public $libraries;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowType.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,44 @@
+<?php
+
+namespace Drupal\views_slideshow\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a slideshow type annotation object.
+ *
+ * @Annotation
+ */
+class ViewsSlideshowType extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The human-readable name of the slideshow type.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $label;
+
+  /**
+   * A list of actions this slideshow type accepts.
+   *
+   * @var string[]
+   */
+  public $accepts;
+
+  /**
+   * A list of actions this slideshow type implements.
+   *
+   * @var string[]
+   */
+  public $calls;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowWidget.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\views_slideshow\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a widget annotation object.
+ *
+ * @Annotation
+ */
+class ViewsSlideshowWidget extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The human-readable name of the widget.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $label;
+
+  /**
+   * The widget type used by the widget.
+   *
+   * @var string
+   */
+  public $type;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Annotation/ViewsSlideshowWidgetType.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,44 @@
+<?php
+
+namespace Drupal\views_slideshow\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a widget type annotation object.
+ *
+ * @Annotation
+ */
+class ViewsSlideshowWidgetType extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The human-readable name of the widget type.
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   *
+   * @ingroup plugin_translatable
+   */
+  public $label;
+
+  /**
+   * A list of actions this widget type accepts.
+   *
+   * @var array
+   */
+  public $accepts;
+
+  /**
+   * A list of actions this widget type implements.
+   *
+   * @var array
+   */
+  public $calls;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/FormatAddonsName.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,21 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+/**
+ * Provides a class to manipulate addons names.
+ */
+class FormatAddonsName implements FormatAddonsNameInterface {
+
+  /**
+   * Format callback to move from underscore separated words to camelCase.
+   */
+  public function format($subject) {
+    return preg_replace_callback('/_(.?)/', function ($matches) {
+      if (isset($matches[1])) {
+        return strtoupper($matches[1]);
+      }
+    }, $subject);
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/FormatAddonsNameInterface.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+/**
+ * Provides a class for CRUD operations on path aliases.
+ */
+interface FormatAddonsNameInterface {
+
+  /**
+   * Format callback manipulate addons names.
+   */
+  public function format($subject);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowSkin/DefaultSkin.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,16 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\ViewsSlideshowSkin;
+
+use Drupal\views_slideshow\ViewsSlideshowSkinBase;
+
+/**
+ * Provides a default basic skin.
+ *
+ * @ViewsSlideshowSkin(
+ *   id = "default",
+ *   label = @Translation("Default"),
+ *   libraries = {}
+ * )
+ */
+class DefaultSkin extends ViewsSlideshowSkinBase {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidget/ControlsText.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,17 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\ViewsSlideshowWidget;
+
+use Drupal\views_slideshow\ViewsSlideshowWidgetBase;
+
+/**
+ * Provides some controls in text format.
+ *
+ * @ViewsSlideshowWidget(
+ *   id = "views_slideshow_controls_text",
+ *   type = "views_slideshow_controls",
+ *   label = @Translation("Text"),
+ * )
+ */
+class ControlsText extends ViewsSlideshowWidgetBase {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidget/PagerBullets.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\ViewsSlideshowWidget;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views_slideshow\ViewsSlideshowWidgetBase;
+
+/**
+ * Provides a pager using bullets.
+ *
+ * @ViewsSlideshowWidget(
+ *   id = "views_slideshow_pager_bullets",
+ *   type = "views_slideshow_pager",
+ *   label = @Translation("Bullets"),
+ * )
+ */
+class PagerBullets extends ViewsSlideshowWidgetBase {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidget/PagerFields.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,90 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\ViewsSlideshowWidget;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views_slideshow\ViewsSlideshowWidgetBase;
+
+/**
+ * Provides a pager using fields.
+ *
+ * @ViewsSlideshowWidget(
+ *   id = "views_slideshow_pager_fields",
+ *   type = "views_slideshow_pager",
+ *   label = @Translation("Fields"),
+ * )
+ */
+class PagerFields extends ViewsSlideshowWidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'views_slideshow_pager_fields_fields' => ['default' => []],
+      'views_slideshow_pager_fields_hover' => ['default' => 0],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    // Settings for fields pager.
+    $options = [];
+
+    // Get each field and it's name.
+    foreach ($this->getConfiguration()['view']->display_handler->getHandlers('field') as $field_name => $field) {
+      $options[$field_name] = $field->adminLabel();
+    }
+
+    // Need to wrap this so it indents correctly.
+    $form['views_slideshow_pager_fields_wrapper'] = [
+      '#markup' => '<div class="vs-dependent">',
+    ];
+
+    // Add ability to choose which fields to show in the pager.
+    $form['views_slideshow_pager_fields_fields'] = [
+      '#type' => 'checkboxes',
+      '#title' => $this->t('Pager fields'),
+      '#options' => $options,
+      '#default_value' => $this->getConfiguration()['views_slideshow_pager_fields_fields'],
+      '#description' => $this->t('Choose the fields that will appear in the pager.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="' . $this->getConfiguration()['dependency'] . '[enable]"]' => ['checked' => TRUE],
+          ':input[name="' . $this->getConfiguration()['dependency'] . '[type]"]' => ['value' => 'views_slideshow_pager_fields'],
+        ],
+      ],
+    ];
+
+    // Add field to see if they would like to activate slide and pause on pager
+    // hover.
+    $form['views_slideshow_pager_fields_hover'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Activate Slide and Pause on Pager Hover'),
+      '#default_value' => $this->getConfiguration()['views_slideshow_pager_fields_hover'],
+      '#description' => $this->t('Should the slide be activated and paused when hovering over a pager item.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="' . $this->getConfiguration()['dependency'] . '[enable]"]' => ['checked' => TRUE],
+          ':input[name="' . $this->getConfiguration()['dependency'] . '[type]"]' => ['value' => 'views_slideshow_pager_fields'],
+        ],
+      ],
+    ];
+
+    $form['views_slideshow_pager_fields_wrapper_close'] = [
+      '#markup' => '</div>',
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function checkCompatiblity($view) {
+    return $view->getStyle()->usesFields();
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidgetType/Controls.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,92 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\ViewsSlideshowWidgetType;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views_slideshow\ViewsSlideshowWidgetTypeBase;
+
+/**
+ * Provides a control widget type.
+ *
+ * @ViewsSlideshowWidgetType(
+ *   id = "views_slideshow_controls",
+ *   label = @Translation("Controls"),
+ *   accepts = {"pause" = {"required" = TRUE}, "play" = {"required" = TRUE}},
+ *   calls = {"nextSlide", "pause", "play", "previousSlide"}
+ * )
+ */
+class Controls extends ViewsSlideshowWidgetTypeBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return parent::defaultConfiguration() + [
+      'type' => ['default' => 0],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+
+    /* @var \Drupal\Component\Plugin\PluginManagerInterface */
+    $widgetManager = \Drupal::service('plugin.manager.views_slideshow.widget');
+
+    $widgets = $widgetManager->getDefinitions($this->getPluginId());
+
+    if (!empty($widgets)) {
+      $options = [];
+      foreach ($widgets as $widgetId => $widgetInfo) {
+        $options[$widgetId] = $widgetInfo['label'];
+      }
+
+      // Need to wrap this so it indents correctly.
+      $form['views_slideshow_controls_wrapper'] = [
+        '#markup' => '<div class="vs-dependent">',
+      ];
+
+      // Create the widget type field.
+      $form['type'] = [
+        '#type' => 'select',
+        '#title' => $this->t('Controls Type'),
+        '#description' => $this->t('Style of the controls'),
+        '#default_value' => $this->getConfiguration()['type'],
+        '#options' => $options,
+        '#states' => [
+          'visible' => [
+            ':input[name="' . $this->getConfiguration()['dependency'] . '[enable]"]' => ['checked' => TRUE],
+          ],
+        ],
+      ];
+
+      foreach ($widgets as $widget_id => $widget_info) {
+        // Get the current configuration of this widget.
+        $configuration = [];
+        if (!empty($this->getConfiguration()[$widget_id])) {
+          $configuration = $this->getConfiguration()[$widget_id];
+        }
+        $configuration['dependency'] = $this->getConfiguration()['dependency'];
+        $instance = $widgetManager->createInstance($widget_id, $configuration);
+
+        // Get the configuration form of this widget type.
+        $form[$widget_id] = isset($form[$widget_id]) ? $form[$widget_id] : [];
+        $form[$widget_id] = $instance->buildConfigurationForm($form[$widget_id], $form_state);
+      }
+
+      $form['controls_wrapper_close'] = [
+        '#markup' => '</div>',
+      ];
+    }
+    else {
+      $form['enable_controls'] = [
+        '#markup' => 'There are no controls available.',
+      ];
+    }
+
+    return $form;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidgetType/Counter.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\ViewsSlideshowWidgetType;
+
+use Drupal\views_slideshow\ViewsSlideshowWidgetTypeBase;
+
+/**
+ * Provides a counter widget type.
+ *
+ * @ViewsSlideshowWidgetType(
+ *   id = "views_slideshow_slide_counter",
+ *   label = @Translation("Slide counter"),
+ *   accepts = {
+ *     "transitionBegin" = {"required" = TRUE},
+ *     "goToSlide",
+ *     "previousSlide",
+ *     "nextSlide"
+ *   },
+ *   calls = {}
+ * )
+ */
+class Counter extends ViewsSlideshowWidgetTypeBase {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/ViewsSlideshowWidgetType/Pager.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,115 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\ViewsSlideshowWidgetType;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views_slideshow\ViewsSlideshowWidgetTypeBase;
+
+/**
+ * Provides a pager widget type.
+ *
+ * @ViewsSlideshowWidgetType(
+ *   id = "views_slideshow_pager",
+ *   label = @Translation("Pager"),
+ *   accepts = {
+ *     "transitionBegin" = {"required" = TRUE},
+ *     "goToSlide",
+ *     "previousSlide",
+ *     "nextSlide"
+ *   },
+ *   calls = {"goToSlide", "pause", "play"}
+ * )
+ */
+class Pager extends ViewsSlideshowWidgetTypeBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    $options = parent::defaultConfiguration() + [
+      'type' => ['default' => 0],
+      'views_slideshow_pager_numbered_hover' => ['default' => 0],
+      'views_slideshow_pager_numbered_click_to_page' => ['default' => 0],
+      'views_slideshow_pager_thumbnails_hover' => ['default' => 0],
+      'views_slideshow_pager_thumbnails_click_to_page' => ['default' => 0],
+    ];
+
+    /* @var \Drupal\Component\Plugin\PluginManagerInterface */
+    $widgetManager = \Drupal::service('plugin.manager.views_slideshow.widget');
+
+    // Get default configuration of all Pager plugins.
+    foreach ($widgetManager->getDefinitions($this->getPluginId()) as $widget_id => $widget_info) {
+      $options += $widgetManager->createInstance($widget_id, [])->defaultConfiguration();
+    }
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+    $view = $form_state->get('view')->get('executable');
+
+    /* @var \Drupal\Component\Plugin\PluginManagerInterface */
+    $widgetManager = \Drupal::service('plugin.manager.views_slideshow.widget');
+
+    // Determine if this widget type is compatible with any slideshow type.
+    $widgets = [];
+    foreach ($widgetManager->getDefinitions($this->getPluginId()) as $widget_id => $widget_info) {
+      if ($widgetManager->createInstance($widget_id, [])->checkCompatiblity($view)) {
+        $widgets[$widget_id] = $widget_info['label'];
+      }
+    }
+
+    if (!empty($widgets)) {
+
+      // Need to wrap this so it indents correctly.
+      $form['views_slideshow_pager_wrapper'] = [
+        '#markup' => '<div class="vs-dependent">',
+      ];
+
+      // Create the widget type field.
+      $form['type'] = [
+        '#type' => 'select',
+        '#title' => $this->t('Pager Type'),
+        '#description' => $this->t('Style of the pager'),
+        '#default_value' => $this->getConfiguration()['type'],
+        '#options' => $widgets,
+        '#states' => [
+          'visible' => [
+            ':input[name="' . $this->getConfiguration()['dependency'] . '[enable]"]' => ['checked' => TRUE],
+          ],
+        ],
+      ];
+
+      foreach ($widgetManager->getDefinitions() as $widget_id => $widget_info) {
+        // Get the current configuration of this widget.
+        $configuration = [];
+        if (!empty($this->getConfiguration()[$widget_id])) {
+          $configuration = $this->getConfiguration()[$widget_id];
+        }
+        $configuration['dependency'] = $this->getConfiguration()['dependency'];
+        $configuration['view'] = $view;
+        $instance = $widgetManager->createInstance($widget_id, $configuration);
+
+        // Get the configuration form of this widget type.
+        $form[$widget_id] = isset($form[$widget_id]) ? $form[$widget_id] : [];
+        $form[$widget_id] = $instance->buildConfigurationForm($form[$widget_id], $form_state);
+      }
+
+      $form['views_slideshow_pager_wrapper_close'] = [
+        '#markup' => '</div>',
+      ];
+    }
+    else {
+      $form['enable_pager'] = [
+        '#markup' => 'There are no pagers available.',
+      ];
+    }
+
+    return $form;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Plugin/views/style/Slideshow.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,324 @@
+<?php
+
+namespace Drupal\views_slideshow\Plugin\views\style;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views\Plugin\views\style\StylePluginBase;
+use Drupal\Core\Url;
+use Drupal\Core\Link;
+
+/**
+ * Style plugin to render each item in a slideshow.
+ *
+ * @ingroup views_style_plugins
+ *
+ * @ViewsStyle(
+ *   id = "slideshow",
+ *   title = @Translation("Slideshow"),
+ *   help = @Translation("Display the results as a slideshow."),
+ *   theme = "views_view_slideshow",
+ *   display_types = {"normal"}
+ * )
+ */
+class Slideshow extends StylePluginBase {
+
+  /**
+   * Does the style plugin allows to use style plugins.
+   *
+   * @var bool
+   */
+  protected $usesRowPlugin = TRUE;
+
+  /**
+   * Does the style plugin support custom css class for the rows.
+   *
+   * @var bool
+   */
+  protected $usesRowClass = TRUE;
+
+  /**
+   * Does the style plugin support grouping of rows.
+   *
+   * @var bool
+   */
+  protected $usesGrouping = FALSE;
+
+  /**
+   * Does the style plugin for itself support to add fields to it's output.
+   *
+   * This option only makes sense on style plugins without row plugins, like
+   * for example table.
+   *
+   * @var bool
+   */
+  protected $usesFields = TRUE;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['row_class_custom'] = ['default' => ''];
+    $options['row_class_default'] = ['default' => TRUE];
+    $options['slideshow_type'] = ['default' => 'views_slideshow_cycle'];
+    $options['slideshow_skin'] = ['default' => 'default'];
+
+    $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
+    foreach ($typeManager->getDefinitions() as $id => $definition) {
+      $instance = $typeManager->createInstance($id, []);
+      $options[$id] = $instance->defaultConfiguration();
+    }
+
+    $widgetTypeManager = \Drupal::service('plugin.manager.views_slideshow.widget_type');
+    $widgetTypes = $widgetTypeManager->getDefinitions();
+    foreach (['top', 'bottom'] as $location) {
+      foreach ($widgetTypes as $widgetTypeId => $widgetTypeDefinition) {
+        $options['widgets']['contains'][$location]['contains'][$widgetTypeId]['contains'] = $widgetTypeManager->createInstance($widgetTypeId, [])->defaultConfiguration();
+      }
+    }
+
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    parent::buildOptionsForm($form, $form_state);
+
+    // Wrap all the form elements to help style the form.
+    $form['views_slideshow_wrapper'] = [
+      '#markup' => '<div id="views-slideshow-form-wrapper">',
+    ];
+
+    // Skins.
+    $form['slideshow_skin_header'] = [
+      '#markup' => '<h2>' . $this->t('Style') . '</h2>',
+    ];
+
+    /* @var \Drupal\Component\Plugin\PluginManagerInterface */
+    $skinManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_skin');
+
+    // Get all skins to create the option list.
+    $skins = [];
+    foreach ($skinManager->getDefinitions() as $id => $definition) {
+      $skins[$id] = $definition['label'];
+    }
+    asort($skins);
+
+    // Create the drop down box so users can choose an available skin.
+    $form['slideshow_skin'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Skin'),
+      '#options' => $skins,
+      '#default_value' => $this->options['slideshow_skin'],
+      '#description' => $this->t('Select the skin to use for this display.  Skins allow for easily swappable layouts of things like next/prev links and thumbnails.  Note that not all skins support all widgets, so a combination of skins and widgets may lead to unpredictable results in layout.'),
+    ];
+
+    // Slides.
+    $form['slides_header'] = [
+      '#markup' => '<h2>' . $this->t('Slides') . '</h2>',
+    ];
+
+    // Get all slideshow types.
+    $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
+    $types = $typeManager->getDefinitions();
+
+    if ($types) {
+
+      // Build our slideshow options for the form.
+      $slideshow_options = [];
+      foreach ($types as $id => $definition) {
+        $slideshow_options[$id] = $definition['label'];
+      }
+
+      $form['slideshow_type'] = [
+        '#type' => 'select',
+        '#title' => $this->t('Slideshow Type'),
+        '#options' => $slideshow_options,
+        '#default_value' => $this->options['slideshow_type'],
+      ];
+
+      // @todo: check if default values are properly passed to the buildConfigurationForm().
+      foreach ($types as $id => $definition) {
+        $configuration = [];
+        if (!empty($this->options[$id])) {
+          $configuration = $this->options[$id];
+        }
+        $instance = $typeManager->createInstance($id, $configuration);
+
+        $form[$id] = [
+          '#type' => 'fieldset',
+          '#title' => $this->t('@module options', ['@module' => $definition['label']]),
+          '#collapsible' => TRUE,
+          '#attributes' => ['class' => [$id]],
+          '#states' => [
+            'visible' => [
+              ':input[name="style_options[slideshow_type]"]' => ['value' => $id],
+            ],
+          ],
+        ];
+
+        $form = $instance->buildConfigurationForm($form, $form_state);
+      }
+    }
+    else {
+      $form['enable_module'] = [
+        '#markup' => $this->t('There is no Views Slideshow plugin enabled. Go to the @modules and enable a Views Slideshow plugin module. For example Views Slideshow Cycle.', ['@modules' => Link::fromTextAndUrl($this->t('Modules Page'), Url::fromRoute('system.modules_list'))->toString()]),
+      ];
+    }
+
+    // Widgets.
+    // @todo: Improve the UX by using Ajax.
+    $form['widgets_header'] = [
+      '#markup' => '<h2>' . $this->t('Widgets') . '</h2>',
+    ];
+
+    // Define the available locations.
+    $location = ['top' => $this->t('Top'), 'bottom' => $this->t('Bottom')];
+
+    // Loop through all locations so we can add header for each location.
+    foreach ($location as $location_id => $location_name) {
+      $form['widgets'][$location_id]['header'] = [
+        '#markup' => '<h3>' . $this->t('@location Widgets', ['@location' => $location_name]) . '</h3>',
+      ];
+    }
+
+    /* @var \Drupal\Component\Plugin\PluginManagerInterface */
+    $widgetTypeManager = \Drupal::service('plugin.manager.views_slideshow.widget_type');
+
+    // Get all widgets types that are registered.
+    $widgets = $widgetTypeManager->getDefinitions();
+    if (!empty($widgets)) {
+
+      // Build our weight values by number of widgets.
+      $weights = [];
+      for ($i = 1; $i <= count($widgets); $i++) {
+        $weights[$i] = $i;
+      }
+
+      // Loop through our widgets and locations to build our form values for
+      // each widget.
+      foreach ($widgets as $widget_id => $widget_info) {
+
+        // Determine if this widget type is compatible with any slideshow type.
+        $compatible_slideshows = [];
+        foreach ($types as $slideshow_id => $slideshow_info) {
+          if ($widgetTypeManager->createInstance($widget_id, [])->checkCompatiblity($slideshow_info)) {
+            $compatible_slideshows[] = $slideshow_id;
+          }
+        }
+
+        // Display the widget config form only if the widget type is compatible
+        // with at least one slideshow type.
+        if (!empty($compatible_slideshows)) {
+          foreach ($location as $location_id => $location_name) {
+            // Use Widget Checkbox.
+            $form['widgets'][$location_id][$widget_id]['enable'] = [
+              '#type' => 'checkbox',
+              '#title' => $widget_info['label'],
+              '#default_value' => $this->options['widgets'][$location_id][$widget_id]['enable'],
+              '#description' => $this->t('Should @name be rendered at the @location of the slides.', ['@name' => $widget_info['label'], '@location' => $location_name]),
+              '#dependency' => [
+                'edit-style-options-slideshow-type' => $compatible_slideshows,
+              ],
+            ];
+
+            // Need to wrap this so it indents correctly.
+            $form['widgets'][$location_id][$widget_id]['wrapper'] = [
+              '#markup' => '<div class="vs-dependent">',
+            ];
+
+            // Widget weight.
+            // We check to see if the default value is greater than the number
+            // of widgets just in case a widget has been removed and the form
+            // hasn't been saved again.
+            $weight = (isset($this->options['widgets'][$location_id][$widget_id]['weight'])) ? $this->options['widgets'][$location_id][$widget_id]['weight'] : 0;
+            if ($weight > count($widgets)) {
+              $weight = count($widgets);
+            }
+            $form['widgets'][$location_id][$widget_id]['weight'] = [
+              '#type' => 'select',
+              '#title' => $this->t('Weight of the @name', ['@name' => $widget_info['label']]),
+              '#default_value' => $weight,
+              '#options' => $weights,
+              '#description' => $this->t('Determines in what order the @name appears. A lower weight will cause the @name to be above higher weight items.', ['@name' => $widget_info['label']]),
+              '#prefix' => '<div class="vs-dependent">',
+              '#suffix' => '</div>',
+              '#states' => [
+                'visible' => [
+                  ':input[name="style_options[widgets][' . $location_id . '][' . $widget_id . '][enable]"]' => ['checked' => TRUE],
+                ],
+              ],
+            ];
+
+            // Build the appropriate array for the states API.
+            $widget_dependency = 'style_options[widgets][' . $location_id . '][' . $widget_id . ']';
+
+            // Get the current configuration of this widget type.
+            $configuration = [];
+            if (!empty($this->options['widgets'][$location_id][$widget_id])) {
+              $configuration = $this->options['widgets'][$location_id][$widget_id];
+            }
+            $configuration['dependency'] = $widget_dependency;
+            $instance = $widgetTypeManager->createInstance($widget_id, $configuration);
+
+            // Get the configuration form of this widget type.
+            $form['widgets'][$location_id][$widget_id] = $instance->buildConfigurationForm($form['widgets'][$location_id][$widget_id], $form_state);
+
+            // Close the vs-dependent wrapper.
+            $form['widgets'][$location_id][$widget_id]['wrapper_close'] = [
+              '#markup' => '</div>',
+            ];
+          }
+        }
+      }
+    }
+
+    // Browse locations and remove the header if no widget is available.
+    foreach ($location as $location_id => $location_name) {
+      // If no widget is available, the only key is "header".
+      if (count(array_keys($form['widgets'][$location_id])) == 1) {
+        unset($form['widgets'][$location_id]);
+      }
+    }
+
+    // Remove the widget section header if there is no widget available.
+    if (empty($form['widgets'])) {
+      unset($form['widgets']);
+      unset($form['widgets_header']);
+    }
+
+    $form['views_slideshow_wrapper_close'] = [
+      '#markup' => '</div>',
+    ];
+
+    // Add a library to style the form.
+    $form['#attached']['library'] = ['views_slideshow/form'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateOptionsForm(&$form, FormStateInterface $form_state) {
+    // Validate all slideshow type plugins values.
+    $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
+    foreach ($typeManager->getDefinitions() as $id => $definition) {
+      $type = $typeManager->createInstance($id);
+      $type->validateConfigurationForm($form, $form_state);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitOptionsForm(&$form, FormStateInterface $form_state) {
+    // Submit all slideshow type plugins values.
+    $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
+    foreach ($typeManager->getDefinitions() as $id => $definition) {
+      $type = $typeManager->createInstance($id);
+      $type->submitConfigurationForm($form, $form_state);
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/Tests/Plugin/StyleSlideshowTest.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,108 @@
+<?php
+
+namespace Drupal\views_slideshow\Tests\Plugin;
+
+use Drupal\views\Entity\View;
+use Drupal\views\Tests\Plugin\PluginTestBase;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests the slideshow style views plugin.
+ *
+ * @group views
+ */
+class StyleSlideshowTest extends PluginTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'views',
+    'views_slideshow',
+    'views_slideshow_cycle',
+    'views_test_config',
+    'views_slideshow_test',
+  ];
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = ['test_style_slideshow'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp();
+
+    $this->enableViewsTestModule();
+    if ($import_test_views) {
+      ViewTestData::createTestViews(get_class($this), ['views_slideshow_test']);
+    }
+  }
+
+  /**
+   * Test slideshow display.
+   */
+  public function testSlideshow() {
+    $this->drupalGet('test-style-slideshow');
+
+    $result = $this->cssSelect('.views_slideshow_main');
+    $this->assertEqual(count($result), 1, 'Slideshow displayed on page');
+  }
+
+  /**
+   * Test slideshow control widgets.
+   */
+  public function testSlideshowWidgets() {
+    $this->drupalGet('test-style-slideshow');
+
+    // Ensure no controls are displayed.
+    $this->assertFalse(count($this->cssSelect('.views-slideshow-controls-top')));
+    $this->assertFalse(count($this->cssSelect('.views-slideshow-controls-bottom')));
+
+    // Test top widget position.
+    $view = View::load('test_style_slideshow');
+    $display = &$view->getDisplay('default');
+    $display['display_options']['style']['options']['widgets'] = [
+      'top' => [
+        'views_slideshow_controls' => [
+          'enable' => TRUE,
+          'weight' => 1,
+          'hide_on_single_slide' => 0,
+          'type' => 'views_slideshow_controls_text',
+        ],
+      ],
+    ];
+    $view->save();
+
+    $this->drupalGet('test-style-slideshow');
+    $this->assertTrue(count($this->cssSelect('.views-slideshow-controls-top')));
+    $this->assertFalse(count($this->cssSelect('.views-slideshow-controls-bottom')));
+
+    // Test bottom widget position.
+    $view = View::load('test_style_slideshow');
+    $display = &$view->getDisplay('default');
+    $display['display_options']['style']['options']['widgets'] = [
+      'bottom' => [
+        'views_slideshow_controls' => [
+          'enable' => TRUE,
+          'weight' => 1,
+          'hide_on_single_slide' => 0,
+          'type' => 'views_slideshow_controls_text',
+        ],
+      ],
+      'top' => [],
+    ];
+    $view->save();
+
+    $this->drupalGet('test-style-slideshow');
+    $this->assertFalse(count($this->cssSelect('.views-slideshow-controls-top')));
+    $this->assertTrue(count($this->cssSelect('.views-slideshow-controls-bottom')));
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowSkinBase.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Component\Plugin\PluginBase;
+
+/**
+ * Provides basic functionality for Views slideshow skins.
+ */
+abstract class ViewsSlideshowSkinBase extends PluginBase implements ViewsSlideshowSkinInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLabel() {
+    return $this->pluginDefinition['label'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getClass() {
+    return $this->pluginDefinition['id'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLibraries() {
+    return $this->pluginDefinition['libraries'];
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowSkinInterface.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+/**
+ * Provides an interface for Views slideshow skins.
+ */
+interface ViewsSlideshowSkinInterface {
+
+  /**
+   * Returns a array of libraries to attach when the skin is used.
+   *
+   * @return array
+   *   The libraries to be attached.
+   */
+  public function getLibraries();
+
+  /**
+   * Returns a class to be added to templates.
+   *
+   * @return string
+   *   The class name.
+   */
+  public function getClass();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowSkinPluginManager.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Manager for Views Slideshow Skin plugins.
+ */
+class ViewsSlideshowSkinPluginManager extends DefaultPluginManager {
+
+  /**
+   * Constructs a new ViewsSlideshowSkinPluginManager.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/ViewsSlideshowSkin', $namespaces, $module_handler, 'Drupal\views_slideshow\ViewsSlideshowSkinInterface', 'Drupal\views_slideshow\Annotation\ViewsSlideshowSkin');
+
+    $this->alterInfo('views_slideshow_skin_info');
+    $this->setCacheBackend($cache_backend, 'views_slideshow_skin');
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowTypeBase.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,74 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Provides basic functionality for Views slideshow types.
+ */
+abstract class ViewsSlideshowTypeBase extends PluginBase implements ViewsSlideshowTypeInterface {
+  use StringTranslationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->setConfiguration($configuration);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTitle() {
+    return $this->pluginDefinition['title'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfiguration() {
+    return [
+      'id' => $this->getPluginId(),
+    ] + $this->configuration;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setConfiguration(array $configuration) {
+    $this->configuration = $configuration + $this->defaultConfiguration();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowTypeInterface.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,12 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+
+/**
+ * Provides an interface for Views slideshow types.
+ */
+interface ViewsSlideshowTypeInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowTypePluginManager.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Manager for Views Slideshow Type plugins.
+ */
+class ViewsSlideshowTypePluginManager extends DefaultPluginManager {
+
+  /**
+   * Constructs a new ViewsSlideshowTypePluginManager.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/ViewsSlideshowType', $namespaces, $module_handler, 'Drupal\views_slideshow\ViewsSlideshowTypeInterface', 'Drupal\views_slideshow\Annotation\ViewsSlideshowType');
+    $this->alterInfo('views_slideshow_type_info');
+    $this->setCacheBackend($cache_backend, 'views_slideshow_type');
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowWidgetBase.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Provides basic functionality for Views slideshow widgets.
+ */
+abstract class ViewsSlideshowWidgetBase extends PluginBase implements ViewsSlideshowWidgetInterface {
+  use StringTranslationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->setConfiguration($configuration);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTitle() {
+    return $this->pluginDefinition['title'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfiguration() {
+    return [
+      'id' => $this->getPluginId(),
+    ] + $this->configuration;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setConfiguration(array $configuration) {
+    $this->configuration = $configuration + $this->defaultConfiguration();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function checkCompatiblity($view) {
+    return TRUE;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowWidgetInterface.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+
+/**
+ * Provides an interface for a Views slideshow widget.
+ */
+interface ViewsSlideshowWidgetInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
+
+  /**
+   * Check if the widget is compatible with the current view configuration.
+   *
+   * @return bool
+   *   TRUE if the widget is compatible with the view.
+   */
+  public function checkCompatiblity($view);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowWidgetPluginManager.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Manager for Views Slideshow Widget plugins.
+ */
+class ViewsSlideshowWidgetPluginManager extends DefaultPluginManager {
+
+  /**
+   * Constructs a new ViewsSlideshowWidgetPluginManager.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/ViewsSlideshowWidget', $namespaces, $module_handler, 'Drupal\views_slideshow\ViewsSlideshowWidgetInterface', 'Drupal\views_slideshow\Annotation\ViewsSlideshowWidget');
+    $this->alterInfo('views_slideshow_widget_info');
+    $this->setCacheBackend($cache_backend, 'views_slideshow_widget');
+  }
+
+  /**
+   * Gets the definition of all or filtered plugins for this type.
+   *
+   * @param mixed $type
+   *   A string or an array of types to filter on.
+   *
+   * @return mixed
+   *   An array of plugin definitions. Keys are plugin IDs.
+   */
+  public function getDefinitions($type = NULL) {
+    $definitions = parent::getDefinitions();
+
+    // Filter widgets to keep only required types.
+    if (!empty($type)) {
+      foreach ($definitions as $widgetId => $widgetInfo) {
+        if ((is_array($type) && !in_array($widgetInfo['type'], $type)) || (is_string($type) && $widgetInfo['type'] !== $type)) {
+          unset($definitions[$widgetId]);
+        }
+      }
+    }
+
+    return $definitions;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowWidgetTypeBase.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,128 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Base class for a Views slideshow widget type.
+ */
+abstract class ViewsSlideshowWidgetTypeBase extends PluginBase implements ViewsSlideshowWidgetTypeInterface {
+  use StringTranslationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->setConfiguration($configuration);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTitle() {
+    return $this->pluginDefinition['title'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    // Add field to see if they would like to hide controls if there is only
+    // one slide.
+    $form['hide_on_single_slide'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Hide controls if there is only one slide'),
+      '#default_value' => $this->getConfiguration()['hide_on_single_slide'],
+      '#description' => $this->t('Should the controls be hidden if there is only one slide.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="' . $this->getConfiguration()['dependency'] . '[enable]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'enable' => ['default' => 0],
+      'weight' => ['default' => 1],
+      'hide_on_single_slide' => ['default' => 0],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfiguration() {
+    return [
+      'id' => $this->getPluginId(),
+    ] + $this->configuration;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setConfiguration(array $configuration) {
+    $this->configuration = $configuration + $this->defaultConfiguration();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function checkCompatiblity($slideshow) {
+    $is_compatible = 1;
+    // Check if every required accept value in the widget has a
+    // corresponding calls value in the slideshow.
+    foreach ($this->pluginDefinition['accepts'] as $accept_key => $accept_value) {
+      if (is_array($accept_value) && !empty($accept_value['required']) && !in_array($accept_key, $slideshow['calls'])) {
+        $is_compatible = 0;
+        break;
+      }
+    }
+
+    // No need to go through this if it's not compatible.
+    if ($is_compatible) {
+      // Check if every required calls value in the widget has a
+      // corresponding accepts call.
+      foreach ($this->pluginDefinition['calls'] as $calls_key => $calls_value) {
+        if (is_array($calls_value) && !empty($calls_value['required']) && !in_array($calls_key, $slideshow['accepts'])) {
+          $is_compatible = 0;
+          break;
+        }
+      }
+    }
+
+    return $is_compatible;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowWidgetTypeInterface.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+
+/**
+ * Provides an interface for a Views slideshow widget type.
+ */
+interface ViewsSlideshowWidgetTypeInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
+
+  /**
+   * Check if the widget type is compatible with the selected slideshow.
+   *
+   * @return bool
+   *   TRUE if the widget type is compatible with the slideshow.
+   */
+  public function checkCompatiblity($slideshow);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/src/ViewsSlideshowWidgetTypePluginManager.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\views_slideshow;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Manager for Views Slideshow widget type plugins.
+ */
+class ViewsSlideshowWidgetTypePluginManager extends DefaultPluginManager {
+
+  /**
+   * Constructs a new ViewsSlideshowWidgetTypePluginManager.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/ViewsSlideshowWidgetType', $namespaces, $module_handler, 'Drupal\views_slideshow\ViewsSlideshowWidgetTypeInterface', 'Drupal\views_slideshow\Annotation\ViewsSlideshowWidgetType');
+    $this->alterInfo('views_slideshow_widget_type_info');
+    $this->setCacheBackend($cache_backend, 'views_slideshow_widget_type');
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-controls-text-next.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,17 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow text next control.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the control.
+ * - vss_id: The slideshow's id.
+ *
+ * @see template_preprocess_views_slideshow_controls_text_next()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<span id="views_slideshow_controls_text_next_{{ vss_id }}" {{ attributes.addClass(classes) }}>
+  <a href="#">{{ 'Next'|t }}</a>
+</span>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-controls-text-pause.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,18 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow text pause control.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the control.
+ * - start_text: Text to display while playing.
+ * - vss_id: The slideshow's id.
+ *
+ * @see template_preprocess_views_slideshow_controls_text_pause()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<span id="views_slideshow_controls_text_pause_{{ vss_id }}" {{ attributes.addClass(classes) }}>
+  <a href="#">{{ start_text }}</a>
+</span>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-controls-text-previous.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,17 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow text previous control.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the control.
+ * - vss_id: The slideshow's id.
+ *
+ * @see template_preprocess_views_slideshow_controls_text_previous()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<span id="views_slideshow_controls_text_previous_{{ vss_id }}" {{ attributes.addClass(classes) }}>
+  <a href="#">{{ 'Previous'|t }}</a>
+</span>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-controls-text.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow text controls.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the control.
+ * - rendered_control_next: Text next control.
+ * - rendered_control_pause: Text pause control.
+ * - rendered_control_previous: Text previous control.
+ * - vss_id: The slideshow's id.
+ *
+ * @see template_preprocess_views_slideshow_controls_text()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div id="views_slideshow_controls_text_{{ vss_id }}" {{ attributes.addClass(classes) }}>
+  {{ rendered_control_previous }}
+  {{ rendered_control_pause }}
+  {{ rendered_control_next }}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-main-section.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,16 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow pager item.
+ *
+ * Available variables:
+ * - plugin: The main frame slideshow plugin.
+ * - slides: The slides.
+ * - vss_id: The slideshow's id.
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div id="{{ plugin }}_main_{{ vss_id }}" class="{{ plugin }}_main views_slideshow_main">
+    {{ slides }}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-pager-bullets.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,13 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow bullets pager.
+ *
+ * Available variables:
+ * - bullet_items: Renderable array of pager items
+ *
+ * @ingroup vss_templates
+ */
+#}
+
+{{ bullet_items }}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-pager-field-field.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow pager field field data.
+ *
+ * Available variables:
+ * - css_identifier: css identified for the field..
+ * - label: Label for the field.
+ * - output: The field data.
+ *
+ * @see template_preprocess_views_slideshow_pager_field_field()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div class="views-field-{{ css_identifier }}">
+  {% if label %}
+    <label class="view-label-{{ css_identifier }}">
+      {{ label }}:
+    </label>
+  {% endif %}
+  <div class="views-content-{{ css_identifier }}">
+    {{ output }}
+  </div>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-pager-field-item.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow pager item.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the element.
+ * - count: The page number.
+ * - location: Location of pager.
+ * - item: Rendered field(s) making up item.
+ * - vss_id: The slideshow's id.
+ *
+ * @see template_preprocess_views_slideshow_pager_field_item()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div id="views_slideshow_pager_field_item_{{ location }}_{{ vss_id }}_{{ count }}" {{ attributes.addClass(classes) }}>
+  {{ item }}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-pager-fields.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,18 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow pager item.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the element.
+ * - rendered_field_items: The individual pager elements.
+ * - widget_id: The pager id.
+ *
+ * @see template_preprocess_views_slideshow_pager_field_item()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div id="{{ widget_id }}" {{ attributes.addClass(classes) }}>
+    {{ rendered_field_items }}
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-slideshow-slide-counter.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,18 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow slide counter.
+ *
+ * Available variables:
+ * - classes: Classes to apply to the counter's div element.
+ * - slide_count: Total number of slides.
+ * - vss_id: The slideshow's id.
+ *
+ * @see template_preprocess_views_slideshow_slide_counter()
+ *
+ * @ingroup vss_templates
+ */
+#}
+<div id="views_slideshow_slide_counter_{{ vss_id }}" {{ attributes.addClass(classes) }}>
+  <span class="num">1</span> {{ 'of'|t }} <span class="total">{{ slide_count }}</span>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/templates/views-view-slideshow.html.twig	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,33 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a views slideshow.
+ *
+ * Available variables:
+ * - bottom_widget_rendered: Widget under the slideshow with controls/data.
+ * - skin: The skin being applied to the slideshow.
+ * - slideshow: The slideshow.
+ * - top_widget_rendered: Widget above the slideshow with controls/data.
+ *
+ * @see _views_slideshow_preprocess_views_view_slideshow()
+ *
+ * @ingroup vss_templates
+ */
+#}
+{% if slideshow %}
+  <div class="skin-{{ skin }}">
+    {% if top_widget_rendered %}
+      <div class="views-slideshow-controls-top clearfix">
+        {{ top_widget_rendered }}
+      </div>
+    {% endif %}
+
+    {{ slideshow }}
+
+    {% if bottom_widget_rendered %}
+      <div class="views-slideshow-controls-bottom clearfix">
+        {{ bottom_widget_rendered }}
+      </div>
+    {% endif %}
+    </div>
+{% endif %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/tests/modules/views_slideshow_test/test_views/views.view.test_style_slideshow.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,52 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - views_slideshow
+    - views_slideshow_cycle
+id: test_style_slideshow
+label: ''
+module: views
+description: ''
+tag: ''
+base_table: views_test_data
+base_field: id
+core: 8.x
+display:
+  default:
+    display_plugin: page
+    id: default
+    display_title: Master
+    position: null
+    display_options:
+      path: test-style-slideshow
+      access:
+        type: none
+        options: {  }
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options: {  }
+      exposed_form:
+        type: basic
+        options: {  }
+      pager:
+        type: full
+        options: {  }
+      style:
+        type: slideshow
+        options:
+          row_class: ''
+          default_row_class: true
+          slideshow_skin: default
+          slideshow_type: views_slideshow_cycle
+      row:
+        type: fields
+        options: {  }
+      fields:
+        name:
+          id: name
+          table: views_test_data
+          field: name
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/tests/modules/views_slideshow_test/views_slideshow_test.info.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,16 @@
+name: 'Views Slideshow Test Config'
+type: module
+description: 'Provides default views for tests.'
+package: Testing
+# version: VERSION
+# core: 8.x
+dependencies:
+  - drupal:views
+  - views_slideshow:views_slideshow
+  - views_slideshow:views_slideshow_cycle
+
+# Information added by Drupal.org packaging script on 2017-11-18
+version: '8.x-4.6'
+core: '8.x'
+project: 'views_slideshow'
+datestamp: 1510987088
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/views_slideshow.developer-documentation.php	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file Provides API homepage for Views Slideshow.
+ */
+
+/**
+ * @mainpage Views Slideshow API & Developer Documentation
+ * Welcome to the Views Slideshow developer's documentation.
+ *
+ * Newcomers to Drupal development should read the conceptual information
+ * in @link https://www.drupal.org/docs/8/api/ Drupal API Introduction @endlink
+ * or @link https://api.drupal.org/api/drupal/8.2.x Drupal API Docs @endlink.
+ * The heavily documented
+ * @link https://api.drupal.org/api/examples/8.x-1.x Example modules @endlink
+ * may also be helpful.
+ *
+ * For tutorials and examples for acheiving specific tasks, also see the
+ * @link https://drupal.org/docs/8/modules/views-slideshow/developer-tutorials Developer Guide @endlink.
+ *
+ * For any comments, support or questions see the
+ * @link https://drupal.org/project/views_slideshow module page @endlink.
+ * Also, feel free to comment here if it is specific to one function/file.
+ *
+ * - Primary components of Views Slideshow
+ *   - @link vss_theme Theme Functions @endlink
+ *   - @link vss_templates Templates @endlink
+ *   - @link modules/views_slideshow_cycle/views_slideshow_cycle.module Cycle Module @endlink
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/views_slideshow.info.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,13 @@
+name: Views Slideshow
+type: module
+description: 'Provides a View style that displays rows as a jQuery slideshow.  This is an API and requires Views Slideshow Cycle or another module that supports the API.'
+package: Views
+# core: 8.x
+dependencies:
+  - drupal:views
+
+# Information added by Drupal.org packaging script on 2017-11-18
+version: '8.x-4.6'
+core: '8.x'
+project: 'views_slideshow'
+datestamp: 1510987088
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/views_slideshow.libraries.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,37 @@
+form:
+  version: VERSION
+  css:
+    theme:
+      css/views_slideshow.css: {}
+
+widget_info:
+  version: VERSION
+  js:
+    js/views_slideshow.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/drupalSettings
+
+controls_text:
+  version: VERSION
+  css:
+    theme:
+      css/controls_text.css: {}
+
+pager_bullets:
+  version: VERSION
+  css:
+    component:
+      css/views-slideshow-pager-bullets.css: {}
+
+jquery_hoverIntent:
+  remote: https://github.com/briancherne/jquery-hoverIntent
+  version: 1.9
+  license:
+      name: MIT
+      gpl-compatible: true
+  js:
+    /libraries/jquery.hoverIntent/jquery.hoverIntent.js: {}
+  dependencies:
+    - core/jquery
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/views_slideshow.module	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,164 @@
+<?php
+
+/**
+ * @file
+ * Provides Slideshow style options for Views.
+ */
+
+use Drupal\Core\Routing\RouteMatchInterface;
+
+/**
+ * Implements hook_help().
+ */
+function views_slideshow_help($route_name, RouteMatchInterface $route_match) {
+  switch ($route_name) {
+    // Main module help for the gss module.
+    case 'help.page.views_slideshow':
+      $output = '<h3>' . t('About') . '</h3>';
+      $output .= '<p>' . t('Views Slideshow can be used to create a slideshow of any content (not just images) that can appear in a View. Powered by jQuery, it is heavily customizable: you may choose slideshow settings for each View you create.') . '</p>';
+      $output .= '<h3>' . t('More Information') . '</h3>';
+      $output .= '<p>' . t('For more information about this module visite the <a href="@link">Views Slideshow</a> module page.', array('@link' => 'https://www.drupal.org/project/views_slideshow')) . '</p>';
+      return $output;
+  }
+}
+
+/**
+ * Implements hook_theme().
+ */
+function views_slideshow_theme() {
+  return [
+    'views_slideshow_main_section' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'slides' => NULL,
+        'plugin' => NULL,
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_pager_widget_render' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+        'location' => NULL,
+        'rows' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+      'function' => 'template_preprocess_views_slideshow_pager_widget_render',
+    ],
+    'views_slideshow_pager_fields' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+        'location' => NULL,
+        'attributes' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_pager_field_field' => [
+      'variables' => [
+        'view' => NULL,
+        'css_identifier' => NULL,
+        'label' => NULL,
+        'output' => NULL,
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_pager_field_item' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'item' => NULL,
+        'count' => NULL,
+        'location' => NULL,
+        'length' => NULL,
+      ],
+    ],
+    'views_slideshow_pager_bullets' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+        'location' => NULL,
+        'attributes' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_controls_widget_render' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+        'location' => NULL,
+        'rows' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+      'function' => 'template_preprocess_views_slideshow_controls_widget_render',
+    ],
+    'views_slideshow_controls_text' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+        'location' => NULL,
+        'rows' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_controls_text_previous' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_controls_text_pause' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_controls_text_next' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+    'views_slideshow_slide_counter_widget_render' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+        'location' => NULL,
+        'rows' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+      'function' => 'template_preprocess_views_slideshow_slide_counter_widget_render',
+    ],
+    'views_slideshow_slide_counter' => [
+      'variables' => [
+        'vss_id' => NULL,
+        'view' => NULL,
+        'settings' => [],
+        'location' => NULL,
+        'rows' => [],
+      ],
+      'file' => 'views_slideshow.theme.inc',
+    ],
+  ];
+}
+
+/**
+ * Views Slideshow: Slideshow.
+ *
+ * As it is a preprocess function, store it with other functions in theme.inc.
+ */
+function template_preprocess_views_view_slideshow(&$vars) {
+  \Drupal::moduleHandler()->loadInclude('views_slideshow', 'inc', 'views_slideshow.theme');
+  _views_slideshow_preprocess_views_view_slideshow($vars);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/views_slideshow.services.yml	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,19 @@
+services:
+  plugin.manager.views_slideshow.slideshow_skin:
+    class: Drupal\views_slideshow\ViewsSlideshowSkinPluginManager
+    parent: default_plugin_manager
+
+  plugin.manager.views_slideshow.slideshow_type:
+    class: Drupal\views_slideshow\ViewsSlideshowTypePluginManager
+    parent: default_plugin_manager
+
+  plugin.manager.views_slideshow.widget_type:
+    class: Drupal\views_slideshow\ViewsSlideshowWidgetTypePluginManager
+    parent: default_plugin_manager
+
+  plugin.manager.views_slideshow.widget:
+    class: Drupal\views_slideshow\ViewsSlideshowWidgetPluginManager
+    parent: default_plugin_manager
+
+  views_slideshow.format_addons_name:
+      class: Drupal\views_slideshow\FormatAddonsName
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/contrib/views_slideshow/views_slideshow.theme.inc	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,419 @@
+<?php
+
+/**
+ * @file
+ * The theme system, which controls the output of views slideshow.
+ */
+
+/**
+ * @defgroup vss_templates Templates
+ * @{
+ * Slideshow and component templates.
+ *
+ * @see vss_theme
+ * @}
+ */
+
+/**
+ * @defgroup vss_theme Theme Functions
+ * @{
+ * Theme processing and display generation.
+ *
+ * Most of the logic behind the generation of the slideshow is here.
+ *
+ * @see vss_templates
+ */
+
+use Drupal\Component\Utility\Html;
+
+/**
+ * Views Slideshow: slideshow.
+ */
+function _views_slideshow_preprocess_views_view_slideshow(&$vars) {
+  $options = $vars['view']->style_plugin->options;
+  $vars['skin'] = 'default';
+  $vars['slideshow'] = '';
+  $main_frame_module = $options['slideshow_type'];
+
+  if (empty($main_frame_module)) {
+    // Get all slideshow types.
+    $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
+    $types = $typeManager->getDefinitions();
+
+    if ($types) {
+      foreach ($types as $id => $definition) {
+        $main_frame_module = $id;
+        break;
+      }
+    }
+  }
+
+  // Make sure the main slideshow settings are defined before building the
+  // slideshow.
+  if (empty($main_frame_module)) {
+    drupal_set_message(
+      t('No main frame module is enabled for views slideshow. This is often because another module which Views Slideshow needs is not enabled. For example, 4.x needs a module like "Views Slideshow: Cycle" enabled.'),
+      'error'
+    );
+  }
+  elseif (empty($options[$main_frame_module])) {
+    drupal_set_message(t('The options for @module does not exists.', ['@module' => $main_frame_module]), 'error');
+  }
+  elseif (!empty($vars['rows'])) {
+    $settings = $options[$main_frame_module];
+    $view = $vars['view'];
+    $rows = $vars['rows'];
+
+    // The #name element is not available on Views edit pages.
+    $view_element_name = (isset($view->element['#name'])) ? $view->element['#name'] : '';
+    $vss_id = $view_element_name . '-' . $view->current_display;
+
+    // Give each slideshow a unique id if there are more than one on the page.
+    static $instances = [];
+    if (isset($instances[$vss_id])) {
+      $instances[$vss_id]++;
+      $vss_id .= "_" . $instances[$vss_id];
+    }
+    else {
+      $instances[$vss_id] = 1;
+    }
+
+    // Building our default methods.
+    $methods = [
+      'goToSlide' => [],
+      'nextSlide' => [],
+      'pause' => [],
+      'play' => [],
+      'previousSlide' => [],
+      'transitionBegin' => [],
+      'transitionEnd' => [],
+    ];
+
+    // Pull all widget info and slideshow info and merge them together.
+    $widgetTypeManager = \Drupal::service('plugin.manager.views_slideshow.widget_type');
+    $widgetTypes = $widgetTypeManager->getDefinitions();
+
+    $slideshowTypeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
+    $slideshowTypes = $slideshowTypeManager->getDefinitions();
+
+    $addons = array_merge($widgetTypes, $slideshowTypes);
+
+    // Loop through all the addons and call their methods if needed.
+    foreach ($addons as $addon_id => $addon_info) {
+      foreach ($addon_info['accepts'] as $imp_key => $imp_value) {
+        if (is_array($imp_value)) {
+          $methods[$imp_key][] = \Drupal::service('views_slideshow.format_addons_name')->format($addon_id);
+        }
+        else {
+          $methods[$imp_value][] = \Drupal::service('views_slideshow.format_addons_name')->format($addon_id);
+        }
+      }
+    }
+
+    $vars['#attached']['library'][] = 'views_slideshow/widget_info';
+    $vars['#attached']['drupalSettings']['viewsSlideshow'][$vss_id] = [
+      'methods' => $methods,
+      'paused' => 0,
+    ];
+
+    // Process Skins.
+    $skinManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_skin');
+    $skin = $skinManager->createInstance($options['slideshow_skin']);
+
+    $vars['skin'] = $skin->getClass();
+
+    foreach ($skin->getLibraries() as $library) {
+      $vars['#attached']['library'][] = $library;
+    }
+
+    // Process Widgets.
+    // Build weights.
+    $weight = [];
+    for ($i = 1; $i <= count($widgetTypes); $i++) {
+      $weight['top'][$i] = [];
+      $weight['bottom'][$i] = [];
+    }
+
+    $slide_count = count($view->result);
+    if ($slide_count && $vars['view']->style_plugin->options['slideshow_type'] == 'views_slideshow_cycle') {
+      $items_per_slide = $vars['view']->style_plugin->options['views_slideshow_cycle']['items_per_slide'];
+      $slide_count = $slide_count / $items_per_slide;
+    }
+    foreach ($widgetTypes as $widgetTypeId => $widgetTypeName) {
+      foreach ($weight as $location => $order) {
+        if ($options['widgets'][$location][$widgetTypeId]['enable']) {
+          // If hide on single slide and only a single slide skip rendering.
+          if ($options['widgets'][$location][$widgetTypeId]['hide_on_single_slide'] && $slide_count <= 1) {
+            continue;
+          }
+          $widgetWeight = ($options['widgets'][$location][$widgetTypeId]['weight'] > count($widgetTypes)) ? count($widgetTypes) : $options['widgets'][$location][$widgetTypeId]['weight'];
+
+          $weight[$location][$widgetWeight][] = [
+            'widgetId' => $widgetTypeId,
+            'widgetSettings' => $options['widgets'][$location][$widgetTypeId],
+          ];
+        }
+      }
+    }
+
+    // Build our widgets.
+    foreach ($weight as $location => $order) {
+      $vars[$location . '_widget_rendered'] = [];
+      foreach ($order as $widgets) {
+        if (is_array($widgets)) {
+          foreach ($widgets as $widgetData) {
+            $vars[$location . '_widget_rendered'][] = [
+              '#theme' => $view->buildThemeFunctions($widgetData['widgetId'] . '_widget_render'),
+              '#vss_id' => $vss_id,
+              '#view' => $view,
+              '#settings' => $widgetData['widgetSettings'],
+              '#location' => $location,
+              '#rows' => $rows,
+            ];
+          }
+        }
+      }
+    }
+
+    // Process Slideshow.
+    $slides = [
+      '#theme' => $view->buildThemeFunctions($main_frame_module . '_main_frame'),
+      '#vss_id' => $vss_id,
+      '#view' => $view,
+      '#settings' => $settings,
+      '#rows' => $rows,
+    ];
+
+    $vars['slideshow'] = [
+      '#theme' => $view->buildThemeFunctions('views_slideshow_main_section'),
+      '#vss_id' => $vss_id,
+      '#slides' => $slides,
+      '#plugin' => $main_frame_module,
+    ];
+  }
+}
+
+/**
+ * Views Slideshow: pager.
+ */
+function template_preprocess_views_slideshow_pager_widget_render(&$vars) {
+  // Add JavaScript settings for the pager type.
+  $vars['#attached']['library'][] = 'views_slideshow/widget_info';
+  $vars['#attached']['drupalSettings']['viewsSlideshowPager'][$vars['vss_id']] = [
+    $vars['location'] => [
+      'type' => \Drupal::service('views_slideshow.format_addons_name')->format($vars['settings']['type']),
+    ],
+  ];
+
+  // Create some attributes.
+  $attributes['class'][] = 'widget_pager widget_pager_' . $vars['location'];
+  $attributes['id'] = 'widget_pager_' . $vars['location'] . '_' . $vars['vss_id'];
+
+  $pager = [
+    '#theme' => $vars['view']->buildThemeFunctions($vars['settings']['type']),
+    '#vss_id' => $vars['vss_id'],
+    '#view' => $vars['view'],
+    '#settings' => $vars['settings'],
+    '#location' => $vars['location'],
+    '#attributes' => $attributes,
+  ];
+
+  return \Drupal::service('renderer')->render($pager);
+}
+
+/**
+ * Theme pager fields.
+ */
+function template_preprocess_views_slideshow_pager_fields(&$vars) {
+  // Add JavaScript settings for the field.
+  $vars['#attached']['library'][] = 'views_slideshow/widget_info';
+  $vars['#attached']['drupalSettings']['viewsSlideshowPagerFields'][$vars['vss_id']] = [
+    $vars['location'] => [
+      'activatePauseOnHover' => $vars['settings']['views_slideshow_pager_fields']['views_slideshow_pager_fields_hover'],
+    ],
+  ];
+
+  // Add hover intent library.
+  if ($vars['settings']['views_slideshow_pager_fields']['views_slideshow_pager_fields_hover']) {
+    $vars['#attached']['library'][] = 'views_slideshow/jquery_hoverIntent';
+  }
+
+  $vars['widget_id'] = $vars['attributes']['id'];
+  // Add our class to the wrapper.
+  $vars['attributes']['class'][] = 'views_slideshow_pager_field';
+
+  // Render all the fields unless there is only 1 slide and the user specified
+  // to hide them when there is only one slide.
+  $vars['rendered_field_items'] = [];
+  foreach ($vars['view']->result as $count => $node) {
+    $rendered_fields = [];
+    foreach ($vars['settings']['views_slideshow_pager_fields']['views_slideshow_pager_fields_fields'] as $field => $use) {
+      if ($use !== 0 && is_object($vars['view']->field[$field])) {
+        $rendered_fields[] = [
+          '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_pager_field_field'),
+          '#view' => $vars['view'],
+          '#label' => $vars['view']->field[$field]->options['label'],
+          '#output' => $vars['view']->style_plugin->getField($count, $field),
+          '#css_identifier' => Html::cleanCssIdentifier($vars['view']->field[$field]->field),
+        ];
+      }
+    }
+
+    $vars['rendered_field_items'][] = [
+      '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_pager_field_item'),
+      '#vss_id' => $vars['vss_id'],
+      '#item' => $rendered_fields,
+      '#count' => $count,
+      '#location' => $vars['location'],
+      '#length' => count($vars['view']->result),
+    ];
+  }
+}
+
+/**
+ * Views Slideshow: pager item.
+ */
+function template_preprocess_views_slideshow_pager_field_item(&$vars) {
+  $vars['attributes']['class'][] = 'views_slideshow_pager_field_item';
+  $vars['attributes']['class'][] = ($vars['count'] % 2) ? 'views-row-even' : 'views-row-odd';
+  if ($vars['count'] == 0) {
+    $vars['attributes']['class'][] = 'views-row-first';
+  }
+  elseif ($vars['count'] == $vars['length'] - 1) {
+    $vars['attributes']['class'][] = 'views-row-last';
+  }
+}
+
+/**
+ * Views Slideshow: Bullets pager.
+ */
+function template_preprocess_views_slideshow_pager_bullets(&$vars) {
+  $vars['#attached']['library'][] = 'views_slideshow/widget_info';
+  $vars['#attached']['library'][] = 'views_slideshow/pager_bullets';
+  $vars['#attached']['drupalSettings']['viewsSlideshowPagerFields'][$vars['vss_id']] = [
+    $vars['location'] => [
+      'activatePauseOnHover' => $vars['settings']['views_slideshow_pager_bullets']['views_slideshow_pager_bullets_hover'],
+    ],
+  ];
+
+  $vars['bullet_items'] = [
+    '#theme' => 'item_list',
+    '#items' => [],
+    '#attributes' => $vars['attributes'],
+  ];
+  $vars['bullet_items']['#attributes']['class'][] = 'views-slideshow-pager-bullets';
+  $vars['bullet_items']['#attributes']['class'][] = 'views_slideshow_pager_field';
+
+  for ($i = 0; $i < count($vars['view']->result); $i++) {
+    $vars['bullet_items']['#items'][] = [
+      '#markup' => $i,
+      '#wrapper_attributes' => [
+        'id' => 'views_slideshow_pager_field_item_' . $vars['location'] . '_' . $vars['vss_id'] . '_' . $i,
+      ],
+    ];
+  }
+}
+
+/**
+ * Views Slideshow: Controls.
+ */
+function template_preprocess_views_slideshow_controls_widget_render(&$vars) {
+  // Add JavaScript settings for the controls type.
+  $vars['#attached']['library'][] = 'views_slideshow/widget_info';
+  $vars['#attached']['drupalSettings']['viewsSlideshowControls'][$vars['vss_id']] = [
+    $vars['location'] => [
+      'type' => \Drupal::service('views_slideshow.format_addons_name')->format($vars['settings']['type']),
+    ],
+  ];
+
+  $output = [
+    '#theme' => $vars['view']->buildThemeFunctions($vars['settings']['type']),
+    '#vss_id' => $vars['vss_id'],
+    '#view' => $vars['view'],
+    '#settings' => $vars['settings'],
+    '#location' => $vars['location'],
+    '#rows' => $vars['rows'],
+  ];
+
+  return \Drupal::service('renderer')->render($output);
+}
+
+/**
+ * The slideshow controls.
+ */
+function template_preprocess_views_slideshow_controls_text(&$vars) {
+  $vars['#attached']['library'][] = 'views_slideshow/controls_text';
+
+  $vars['attributes']['class'][] = 'views_slideshow_controls_text';
+
+  $vars['rendered_control_previous'] = [
+    '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_controls_text_previous'),
+    '#vss_id' => $vars['vss_id'],
+    '#view' => $vars['view'],
+    '#settings' => $vars['settings'],
+  ];
+
+  $vars['rendered_control_pause'] = [
+    '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_controls_text_pause'),
+    '#vss_id' => $vars['vss_id'],
+    '#view' => $vars['view'],
+    '#settings' => $vars['settings'],
+  ];
+
+  $vars['rendered_control_next'] = [
+    '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_controls_text_next'),
+    '#vss_id' => $vars['vss_id'],
+    '#view' => $vars['view'],
+    '#settings' => $vars['settings'],
+  ];
+}
+
+/**
+ * Views Slideshow: "previous" control.
+ */
+function template_preprocess_views_slideshow_controls_text_previous(&$vars) {
+  $vars['attributes']['class'][] = 'views_slideshow_controls_text_previous';
+}
+
+/**
+ * Views Slideshow: "pause" control.
+ */
+function template_preprocess_views_slideshow_controls_text_pause(&$vars) {
+  $vars['attributes']['class'][] = 'views_slideshow_controls_text_pause  views-slideshow-controls-text-status-play';
+  $vars['start_text'] = t('Pause');
+}
+
+/**
+ * Views Slideshow: "next" control.
+ */
+function template_preprocess_views_slideshow_controls_text_next(&$vars) {
+  $vars['attributes']['class'][] = 'views_slideshow_controls_text_next';
+}
+
+/**
+ * Views Slideshow: Slide Counter.
+ */
+function template_preprocess_views_slideshow_slide_counter_widget_render(&$vars) {
+  $slide = [
+    '#theme' => $vars['view']->buildThemeFunctions('views_slideshow_slide_counter'),
+    '#vss_id' => $vars['vss_id'],
+    '#view' => $vars['view'],
+    '#settings' => $vars['settings'],
+    '#location' => $vars['location'],
+    '#rows' => $vars['rows'],
+  ];
+
+  return \Drupal::service('renderer')->render($slide);
+}
+
+/**
+ * Views Slideshow: slide counter.
+ */
+function template_preprocess_views_slideshow_slide_counter(&$vars) {
+  $vars['attributes']['class'][] = 'views_slideshow_slide_counter';
+  $vars['slide_count'] = count($vars['rows']);
+}
+
+/**
+ * @} End of "defgroup vss_theme".
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/default/files/color/isobartik-e35cfd6a/colors.css	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,74 @@
+/* ---------- Color Module Styles ----------- */
+
+body {
+  color: #000000;
+  background: #1f1d1c;
+}
+#page,
+#main-wrapper,
+.region-primary-menu .menu-item a.is-active,
+.region-primary-menu .menu-item--active-trail a {
+  background: #ffffff;
+}
+.tabs ul.primary li a.is-active {
+  background-color: #ffffff;
+}
+.tabs ul.primary li.is-active a {
+  background-color: #ffffff;
+  border-bottom-color: #ffffff;
+}
+#header {
+  background-color: #000000;
+  background-image: url("/sites/default/files/isophonics.jpg");
+  background-position: center;
+  background-size: contain;
+  background-repeat: no-repeat;
+  height: 14em;
+}
+
+a,
+.link {
+  color: #990000;
+}
+a:hover,
+a:focus,
+.link:hover,
+.link:focus {
+  color: #c80404;
+}
+a:active,
+.link:active {
+  color: #f11f1f;
+}
+.sidebar .block {
+  background-color: #f1f4f0;
+  border-color: #ededed;
+}
+.site-footer {
+  background: #1f1d1c;
+}
+.region-header,
+.region-header a,
+.region-header li a.is-active,
+.site-branding__text,
+.site-branding,
+.site-branding__text a,
+.site-branding a,
+.region-secondary-menu .menu-item a,
+.region-secondary-menu .menu-item a.is-active {
+  color: #fffeff;
+}
+
+/* ---------- Color Form ----------- */
+
+[dir="rtl"] .color-form .color-palette {
+  margin-left: 0;
+  margin-right: 20px;
+}
+[dir="rtl"] .color-form .form-item label {
+  float: right;
+}
+[dir="rtl"] .color-form .color-palette .lock {
+  right: -20px;
+  left: 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/default/files/color/isobartik-e35cfd6a/logo.svg	Thu Dec 07 14:46:23 2017 +0000
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="57" height="66" viewBox="471.5 467 57 66" enable-background="new 471.5 467 57 66"><path opacity=".2" fill="#303030" d="M528.5 504.965c0 16.634-13.123 27.615-28.24 27.615-10.29 0-19.894-5.523-24.978-14.167l.605-.027c1.313 1.192 3.39 2.58 7.404 2.515 4.77-.064 5.645-.875 9.855-2.756 22.716-10.17 26.925-19.457 27.736-21.59s2.013-5.587.756-9.415c-.242-.737-.42-1.333-.54-1.808-3.018-3.372-6.017-5.225-6.92-5.784-.14-.093-.29-.177-.43-.26l.44.26c2.01 1.247 14.314 8.782 14.314 25.417z"/><path fill="#fff" d="M509.09 518.507c1.006 0 2.077.065 2.83.568.756.503 1.193 1.63 1.445 2.263.25.634 0 1.006-.503 1.258-.438.25-.503.12-.94-.69-.44-.81-.82-1.63-3.01-1.63s-2.887.755-3.948 1.63c-1.062.876-1.443 1.193-1.825.69s-.253-1.006.437-1.63 1.825-1.63 2.888-2.077c1.06-.45 1.62-.383 2.625-.383zm-10.413 7.152c1.257 1.005 3.14 1.825 7.153 1.825 4.015 0 6.836-1.137 8.094-2.077.568-.438.82-.065.875.187.056.25.186.624-.252 1.07-.316.317-3.194 2.33-6.594 2.636-3.4.31-7.964.504-10.73-2.01-.438-.44-.316-1.07 0-1.323.317-.25.568-.438.94-.438.374.008.317.008.513.13z"/><path opacity=".2" fill="#aaa" d="M520.89 496.545c-.81 2.133-5.02 11.42-27.735 21.59-4.21 1.88-5.085 2.69-9.854 2.756-4.013.066-6.09-1.32-7.403-2.514l-.605.028h-.01c-2.393-4.042-3.78-8.783-3.78-13.952 0-7.852 2.97-13.654 6.287-17.687.11-.13.213-.26.325-.382 2.683-3.148 5.55-5.17 7.218-6.203.038-.028.075-.047.112-.065.42-.25.754-.447.987-.568 2.757-1.51 4.77-2.263 7.963-4.77.12-.092.242-.186.354-.288l.008-.01c.875-.754 1.64-1.76 2.18-3.4v-.008c.325-.97.567-2.16.716-3.65l.02.018c2.253 2.69 4.954 5.886 6.89 7.144.69.447 1.38.848 2.068 1.202l.3.15c2.243 1.126 4.507 1.945 6.807 3.333l.428.26c.903.56 3.902 2.412 6.92 5.784.12.475.298 1.07.54 1.807 1.274 3.837.073 7.292-.737 9.425z"/><path opacity=".5" fill="#333" d="M514.176 479.538c-3.26-2.077-6.464-2.887-9.603-4.955-1.938-1.267-4.64-4.47-6.893-7.162-.438 4.332-1.686 6.148-3.26 7.35-3.195 2.515-5.207 3.26-7.963 4.77-2.338 1.256-14.958 8.726-14.958 24.913 0 5.17 1.387 9.91 3.77 13.96 5.077 8.635 14.68 14.158 24.97 14.158 15.126 0 28.24-10.98 28.24-27.614 0-9.127-3.707-15.526-7.386-19.633-3.016-3.382-6.015-5.217-6.918-5.785zm7.627 7.34c4.117 5.15 6.213 11.23 6.213 18.077 0 3.968-.755 7.712-2.245 11.148-1.414 3.25-3.444 6.13-6.053 8.56-5.15 4.806-12.062 7.45-19.475 7.45-3.67 0-7.265-.698-10.692-2.086-3.372-1.36-6.398-3.297-9.016-5.774-5.532-5.225-8.57-12.257-8.57-19.8 0-6.716 2.18-12.695 6.483-17.753 3.288-3.865 6.836-6.007 8.196-6.743.67-.363 1.285-.69 1.89-.997 1.892-.97 3.68-1.89 6.14-3.818 1.312-.997 2.71-2.58 3.305-6.585 2.077 2.468 4.48 5.234 6.314 6.426 1.63 1.08 3.307 1.835 4.918 2.562 1.527.69 3.11 1.406 4.676 2.403l.056.037c4.62 2.84 7.06 5.896 7.86 6.892z"/><path opacity=".5" fill="#fff" d="M497.98 468.678c.874 2.58.753 3.893.753 4.452 0 .56-.307 2.077-1.313 2.832-.438.317-.568.568-.568.624 0 .25.568.438.568 1.006 0 .69-.317 2.077-3.642 5.393-3.325 3.316-8.103 6.278-11.8 8.103-3.698 1.826-5.468 1.686-5.97.81s.185-2.83 2.514-5.392l9.667-6.278 9.164-6.398.503-2.44"/><path fill="#fff" d="M497.98 468.613c-.57 4.145-1.826 5.393-3.512 6.715-2.83 2.133-5.588 3.446-6.212 3.763-1.63.82-7.535 4.08-10.608 8.784-.94 1.444 0 2.012.186 2.133.187.12 2.33.372 6.9-2.385 4.574-2.757 6.595-4.387 9.175-7.078 1.377-1.444 1.573-2.263 1.573-2.636 0-.438-.316-.624-.82-.754-.25-.065-.316-.187 0-.373.317-.186 1.622-.82 1.938-1.07.318-.25 1.827-1.257 1.882-2.887.065-1.63-.056-2.766-.503-4.21zm-14.112 45.628c.065-4.898 4.648-9.472 10.422-9.536 7.348-.065 12.424 7.283 16.13 7.208 3.14-.064 9.166-6.212 12.118-6.212 3.14 0 4.014 3.26 4.014 5.206 0 1.938-.623 5.458-2.133 7.656-1.51 2.198-2.44 3.008-4.2 2.888-2.264-.187-6.78-7.21-9.67-7.35-3.64-.12-11.547 7.6-17.75 7.6-3.763 0-4.9-.567-6.147-1.378-1.92-1.312-2.85-3.315-2.785-6.08z"/></svg>