;
if (typeof ShowUpTheme == 'undefined') {
	ShowUpTheme = {
		'_defaultTheme': {

			options: {},

			labels: {},

			getPadding: function () {
				return {
					top: 0,
					right: 0,
					bottom: 0,
					left: 0
				};
			},

			init: function (panel) {

			}
		}
	};
}

if (typeof ShowUpTransition == 'undefined') {
	ShowUpTransition = {
		'_defaultTransition': {

			options: {},

			setDefaults: function (content, width, height) {
				return {
					w: width,
					h: height
				};
			},

			apply: function (content, width, height) {
				return [
					{
						x: 0,
						y: 0,
						animations: []
					}
				];
			}

		}
	};
}

(function ($, window, document, undefined) {

	ShowUp = {

		// Current version of the ShowUp
		version: '2.1.9', // 2017-06-02

		// The list of user selected options
		options: {},

		// Contains the default values for all options
		getDefaults: function () {
			return {
				duration: 100,

				overflow: true,
				closeOnEsc: true,
				keyboardControls: true,

				/*
				minMargin: {
					desktop: 20,
					laptop: 15,
					tablet: 10,
					mobile: 5
				},
				*/
				minMargin: 20,

				gallery: null,
				galleryThumbs: null,

				overlay: {
					show: true,
					color: '#000000',
					opacity: 0.65,
					closeOnClick: true
				},

				transitions: {
					blocks: {}
				},

				theme: {
					name: 'social',
					colorscheme: 'white'
				},

				path: $("script[src*='showup-" + ShowUp.version + ".js']").attr("src").split('?')[0].split('/').slice(0, -1).join('/') + '/',

				loop: false,
				autoplay: false,
				playInterval: 2200,

				fadeInTime: 400,
				fadeOutTime: 300,
			};
		},

		// The selected theme
		theme: null,

		// Gallery, required
		gallery: [],
		galleryThumbs: [],
		galleryCount: 0,
		galleryPointer: 0,

		// DOM objects and statuses
		DOM: {},
		animating: false,
		loaderTimer: null,

		// Holds the list of all loading transitions for donwload optimization
		loadingTransitions: [],

		// Holds the references to all registered events
		registeredEvents: {},
		getRegisteredTemplate: function () {
			return {
				'onCreatePanel': [],

				'init': [],

				'onClick': [],
				'onShow': [],
				'onShown': [],
				'onShowImage': [],
				'onShowHTML': [],
				'onHide': [],

				'onAnimateSlices': [],
				'onAnimateContent': [],
				'onAnimateTransition': [],
				'onAnimationComplete': [],

				'onOverlayClick': [],

				'onHoverIn': [],
				'onHoverOut': [],

				'onNext': [],
				'onPrev': [],
				'onPlay': [],
				'onPause': [],
				'onUnpause': [],
				'onStop': []
			};
		},


		/**
		 * Trigger the event and invoke all registered methods.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		triggerEvent: function (name, arg1, arg2, arg3, arg4, arg5) {
			var ret = arg1;
			var value = null;
			//for(var i in ShowUp.registeredEvents[name]) {
			for (var i = 0; i < ShowUp.registeredEvents[name].length; i++) {
				if (typeof ShowUp.registeredEvents[name][i] != 'function') {
					continue;
				}
				value = ShowUp.registeredEvents[name][i](arg1, arg2, arg3, arg4, arg5);

				if (typeof value != 'undefined' && value != null) {
					ret = value;
				}
			}

			return ret;
		},


		/**
		 * Attaches the ShowUp to an HTML element.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		attach: function (element, options) {
			ShowUp.options = $.extend(true, {}, this.getDefaults(), ShowUp.options, options);
			delete ShowUp.options.options;

			// Default transition
			if (typeof ShowUp.options.transitions == 'undefined' || Object.keys(ShowUp.options.transitions).length == 0) {
				ShowUp.options.transitions = {blocks: {}};
			}
			// Build panel if not built yet
			ShowUp.loadTransitions(false);
			if (typeof ShowUp.DOM.panel == 'undefined') {
				ShowUp.buildPanel();
			}

			// Intercept element's onclick event
			element.on('click', function (event) {

				ShowUp.onClick(element, options);

				event.preventDefault();
				return false;
			});
		},


		/**
		 * Handle click action on the element that triggers the ShowUp.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		onClick: function (element, options) {

			// Load the options
			if ($.isEmptyObject(ShowUp.options)) {
				ShowUp.options = $.extend({}, this.getDefaults());
			}
			ShowUp.options = $.extend(ShowUp.options, ShowUpTheme[ShowUp.options.theme], options);

			// Default transition
			if (typeof ShowUp.options.transitions == 'undefined' || Object.keys(ShowUp.options.transitions).length == 0) {
				ShowUp.options.transitions = {blocks: {}};
			}

			// Make sure we have transitions
			ShowUp.loadTransitions(true);

			// Handle percentages
			ShowUp.options.overlay.opacity = ShowUp.percentToFloat(ShowUp.options.overlay.opacity);
			ShowUp.options.duration = ShowUp.percentToFloat(ShowUp.options.duration);

			// Set the current element
			this.element = element;
			var elements;
			ShowUp.galleryPointer = 0;

			// Set the gallery
			ShowUp.gallery = [];
			ShowUp.galleryThumbs = [];
			ShowUp.galleryCount = 0;
			if (ShowUp.options.gallery != null) {
				ShowUp.gallery = ShowUp.options.gallery;
				if (ShowUp.options.galleryThumbs != null) {
					ShowUp.galleryThumbs = ShowUp.options.galleryThumbs;
				}
				else {
					ShowUp.galleryThumbs = ShowUp.options.gallery;
				}
				elements = $(element);
			} else {
				var rel = element.attr('rel');
				elements = rel ? $('a[rel=' + rel + ']') : $(element);
				elements.each(function (i, item) {
					ShowUp.gallery.push($(item).attr('href'));
					ShowUp.galleryThumbs.push($(item).data('showup-thumb') ? $(item).data('showup-thumb') : $(item).attr('href'));
					ShowUp.galleryCount++;
				});

				// Mark pointer
				var href = element.attr('href');
				for (var i = 0; i < ShowUp.galleryCount; i++) {
					if (ShowUp.gallery[i] == href) {
						ShowUp.galleryPointer = i;
						break;
					}
				}
			}
			//ShowUp.galleryCount = ShowUp.gallery.length;

			// Invoke listener
			options = ShowUp.triggerEvent('onClick', options, element, elements, ShowUp.gallery, ShowUp.galleryThumbs, ShowUp.galleryPointer);

			// Show overlay
			ShowUp.showContent(this.getSlide());
			ShowUp.showOverlay();

			// Execute autoplay if requested
			if (ShowUp.options.autoplay != false && (ShowUp.options.loop || ShowUp.galleryPointer < ShowUp.galleryCount - 1)) {
				ShowUp.goPlay(null, null, true);
			}

			$(window).on('resize', this.handleResize);
		},

		/**
		 * Handle resize and rotation.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		handleResize: function () {
			if ($('#ShowUpWrapper').is(':visible')) {
				ShowUp.showContent(ShowUp.getSlide());
				ShowUp.showOverlay();
			}
		},

		/**
		 * Loads the transition from the server.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		loadTransitions: function (force) {

			// Load transitions
			for (var transition in ShowUp.options.transitions) {
				if ((force || $.inArray(transition, ShowUp.loadingTransitions) == -1) && typeof ShowUpTransition[transition] == 'undefined') {
					ShowUp.loadingTransitions.push(transition);
					$.getScript(ShowUp.options.path + 'transitions/showup.' + transition + '.js');
				}
			}
		},


		/**
		 * Build the frame for the ShowUp.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		buildPanel: function (rebuild) {
			var self = this;

			// If it is already loading
			if (ShowUp.building) {
				return;
			}
			ShowUp.building = true;

			// Get transitions
			ShowUp.loadTransitions(false);

			// Append theme js
			$.getScript(ShowUp.options.path + 'themes/' + ShowUp.options.theme.name + '/theme.js', function (data, textStatus, jqxhr) {

				// Setup theme
				self.setupTheme();

				// Rebuild panel from the scratch
				if (rebuild == true) {
					$('#ShowUpWrapper').remove();
				}

				// If no panel is active create one
				if ($('#ShowUpPanel').length == 0) {

					var panel = $('<div id="ShowUpPanel">');
					var overlay = $('<div id="ShowUpOverlay">');
					var container = $('<div id="ShowUpContainer">');

					// Load the theme labels and options
					ShowUp.theme.labels = $.extend({}, ShowUp.theme.labels, ShowUp.options.theme.labels);
					ShowUp.theme.options = $.extend({}, ShowUp.theme.options, ShowUp.options.theme.options);

					// Load color scheme
					$.get(
						ShowUp.options.path + 'themes/' + ShowUp.options.theme.name + '/theme.html',
						function (response) {

							// Put the labels
							if (ShowUp.theme.labels) {
								for (var key in ShowUp.theme.labels) {
									ShowUp.theme.options['label:' + key] = ShowUp.theme.labels[key];
								}
							}

							// Set the options
							ShowUp.theme.options.path = ShowUp.options.path;
							for (var key in ShowUp.theme.options) if (typeof ShowUp.theme.options[key] != 'object') {
								response = response.replace(new RegExp('{\\$' + key + '}', 'g'), ShowUp.theme.options[key]);
							}

							// Add the theme
							response += '<link href="' + ShowUp.options.path + 'themes/' + ShowUp.options.theme.name + '/' + ShowUp.options.theme.colorscheme + '.colorscheme.css" type="text/css" rel="stylesheet" media="all" />';

							// Append to panel
							panel = ShowUp.triggerEvent('init', panel.html(response));

							// Attach viewport
							ShowUp.DOM.viewport = $('#ShowUpViewport');

							// Hover and touch events on viewpoint
							ShowUp.DOM.viewpoint = $('#ShowUpViewpoint');
							ShowUp.DOM.viewpoint
								.on('mouseenter', function () {
									ShowUp.triggerEvent('onHoverIn');
								})
								.on('mouseleave', function () {
									ShowUp.triggerEvent('onHoverOut');
								})
								.on('touchstart', function (e) {
									ShowUp._touchSliding = false;
									ShowUp._touchStart = e.originalEvent.touches[0].screenX;
								})
								.on('touchmove', function (e) {
									e.preventDefault();
									if (ShowUp._touchSliding || !ShowUp._touchStart || ShowUp._touchStart < 0 || Math.abs(ShowUp._touchStart - e.originalEvent.touches[0].screenX) < 50) {
										return false;
									}
									else {
										if (ShowUp._touchStart > e.originalEvent.touches[0].screenX) {
											ShowUp.goNext();
										}
										else if (ShowUp._touchStart < e.originalEvent.touches[0].screenX) {
											ShowUp.goPrev();
										}
										ShowUp._touchSliding = true;
										return true;
									}
								})
								.on('touchend', function (e) {
									ShowUp._touchSliding = false;
								});


							ShowUp.building = false;
						}
					);

					// Actions
					overlay.on('click', function () {
						ShowUp.overlayClick();
					});

					// Base css
					var style = '/* Necessary styling for ShowUp, please use external CSS to adapt */\n';
					style += '#ShowUpWrapper { z-index: 3000; }\n';
					style += '#ShowUpPanel { z-index: 3001; display: none; overflow: visible!important; }\n';
					style += '#ShowUpOverlay { position: absolute; left: 0; top: 0; z-index: 3000; opacity: 0; transition: opacity 400ms ease; }\n';
					style += '#ShowUpViewport { position: relative; z-index: 3002; }\n';
					style += '#ShowUpContainer { position: absolute; left: -5000px; top: -5000px; overflow: hidden; }\n';
					style += '#ShowUpViewport .final { width: 100%; height: 100%; }\n';
					style += '#ShowUpPanel a { outline: none!important; }\n';

					style += '#ShowUpViewport .obsolete { overflow: hidden; z-index: 3005; }\n';
					style += '#ShowUpViewport .slice { position: absolute; overflow: hidden; z-index: 3006; ';
					style += '-webkit-transform: translateZ(0);';
					style += '-webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden; ';
					style += '-webkit-perspective: 1000; -moz-perspective: 1000; -ms-perspective: 1000; perspective: 1000; ';
					style += '}\n';
					style += '#ShowUpViewport .slice .relative { position: relative; }\n';

					// Append elements to document
					$('body').append($('<div id="ShowUpWrapper">').append('<style>' + style + '</style>').append(panel).append(overlay).append(container));
					panel = ShowUp.triggerEvent('onCreatePanel', panel);
				}

				// Init DOM elements
				ShowUp.DOM.wrap = $('#ShowUpWrapper');
				ShowUp.DOM.panel = $('#ShowUpPanel');
				ShowUp.DOM.overlay = $('#ShowUpOverlay');
				ShowUp.DOM.container = $('#ShowUpContainer');
			});
		},


		/**
		 * Initialize theme.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		setupTheme: function (options) {
			this.registeredEvents = this.getRegisteredTemplate();

			ShowUp.theme = ShowUpTheme[ShowUp.options.theme.name];

			if (options) {
				ShowUp.options = $.extend(ShowUp.options, ShowUp.theme);
			}


			// Default theme
			if (typeof ShowUp.theme == 'undefined') {
				ShowUp.theme = {
					name: 'default',
					colorscheme: 'light',
					options: {
						pauseOnHover: true
					},
					labels: {
						image: 'Image'
					}
				};
			}

			// Set up the theme
			for (var i in ShowUp.theme) {
				if (typeof ShowUp.theme[i] == 'function' && typeof ShowUp.registeredEvents[i] != 'undefined') {
					ShowUp.registeredEvents[i].push(ShowUp.theme[i]);
					ShowUp.theme[i] = null;
				}
			}

			// Initialize events
			for (var i in ShowUp.options) {
				if (typeof ShowUp.options[i] == 'function' && typeof ShowUp.registeredEvents[i] != 'undefined') {
					ShowUp.registeredEvents[i].push(ShowUp.options[i]);
				}
			}
		},


		/**
		 * Called when the overlay has been clicked.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		overlayClick: function () {
			ShowUp.triggerEvent('onOverlayClick');

			if (ShowUp.options.overlay.closeOnClick) {
				ShowUp.hide();
			}
		},


		/**
		 * Sets the slices from the content, using the specified transition.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		setSlices: function (transition, content, width, height) {

			// Make sure we have default options
			if (typeof transition.options == 'undefined') transition.options = {};
			transition.options = $.extend({duration: 1}, transition.options);

			// Make sure we have defaults variable
			if (typeof transition.defaults == 'undefined') transition.defaults = {};
			if (typeof transition.setDefaults == 'function') {
				transition.defaults = transition.setDefaults(content, width, height);
			}

			// Fill up missing defaults values
			transition.defaults = $.extend({
				x: 0,
				y: 0,
				w: 1,
				h: 1,
				delay: 0,
				speed: transition.options.speed,
				easing: transition.options.easing
			}, transition.defaults);

			// Initially create slices and fill with dafault values if needed
			var slices = transition.apply(content, width, height);
			for (var i in slices) {
				if (typeof slices[i].x == 'undefined') slices[i].x = transition.defaults.x;
				if (typeof slices[i].y == 'undefined') slices[i].y = transition.defaults.y;
				if (typeof slices[i].w == 'undefined') slices[i].w = transition.defaults.w + 1;
				if (typeof slices[i].h == 'undefined') slices[i].h = transition.defaults.h + 1;

				// Default values for animations
				for (var c in slices[i].animations) {
					if (typeof slices[i].animations[c].speed == 'undefined') slices[i].animations[c].speed = transition.defaults.speed;
					if (typeof slices[i].animations[c].easing == 'undefined') slices[i].animations[c].easing = transition.defaults.easing;
				}
			}

			return slices;
		},


		/**
		 * Show content.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		showContent: function (href) {
			// Trigger onShow
			href = ShowUp.triggerEvent('onShow', href, ShowUp.gallery, ShowUp.galleryThumbs, ShowUp.galleryPointer);

			// Show wrapper
			ShowUp.DOM.wrap.show();

			// Detect content
			if (href.match(/\.(jpe?g|gif|png)$/i)) {
				ShowUp.showImage(href);
			} else if (href.match(/^#/)) {
				ShowUp.showHTML(href);
			}
		},

		/**
		 * Get the currently active slide.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		getSlide: function () {
			return ShowUp.gallery[ShowUp.galleryPointer];
		},

		/**
		 * Get surrounding slides.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		fetchSurroundingImages: function () {
			var imagesOnEachSide = 2;
			var surrounding = {
				prev: [],
				next: []
			};
			for (var i = 1; i <= imagesOnEachSide; i++) {
				var pointerPrev = (ShowUp.galleryPointer + i + ShowUp.gallery.length) % ShowUp.gallery.length,
					pointerNext = (ShowUp.galleryPointer - i + ShowUp.gallery.length) % ShowUp.gallery.length;
				surrounding.prev.push(ShowUp.gallery[pointerPrev]);
				surrounding.next.push(ShowUp.gallery[pointerNext]);
			}

			function loadPrevImage() {
				var imgPrev = new Image();

				imgPrev.onload = function () {
					viewport.append('<div class="ShowUp-SurroundingPreloader prev" style="position: absolute; width: 1px; height: 1px; overflow: hidden; opacity: 0.01; top: 50%; left: 0;"><img src="' + surrounding.prev[indexPrev++] + '"></div>');
					if (indexPrev < surrounding.prev.length) {
						loadPrevImage();
					}
				};
				imgPrev.src = surrounding.prev[indexPrev];
			}

			function loadNextImage() {
				var imgNext = new Image();

				imgNext.onload = function () {
					viewport.append('<div class="ShowUp-SurroundingPreloader prev" style="position: absolute; width: 1px; height: 1px; overflow: hidden; opacity: 0.01; top: 50%; right: 0;"><img src="' + surrounding.next[indexNext++] + '"></div>');
					if (indexNext < surrounding.next.length) {
						loadNextImage();
					}
				};
				imgNext.src = surrounding.next[indexNext];
			}

			var viewport = $('#ShowUpViewport');
			viewport.find(".ShowUp-SurroundingPreloader").remove();

			var indexPrev = 0,
				indexNext = 0;
			loadPrevImage();
			loadNextImage();
		},


		/**
		 * Show image from element.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		showImage: function (href) {
			var self = this;

			var image = $('<img>');

			ShowUp.loaderTimer = setTimeout(function () {
				self.showLoader();
			}, 100);

			image.on('load', function () {
				ShowUp.animateContent(image);

				// Trigger onShown event
				ShowUp.triggerEvent('onShown', href, ShowUp.gallery, ShowUp.galleryThumbs, ShowUp.galleryPointer);

				// Fetch surrounding slides to minimize preloading time
				self.fetchSurroundingImages();
			});

			image = ShowUp.triggerEvent('onShowImage', image, this.element);

			image.attr('src', href);
		},

		/**
		 * Show HTML as popup.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		showHTML: function (href) {
			var HTML = $(href).show();
			HTML = ShowUp.triggerEvent('onShowHTML', HTML, this.element);

			// Append hidden anchor to return the DOM object
			var anchor = $('<a style="display:none!important" class="ShowUp-anchor" />');
			HTML.addClass('showup-anchored');
			HTML.data('showup-anchor', anchor);
			HTML.before(anchor);

			// Animate HTML
			ShowUp.animateContent(HTML);

			// Trigger onShown event
			ShowUp.triggerEvent('onShown', href, ShowUp.gallery, ShowUp.galleryThumbs, ShowUp.galleryPointer);
		},


		/**
		 * Show background overlay.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		showOverlay: function () {

			// Set the style of the overlay
			ShowUp.DOM.overlay.css({
				opacity: 0,
				width: $(document).width(),
				height: $(document).height(),
				background: ShowUp.options.overlay.color,
			}).show();

			// Fade in
			if (ShowUp.options.overlay.show) {
				ShowUp.DOM.overlay.css('transition', 'opacity ' + ShowUp.options.fadeInTime * ShowUp.options.duration + 'ms ease');
				ShowUp.DOM.overlay.css('opacity', ShowUp.options.overlay.opacity);
			}
		},


		/**
		 * Show loader
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		showLoader: function () {
			// Loader already there
			if (ShowUp.DOM.overlay.find('#ShowUp-Loader').length > 0) {
				return;
			}

			// Create loader
			var loader = $('<div id="ShowUp-Loader">');

			// Create inner div
			var loaderInner = $('<div id="ShowUp-LoaderInner">');

			// Loader image
			var loaderImage = $('<img src="' + ShowUp.options.path + 'themes/' + ShowUp.options.theme.name + '/img/loader.gif' + '"/>');

			loaderInner.append(loaderImage);

			// Append image
			loader.append(loaderInner);
			ShowUp.DOM.wrap.append(loader);

			loaderImage.on('load', function () {
				loader.show();
			});
		},


		/**
		 * Hide loader
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		hideLoader: function () {
			// Cancel timer
			if (ShowUp.loaderTimer) {
				clearTimeout(ShowUp.loaderTimer);
				ShowUp.loaderTimer = null;
			}
			ShowUp.DOM.wrap.find('#ShowUp-Loader').remove();
		},


		/**
		 * Animate content.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		animateContent: function (content) {
			ShowUp.hideLoader();
			ShowUp.animating = true;

			// Prepare viewport
			ShowUp.DOM.viewport = $('#ShowUpViewport');

			// Initialize
			var animationsTotal = 0;
			var aligned = ShowUp.alignPanel(content, width, height);

			content = aligned.content;
			var width = aligned.width;
			var height = aligned.height;

			// Random transition or static one
			var transition = ShowUp.getTransition();
			var slices = ShowUp.setSlices(transition, content, width, height);

			// Remove obsolete images
			ShowUp.DOM.viewport.attr('rel', 0);
			$('.slice', ShowUp.DOM.viewport).addClass('obsolete');

			// Get hash
			var hash = Math.random().toString(36).substring(2);

			slices = ShowUp.triggerEvent('onAnimateSlices', slices);
			content = ShowUp.triggerEvent('onAnimateContent', content, width, height);
			transition = ShowUp.triggerEvent('onAnimateTransition', transition);

			var i = -1;
			var totalDuration = -1;
			var count = slices.length;
			while (++i < count) {

				var sliceContent = $('<div class="slice-content">').html(content.clone().removeClass('showup-anchored'));
				sliceContent.css({
					'margin-top': -slices[i].y,
					'margin-left': -slices[i].x
				});

				// Set end position for the animation
				var finalState = {
					top: slices[i].y,
					left: slices[i].x,
					width: slices[i].w,
					height: slices[i].h,
					opacity: 1,
					"border-radius": '0%'
				};

				// Append the slice
				var slice = $('<div class="slice">').html(sliceContent).css(finalState);
				ShowUp.DOM.viewport.append(slice);

				// Prepare variables
				var anims = {};
				var transitions = '';

				var c = -1;
				var animationCount = slices[i].animations.length;
				animationsTotal += animationCount;
				while (++c < animationCount) {
					var animation = slices[i].animations[c];

					// Set start value for the property
					var value = animation.value;
					slice.css(animation.property, value);

					// Get the speeds
					var duration = animation.duration * ShowUp.options.duration / 1000;
					var delay = animation.delay / 1000;
					var total = duration + delay;

					// Calculate the total duration
					totalDuration = Math.max(totalDuration, total);

					// Set the animation
					anims[animation.property] = finalState[animation.property];

					// Define the transition
					if (transitions) transitions += ', ';
					transitions += animation.property + ' ' + duration + 's ease ' + delay + 's';
					slice.css('transition', transitions);
				}

				slice.data('animations', anims);
			}

			ShowUp.DOM.viewport.data(hash, animationsTotal);

			// Triger animations
			var animationDelay = 0;
			var numberOfSlices = count;
			var sliceObjects = $('.slice', ShowUp.DOM.viewport);
			setTimeout(function () {
				sliceObjects
					.each(function () {
						$(this).css($(this).data('animations'));
					})
					.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend', function (event) {
						$(this).off('transitionend webkitTransitionEnd oTransitionEnd otransitionend');
						numberOfSlices--;
						if (!numberOfSlices) {
							// Clean up
							sliceObjects.addClass('obsolete');
							ShowUp.removeObsolete(content);
						}
					});
			}, animationDelay);

			/*
			// Clean up
			setTimeout(function() {
				$('.slice', ShowUp.DOM.viewport).addClass('obsolete');
				ShowUp.removeObsolete(content);
			}, animationDelay + totalDuration * 1000 + 1000);
			*/
		},

		/**
		 * Gets the margin depending on the depending on the screen size
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		getMargin() {
			var winW = $(window).width();
			var margin;

			if (winW < 768) {
				margin = Math.round(ShowUp.options.minMargin * 0.25);
			}
			else if (winW < 1200) {
				margin = Math.round(ShowUp.options.minMargin * 0.5);
			}
			else if (winW < 1441) {
				margin = Math.round(ShowUp.options.minMargin * 0.75);
			}
			else {
				margin = ShowUp.options.minMargin;
			}

			return margin;
		},


		/**
		 * Aligns the panel in the user window.
		 * Alignment is based either on the content or the width and height.
		 * If width and height are set, then the content is ignored.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		alignPanel: function (content) {

			// Use width and height of the content?
			ShowUp.DOM.container.html('').append(content);
			var width = content.outerWidth();
			var height = content.outerHeight();

			// Get the padding from the theme
			var themePadding = ShowUp.theme.getPadding(ShowUp.DOM.panel);
			//$("#ShowUpMain").css('padding', themePadding.left + 'px');

			// Get the minimum margin from the theme
			var margin = ShowUp.getMargin();

			// Get the available space
			var user = $(window);
			var maxWidth = user.width() - themePadding.left - themePadding.right - 2 * margin;
			var maxHeight = user.height() - themePadding.top - themePadding.bottom - 2 * margin;

			// Resize the content if needed
			var scale = Math.max(1, width / maxWidth, height / maxHeight);
			var contentSize = {width: width /= scale, height: height /= scale};
			content.css(contentSize);

			// Define CSS for the panel and viewport
			var overflow = ShowUp.options.overflow ? 'visible' : 'hidden';
			var position = {
				opacity: 1,
				display: 'block',
				width: width + themePadding.left + themePadding.right,
				left: (user.width() - (contentSize.width + themePadding.left + themePadding.right)) / 2,
				"padding-top": (user.height() - (contentSize.height + themePadding.top + themePadding.bottom)) / 2
			};

			// Fade in panel
			ShowUp.DOM.panel.parents().not(':visible').show();
			ShowUp.DOM.panel.css({
				transition: 'all ' + (ShowUp.options.fadeInTime * ShowUp.options.duration) + 'ms ease',
				overflow: 'visible'
			});
			ShowUp.DOM.panel.css(position);

			// Fade in view port
			ShowUp.DOM.panel.parents().not(':visible').show();
			ShowUp.DOM.viewport.css({
				transition: 'all ' + (ShowUp.options.fadeInTime * ShowUp.options.duration) + 'ms ease',
				overflow: overflow
			});
			ShowUp.DOM.viewport.css(contentSize);

			// Return resized content
			return {content: content, width: width, height: height};
		},


		/**
		 * Returns all anchored elemets to their original position.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		restoreAnchored: function (ignoredElement) {

			// Ignore supplied element
			var ignored = false;
			if (typeof ignoredElement != 'undefined' && ignoredElement.is('.showup-anchored')) {
				ignored = true;
				ignoredElement.removeClass('showup-anchored');
			}

			// Check if there are valid achored elements
			$('.showup-anchored').each(function (i, content) {
				content = $(content).removeClass('showup-anchored');

				var anchor = content.data('showup-anchor');
				if (anchor != null) {
					content.data('showup-anchor', null);
					anchor.after(content.hide());
					anchor.remove();
				}
			});

			// Restore class to ignored element
			if (ignored) {
				ignoredElement.addClass('showup-anchored');
			}
		},


		/**
		 * Remove the obsolete slices from the viewport.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		removeObsolete: function (content) {
			ShowUp.restoreAnchored(content);
			$('.obsolete', ShowUp.DOM.viewport).remove();

			if (typeof content != 'undefined') {
				ShowUp.animating = false;
				content = ShowUp.triggerEvent('onAnimationComplete', content);

				// Full width for images
				if (content.is('img')) {
					content.css({width: '100%', height: '100%'});
				}

				var final = $('<div class="final content obsolete">').html(content);
				ShowUp.DOM.viewport.append(final);
			}
		},


		/**
		 * Get the transition from the options array.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		getTransition: function () {
			var transitions = ShowUp.options.transitions;

			// Simple string
			if (typeof ShowUp.options.transition == 'string') {
				return ShowUpTransition[transitions];
			}

			// Multiple
			var names = [];
			var available = [];
			for (var i in transitions) {
				var transition = {};

				// Array
				if (i.match(/^\d+$/)) {
					names.push(transitions[i]);
					transition[transitions[i]] = {};
				}
				// JSON
				else {
					names.push(i);
					transition[i] = transitions[i];
				}

				available.push(transition);
			}

			var key = Math.floor(Math.random() * names.length);
			var selected = ShowUpTransition[names[key]];
			selected.options = $.extend(selected.options, available[key][names[key]]);

			return selected;
		},


		/**
		 * Hides the panel from the user.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		hide: function () {

			if (!ShowUp.triggerEvent('onHide', true)) {
				return;
			}

			$(window).off('resize', this.handleResize);

			// Clear current gallery state
			ShowUp.gallery = [];
			ShowUp.galleryThumbs = [];
			ShowUp.galleryCount = 0;
			ShowUp.galleryPointer = 0;
			ShowUp.element = null;

			// Fade out overlay
			ShowUp.DOM.overlay.css('transition', 'opacity ' + ShowUp.options.fadeOutTime + 'ms ease');
			ShowUp.DOM.overlay.css('opacity', 0);

			// Fade out panel
			ShowUp.DOM.panel.css('transition', 'opacity ' + ShowUp.options.fadeOutTime + 'ms ease');
			ShowUp.DOM.panel.css('opacity', 0);

			// Fade out
			setTimeout(
				function () {
					ShowUp.DOM.wrap.hide();
					ShowUp.restoreAnchored();
					ShowUp.DOM.viewport.html('');
				},
				ShowUp.options.fadeOutTime
			);

			// Stop all animations
			ShowUp.goStop();
		},


		/**
		 * Convert percentages to float (0 - 1).
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		percentToFloat: function (percent) {
			return percent > 1
				? ("" + percent).replace(/[^0-9]+/g, '') / 100
				: percent;
		},


		pause: false,
		player: null,


		/**
		 * Publicly available statuses.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
		status: {
			isActive: function () {
				return ShowUp.DOM.panel.is(':visible');
			},

			animating: function () {
				return ShowUp.animating;
			},

			playing: function () {
				return ShowUp.player != null;
			},

			paused: function () {
				return ShowUp.player != null && ShowUp.pause;
			},

			hasNext: function () {
				return ShowUp.galleryPointer + 1 < ShowUp.galleryCount;
			},

			hasPrev: function () {
				return ShowUp.galleryPointer > 0;
			}

		},


		/**
		 * The public API.
		 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

		goTo: function (index, loop, force) {
			if (ShowUp.galleryPointer == index) {
				return false;
			}

			if (ShowUp.status.animating() || ShowUp.galleryCount == 0 || (!force && this.status.playing())) return false;

			// Should we loop
			if (typeof loop == 'undefined') {
				loop = ShowUp.options.loop;
			}

			// Which event to trigger
			var event = ShowUp.galleryPointer > index ? 'onPrev' : 'onNext';

			// Trigger event
			index = ShowUp.triggerEvent(event, index, ShowUp.gallery, ShowUp.galleryThumbs, loop);

			// Handle last
			if (index >= ShowUp.galleryCount) {
				if (loop) {
					index = 0;
				} else {
					ShowUp.goStop();
					return false;
				}
			}

			// Handle first
			if (index < 0) {
				if (loop) {
					index = ShowUp.galleryCount - 1;
				} else {
					return false;
				}
			}

			// Update pointer and show content
			ShowUp.galleryPointer = index;
			ShowUp.showContent(this.getSlide());
			return true;

		},

		goNext: function (loop, force) {
			return this.goTo(ShowUp.galleryPointer + 1, loop, force);
		},

		goPrev: function (loop, force) {
			return this.goTo(ShowUp.galleryPointer - 1, loop, force);
		},

		goPlay: function (interval, loop, init) {
			if (!loop) loop = ShowUp.options.loop;
			if (!interval) interval = ShowUp.options.playInterval;

			// Get the interval
			interval = ShowUp.triggerEvent('onPlay', Math.max(interval, 2000));
			if (ShowUp.galleryCount < 2 || interval == 0) return false;

			if (!loop && ShowUp.galleryPointer == ShowUp.galleryCount - 1) {
				ShowUp.galleryPointer = -1;
			}

			if (!init) ShowUp.goNext(loop, true);
			ShowUp.player = setInterval(function () {
				if (!ShowUp.pause) ShowUp.goNext(loop, true);
			}, interval);
			return true;
		},

		goStop: function () {
			if (ShowUp.player != null && ShowUp.triggerEvent('onStop', true)) {
				clearInterval(ShowUp.player);
				ShowUp.player = null;
				return true;
			}

			return false;
		},

		goPause: function () {
			if (ShowUp.status.playing() && !ShowUp.status.paused()) {
				ShowUp.pause = ShowUp.triggerEvent('onPause', true);
				return true;
			}

			return false;
		},

		goUnpause: function () {
			if (ShowUp.status.paused()) {
				ShowUp.pause = !ShowUp.triggerEvent('onUnpause', true);
				return true;
			}

			return false;
		},

		goHide: function () {
			ShowUp.hide();
		}
	};

	/**
	 * Define jQuery plugin.
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
	$.fn.showUp = function (options) {
		return this.each(function () {
			_this = $(this);
			if (!_this.data('plugin_showUp')) {
				ShowUp.attach(_this, options);
				_this.data('plugin_showUp', options);
			}
		});
	};

	/**
	 * Detects keyboard input.
	 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
	document.onkeydown = function (evt) {
		evt = evt || window.event;
		if (evt.keyCode == 27 && ShowUp.options.closeOnEsc && ShowUp.status.isActive()) {
			ShowUp.goHide();
		}
		else if (evt.keyCode == 37 && ShowUp.options.keyboardControls && ShowUp.status.isActive()) {
			ShowUp.goPrev();
		}
		else if ((evt.keyCode == 39 || evt.keyCode == 32) && ShowUp.options.keyboardControls && ShowUp.status.isActive()) {
			ShowUp.goNext();
		}
	};

})(jQuery, window, document);
