\\',\\n btnTpl: {\\n download: \\'\\' + \\'\\' + \"\",\\n zoom: \\'\",\\n close: \\'\",\\n // Arrows\\n arrowLeft: \\'\",\\n arrowRight: \\'\",\\n // This small close button will be appended to your html/inline/ajax content by default,\\n // if \"smallBtn\" option is not set to false\\n smallBtn: \\'\"\\n },\\n // Container is injected into this element\\n parentEl: \"body\",\\n // Hide browser vertical scrollbars; use at your own risk\\n hideScrollbar: true,\\n // Focus handling\\n // ==============\\n // Try to focus on the first focusable element after opening\\n autoFocus: true,\\n // Put focus back to active element after closing\\n backFocus: true,\\n // Do not let user to focus on element outside modal content\\n trapFocus: true,\\n // Module specific options\\n // =======================\\n fullScreen: {\\n autoStart: false\\n },\\n // Set `touch: false` to disable panning/swiping\\n touch: {\\n vertical: true,\\n // Allow to drag content vertically\\n momentum: true // Continue movement after releasing mouse/touch when panning\\n\\n },\\n // Hash value when initializing manually,\\n // set `false` to disable hash change\\n hash: null,\\n // Customize or add new media types\\n // Example:\\n\\n /*\\r\\n media : {\\r\\n youtube : {\\r\\n params : {\\r\\n autoplay : 0\\r\\n }\\r\\n }\\r\\n }\\r\\n */\\n media: {},\\n slideShow: {\\n autoStart: false,\\n speed: 3000\\n },\\n thumbs: {\\n autoStart: false,\\n // Display thumbnails on opening\\n hideOnClose: true,\\n // Hide thumbnail grid when closing animation starts\\n parentEl: \".fancybox-container\",\\n // Container is injected into this element\\n axis: \"y\" // Vertical (y) or horizontal (x) scrolling\\n\\n },\\n // Use mousewheel to navigate gallery\\n // If \\'auto\\' - enabled for images only\\n wheel: \"auto\",\\n // Callbacks\\n //==========\\n // See Documentation/API/Events for more information\\n // Example:\\n\\n /*\\r\\n afterShow: function( instance, current ) {\\r\\n console.info( \\'Clicked element:\\' );\\r\\n console.info( current.opts.$orig );\\r\\n }\\r\\n */\\n onInit: $.noop,\\n // When instance has been initialized\\n beforeLoad: $.noop,\\n // Before the content of a slide is being loaded\\n afterLoad: $.noop,\\n // When the content of a slide is done loading\\n beforeShow: $.noop,\\n // Before open animation starts\\n afterShow: $.noop,\\n // When content is done loading and animating\\n beforeClose: $.noop,\\n // Before the instance attempts to close. Return false to cancel the close.\\n afterClose: $.noop,\\n // After instance has been closed\\n onActivate: $.noop,\\n // When instance is brought to front\\n onDeactivate: $.noop,\\n // When other instance has been activated\\n // Interaction\\n // ===========\\n // Use options below to customize taken action when user clicks or double clicks on the fancyBox area,\\n // each option can be string or method that returns value.\\n //\\n // Possible values:\\n // \"close\" - close instance\\n // \"next\" - move to next gallery item\\n // \"nextOrClose\" - move to next gallery item or close if gallery has only one item\\n // \"toggleControls\" - show/hide controls\\n // \"zoom\" - zoom image (if loaded)\\n // false - do nothing\\n // Clicked on the content\\n clickContent: function clickContent(current, event) {\\n return current.type === \"image\" ? \"zoom\" : false;\\n },\\n // Clicked on the slide\\n clickSlide: \"close\",\\n // Clicked on the background (backdrop) element;\\n // if you have not changed the layout, then most likely you need to use `clickSlide` option\\n clickOutside: \"close\",\\n // Same as previous two, but for double click\\n dblclickContent: false,\\n dblclickSlide: false,\\n dblclickOutside: false,\\n // Custom options when mobile device is detected\\n // =============================================\\n mobile: {\\n preventCaptionOverlap: false,\\n idleTime: false,\\n clickContent: function clickContent(current, event) {\\n return current.type === \"image\" ? \"toggleControls\" : false;\\n },\\n clickSlide: function clickSlide(current, event) {\\n return current.type === \"image\" ? \"toggleControls\" : \"close\";\\n },\\n dblclickContent: function dblclickContent(current, event) {\\n return current.type === \"image\" ? \"zoom\" : false;\\n },\\n dblclickSlide: function dblclickSlide(current, event) {\\n return current.type === \"image\" ? \"zoom\" : false;\\n }\\n },\\n // Internationalization\\n // ====================\\n lang: \"en\",\\n i18n: {\\n en: {\\n CLOSE: \"Close\",\\n NEXT: \"Next\",\\n PREV: \"Previous\",\\n ERROR: \"The requested content cannot be loaded. Please try again later.\",\\n PLAY_START: \"Start slideshow\",\\n PLAY_STOP: \"Pause slideshow\",\\n FULL_SCREEN: \"Full screen\",\\n THUMBS: \"Thumbnails\",\\n DOWNLOAD: \"Download\",\\n SHARE: \"Share\",\\n ZOOM: \"Zoom\"\\n },\\n de: {\\n CLOSE: \"Schließen\",\\n NEXT: \"Weiter\",\\n PREV: \"Zurück\",\\n ERROR: \"Die angeforderten Daten konnten nicht geladen werden. Bitte versuchen Sie es später nochmal.\",\\n PLAY_START: \"Diaschau starten\",\\n PLAY_STOP: \"Diaschau beenden\",\\n FULL_SCREEN: \"Vollbild\",\\n THUMBS: \"Vorschaubilder\",\\n DOWNLOAD: \"Herunterladen\",\\n SHARE: \"Teilen\",\\n ZOOM: \"Vergrößern\"\\n }\\n }\\n }; // Few useful variables and methods\\n // ================================\\n\\n var $W = $(window);\\n var $D = $(document);\\n var called = 0; // Check if an object is a jQuery object and not a native JavaScript object\\n // ========================================================================\\n\\n var isQuery = function isQuery(obj) {\\n return obj && obj.hasOwnProperty && obj instanceof $;\\n }; // Handle multiple browsers for \"requestAnimationFrame\" and \"cancelAnimationFrame\"\\n // ===============================================================================\\n\\n\\n var requestAFrame = function () {\\n return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || // if all else fails, use setTimeout\\n function (callback) {\\n return window.setTimeout(callback, 1000 / 60);\\n };\\n }();\\n\\n var cancelAFrame = function () {\\n return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || function (id) {\\n window.clearTimeout(id);\\n };\\n }(); // Detect the supported transition-end event property name\\n // =======================================================\\n\\n\\n var transitionEnd = function () {\\n var el = document.createElement(\"fakeelement\"),\\n t;\\n var transitions = {\\n transition: \"transitionend\",\\n OTransition: \"oTransitionEnd\",\\n MozTransition: \"transitionend\",\\n WebkitTransition: \"webkitTransitionEnd\"\\n };\\n\\n for (t in transitions) {\\n if (el.style[t] !== undefined) {\\n return transitions[t];\\n }\\n }\\n\\n return \"transitionend\";\\n }(); // Force redraw on an element.\\n // This helps in cases where the browser doesn\\'t redraw an updated element properly\\n // ================================================================================\\n\\n\\n var forceRedraw = function forceRedraw($el) {\\n return $el && $el.length && $el[0].offsetHeight;\\n }; // Exclude array (`buttons`) options from deep merging\\n // ===================================================\\n\\n\\n var mergeOpts = function mergeOpts(opts1, opts2) {\\n var rez = $.extend(true, {}, opts1, opts2);\\n $.each(opts2, function (key, value) {\\n if ($.isArray(value)) {\\n rez[key] = value;\\n }\\n });\\n return rez;\\n }; // How much of an element is visible in viewport\\n // =============================================\\n\\n\\n var inViewport = function inViewport(elem) {\\n var elemCenter, rez;\\n\\n if (!elem || elem.ownerDocument !== document) {\\n return false;\\n }\\n\\n $(\".fancybox-container\").css(\"pointer-events\", \"none\");\\n elemCenter = {\\n x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,\\n y: elem.getBoundingClientRect().top + elem.offsetHeight / 2\\n };\\n rez = document.elementFromPoint(elemCenter.x, elemCenter.y) === elem;\\n $(\".fancybox-container\").css(\"pointer-events\", \"\");\\n return rez;\\n }; // Class definition\\n // ================\\n\\n\\n var FancyBox = function FancyBox(content, opts, index) {\\n var self = this;\\n self.opts = mergeOpts({\\n index: index\\n }, $.fancybox.defaults);\\n\\n if ($.isPlainObject(opts)) {\\n self.opts = mergeOpts(self.opts, opts);\\n }\\n\\n if ($.fancybox.isMobile) {\\n self.opts = mergeOpts(self.opts, self.opts.mobile);\\n }\\n\\n self.id = self.opts.id || ++called;\\n self.currIndex = parseInt(self.opts.index, 10) || 0;\\n self.prevIndex = null;\\n self.prevPos = null;\\n self.currPos = 0;\\n self.firstRun = true; // All group items\\n\\n self.group = []; // Existing slides (for current, next and previous gallery items)\\n\\n self.slides = {}; // Create group elements\\n\\n self.addContent(content);\\n\\n if (!self.group.length) {\\n return;\\n }\\n\\n self.init();\\n };\\n\\n $.extend(FancyBox.prototype, {\\n // Create DOM structure\\n // ====================\\n init: function init() {\\n var self = this,\\n firstItem = self.group[self.currIndex],\\n firstItemOpts = firstItem.opts,\\n $container,\\n buttonStr;\\n\\n if (firstItemOpts.closeExisting) {\\n $.fancybox.close(true);\\n } // Hide scrollbars\\n // ===============\\n\\n\\n $(\"body\").addClass(\"fancybox-active\");\\n\\n if (!$.fancybox.getInstance() && firstItemOpts.hideScrollbar !== false && !$.fancybox.isMobile && document.body.scrollHeight > window.innerHeight) {\\n $(\"head\").append(\\'\");\\n $(\"body\").addClass(\"compensate-for-scrollbar\");\\n } // Build html markup and set references\\n // ====================================\\n // Build html code for buttons and insert into main template\\n\\n\\n buttonStr = \"\";\\n $.each(firstItemOpts.buttons, function (index, value) {\\n buttonStr += firstItemOpts.btnTpl[value] || \"\";\\n }); // Create markup from base template, it will be initially hidden to\\n // avoid unnecessary work like painting while initializing is not complete\\n\\n $container = $(self.translate(self, firstItemOpts.baseTpl.replace(\"{{buttons}}\", buttonStr).replace(\"{{arrows}}\", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight))).attr(\"id\", \"fancybox-container-\" + self.id).addClass(firstItemOpts.baseClass).data(\"FancyBox\", self).appendTo(firstItemOpts.parentEl); // Create object holding references to jQuery wrapped nodes\\n\\n self.$refs = {\\n container: $container\\n };\\n [\"bg\", \"inner\", \"infobar\", \"toolbar\", \"stage\", \"caption\", \"navigation\"].forEach(function (item) {\\n self.$refs[item] = $container.find(\".fancybox-\" + item);\\n });\\n self.trigger(\"onInit\"); // Enable events, deactive previous instances\\n\\n self.activate(); // Build slides, load and reveal content\\n\\n self.jumpTo(self.currIndex);\\n },\\n // Simple i18n support - replaces object keys found in template\\n // with corresponding values\\n // ============================================================\\n translate: function translate(obj, str) {\\n var arr = obj.opts.i18n[obj.opts.lang] || obj.opts.i18n.en;\\n return str.replace(/\\\\{\\\\{(\\\\w+)\\\\}\\\\}/g, function (match, n) {\\n return arr[n] === undefined ? match : arr[n];\\n });\\n },\\n // Populate current group with fresh content\\n // Check if each object has valid type and content\\n // ===============================================\\n addContent: function addContent(content) {\\n var self = this,\\n items = $.makeArray(content),\\n thumbs;\\n $.each(items, function (i, item) {\\n var obj = {},\\n opts = {},\\n $item,\\n type,\\n found,\\n src,\\n srcParts; // Step 1 - Make sure we have an object\\n // ====================================\\n\\n if ($.isPlainObject(item)) {\\n // We probably have manual usage here, something like\\n // $.fancybox.open( [ { src : \"image.jpg\", type : \"image\" } ] )\\n obj = item;\\n opts = item.opts || item;\\n } else if ($.type(item) === \"object\" && $(item).length) {\\n // Here we probably have jQuery collection returned by some selector\\n $item = $(item); // Support attributes like `data-options=\\'{\"touch\" : false}\\'` and `data-touch=\\'false\\'`\\n\\n opts = $item.data() || {};\\n opts = $.extend(true, {}, opts, opts.options); // Here we store clicked element\\n\\n opts.$orig = $item;\\n obj.src = self.opts.src || opts.src || $item.attr(\"href\"); // Assume that simple syntax is used, for example:\\n // `$.fancybox.open( $(\"#test\"), {} );`\\n\\n if (!obj.type && !obj.src) {\\n obj.type = \"inline\";\\n obj.src = item;\\n }\\n } else {\\n // Assume we have a simple html code, for example:\\n // $.fancybox.open( \\'
Hi!
\\' );\\n obj = {\\n type: \"html\",\\n src: item + \"\"\\n };\\n } // Each gallery object has full collection of options\\n\\n\\n obj.opts = $.extend(true, {}, self.opts, opts); // Do not merge buttons array\\n\\n if ($.isArray(opts.buttons)) {\\n obj.opts.buttons = opts.buttons;\\n }\\n\\n if ($.fancybox.isMobile && obj.opts.mobile) {\\n obj.opts = mergeOpts(obj.opts, obj.opts.mobile);\\n } // Step 2 - Make sure we have content type, if not - try to guess\\n // ==============================================================\\n\\n\\n type = obj.type || obj.opts.type;\\n src = obj.src || \"\";\\n\\n if (!type && src) {\\n if (found = src.match(/\\\\.(mp4|mov|ogv|webm)((\\\\?|#).*)?$/i)) {\\n type = \"video\";\\n\\n if (!obj.opts.video.format) {\\n obj.opts.video.format = \"video/\" + (found[1] === \"ogv\" ? \"ogg\" : found[1]);\\n }\\n } else if (src.match(/(^data:image\\\\/[a-z0-9+\\\\/=]*,)|(\\\\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\\\\?|#).*)?$)/i)) {\\n type = \"image\";\\n } else if (src.match(/\\\\.(pdf)((\\\\?|#).*)?$/i)) {\\n type = \"iframe\";\\n obj = $.extend(true, obj, {\\n contentType: \"pdf\",\\n opts: {\\n iframe: {\\n preload: false\\n }\\n }\\n });\\n } else if (src.charAt(0) === \"#\") {\\n type = \"inline\";\\n }\\n }\\n\\n if (type) {\\n obj.type = type;\\n } else {\\n self.trigger(\"objectNeedsType\", obj);\\n }\\n\\n if (!obj.contentType) {\\n obj.contentType = $.inArray(obj.type, [\"html\", \"inline\", \"ajax\"]) > -1 ? \"html\" : obj.type;\\n } // Step 3 - Some adjustments\\n // =========================\\n\\n\\n obj.index = self.group.length;\\n\\n if (obj.opts.smallBtn == \"auto\") {\\n obj.opts.smallBtn = $.inArray(obj.type, [\"html\", \"inline\", \"ajax\"]) > -1;\\n }\\n\\n if (obj.opts.toolbar === \"auto\") {\\n obj.opts.toolbar = !obj.opts.smallBtn;\\n } // Find thumbnail image, check if exists and if is in the viewport\\n\\n\\n obj.$thumb = obj.opts.$thumb || null;\\n\\n if (obj.opts.$trigger && obj.index === self.opts.index) {\\n obj.$thumb = obj.opts.$trigger.find(\"img:first\");\\n\\n if (obj.$thumb.length) {\\n obj.opts.$orig = obj.opts.$trigger;\\n }\\n }\\n\\n if (!(obj.$thumb && obj.$thumb.length) && obj.opts.$orig) {\\n obj.$thumb = obj.opts.$orig.find(\"img:first\");\\n }\\n\\n if (obj.$thumb && !obj.$thumb.length) {\\n obj.$thumb = null;\\n }\\n\\n obj.thumb = obj.opts.thumb || (obj.$thumb ? obj.$thumb[0].src : null); // \"caption\" is a \"special\" option, it can be used to customize caption per gallery item\\n\\n if ($.type(obj.opts.caption) === \"function\") {\\n obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);\\n }\\n\\n if ($.type(self.opts.caption) === \"function\") {\\n obj.opts.caption = self.opts.caption.apply(item, [self, obj]);\\n } // Make sure we have caption as a string or jQuery object\\n\\n\\n if (!(obj.opts.caption instanceof $)) {\\n obj.opts.caption = obj.opts.caption === undefined ? \"\" : obj.opts.caption + \"\";\\n } // Check if url contains \"filter\" used to filter the content\\n // Example: \"ajax.html #something\"\\n\\n\\n if (obj.type === \"ajax\") {\\n srcParts = src.split(/\\\\s+/, 2);\\n\\n if (srcParts.length > 1) {\\n obj.src = srcParts.shift();\\n obj.opts.filter = srcParts.shift();\\n }\\n } // Hide all buttons and disable interactivity for modal items\\n\\n\\n if (obj.opts.modal) {\\n obj.opts = $.extend(true, obj.opts, {\\n trapFocus: true,\\n // Remove buttons\\n infobar: 0,\\n toolbar: 0,\\n smallBtn: 0,\\n // Disable keyboard navigation\\n keyboard: 0,\\n // Disable some modules\\n slideShow: 0,\\n fullScreen: 0,\\n thumbs: 0,\\n touch: 0,\\n // Disable click event handlers\\n clickContent: false,\\n clickSlide: false,\\n clickOutside: false,\\n dblclickContent: false,\\n dblclickSlide: false,\\n dblclickOutside: false\\n });\\n } // Step 4 - Add processed object to group\\n // ======================================\\n\\n\\n self.group.push(obj);\\n }); // Update controls if gallery is already opened\\n\\n if (Object.keys(self.slides).length) {\\n self.updateControls(); // Update thumbnails, if needed\\n\\n thumbs = self.Thumbs;\\n\\n if (thumbs && thumbs.isActive) {\\n thumbs.create();\\n thumbs.focus();\\n }\\n }\\n },\\n // Attach an event handler functions for:\\n // - navigation buttons\\n // - browser scrolling, resizing;\\n // - focusing\\n // - keyboard\\n // - detecting inactivity\\n // ======================================\\n addEvents: function addEvents() {\\n var self = this;\\n self.removeEvents(); // Make navigation elements clickable\\n // ==================================\\n\\n self.$refs.container.on(\"click.fb-close\", \"[data-fancybox-close]\", function (e) {\\n e.stopPropagation();\\n e.preventDefault();\\n self.close(e);\\n }).on(\"touchstart.fb-prev click.fb-prev\", \"[data-fancybox-prev]\", function (e) {\\n e.stopPropagation();\\n e.preventDefault();\\n self.previous();\\n }).on(\"touchstart.fb-next click.fb-next\", \"[data-fancybox-next]\", function (e) {\\n e.stopPropagation();\\n e.preventDefault();\\n self.next();\\n }).on(\"click.fb\", \"[data-fancybox-zoom]\", function (e) {\\n // Click handler for zoom button\\n self[self.isScaledDown() ? \"scaleToActual\" : \"scaleToFit\"]();\\n }); // Handle page scrolling and browser resizing\\n // ==========================================\\n\\n $W.on(\"orientationchange.fb resize.fb\", function (e) {\\n if (e && e.originalEvent && e.originalEvent.type === \"resize\") {\\n if (self.requestId) {\\n cancelAFrame(self.requestId);\\n }\\n\\n self.requestId = requestAFrame(function () {\\n self.update(e);\\n });\\n } else {\\n if (self.current && self.current.type === \"iframe\") {\\n self.$refs.stage.hide();\\n }\\n\\n setTimeout(function () {\\n self.$refs.stage.show();\\n self.update(e);\\n }, $.fancybox.isMobile ? 600 : 250);\\n }\\n });\\n $D.on(\"keydown.fb\", function (e) {\\n var instance = $.fancybox ? $.fancybox.getInstance() : null,\\n current = instance.current,\\n keycode = e.keyCode || e.which; // Trap keyboard focus inside of the modal\\n // =======================================\\n\\n if (keycode == 9) {\\n if (current.opts.trapFocus) {\\n self.focus(e);\\n }\\n\\n return;\\n } // Enable keyboard navigation\\n // ==========================\\n\\n\\n if (!current.opts.keyboard || e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is(\"input,textarea,video,audio,select\")) {\\n return;\\n } // Backspace and Esc keys\\n\\n\\n if (keycode === 8 || keycode === 27) {\\n e.preventDefault();\\n self.close(e);\\n return;\\n } // Left arrow and Up arrow\\n\\n\\n if (keycode === 37 || keycode === 38) {\\n e.preventDefault();\\n self.previous();\\n return;\\n } // Righ arrow and Down arrow\\n\\n\\n if (keycode === 39 || keycode === 40) {\\n e.preventDefault();\\n self.next();\\n return;\\n }\\n\\n self.trigger(\"afterKeydown\", e, keycode);\\n }); // Hide controls after some inactivity period\\n\\n if (self.group[self.currIndex].opts.idleTime) {\\n self.idleSecondsCounter = 0;\\n $D.on(\"mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle\", function (e) {\\n self.idleSecondsCounter = 0;\\n\\n if (self.isIdle) {\\n self.showControls();\\n }\\n\\n self.isIdle = false;\\n });\\n self.idleInterval = window.setInterval(function () {\\n self.idleSecondsCounter++;\\n\\n if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) {\\n self.isIdle = true;\\n self.idleSecondsCounter = 0;\\n self.hideControls();\\n }\\n }, 1000);\\n }\\n },\\n // Remove events added by the core\\n // ===============================\\n removeEvents: function removeEvents() {\\n var self = this;\\n $W.off(\"orientationchange.fb resize.fb\");\\n $D.off(\"keydown.fb .fb-idle\");\\n this.$refs.container.off(\".fb-close .fb-prev .fb-next\");\\n\\n if (self.idleInterval) {\\n window.clearInterval(self.idleInterval);\\n self.idleInterval = null;\\n }\\n },\\n // Change to previous gallery item\\n // ===============================\\n previous: function previous(duration) {\\n return this.jumpTo(this.currPos - 1, duration);\\n },\\n // Change to next gallery item\\n // ===========================\\n next: function next(duration) {\\n return this.jumpTo(this.currPos + 1, duration);\\n },\\n // Switch to selected gallery item\\n // ===============================\\n jumpTo: function jumpTo(pos, duration) {\\n var self = this,\\n groupLen = self.group.length,\\n firstRun,\\n isMoved,\\n loop,\\n current,\\n previous,\\n slidePos,\\n stagePos,\\n prop,\\n diff;\\n\\n if (self.isDragging || self.isClosing || self.isAnimating && self.firstRun) {\\n return;\\n } // Should loop?\\n\\n\\n pos = parseInt(pos, 10);\\n loop = self.current ? self.current.opts.loop : self.opts.loop;\\n\\n if (!loop && (pos < 0 || pos >= groupLen)) {\\n return false;\\n } // Check if opening for the first time; this helps to speed things up\\n\\n\\n firstRun = self.firstRun = !Object.keys(self.slides).length; // Create slides\\n\\n previous = self.current;\\n self.prevIndex = self.currIndex;\\n self.prevPos = self.currPos;\\n current = self.createSlide(pos);\\n\\n if (groupLen > 1) {\\n if (loop || current.index < groupLen - 1) {\\n self.createSlide(pos + 1);\\n }\\n\\n if (loop || current.index > 0) {\\n self.createSlide(pos - 1);\\n }\\n }\\n\\n self.current = current;\\n self.currIndex = current.index;\\n self.currPos = current.pos;\\n self.trigger(\"beforeShow\", firstRun);\\n self.updateControls(); // Validate duration length\\n\\n current.forcedDuration = undefined;\\n\\n if ($.isNumeric(duration)) {\\n current.forcedDuration = duration;\\n } else {\\n duration = current.opts[firstRun ? \"animationDuration\" : \"transitionDuration\"];\\n }\\n\\n duration = parseInt(duration, 10); // Check if user has swiped the slides or if still animating\\n\\n isMoved = self.isMoved(current); // Make sure current slide is visible\\n\\n current.$slide.addClass(\"fancybox-slide--current\"); // Fresh start - reveal container, current slide and start loading content\\n\\n if (firstRun) {\\n if (current.opts.animationEffect && duration) {\\n self.$refs.container.css(\"transition-duration\", duration + \"ms\");\\n }\\n\\n self.$refs.container.addClass(\"fancybox-is-open\").trigger(\"focus\"); // Attempt to load content into slide\\n // This will later call `afterLoad` -> `revealContent`\\n\\n self.loadSlide(current);\\n self.preload(\"image\");\\n return;\\n } // Get actual slide/stage positions (before cleaning up)\\n\\n\\n slidePos = $.fancybox.getTranslate(previous.$slide);\\n stagePos = $.fancybox.getTranslate(self.$refs.stage); // Clean up all slides\\n\\n $.each(self.slides, function (index, slide) {\\n $.fancybox.stop(slide.$slide, true);\\n });\\n\\n if (previous.pos !== current.pos) {\\n previous.isComplete = false;\\n }\\n\\n previous.$slide.removeClass(\"fancybox-slide--complete fancybox-slide--current\"); // If slides are out of place, then animate them to correct position\\n\\n if (isMoved) {\\n // Calculate horizontal swipe distance\\n diff = slidePos.left - (previous.pos * slidePos.width + previous.pos * previous.opts.gutter);\\n $.each(self.slides, function (index, slide) {\\n slide.$slide.removeClass(\"fancybox-animated\").removeClass(function (index, className) {\\n return (className.match(/(^|\\\\s)fancybox-fx-\\\\S+/g) || []).join(\" \");\\n }); // Make sure that each slide is in equal distance\\n // This is mostly needed for freshly added slides, because they are not yet positioned\\n\\n var leftPos = slide.pos * slidePos.width + slide.pos * slide.opts.gutter;\\n $.fancybox.setTranslate(slide.$slide, {\\n top: 0,\\n left: leftPos - stagePos.left + diff\\n });\\n\\n if (slide.pos !== current.pos) {\\n slide.$slide.addClass(\"fancybox-slide--\" + (slide.pos > current.pos ? \"next\" : \"previous\"));\\n } // Redraw to make sure that transition will start\\n\\n\\n forceRedraw(slide.$slide); // Animate the slide\\n\\n $.fancybox.animate(slide.$slide, {\\n top: 0,\\n left: (slide.pos - current.pos) * slidePos.width + (slide.pos - current.pos) * slide.opts.gutter\\n }, duration, function () {\\n slide.$slide.css({\\n transform: \"\",\\n opacity: \"\"\\n }).removeClass(\"fancybox-slide--next fancybox-slide--previous\");\\n\\n if (slide.pos === self.currPos) {\\n self.complete();\\n }\\n });\\n });\\n } else if (duration && current.opts.transitionEffect) {\\n // Set transition effect for previously active slide\\n prop = \"fancybox-animated fancybox-fx-\" + current.opts.transitionEffect;\\n previous.$slide.addClass(\"fancybox-slide--\" + (previous.pos > current.pos ? \"next\" : \"previous\"));\\n $.fancybox.animate(previous.$slide, prop, duration, function () {\\n previous.$slide.removeClass(prop).removeClass(\"fancybox-slide--next fancybox-slide--previous\");\\n }, false);\\n }\\n\\n if (current.isLoaded) {\\n self.revealContent(current);\\n } else {\\n self.loadSlide(current);\\n }\\n\\n self.preload(\"image\");\\n },\\n // Create new \"slide\" element\\n // These are gallery items that are actually added to DOM\\n // =======================================================\\n createSlide: function createSlide(pos) {\\n var self = this,\\n $slide,\\n index;\\n index = pos % self.group.length;\\n index = index < 0 ? self.group.length + index : index;\\n\\n if (!self.slides[pos] && self.group[index]) {\\n $slide = $(\\'\\').appendTo(self.$refs.stage);\\n self.slides[pos] = $.extend(true, {}, self.group[index], {\\n pos: pos,\\n $slide: $slide,\\n isLoaded: false\\n });\\n self.updateSlide(self.slides[pos]);\\n }\\n\\n return self.slides[pos];\\n },\\n // Scale image to the actual size of the image;\\n // x and y values should be relative to the slide\\n // ==============================================\\n scaleToActual: function scaleToActual(x, y, duration) {\\n var self = this,\\n current = self.current,\\n $content = current.$content,\\n canvasWidth = $.fancybox.getTranslate(current.$slide).width,\\n canvasHeight = $.fancybox.getTranslate(current.$slide).height,\\n newImgWidth = current.width,\\n newImgHeight = current.height,\\n imgPos,\\n posX,\\n posY,\\n scaleX,\\n scaleY;\\n\\n if (self.isAnimating || self.isMoved() || !$content || !(current.type == \"image\" && current.isLoaded && !current.hasError)) {\\n return;\\n }\\n\\n self.isAnimating = true;\\n $.fancybox.stop($content);\\n x = x === undefined ? canvasWidth * 0.5 : x;\\n y = y === undefined ? canvasHeight * 0.5 : y;\\n imgPos = $.fancybox.getTranslate($content);\\n imgPos.top -= $.fancybox.getTranslate(current.$slide).top;\\n imgPos.left -= $.fancybox.getTranslate(current.$slide).left;\\n scaleX = newImgWidth / imgPos.width;\\n scaleY = newImgHeight / imgPos.height; // Get center position for original image\\n\\n posX = canvasWidth * 0.5 - newImgWidth * 0.5;\\n posY = canvasHeight * 0.5 - newImgHeight * 0.5; // Make sure image does not move away from edges\\n\\n if (newImgWidth > canvasWidth) {\\n posX = imgPos.left * scaleX - (x * scaleX - x);\\n\\n if (posX > 0) {\\n posX = 0;\\n }\\n\\n if (posX < canvasWidth - newImgWidth) {\\n posX = canvasWidth - newImgWidth;\\n }\\n }\\n\\n if (newImgHeight > canvasHeight) {\\n posY = imgPos.top * scaleY - (y * scaleY - y);\\n\\n if (posY > 0) {\\n posY = 0;\\n }\\n\\n if (posY < canvasHeight - newImgHeight) {\\n posY = canvasHeight - newImgHeight;\\n }\\n }\\n\\n self.updateCursor(newImgWidth, newImgHeight);\\n $.fancybox.animate($content, {\\n top: posY,\\n left: posX,\\n scaleX: scaleX,\\n scaleY: scaleY\\n }, duration || 366, function () {\\n self.isAnimating = false;\\n }); // Stop slideshow\\n\\n if (self.SlideShow && self.SlideShow.isActive) {\\n self.SlideShow.stop();\\n }\\n },\\n // Scale image to fit inside parent element\\n // ========================================\\n scaleToFit: function scaleToFit(duration) {\\n var self = this,\\n current = self.current,\\n $content = current.$content,\\n end;\\n\\n if (self.isAnimating || self.isMoved() || !$content || !(current.type == \"image\" && current.isLoaded && !current.hasError)) {\\n return;\\n }\\n\\n self.isAnimating = true;\\n $.fancybox.stop($content);\\n end = self.getFitPos(current);\\n self.updateCursor(end.width, end.height);\\n $.fancybox.animate($content, {\\n top: end.top,\\n left: end.left,\\n scaleX: end.width / $content.width(),\\n scaleY: end.height / $content.height()\\n }, duration || 366, function () {\\n self.isAnimating = false;\\n });\\n },\\n // Calculate image size to fit inside viewport\\n // ===========================================\\n getFitPos: function getFitPos(slide) {\\n var self = this,\\n $content = slide.$content,\\n $slide = slide.$slide,\\n width = slide.width || slide.opts.width,\\n height = slide.height || slide.opts.height,\\n maxWidth,\\n maxHeight,\\n minRatio,\\n aspectRatio,\\n rez = {};\\n\\n if (!slide.isLoaded || !$content || !$content.length) {\\n return false;\\n }\\n\\n maxWidth = $.fancybox.getTranslate(self.$refs.stage).width;\\n maxHeight = $.fancybox.getTranslate(self.$refs.stage).height;\\n maxWidth -= parseFloat($slide.css(\"paddingLeft\")) + parseFloat($slide.css(\"paddingRight\")) + parseFloat($content.css(\"marginLeft\")) + parseFloat($content.css(\"marginRight\"));\\n maxHeight -= parseFloat($slide.css(\"paddingTop\")) + parseFloat($slide.css(\"paddingBottom\")) + parseFloat($content.css(\"marginTop\")) + parseFloat($content.css(\"marginBottom\"));\\n\\n if (!width || !height) {\\n width = maxWidth;\\n height = maxHeight;\\n }\\n\\n minRatio = Math.min(1, maxWidth / width, maxHeight / height);\\n width = minRatio * width;\\n height = minRatio * height; // Adjust width/height to precisely fit into container\\n\\n if (width > maxWidth - 0.5) {\\n width = maxWidth;\\n }\\n\\n if (height > maxHeight - 0.5) {\\n height = maxHeight;\\n }\\n\\n if (slide.type === \"image\") {\\n rez.top = Math.floor((maxHeight - height) * 0.5) + parseFloat($slide.css(\"paddingTop\"));\\n rez.left = Math.floor((maxWidth - width) * 0.5) + parseFloat($slide.css(\"paddingLeft\"));\\n } else if (slide.contentType === \"video\") {\\n // Force aspect ratio for the video\\n // \"I say the whole world must learn of our peaceful ways… by force!\"\\n aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9;\\n\\n if (height > width / aspectRatio) {\\n height = width / aspectRatio;\\n } else if (width > height * aspectRatio) {\\n width = height * aspectRatio;\\n }\\n }\\n\\n rez.width = width;\\n rez.height = height;\\n return rez;\\n },\\n // Update content size and position for all slides\\n // ==============================================\\n update: function update(e) {\\n var self = this;\\n $.each(self.slides, function (key, slide) {\\n self.updateSlide(slide, e);\\n });\\n },\\n // Update slide content position and size\\n // ======================================\\n updateSlide: function updateSlide(slide, e) {\\n var self = this,\\n $content = slide && slide.$content,\\n width = slide.width || slide.opts.width,\\n height = slide.height || slide.opts.height,\\n $slide = slide.$slide; // First, prevent caption overlap, if needed\\n\\n self.adjustCaption(slide); // Then resize content to fit inside the slide\\n\\n if ($content && (width || height || slide.contentType === \"video\") && !slide.hasError) {\\n $.fancybox.stop($content);\\n $.fancybox.setTranslate($content, self.getFitPos(slide));\\n\\n if (slide.pos === self.currPos) {\\n self.isAnimating = false;\\n self.updateCursor();\\n }\\n } // Then some adjustments\\n\\n\\n self.adjustLayout(slide);\\n\\n if ($slide.length) {\\n $slide.trigger(\"refresh\");\\n\\n if (slide.pos === self.currPos) {\\n self.$refs.toolbar.add(self.$refs.navigation.find(\".fancybox-button--arrow_right\")).toggleClass(\"compensate-for-scrollbar\", $slide.get(0).scrollHeight > $slide.get(0).clientHeight);\\n }\\n }\\n\\n self.trigger(\"onUpdate\", slide, e);\\n },\\n // Horizontally center slide\\n // =========================\\n centerSlide: function centerSlide(duration) {\\n var self = this,\\n current = self.current,\\n $slide = current.$slide;\\n\\n if (self.isClosing || !current) {\\n return;\\n }\\n\\n $slide.siblings().css({\\n transform: \"\",\\n opacity: \"\"\\n });\\n $slide.parent().children().removeClass(\"fancybox-slide--previous fancybox-slide--next\");\\n $.fancybox.animate($slide, {\\n top: 0,\\n left: 0,\\n opacity: 1\\n }, duration === undefined ? 0 : duration, function () {\\n // Clean up\\n $slide.css({\\n transform: \"\",\\n opacity: \"\"\\n });\\n\\n if (!current.isComplete) {\\n self.complete();\\n }\\n }, false);\\n },\\n // Check if current slide is moved (swiped)\\n // ========================================\\n isMoved: function isMoved(slide) {\\n var current = slide || this.current,\\n slidePos,\\n stagePos;\\n\\n if (!current) {\\n return false;\\n }\\n\\n stagePos = $.fancybox.getTranslate(this.$refs.stage);\\n slidePos = $.fancybox.getTranslate(current.$slide);\\n return !current.$slide.hasClass(\"fancybox-animated\") && (Math.abs(slidePos.top - stagePos.top) > 0.5 || Math.abs(slidePos.left - stagePos.left) > 0.5);\\n },\\n // Update cursor style depending if content can be zoomed\\n // ======================================================\\n updateCursor: function updateCursor(nextWidth, nextHeight) {\\n var self = this,\\n current = self.current,\\n $container = self.$refs.container,\\n canPan,\\n isZoomable;\\n\\n if (!current || self.isClosing || !self.Guestures) {\\n return;\\n }\\n\\n $container.removeClass(\"fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan\");\\n canPan = self.canPan(nextWidth, nextHeight);\\n isZoomable = canPan ? true : self.isZoomable();\\n $container.toggleClass(\"fancybox-is-zoomable\", isZoomable);\\n $(\"[data-fancybox-zoom]\").prop(\"disabled\", !isZoomable);\\n\\n if (canPan) {\\n $container.addClass(\"fancybox-can-pan\");\\n } else if (isZoomable && (current.opts.clickContent === \"zoom\" || $.isFunction(current.opts.clickContent) && current.opts.clickContent(current) == \"zoom\")) {\\n $container.addClass(\"fancybox-can-zoomIn\");\\n } else if (current.opts.touch && (current.opts.touch.vertical || self.group.length > 1) && current.contentType !== \"video\") {\\n $container.addClass(\"fancybox-can-swipe\");\\n }\\n },\\n // Check if current slide is zoomable\\n // ==================================\\n isZoomable: function isZoomable() {\\n var self = this,\\n current = self.current,\\n fitPos; // Assume that slide is zoomable if:\\n // - image is still loading\\n // - actual size of the image is smaller than available area\\n\\n if (current && !self.isClosing && current.type === \"image\" && !current.hasError) {\\n if (!current.isLoaded) {\\n return true;\\n }\\n\\n fitPos = self.getFitPos(current);\\n\\n if (fitPos && (current.width > fitPos.width || current.height > fitPos.height)) {\\n return true;\\n }\\n }\\n\\n return false;\\n },\\n // Check if current image dimensions are smaller than actual\\n // =========================================================\\n isScaledDown: function isScaledDown(nextWidth, nextHeight) {\\n var self = this,\\n rez = false,\\n current = self.current,\\n $content = current.$content;\\n\\n if (nextWidth !== undefined && nextHeight !== undefined) {\\n rez = nextWidth < current.width && nextHeight < current.height;\\n } else if ($content) {\\n rez = $.fancybox.getTranslate($content);\\n rez = rez.width < current.width && rez.height < current.height;\\n }\\n\\n return rez;\\n },\\n // Check if image dimensions exceed parent element\\n // ===============================================\\n canPan: function canPan(nextWidth, nextHeight) {\\n var self = this,\\n current = self.current,\\n pos = null,\\n rez = false;\\n\\n if (current.type === \"image\" && (current.isComplete || nextWidth && nextHeight) && !current.hasError) {\\n rez = self.getFitPos(current);\\n\\n if (nextWidth !== undefined && nextHeight !== undefined) {\\n pos = {\\n width: nextWidth,\\n height: nextHeight\\n };\\n } else if (current.isComplete) {\\n pos = $.fancybox.getTranslate(current.$content);\\n }\\n\\n if (pos && rez) {\\n rez = Math.abs(pos.width - rez.width) > 1.5 || Math.abs(pos.height - rez.height) > 1.5;\\n }\\n }\\n\\n return rez;\\n },\\n // Load content into the slide\\n // ===========================\\n loadSlide: function loadSlide(slide) {\\n var self = this,\\n type,\\n $slide,\\n ajaxLoad;\\n\\n if (slide.isLoading || slide.isLoaded) {\\n return;\\n }\\n\\n slide.isLoading = true;\\n\\n if (self.trigger(\"beforeLoad\", slide) === false) {\\n slide.isLoading = false;\\n return false;\\n }\\n\\n type = slide.type;\\n $slide = slide.$slide;\\n $slide.off(\"refresh\").trigger(\"onReset\").addClass(slide.opts.slideClass); // Create content depending on the type\\n\\n switch (type) {\\n case \"image\":\\n self.setImage(slide);\\n break;\\n\\n case \"iframe\":\\n self.setIframe(slide);\\n break;\\n\\n case \"html\":\\n self.setContent(slide, slide.src || slide.content);\\n break;\\n\\n case \"video\":\\n self.setContent(slide, slide.opts.video.tpl.replace(/\\\\{\\\\{src\\\\}\\\\}/gi, slide.src).replace(\"{{format}}\", slide.opts.videoFormat || slide.opts.video.format || \"\").replace(\"{{poster}}\", slide.thumb || \"\"));\\n break;\\n\\n case \"inline\":\\n if ($(slide.src).length) {\\n self.setContent(slide, $(slide.src));\\n } else {\\n self.setError(slide);\\n }\\n\\n break;\\n\\n case \"ajax\":\\n self.showLoading(slide);\\n ajaxLoad = $.ajax($.extend({}, slide.opts.ajax.settings, {\\n url: slide.src,\\n success: function success(data, textStatus) {\\n if (textStatus === \"success\") {\\n self.setContent(slide, data);\\n }\\n },\\n error: function error(jqXHR, textStatus) {\\n if (jqXHR && textStatus !== \"abort\") {\\n self.setError(slide);\\n }\\n }\\n }));\\n $slide.one(\"onReset\", function () {\\n ajaxLoad.abort();\\n });\\n break;\\n\\n default:\\n self.setError(slide);\\n break;\\n }\\n\\n return true;\\n },\\n // Use thumbnail image, if possible\\n // ================================\\n setImage: function setImage(slide) {\\n var self = this,\\n ghost; // Check if need to show loading icon\\n\\n setTimeout(function () {\\n var $img = slide.$image;\\n\\n if (!self.isClosing && slide.isLoading && (!$img || !$img.length || !$img[0].complete) && !slide.hasError) {\\n self.showLoading(slide);\\n }\\n }, 50); //Check if image has srcset\\n\\n self.checkSrcset(slide); // This will be wrapper containing both ghost and actual image\\n\\n slide.$content = $(\\'\\').addClass(\"fancybox-is-hidden\").appendTo(slide.$slide.addClass(\"fancybox-slide--image\")); // If we have a thumbnail, we can display it while actual image is loading\\n // Users will not stare at black screen and actual image will appear gradually\\n\\n if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && slide.thumb) {\\n slide.width = slide.opts.width;\\n slide.height = slide.opts.height;\\n ghost = document.createElement(\"img\");\\n\\n ghost.onerror = function () {\\n $(this).remove();\\n slide.$ghost = null;\\n };\\n\\n ghost.onload = function () {\\n self.afterLoad(slide);\\n };\\n\\n slide.$ghost = $(ghost).addClass(\"fancybox-image\").appendTo(slide.$content).attr(\"src\", slide.thumb);\\n } // Start loading actual image\\n\\n\\n self.setBigImage(slide);\\n },\\n // Check if image has srcset and get the source\\n // ============================================\\n checkSrcset: function checkSrcset(slide) {\\n var srcset = slide.opts.srcset || slide.opts.image.srcset,\\n found,\\n temp,\\n pxRatio,\\n windowWidth; // If we have \"srcset\", then we need to find first matching \"src\" value.\\n // This is necessary, because when you set an src attribute, the browser will preload the image\\n // before any javascript or even CSS is applied.\\n\\n if (srcset) {\\n pxRatio = window.devicePixelRatio || 1;\\n windowWidth = window.innerWidth * pxRatio;\\n temp = srcset.split(\",\").map(function (el) {\\n var ret = {};\\n el.trim().split(/\\\\s+/).forEach(function (el, i) {\\n var value = parseInt(el.substring(0, el.length - 1), 10);\\n\\n if (i === 0) {\\n return ret.url = el;\\n }\\n\\n if (value) {\\n ret.value = value;\\n ret.postfix = el[el.length - 1];\\n }\\n });\\n return ret;\\n }); // Sort by value\\n\\n temp.sort(function (a, b) {\\n return a.value - b.value;\\n }); // Ok, now we have an array of all srcset values\\n\\n for (var j = 0; j < temp.length; j++) {\\n var el = temp[j];\\n\\n if (el.postfix === \"w\" && el.value >= windowWidth || el.postfix === \"x\" && el.value >= pxRatio) {\\n found = el;\\n break;\\n }\\n } // If not found, take the last one\\n\\n\\n if (!found && temp.length) {\\n found = temp[temp.length - 1];\\n }\\n\\n if (found) {\\n slide.src = found.url; // If we have default width/height values, we can calculate height for matching source\\n\\n if (slide.width && slide.height && found.postfix == \"w\") {\\n slide.height = slide.width / slide.height * found.value;\\n slide.width = found.value;\\n }\\n\\n slide.opts.srcset = srcset;\\n }\\n }\\n },\\n // Create full-size image\\n // ======================\\n setBigImage: function setBigImage(slide) {\\n var self = this,\\n img = document.createElement(\"img\"),\\n $img = $(img);\\n slide.$image = $img.one(\"error\", function () {\\n self.setError(slide);\\n }).one(\"load\", function () {\\n var sizes;\\n\\n if (!slide.$ghost) {\\n self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight);\\n self.afterLoad(slide);\\n }\\n\\n if (self.isClosing) {\\n return;\\n }\\n\\n if (slide.opts.srcset) {\\n sizes = slide.opts.sizes;\\n\\n if (!sizes || sizes === \"auto\") {\\n sizes = (slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? \"100\" : Math.round(slide.width / slide.height * 100)) + \"vw\";\\n }\\n\\n $img.attr(\"sizes\", sizes).attr(\"srcset\", slide.opts.srcset);\\n } // Hide temporary image after some delay\\n\\n\\n if (slide.$ghost) {\\n setTimeout(function () {\\n if (slide.$ghost && !self.isClosing) {\\n slide.$ghost.hide();\\n }\\n }, Math.min(300, Math.max(1000, slide.height / 1600)));\\n }\\n\\n self.hideLoading(slide);\\n }).addClass(\"fancybox-image\").attr(\"src\", slide.src).appendTo(slide.$content);\\n\\n if ((img.complete || img.readyState == \"complete\") && $img.naturalWidth && $img.naturalHeight) {\\n $img.trigger(\"load\");\\n } else if (img.error) {\\n $img.trigger(\"error\");\\n }\\n },\\n // Computes the slide size from image size and maxWidth/maxHeight\\n // ==============================================================\\n resolveImageSlideSize: function resolveImageSlideSize(slide, imgWidth, imgHeight) {\\n var maxWidth = parseInt(slide.opts.width, 10),\\n maxHeight = parseInt(slide.opts.height, 10); // Sets the default values from the image\\n\\n slide.width = imgWidth;\\n slide.height = imgHeight;\\n\\n if (maxWidth > 0) {\\n slide.width = maxWidth;\\n slide.height = Math.floor(maxWidth * imgHeight / imgWidth);\\n }\\n\\n if (maxHeight > 0) {\\n slide.width = Math.floor(maxHeight * imgWidth / imgHeight);\\n slide.height = maxHeight;\\n }\\n },\\n // Create iframe wrapper, iframe and bindings\\n // ==========================================\\n setIframe: function setIframe(slide) {\\n var self = this,\\n opts = slide.opts.iframe,\\n $slide = slide.$slide,\\n $iframe;\\n slide.$content = $(\\'\\').css(opts.css).appendTo($slide);\\n $slide.addClass(\"fancybox-slide--\" + slide.contentType);\\n slide.$iframe = $iframe = $(opts.tpl.replace(/\\\\{rnd\\\\}/g, new Date().getTime())).attr(opts.attr).appendTo(slide.$content);\\n\\n if (opts.preload) {\\n self.showLoading(slide); // Unfortunately, it is not always possible to determine if iframe is successfully loaded\\n // (due to browser security policy)\\n\\n $iframe.on(\"load.fb error.fb\", function (e) {\\n this.isReady = 1;\\n slide.$slide.trigger(\"refresh\");\\n self.afterLoad(slide);\\n }); // Recalculate iframe content size\\n // ===============================\\n\\n $slide.on(\"refresh.fb\", function () {\\n var $content = slide.$content,\\n frameWidth = opts.css.width,\\n frameHeight = opts.css.height,\\n $contents,\\n $body;\\n\\n if ($iframe[0].isReady !== 1) {\\n return;\\n }\\n\\n try {\\n $contents = $iframe.contents();\\n $body = $contents.find(\"body\");\\n } catch (ignore) {} // Calculate content dimensions, if it is accessible\\n\\n\\n if ($body && $body.length && $body.children().length) {\\n // Avoid scrolling to top (if multiple instances)\\n $slide.css(\"overflow\", \"visible\");\\n $content.css({\\n width: \"100%\",\\n \"max-width\": \"100%\",\\n height: \"9999px\"\\n });\\n\\n if (frameWidth === undefined) {\\n frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true)));\\n }\\n\\n $content.css(\"width\", frameWidth ? frameWidth : \"\").css(\"max-width\", \"\");\\n\\n if (frameHeight === undefined) {\\n frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true)));\\n }\\n\\n $content.css(\"height\", frameHeight ? frameHeight : \"\");\\n $slide.css(\"overflow\", \"auto\");\\n }\\n\\n $content.removeClass(\"fancybox-is-hidden\");\\n });\\n } else {\\n self.afterLoad(slide);\\n }\\n\\n $iframe.attr(\"src\", slide.src); // Remove iframe if closing or changing gallery item\\n\\n $slide.one(\"onReset\", function () {\\n // This helps IE not to throw errors when closing\\n try {\\n $(this).find(\"iframe\").hide().unbind().attr(\"src\", \"//about:blank\");\\n } catch (ignore) {}\\n\\n $(this).off(\"refresh.fb\").empty();\\n slide.isLoaded = false;\\n slide.isRevealed = false;\\n });\\n },\\n // Wrap and append content to the slide\\n // ======================================\\n setContent: function setContent(slide, content) {\\n var self = this;\\n\\n if (self.isClosing) {\\n return;\\n }\\n\\n self.hideLoading(slide);\\n\\n if (slide.$content) {\\n $.fancybox.stop(slide.$content);\\n }\\n\\n slide.$slide.empty(); // If content is a jQuery object, then it will be moved to the slide.\\n // The placeholder is created so we will know where to put it back.\\n\\n if (isQuery(content) && content.parent().length) {\\n // Make sure content is not already moved to fancyBox\\n if (content.hasClass(\"fancybox-content\") || content.parent().hasClass(\"fancybox-content\")) {\\n content.parents(\".fancybox-slide\").trigger(\"onReset\");\\n } // Create temporary element marking original place of the content\\n\\n\\n slide.$placeholder = $(\"
\").hide().insertAfter(content); // Make sure content is visible\\n\\n content.css(\"display\", \"inline-block\");\\n } else if (!slide.hasError) {\\n // If content is just a plain text, try to convert it to html\\n if ($.type(content) === \"string\") {\\n content = $(\"
\").append($.trim(content)).contents();\\n } // If \"filter\" option is provided, then filter content\\n\\n\\n if (slide.opts.filter) {\\n content = $(\"
\").html(content).find(slide.opts.filter);\\n }\\n }\\n\\n slide.$slide.one(\"onReset\", function () {\\n // Pause all html5 video/audio\\n $(this).find(\"video,audio\").trigger(\"pause\"); // Put content back\\n\\n if (slide.$placeholder) {\\n slide.$placeholder.after(content.removeClass(\"fancybox-content\").hide()).remove();\\n slide.$placeholder = null;\\n } // Remove custom close button\\n\\n\\n if (slide.$smallBtn) {\\n slide.$smallBtn.remove();\\n slide.$smallBtn = null;\\n } // Remove content and mark slide as not loaded\\n\\n\\n if (!slide.hasError) {\\n $(this).empty();\\n slide.isLoaded = false;\\n slide.isRevealed = false;\\n }\\n });\\n $(content).appendTo(slide.$slide);\\n\\n if ($(content).is(\"video,audio\")) {\\n $(content).addClass(\"fancybox-video\");\\n $(content).wrap(\"\");\\n slide.contentType = \"video\";\\n slide.opts.width = slide.opts.width || $(content).attr(\"width\");\\n slide.opts.height = slide.opts.height || $(content).attr(\"height\");\\n }\\n\\n slide.$content = slide.$slide.children().filter(\"div,form,main,video,audio,article,.fancybox-content\").first();\\n slide.$content.siblings().hide(); // Re-check if there is a valid content\\n // (in some cases, ajax response can contain various elements or plain text)\\n\\n if (!slide.$content.length) {\\n slide.$content = slide.$slide.wrapInner(\"\").children().first();\\n }\\n\\n slide.$content.addClass(\"fancybox-content\");\\n slide.$slide.addClass(\"fancybox-slide--\" + slide.contentType);\\n self.afterLoad(slide);\\n },\\n // Display error message\\n // =====================\\n setError: function setError(slide) {\\n slide.hasError = true;\\n slide.$slide.trigger(\"onReset\").removeClass(\"fancybox-slide--\" + slide.contentType).addClass(\"fancybox-slide--error\");\\n slide.contentType = \"html\";\\n this.setContent(slide, this.translate(slide, slide.opts.errorTpl));\\n\\n if (slide.pos === this.currPos) {\\n this.isAnimating = false;\\n }\\n },\\n // Show loading icon inside the slide\\n // ==================================\\n showLoading: function showLoading(slide) {\\n var self = this;\\n slide = slide || self.current;\\n\\n if (slide && !slide.$spinner) {\\n slide.$spinner = $(self.translate(self, self.opts.spinnerTpl)).appendTo(slide.$slide).hide().fadeIn(\"fast\");\\n }\\n },\\n // Remove loading icon from the slide\\n // ==================================\\n hideLoading: function hideLoading(slide) {\\n var self = this;\\n slide = slide || self.current;\\n\\n if (slide && slide.$spinner) {\\n slide.$spinner.stop().remove();\\n delete slide.$spinner;\\n }\\n },\\n // Adjustments after slide content has been loaded\\n // ===============================================\\n afterLoad: function afterLoad(slide) {\\n var self = this;\\n\\n if (self.isClosing) {\\n return;\\n }\\n\\n slide.isLoading = false;\\n slide.isLoaded = true;\\n self.trigger(\"afterLoad\", slide);\\n self.hideLoading(slide); // Add small close button\\n\\n if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) {\\n slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);\\n } // Disable right click\\n\\n\\n if (slide.opts.protect && slide.$content && !slide.hasError) {\\n slide.$content.on(\"contextmenu.fb\", function (e) {\\n if (e.button == 2) {\\n e.preventDefault();\\n }\\n\\n return true;\\n }); // Add fake element on top of the image\\n // This makes a bit harder for user to select image\\n\\n if (slide.type === \"image\") {\\n $(\\'\\').appendTo(slide.$content);\\n }\\n }\\n\\n self.adjustCaption(slide);\\n self.adjustLayout(slide);\\n\\n if (slide.pos === self.currPos) {\\n self.updateCursor();\\n }\\n\\n self.revealContent(slide);\\n },\\n // Prevent caption overlap,\\n // fix css inconsistency across browsers\\n // =====================================\\n adjustCaption: function adjustCaption(slide) {\\n var self = this,\\n current = slide || self.current,\\n caption = current.opts.caption,\\n preventOverlap = current.opts.preventCaptionOverlap,\\n $caption = self.$refs.caption,\\n $clone,\\n captionH = false;\\n $caption.toggleClass(\"fancybox-caption--separate\", preventOverlap);\\n\\n if (preventOverlap && caption && caption.length) {\\n if (current.pos !== self.currPos) {\\n $clone = $caption.clone().appendTo($caption.parent());\\n $clone.children().eq(0).empty().html(caption);\\n captionH = $clone.outerHeight(true);\\n $clone.empty().remove();\\n } else if (self.$caption) {\\n captionH = self.$caption.outerHeight(true);\\n }\\n\\n current.$slide.css(\"padding-bottom\", captionH || \"\");\\n }\\n },\\n // Simple hack to fix inconsistency across browsers, described here (affects Edge, too):\\n // https://bugzilla.mozilla.org/show_bug.cgi?id=748518\\n // ====================================================================================\\n adjustLayout: function adjustLayout(slide) {\\n var self = this,\\n current = slide || self.current,\\n scrollHeight,\\n marginBottom,\\n inlinePadding,\\n actualPadding;\\n\\n if (current.isLoaded && current.opts.disableLayoutFix !== true) {\\n current.$content.css(\"margin-bottom\", \"\"); // If we would always set margin-bottom for the content,\\n // then it would potentially break vertical align\\n\\n if (current.$content.outerHeight() > current.$slide.height() + 0.5) {\\n inlinePadding = current.$slide[0].style[\"padding-bottom\"];\\n actualPadding = current.$slide.css(\"padding-bottom\");\\n\\n if (parseFloat(actualPadding) > 0) {\\n scrollHeight = current.$slide[0].scrollHeight;\\n current.$slide.css(\"padding-bottom\", 0);\\n\\n if (Math.abs(scrollHeight - current.$slide[0].scrollHeight) < 1) {\\n marginBottom = actualPadding;\\n }\\n\\n current.$slide.css(\"padding-bottom\", inlinePadding);\\n }\\n }\\n\\n current.$content.css(\"margin-bottom\", marginBottom);\\n }\\n },\\n // Make content visible\\n // This method is called right after content has been loaded or\\n // user navigates gallery and transition should start\\n // ============================================================\\n revealContent: function revealContent(slide) {\\n var self = this,\\n $slide = slide.$slide,\\n end = false,\\n start = false,\\n isMoved = self.isMoved(slide),\\n isRevealed = slide.isRevealed,\\n effect,\\n effectClassName,\\n duration,\\n opacity;\\n slide.isRevealed = true;\\n effect = slide.opts[self.firstRun ? \"animationEffect\" : \"transitionEffect\"];\\n duration = slide.opts[self.firstRun ? \"animationDuration\" : \"transitionDuration\"];\\n duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);\\n\\n if (isMoved || slide.pos !== self.currPos || !duration) {\\n effect = false;\\n } // Check if can zoom\\n\\n\\n if (effect === \"zoom\") {\\n if (slide.pos === self.currPos && duration && slide.type === \"image\" && !slide.hasError && (start = self.getThumbPos(slide))) {\\n end = self.getFitPos(slide);\\n } else {\\n effect = \"fade\";\\n }\\n } // Zoom animation\\n // ==============\\n\\n\\n if (effect === \"zoom\") {\\n self.isAnimating = true;\\n end.scaleX = end.width / start.width;\\n end.scaleY = end.height / start.height; // Check if we need to animate opacity\\n\\n opacity = slide.opts.zoomOpacity;\\n\\n if (opacity == \"auto\") {\\n opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;\\n }\\n\\n if (opacity) {\\n start.opacity = 0.1;\\n end.opacity = 1;\\n } // Draw image at start position\\n\\n\\n $.fancybox.setTranslate(slide.$content.removeClass(\"fancybox-is-hidden\"), start);\\n forceRedraw(slide.$content); // Start animation\\n\\n $.fancybox.animate(slide.$content, end, duration, function () {\\n self.isAnimating = false;\\n self.complete();\\n });\\n return;\\n }\\n\\n self.updateSlide(slide); // Simply show content if no effect\\n // ================================\\n\\n if (!effect) {\\n slide.$content.removeClass(\"fancybox-is-hidden\");\\n\\n if (!isRevealed && isMoved && slide.type === \"image\" && !slide.hasError) {\\n slide.$content.hide().fadeIn(\"fast\");\\n }\\n\\n if (slide.pos === self.currPos) {\\n self.complete();\\n }\\n\\n return;\\n } // Prepare for CSS transiton\\n // =========================\\n\\n\\n $.fancybox.stop($slide); //effectClassName = \"fancybox-animated fancybox-slide--\" + (slide.pos >= self.prevPos ? \"next\" : \"previous\") + \" fancybox-fx-\" + effect;\\n\\n effectClassName = \"fancybox-slide--\" + (slide.pos >= self.prevPos ? \"next\" : \"previous\") + \" fancybox-animated fancybox-fx-\" + effect;\\n $slide.addClass(effectClassName).removeClass(\"fancybox-slide--current\"); //.addClass(effectClassName);\\n\\n slide.$content.removeClass(\"fancybox-is-hidden\"); // Force reflow\\n\\n forceRedraw($slide);\\n\\n if (slide.type !== \"image\") {\\n slide.$content.hide().show(0);\\n }\\n\\n $.fancybox.animate($slide, \"fancybox-slide--current\", duration, function () {\\n $slide.removeClass(effectClassName).css({\\n transform: \"\",\\n opacity: \"\"\\n });\\n\\n if (slide.pos === self.currPos) {\\n self.complete();\\n }\\n }, true);\\n },\\n // Check if we can and have to zoom from thumbnail\\n //================================================\\n getThumbPos: function getThumbPos(slide) {\\n var rez = false,\\n $thumb = slide.$thumb,\\n thumbPos,\\n btw,\\n brw,\\n bbw,\\n blw;\\n\\n if (!$thumb || !inViewport($thumb[0])) {\\n return false;\\n }\\n\\n thumbPos = $.fancybox.getTranslate($thumb);\\n btw = parseFloat($thumb.css(\"border-top-width\") || 0);\\n brw = parseFloat($thumb.css(\"border-right-width\") || 0);\\n bbw = parseFloat($thumb.css(\"border-bottom-width\") || 0);\\n blw = parseFloat($thumb.css(\"border-left-width\") || 0);\\n rez = {\\n top: thumbPos.top + btw,\\n left: thumbPos.left + blw,\\n width: thumbPos.width - brw - blw,\\n height: thumbPos.height - btw - bbw,\\n scaleX: 1,\\n scaleY: 1\\n };\\n return thumbPos.width > 0 && thumbPos.height > 0 ? rez : false;\\n },\\n // Final adjustments after current gallery item is moved to position\\n // and it`s content is loaded\\n // ==================================================================\\n complete: function complete() {\\n var self = this,\\n current = self.current,\\n slides = {},\\n $el;\\n\\n if (self.isMoved() || !current.isLoaded) {\\n return;\\n }\\n\\n if (!current.isComplete) {\\n current.isComplete = true;\\n current.$slide.siblings().trigger(\"onReset\");\\n self.preload(\"inline\"); // Trigger any CSS transiton inside the slide\\n\\n forceRedraw(current.$slide);\\n current.$slide.addClass(\"fancybox-slide--complete\"); // Remove unnecessary slides\\n\\n $.each(self.slides, function (key, slide) {\\n if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {\\n slides[slide.pos] = slide;\\n } else if (slide) {\\n $.fancybox.stop(slide.$slide);\\n slide.$slide.off().remove();\\n }\\n });\\n self.slides = slides;\\n }\\n\\n self.isAnimating = false;\\n self.updateCursor();\\n self.trigger(\"afterShow\"); // Autoplay first html5 video/audio\\n\\n if (!!current.opts.video.autoStart) {\\n current.$slide.find(\"video,audio\").filter(\":visible:first\").trigger(\"play\").one(\"ended\", function () {\\n if (Document.exitFullscreen) {\\n Document.exitFullscreen();\\n } else if (this.webkitExitFullscreen) {\\n this.webkitExitFullscreen();\\n }\\n\\n self.next();\\n });\\n } // Try to focus on the first focusable element\\n\\n\\n if (current.opts.autoFocus && current.contentType === \"html\") {\\n // Look for the first input with autofocus attribute\\n $el = current.$content.find(\"input[autofocus]:enabled:visible:first\");\\n\\n if ($el.length) {\\n $el.trigger(\"focus\");\\n } else {\\n self.focus(null, true);\\n }\\n } // Avoid jumping\\n\\n\\n current.$slide.scrollTop(0).scrollLeft(0);\\n },\\n // Preload next and previous slides\\n // ================================\\n preload: function preload(type) {\\n var self = this,\\n prev,\\n next;\\n\\n if (self.group.length < 2) {\\n return;\\n }\\n\\n next = self.slides[self.currPos + 1];\\n prev = self.slides[self.currPos - 1];\\n\\n if (prev && prev.type === type) {\\n self.loadSlide(prev);\\n }\\n\\n if (next && next.type === type) {\\n self.loadSlide(next);\\n }\\n },\\n // Try to find and focus on the first focusable element\\n // ====================================================\\n focus: function focus(e, firstRun) {\\n var self = this,\\n focusableStr = [\"a[href]\", \"area[href]\", \\'input:not([disabled]):not([type=\"hidden\"]):not([aria-hidden])\\', \"select:not([disabled]):not([aria-hidden])\", \"textarea:not([disabled]):not([aria-hidden])\", \"button:not([disabled]):not([aria-hidden])\", \"iframe\", \"object\", \"embed\", \"video\", \"audio\", \"[contenteditable]\", \\'[tabindex]:not([tabindex^=\"-\"])\\'].join(\",\"),\\n focusableItems,\\n focusedItemIndex;\\n\\n if (self.isClosing) {\\n return;\\n }\\n\\n if (e || !self.current || !self.current.isComplete) {\\n // Focus on any element inside fancybox\\n focusableItems = self.$refs.container.find(\"*:visible\");\\n } else {\\n // Focus inside current slide\\n focusableItems = self.current.$slide.find(\"*:visible\" + (firstRun ? \":not(.fancybox-close-small)\" : \"\"));\\n }\\n\\n focusableItems = focusableItems.filter(focusableStr).filter(function () {\\n return $(this).css(\"visibility\") !== \"hidden\" && !$(this).hasClass(\"disabled\");\\n });\\n\\n if (focusableItems.length) {\\n focusedItemIndex = focusableItems.index(document.activeElement);\\n\\n if (e && e.shiftKey) {\\n // Back tab\\n if (focusedItemIndex < 0 || focusedItemIndex == 0) {\\n e.preventDefault();\\n focusableItems.eq(focusableItems.length - 1).trigger(\"focus\");\\n }\\n } else {\\n // Outside or Forward tab\\n if (focusedItemIndex < 0 || focusedItemIndex == focusableItems.length - 1) {\\n if (e) {\\n e.preventDefault();\\n }\\n\\n focusableItems.eq(0).trigger(\"focus\");\\n }\\n }\\n } else {\\n self.$refs.container.trigger(\"focus\");\\n }\\n },\\n // Activates current instance - brings container to the front and enables keyboard,\\n // notifies other instances about deactivating\\n // =================================================================================\\n activate: function activate() {\\n var self = this; // Deactivate all instances\\n\\n $(\".fancybox-container\").each(function () {\\n var instance = $(this).data(\"FancyBox\"); // Skip self and closing instances\\n\\n if (instance && instance.id !== self.id && !instance.isClosing) {\\n instance.trigger(\"onDeactivate\");\\n instance.removeEvents();\\n instance.isVisible = false;\\n }\\n });\\n self.isVisible = true;\\n\\n if (self.current || self.isIdle) {\\n self.update();\\n self.updateControls();\\n }\\n\\n self.trigger(\"onActivate\");\\n self.addEvents();\\n },\\n // Start closing procedure\\n // This will start \"zoom-out\" animation if needed and clean everything up afterwards\\n // =================================================================================\\n close: function close(e, d) {\\n var self = this,\\n current = self.current,\\n effect,\\n duration,\\n $content,\\n domRect,\\n opacity,\\n start,\\n end;\\n\\n var done = function done() {\\n self.cleanUp(e);\\n };\\n\\n if (self.isClosing) {\\n return false;\\n }\\n\\n self.isClosing = true; // If beforeClose callback prevents closing, make sure content is centered\\n\\n if (self.trigger(\"beforeClose\", e) === false) {\\n self.isClosing = false;\\n requestAFrame(function () {\\n self.update();\\n });\\n return false;\\n } // Remove all events\\n // If there are multiple instances, they will be set again by \"activate\" method\\n\\n\\n self.removeEvents();\\n $content = current.$content;\\n effect = current.opts.animationEffect;\\n duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0;\\n current.$slide.removeClass(\"fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated\");\\n\\n if (e !== true) {\\n $.fancybox.stop(current.$slide);\\n } else {\\n effect = false;\\n } // Remove other slides\\n\\n\\n current.$slide.siblings().trigger(\"onReset\").remove(); // Trigger animations\\n\\n if (duration) {\\n self.$refs.container.removeClass(\"fancybox-is-open\").addClass(\"fancybox-is-closing\").css(\"transition-duration\", duration + \"ms\");\\n } // Clean up\\n\\n\\n self.hideLoading(current);\\n self.hideControls(true);\\n self.updateCursor(); // Check if possible to zoom-out\\n\\n if (effect === \"zoom\" && !($content && duration && current.type === \"image\" && !self.isMoved() && !current.hasError && (end = self.getThumbPos(current)))) {\\n effect = \"fade\";\\n }\\n\\n if (effect === \"zoom\") {\\n $.fancybox.stop($content);\\n domRect = $.fancybox.getTranslate($content);\\n start = {\\n top: domRect.top,\\n left: domRect.left,\\n scaleX: domRect.width / end.width,\\n scaleY: domRect.height / end.height,\\n width: end.width,\\n height: end.height\\n }; // Check if we need to animate opacity\\n\\n opacity = current.opts.zoomOpacity;\\n\\n if (opacity == \"auto\") {\\n opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;\\n }\\n\\n if (opacity) {\\n end.opacity = 0;\\n }\\n\\n $.fancybox.setTranslate($content, start);\\n forceRedraw($content);\\n $.fancybox.animate($content, end, duration, done);\\n return true;\\n }\\n\\n if (effect && duration) {\\n $.fancybox.animate(current.$slide.addClass(\"fancybox-slide--previous\").removeClass(\"fancybox-slide--current\"), \"fancybox-animated fancybox-fx-\" + effect, duration, done);\\n } else {\\n // If skip animation\\n if (e === true) {\\n setTimeout(done, duration);\\n } else {\\n done();\\n }\\n }\\n\\n return true;\\n },\\n // Final adjustments after removing the instance\\n // =============================================\\n cleanUp: function cleanUp(e) {\\n var self = this,\\n instance,\\n $focus = self.current.opts.$orig,\\n x,\\n y;\\n self.current.$slide.trigger(\"onReset\");\\n self.$refs.container.empty().remove();\\n self.trigger(\"afterClose\", e); // Place back focus\\n\\n if (!!self.current.opts.backFocus) {\\n if (!$focus || !$focus.length || !$focus.is(\":visible\")) {\\n $focus = self.$trigger;\\n }\\n\\n if ($focus && $focus.length) {\\n x = window.scrollX;\\n y = window.scrollY;\\n $focus.trigger(\"focus\");\\n $(\"html, body\").scrollTop(y).scrollLeft(x);\\n }\\n }\\n\\n self.current = null; // Check if there are other instances\\n\\n instance = $.fancybox.getInstance();\\n\\n if (instance) {\\n instance.activate();\\n } else {\\n $(\"body\").removeClass(\"fancybox-active compensate-for-scrollbar\");\\n $(\"#fancybox-style-noscroll\").remove();\\n }\\n },\\n // Call callback and trigger an event\\n // ==================================\\n trigger: function trigger(name, slide) {\\n var args = Array.prototype.slice.call(arguments, 1),\\n self = this,\\n obj = slide && slide.opts ? slide : self.current,\\n rez;\\n\\n if (obj) {\\n args.unshift(obj);\\n } else {\\n obj = self;\\n }\\n\\n args.unshift(self);\\n\\n if ($.isFunction(obj.opts[name])) {\\n rez = obj.opts[name].apply(obj, args);\\n }\\n\\n if (rez === false) {\\n return rez;\\n }\\n\\n if (name === \"afterClose\" || !self.$refs) {\\n $D.trigger(name + \".fb\", args);\\n } else {\\n self.$refs.container.trigger(name + \".fb\", args);\\n }\\n },\\n // Update infobar values, navigation button states and reveal caption\\n // ==================================================================\\n updateControls: function updateControls() {\\n var self = this,\\n current = self.current,\\n index = current.index,\\n $container = self.$refs.container,\\n $caption = self.$refs.caption,\\n caption = current.opts.caption; // Recalculate content dimensions\\n\\n current.$slide.trigger(\"refresh\"); // Set caption\\n\\n if (caption && caption.length) {\\n self.$caption = $caption;\\n $caption.children().eq(0).html(caption);\\n } else {\\n self.$caption = null;\\n }\\n\\n if (!self.hasHiddenControls && !self.isIdle) {\\n self.showControls();\\n } // Update info and navigation elements\\n\\n\\n $container.find(\"[data-fancybox-count]\").html(self.group.length);\\n $container.find(\"[data-fancybox-index]\").html(index + 1);\\n $container.find(\"[data-fancybox-prev]\").prop(\"disabled\", !current.opts.loop && index <= 0);\\n $container.find(\"[data-fancybox-next]\").prop(\"disabled\", !current.opts.loop && index >= self.group.length - 1);\\n\\n if (current.type === \"image\") {\\n // Re-enable buttons; update download button source\\n $container.find(\"[data-fancybox-zoom]\").show().end().find(\"[data-fancybox-download]\").attr(\"href\", current.opts.image.src || current.src).show();\\n } else if (current.opts.toolbar) {\\n $container.find(\"[data-fancybox-download],[data-fancybox-zoom]\").hide();\\n } // Make sure focus is not on disabled button/element\\n\\n\\n if ($(document.activeElement).is(\":hidden,[disabled]\")) {\\n self.$refs.container.trigger(\"focus\");\\n }\\n },\\n // Hide toolbar and caption\\n // ========================\\n hideControls: function hideControls(andCaption) {\\n var self = this,\\n arr = [\"infobar\", \"toolbar\", \"nav\"];\\n\\n if (andCaption || !self.current.opts.preventCaptionOverlap) {\\n arr.push(\"caption\");\\n }\\n\\n this.$refs.container.removeClass(arr.map(function (i) {\\n return \"fancybox-show-\" + i;\\n }).join(\" \"));\\n this.hasHiddenControls = true;\\n },\\n showControls: function showControls() {\\n var self = this,\\n opts = self.current ? self.current.opts : self.opts,\\n $container = self.$refs.container;\\n self.hasHiddenControls = false;\\n self.idleSecondsCounter = 0;\\n $container.toggleClass(\"fancybox-show-toolbar\", !!(opts.toolbar && opts.buttons)).toggleClass(\"fancybox-show-infobar\", !!(opts.infobar && self.group.length > 1)).toggleClass(\"fancybox-show-caption\", !!self.$caption).toggleClass(\"fancybox-show-nav\", !!(opts.arrows && self.group.length > 1)).toggleClass(\"fancybox-is-modal\", !!opts.modal);\\n },\\n // Toggle toolbar and caption\\n // ==========================\\n toggleControls: function toggleControls() {\\n if (this.hasHiddenControls) {\\n this.showControls();\\n } else {\\n this.hideControls();\\n }\\n }\\n });\\n $.fancybox = {\\n version: \"3.5.7\",\\n defaults: defaults,\\n // Get current instance and execute a command.\\n //\\n // Examples of usage:\\n //\\n // $instance = $.fancybox.getInstance();\\n // $.fancybox.getInstance().jumpTo( 1 );\\n // $.fancybox.getInstance( \\'jumpTo\\', 1 );\\n // $.fancybox.getInstance( function() {\\n // console.info( this.currIndex );\\n // });\\n // ======================================================\\n getInstance: function getInstance(command) {\\n var instance = $(\\'.fancybox-container:not(\".fancybox-is-closing\"):last\\').data(\"FancyBox\"),\\n args = Array.prototype.slice.call(arguments, 1);\\n\\n if (instance instanceof FancyBox) {\\n if ($.type(command) === \"string\") {\\n instance[command].apply(instance, args);\\n } else if ($.type(command) === \"function\") {\\n command.apply(instance, args);\\n }\\n\\n return instance;\\n }\\n\\n return false;\\n },\\n // Create new instance\\n // ===================\\n open: function open(items, opts, index) {\\n return new FancyBox(items, opts, index);\\n },\\n // Close current or all instances\\n // ==============================\\n close: function close(all) {\\n var instance = this.getInstance();\\n\\n if (instance) {\\n instance.close(); // Try to find and close next instance\\n\\n if (all === true) {\\n this.close(all);\\n }\\n }\\n },\\n // Close all instances and unbind all events\\n // =========================================\\n destroy: function destroy() {\\n this.close(true);\\n $D.add(\"body\").off(\"click.fb-start\", \"**\");\\n },\\n // Try to detect mobile devices\\n // ============================\\n isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),\\n // Detect if \\'translate3d\\' support is available\\n // ============================================\\n use3d: function () {\\n var div = document.createElement(\"div\");\\n return window.getComputedStyle && window.getComputedStyle(div) && window.getComputedStyle(div).getPropertyValue(\"transform\") && !(document.documentMode && document.documentMode < 11);\\n }(),\\n // Helper function to get current visual state of an element\\n // returns array[ top, left, horizontal-scale, vertical-scale, opacity ]\\n // =====================================================================\\n getTranslate: function getTranslate($el) {\\n var domRect;\\n\\n if (!$el || !$el.length) {\\n return false;\\n }\\n\\n domRect = $el[0].getBoundingClientRect();\\n return {\\n top: domRect.top || 0,\\n left: domRect.left || 0,\\n width: domRect.width,\\n height: domRect.height,\\n opacity: parseFloat($el.css(\"opacity\"))\\n };\\n },\\n // Shortcut for setting \"translate3d\" properties for element\\n // Can set be used to set opacity, too\\n // ========================================================\\n setTranslate: function setTranslate($el, props) {\\n var str = \"\",\\n css = {};\\n\\n if (!$el || !props) {\\n return;\\n }\\n\\n if (props.left !== undefined || props.top !== undefined) {\\n str = (props.left === undefined ? $el.position().left : props.left) + \"px, \" + (props.top === undefined ? $el.position().top : props.top) + \"px\";\\n\\n if (this.use3d) {\\n str = \"translate3d(\" + str + \", 0px)\";\\n } else {\\n str = \"translate(\" + str + \")\";\\n }\\n }\\n\\n if (props.scaleX !== undefined && props.scaleY !== undefined) {\\n str += \" scale(\" + props.scaleX + \", \" + props.scaleY + \")\";\\n } else if (props.scaleX !== undefined) {\\n str += \" scaleX(\" + props.scaleX + \")\";\\n }\\n\\n if (str.length) {\\n css.transform = str;\\n }\\n\\n if (props.opacity !== undefined) {\\n css.opacity = props.opacity;\\n }\\n\\n if (props.width !== undefined) {\\n css.width = props.width;\\n }\\n\\n if (props.height !== undefined) {\\n css.height = props.height;\\n }\\n\\n return $el.css(css);\\n },\\n // Simple CSS transition handler\\n // =============================\\n animate: function animate($el, to, duration, callback, leaveAnimationName) {\\n var self = this,\\n from;\\n\\n if ($.isFunction(duration)) {\\n callback = duration;\\n duration = null;\\n }\\n\\n self.stop($el);\\n from = self.getTranslate($el);\\n $el.on(transitionEnd, function (e) {\\n // Skip events from child elements and z-index change\\n if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == \"z-index\")) {\\n return;\\n }\\n\\n self.stop($el);\\n\\n if ($.isNumeric(duration)) {\\n $el.css(\"transition-duration\", \"\");\\n }\\n\\n if ($.isPlainObject(to)) {\\n if (to.scaleX !== undefined && to.scaleY !== undefined) {\\n self.setTranslate($el, {\\n top: to.top,\\n left: to.left,\\n width: from.width * to.scaleX,\\n height: from.height * to.scaleY,\\n scaleX: 1,\\n scaleY: 1\\n });\\n }\\n } else if (leaveAnimationName !== true) {\\n $el.removeClass(to);\\n }\\n\\n if ($.isFunction(callback)) {\\n callback(e);\\n }\\n });\\n\\n if ($.isNumeric(duration)) {\\n $el.css(\"transition-duration\", duration + \"ms\");\\n } // Start animation by changing CSS properties or class name\\n\\n\\n if ($.isPlainObject(to)) {\\n if (to.scaleX !== undefined && to.scaleY !== undefined) {\\n delete to.width;\\n delete to.height;\\n\\n if ($el.parent().hasClass(\"fancybox-slide--image\")) {\\n $el.parent().addClass(\"fancybox-is-scaling\");\\n }\\n }\\n\\n $.fancybox.setTranslate($el, to);\\n } else {\\n $el.addClass(to);\\n } // Make sure that `transitionend` callback gets fired\\n\\n\\n $el.data(\"timer\", setTimeout(function () {\\n $el.trigger(transitionEnd);\\n }, duration + 33));\\n },\\n stop: function stop($el, callCallback) {\\n if ($el && $el.length) {\\n clearTimeout($el.data(\"timer\"));\\n\\n if (callCallback) {\\n $el.trigger(transitionEnd);\\n }\\n\\n $el.off(transitionEnd).css(\"transition-duration\", \"\");\\n $el.parent().removeClass(\"fancybox-is-scaling\");\\n }\\n }\\n }; // Default click handler for \"fancyboxed\" links\\n // ============================================\\n\\n function _run(e, opts) {\\n var items = [],\\n index = 0,\\n $target,\\n value,\\n instance; // Avoid opening multiple times\\n\\n if (e && e.isDefaultPrevented()) {\\n return;\\n }\\n\\n e.preventDefault();\\n opts = opts || {};\\n\\n if (e && e.data) {\\n opts = mergeOpts(e.data.options, opts);\\n }\\n\\n $target = opts.$target || $(e.currentTarget).trigger(\"blur\");\\n instance = $.fancybox.getInstance();\\n\\n if (instance && instance.$trigger && instance.$trigger.is($target)) {\\n return;\\n }\\n\\n if (opts.selector) {\\n items = $(opts.selector);\\n } else {\\n // Get all related items and find index for clicked one\\n value = $target.attr(\"data-fancybox\") || \"\";\\n\\n if (value) {\\n items = e.data ? e.data.items : [];\\n items = items.length ? items.filter(\\'[data-fancybox=\"\\' + value + \\'\"]\\') : $(\\'[data-fancybox=\"\\' + value + \\'\"]\\');\\n } else {\\n items = [$target];\\n }\\n }\\n\\n index = $(items).index($target); // Sometimes current item can not be found\\n\\n if (index < 0) {\\n index = 0;\\n }\\n\\n instance = $.fancybox.open(items, opts, index); // Save last active element\\n\\n instance.$trigger = $target;\\n } // Create a jQuery plugin\\n // ======================\\n\\n\\n $.fn.fancybox = function (options) {\\n var selector;\\n options = options || {};\\n selector = options.selector || false;\\n\\n if (selector) {\\n // Use body element instead of document so it executes first\\n $(\"body\").off(\"click.fb-start\", selector).on(\"click.fb-start\", selector, {\\n options: options\\n }, _run);\\n } else {\\n this.off(\"click.fb-start\").on(\"click.fb-start\", {\\n items: this,\\n options: options\\n }, _run);\\n }\\n\\n return this;\\n }; // Self initializing plugin for all elements having `data-fancybox` attribute\\n // ==========================================================================\\n\\n\\n $D.on(\"click.fb-start\", \"[data-fancybox]\", _run); // Enable \"trigger elements\"\\n // =========================\\n\\n $D.on(\"click.fb-start\", \"[data-fancybox-trigger]\", function (e) {\\n $(\\'[data-fancybox=\"\\' + $(this).attr(\"data-fancybox-trigger\") + \\'\"]\\').eq($(this).attr(\"data-fancybox-index\") || 0).trigger(\"click.fb-start\", {\\n $trigger: $(this)\\n });\\n }); // Track focus event for better accessibility styling\\n // ==================================================\\n\\n (function () {\\n var buttonStr = \".fancybox-button\",\\n focusStr = \"fancybox-focus\",\\n $pressed = null;\\n $D.on(\"mousedown mouseup focus blur\", buttonStr, function (e) {\\n switch (e.type) {\\n case \"mousedown\":\\n $pressed = $(this);\\n break;\\n\\n case \"mouseup\":\\n $pressed = null;\\n break;\\n\\n case \"focusin\":\\n $(buttonStr).removeClass(focusStr);\\n\\n if (!$(this).is($pressed) && !$(this).is(\"[disabled]\")) {\\n $(this).addClass(focusStr);\\n }\\n\\n break;\\n\\n case \"focusout\":\\n $(buttonStr).removeClass(focusStr);\\n break;\\n }\\n });\\n })();\\n})(window, document, jQuery); // ==========================================================================\\n//\\n// Media\\n// Adds additional media type support\\n//\\n// ==========================================================================\\n\\n\\n(function ($) {\\n \"use strict\"; // Object containing properties for each media type\\n\\n var defaults = {\\n youtube: {\\n matcher: /(youtube\\\\.com|youtu\\\\.be|youtube\\\\-nocookie\\\\.com)\\\\/(watch\\\\?(.*&)?v=|v\\\\/|u\\\\/|embed\\\\/?)?(videoseries\\\\?list=(.*)|[\\\\w-]{11}|\\\\?listType=(.*)&list=(.*))(.*)/i,\\n params: {\\n autoplay: 1,\\n autohide: 1,\\n fs: 1,\\n rel: 0,\\n hd: 1,\\n wmode: \"transparent\",\\n enablejsapi: 1,\\n html5: 1\\n },\\n paramPlace: 8,\\n type: \"iframe\",\\n url: \"https://www.youtube-nocookie.com/embed/$4\",\\n thumb: \"https://img.youtube.com/vi/$4/hqdefault.jpg\"\\n },\\n vimeo: {\\n matcher: /^.+vimeo.com\\\\/(.*\\\\/)?([\\\\d]+)(.*)?/,\\n params: {\\n autoplay: 1,\\n hd: 1,\\n show_title: 1,\\n show_byline: 1,\\n show_portrait: 0,\\n fullscreen: 1\\n },\\n paramPlace: 3,\\n type: \"iframe\",\\n url: \"//player.vimeo.com/video/$2\"\\n },\\n instagram: {\\n matcher: /(instagr\\\\.am|instagram\\\\.com)\\\\/p\\\\/([a-zA-Z0-9_\\\\-]+)\\\\/?/i,\\n type: \"image\",\\n url: \"//$1/p/$2/media/?size=l\"\\n },\\n // Examples:\\n // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16\\n // https://www.google.com/maps/@37.7852006,-122.4146355,14.65z\\n // https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en\\n // https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572\\n gmap_place: {\\n matcher: /(maps\\\\.)?google\\\\.([a-z]{2,3}(\\\\.[a-z]{2})?)\\\\/(((maps\\\\/(place\\\\/(.*)\\\\/)?\\\\@(.*),(\\\\d+.?\\\\d+?)z))|(\\\\?ll=))(.*)?/i,\\n type: \"iframe\",\\n url: function url(rez) {\\n return \"//maps.google.\" + rez[2] + \"/?ll=\" + (rez[9] ? rez[9] + \"&z=\" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\\\\//, \"&\") : \"\") : rez[12] + \"\").replace(/\\\\?/, \"&\") + \"&output=\" + (rez[12] && rez[12].indexOf(\"layer=c\") > 0 ? \"svembed\" : \"embed\");\\n }\\n },\\n // Examples:\\n // https://www.google.com/maps/search/Empire+State+Building/\\n // https://www.google.com/maps/search/?api=1&query=centurylink+field\\n // https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393\\n gmap_search: {\\n matcher: /(maps\\\\.)?google\\\\.([a-z]{2,3}(\\\\.[a-z]{2})?)\\\\/(maps\\\\/search\\\\/)(.*)/i,\\n type: \"iframe\",\\n url: function url(rez) {\\n return \"//maps.google.\" + rez[2] + \"/maps?q=\" + rez[5].replace(\"query=\", \"q=\").replace(\"api=1\", \"\") + \"&output=embed\";\\n }\\n }\\n }; // Formats matching url to final form\\n\\n var format = function format(url, rez, params) {\\n if (!url) {\\n return;\\n }\\n\\n params = params || \"\";\\n\\n if ($.type(params) === \"object\") {\\n params = $.param(params, true);\\n }\\n\\n $.each(rez, function (key, value) {\\n url = url.replace(\"$\" + key, value || \"\");\\n });\\n\\n if (params.length) {\\n url += (url.indexOf(\"?\") > 0 ? \"&\" : \"?\") + params;\\n }\\n\\n return url;\\n };\\n\\n $(document).on(\"objectNeedsType.fb\", function (e, instance, item) {\\n var url = item.src || \"\",\\n type = false,\\n media,\\n thumb,\\n rez,\\n params,\\n urlParams,\\n paramObj,\\n provider;\\n media = $.extend(true, {}, defaults, item.opts.media); // Look for any matching media type\\n\\n $.each(media, function (providerName, providerOpts) {\\n rez = url.match(providerOpts.matcher);\\n\\n if (!rez) {\\n return;\\n }\\n\\n type = providerOpts.type;\\n provider = providerName;\\n paramObj = {};\\n\\n if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) {\\n urlParams = rez[providerOpts.paramPlace];\\n\\n if (urlParams[0] == \"?\") {\\n urlParams = urlParams.substring(1);\\n }\\n\\n urlParams = urlParams.split(\"&\");\\n\\n for (var m = 0; m < urlParams.length; ++m) {\\n var p = urlParams[m].split(\"=\", 2);\\n\\n if (p.length == 2) {\\n paramObj[p[0]] = decodeURIComponent(p[1].replace(/\\\\+/g, \" \"));\\n }\\n }\\n }\\n\\n params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj);\\n url = $.type(providerOpts.url) === \"function\" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params);\\n thumb = $.type(providerOpts.thumb) === \"function\" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez);\\n\\n if (providerName === \"youtube\") {\\n url = url.replace(/&t=((\\\\d+)m)?(\\\\d+)s/, function (match, p1, m, s) {\\n return \"&start=\" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10));\\n });\\n } else if (providerName === \"vimeo\") {\\n url = url.replace(\"&%23\", \"#\");\\n }\\n\\n return false;\\n }); // If it is found, then change content type and update the url\\n\\n if (type) {\\n if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {\\n item.opts.thumb = thumb;\\n }\\n\\n if (type === \"iframe\") {\\n item.opts = $.extend(true, item.opts, {\\n iframe: {\\n preload: false,\\n attr: {\\n scrolling: \"no\"\\n }\\n }\\n });\\n }\\n\\n $.extend(item, {\\n type: type,\\n src: url,\\n origSrc: item.src,\\n contentSource: provider,\\n contentType: type === \"image\" ? \"image\" : provider == \"gmap_place\" || provider == \"gmap_search\" ? \"map\" : \"video\"\\n });\\n } else if (url) {\\n item.type = item.opts.defaultType;\\n }\\n }); // Load YouTube/Video API on request to detect when video finished playing\\n\\n var VideoAPILoader = {\\n youtube: {\\n src: \"https://www.youtube.com/iframe_api\",\\n \"class\": \"YT\",\\n loading: false,\\n loaded: false\\n },\\n vimeo: {\\n src: \"https://player.vimeo.com/api/player.js\",\\n \"class\": \"Vimeo\",\\n loading: false,\\n loaded: false\\n },\\n load: function load(vendor) {\\n var _this = this,\\n script;\\n\\n if (this[vendor].loaded) {\\n setTimeout(function () {\\n _this.done(vendor);\\n });\\n return;\\n }\\n\\n if (this[vendor].loading) {\\n return;\\n }\\n\\n this[vendor].loading = true;\\n script = document.createElement(\"script\");\\n script.type = \"text/javascript\";\\n script.src = this[vendor].src;\\n\\n if (vendor === \"youtube\") {\\n window.onYouTubeIframeAPIReady = function () {\\n _this[vendor].loaded = true;\\n\\n _this.done(vendor);\\n };\\n } else {\\n script.onload = function () {\\n _this[vendor].loaded = true;\\n\\n _this.done(vendor);\\n };\\n }\\n\\n document.body.appendChild(script);\\n },\\n done: function done(vendor) {\\n var instance, $el, player;\\n\\n if (vendor === \"youtube\") {\\n delete window.onYouTubeIframeAPIReady;\\n }\\n\\n instance = $.fancybox.getInstance();\\n\\n if (instance) {\\n $el = instance.current.$content.find(\"iframe\");\\n\\n if (vendor === \"youtube\" && YT !== undefined && YT) {\\n player = new YT.Player($el.attr(\"id\"), {\\n events: {\\n onStateChange: function onStateChange(e) {\\n if (e.data == 0) {\\n instance.next();\\n }\\n }\\n }\\n });\\n } else if (vendor === \"vimeo\" && Vimeo !== undefined && Vimeo) {\\n player = new Vimeo.Player($el);\\n player.on(\"ended\", function () {\\n instance.next();\\n });\\n }\\n }\\n }\\n };\\n $(document).on({\\n \"afterShow.fb\": function afterShowFb(e, instance, current) {\\n if (instance.group.length > 1 && (current.contentSource === \"youtube\" || current.contentSource === \"vimeo\")) {\\n VideoAPILoader.load(current.contentSource);\\n }\\n }\\n });\\n})(jQuery); // ==========================================================================\\n//\\n// Guestures\\n// Adds touch guestures, handles click and tap events\\n//\\n// ==========================================================================\\n\\n\\n(function (window, document, $) {\\n \"use strict\";\\n\\n var requestAFrame = function () {\\n return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || // if all else fails, use setTimeout\\n function (callback) {\\n return window.setTimeout(callback, 1000 / 60);\\n };\\n }();\\n\\n var cancelAFrame = function () {\\n return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || function (id) {\\n window.clearTimeout(id);\\n };\\n }();\\n\\n var getPointerXY = function getPointerXY(e) {\\n var result = [];\\n e = e.originalEvent || e || window.e;\\n e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e];\\n\\n for (var key in e) {\\n if (e[key].pageX) {\\n result.push({\\n x: e[key].pageX,\\n y: e[key].pageY\\n });\\n } else if (e[key].clientX) {\\n result.push({\\n x: e[key].clientX,\\n y: e[key].clientY\\n });\\n }\\n }\\n\\n return result;\\n };\\n\\n var distance = function distance(point2, point1, what) {\\n if (!point1 || !point2) {\\n return 0;\\n }\\n\\n if (what === \"x\") {\\n return point2.x - point1.x;\\n } else if (what === \"y\") {\\n return point2.y - point1.y;\\n }\\n\\n return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));\\n };\\n\\n var isClickable = function isClickable($el) {\\n if ($el.is(\\'a,area,button,[role=\"button\"],input,label,select,summary,textarea,video,audio,iframe\\') || $.isFunction($el.get(0).onclick) || $el.data(\"selectable\")) {\\n return true;\\n } // Check for attributes like data-fancybox-next or data-fancybox-close\\n\\n\\n for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {\\n if (atts[i].nodeName.substr(0, 14) === \"data-fancybox-\") {\\n return true;\\n }\\n }\\n\\n return false;\\n };\\n\\n var hasScrollbars = function hasScrollbars(el) {\\n var overflowY = window.getComputedStyle(el)[\"overflow-y\"],\\n overflowX = window.getComputedStyle(el)[\"overflow-x\"],\\n vertical = (overflowY === \"scroll\" || overflowY === \"auto\") && el.scrollHeight > el.clientHeight,\\n horizontal = (overflowX === \"scroll\" || overflowX === \"auto\") && el.scrollWidth > el.clientWidth;\\n return vertical || horizontal;\\n };\\n\\n var isScrollable = function isScrollable($el) {\\n var rez = false;\\n\\n while (true) {\\n rez = hasScrollbars($el.get(0));\\n\\n if (rez) {\\n break;\\n }\\n\\n $el = $el.parent();\\n\\n if (!$el.length || $el.hasClass(\"fancybox-stage\") || $el.is(\"body\")) {\\n break;\\n }\\n }\\n\\n return rez;\\n };\\n\\n var Guestures = function Guestures(instance) {\\n var self = this;\\n self.instance = instance;\\n self.$bg = instance.$refs.bg;\\n self.$stage = instance.$refs.stage;\\n self.$container = instance.$refs.container;\\n self.destroy();\\n self.$container.on(\"touchstart.fb.touch mousedown.fb.touch\", $.proxy(self, \"ontouchstart\"));\\n };\\n\\n Guestures.prototype.destroy = function () {\\n var self = this;\\n self.$container.off(\".fb.touch\");\\n $(document).off(\".fb.touch\");\\n\\n if (self.requestId) {\\n cancelAFrame(self.requestId);\\n self.requestId = null;\\n }\\n\\n if (self.tapped) {\\n clearTimeout(self.tapped);\\n self.tapped = null;\\n }\\n };\\n\\n Guestures.prototype.ontouchstart = function (e) {\\n var self = this,\\n $target = $(e.target),\\n instance = self.instance,\\n current = instance.current,\\n $slide = current.$slide,\\n $content = current.$content,\\n isTouchDevice = e.type == \"touchstart\"; // Do not respond to both (touch and mouse) events\\n\\n if (isTouchDevice) {\\n self.$container.off(\"mousedown.fb.touch\");\\n } // Ignore right click\\n\\n\\n if (e.originalEvent && e.originalEvent.button == 2) {\\n return;\\n } // Ignore taping on links, buttons, input elements\\n\\n\\n if (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) {\\n return;\\n } // Ignore clicks on the scrollbar\\n\\n\\n if (!$target.is(\"img\") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {\\n return;\\n } // Ignore clicks while zooming or closing\\n\\n\\n if (!current || instance.isAnimating || current.$slide.hasClass(\"fancybox-animated\")) {\\n e.stopPropagation();\\n e.preventDefault();\\n return;\\n }\\n\\n self.realPoints = self.startPoints = getPointerXY(e);\\n\\n if (!self.startPoints.length) {\\n return;\\n } // Allow other scripts to catch touch event if \"touch\" is set to false\\n\\n\\n if (current.touch) {\\n e.stopPropagation();\\n }\\n\\n self.startEvent = e;\\n self.canTap = true;\\n self.$target = $target;\\n self.$content = $content;\\n self.opts = current.opts.touch;\\n self.isPanning = false;\\n self.isSwiping = false;\\n self.isZooming = false;\\n self.isScrolling = false;\\n self.canPan = instance.canPan();\\n self.startTime = new Date().getTime();\\n self.distanceX = self.distanceY = self.distance = 0;\\n self.canvasWidth = Math.round($slide[0].clientWidth);\\n self.canvasHeight = Math.round($slide[0].clientHeight);\\n self.contentLastPos = null;\\n self.contentStartPos = $.fancybox.getTranslate(self.$content) || {\\n top: 0,\\n left: 0\\n };\\n self.sliderStartPos = $.fancybox.getTranslate($slide); // Since position will be absolute, but we need to make it relative to the stage\\n\\n self.stagePos = $.fancybox.getTranslate(instance.$refs.stage);\\n self.sliderStartPos.top -= self.stagePos.top;\\n self.sliderStartPos.left -= self.stagePos.left;\\n self.contentStartPos.top -= self.stagePos.top;\\n self.contentStartPos.left -= self.stagePos.left;\\n $(document).off(\".fb.touch\").on(isTouchDevice ? \"touchend.fb.touch touchcancel.fb.touch\" : \"mouseup.fb.touch mouseleave.fb.touch\", $.proxy(self, \"ontouchend\")).on(isTouchDevice ? \"touchmove.fb.touch\" : \"mousemove.fb.touch\", $.proxy(self, \"ontouchmove\"));\\n\\n if ($.fancybox.isMobile) {\\n document.addEventListener(\"scroll\", self.onscroll, true);\\n } // Skip if clicked outside the sliding area\\n\\n\\n if (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) {\\n if ($target.is(\".fancybox-image\")) {\\n e.preventDefault();\\n }\\n\\n if (!($.fancybox.isMobile && $target.parents(\".fancybox-caption\").length)) {\\n return;\\n }\\n }\\n\\n self.isScrollable = isScrollable($target) || isScrollable($target.parent()); // Check if element is scrollable and try to prevent default behavior (scrolling)\\n\\n if (!($.fancybox.isMobile && self.isScrollable)) {\\n e.preventDefault();\\n } // One finger or mouse click - swipe or pan an image\\n\\n\\n if (self.startPoints.length === 1 || current.hasError) {\\n if (self.canPan) {\\n $.fancybox.stop(self.$content);\\n self.isPanning = true;\\n } else {\\n self.isSwiping = true;\\n }\\n\\n self.$container.addClass(\"fancybox-is-grabbing\");\\n } // Two fingers - zoom image\\n\\n\\n if (self.startPoints.length === 2 && current.type === \"image\" && (current.isLoaded || current.$ghost)) {\\n self.canTap = false;\\n self.isSwiping = false;\\n self.isPanning = false;\\n self.isZooming = true;\\n $.fancybox.stop(self.$content);\\n self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft();\\n self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop();\\n self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;\\n self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;\\n self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);\\n }\\n };\\n\\n Guestures.prototype.onscroll = function (e) {\\n var self = this;\\n self.isScrolling = true;\\n document.removeEventListener(\"scroll\", self.onscroll, true);\\n };\\n\\n Guestures.prototype.ontouchmove = function (e) {\\n var self = this; // Make sure user has not released over iframe or disabled element\\n\\n if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) {\\n self.ontouchend(e);\\n return;\\n }\\n\\n if (self.isScrolling) {\\n self.canTap = false;\\n return;\\n }\\n\\n self.newPoints = getPointerXY(e);\\n\\n if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) {\\n return;\\n }\\n\\n if (!(self.isSwiping && self.isSwiping === true)) {\\n e.preventDefault();\\n }\\n\\n self.distanceX = distance(self.newPoints[0], self.startPoints[0], \"x\");\\n self.distanceY = distance(self.newPoints[0], self.startPoints[0], \"y\");\\n self.distance = distance(self.newPoints[0], self.startPoints[0]); // Skip false ontouchmove events (Chrome)\\n\\n if (self.distance > 0) {\\n if (self.isSwiping) {\\n self.onSwipe(e);\\n } else if (self.isPanning) {\\n self.onPan();\\n } else if (self.isZooming) {\\n self.onZoom();\\n }\\n }\\n };\\n\\n Guestures.prototype.onSwipe = function (e) {\\n var self = this,\\n instance = self.instance,\\n swiping = self.isSwiping,\\n left = self.sliderStartPos.left || 0,\\n angle; // If direction is not yet determined\\n\\n if (swiping === true) {\\n // We need at least 10px distance to correctly calculate an angle\\n if (Math.abs(self.distance) > 10) {\\n self.canTap = false;\\n\\n if (instance.group.length < 2 && self.opts.vertical) {\\n self.isSwiping = \"y\";\\n } else if (instance.isDragging || self.opts.vertical === false || self.opts.vertical === \"auto\" && $(window).width() > 800) {\\n self.isSwiping = \"x\";\\n } else {\\n angle = Math.abs(Math.atan2(self.distanceY, self.distanceX) * 180 / Math.PI);\\n self.isSwiping = angle > 45 && angle < 135 ? \"y\" : \"x\";\\n }\\n\\n if (self.isSwiping === \"y\" && $.fancybox.isMobile && self.isScrollable) {\\n self.isScrolling = true;\\n return;\\n }\\n\\n instance.isDragging = self.isSwiping; // Reset points to avoid jumping, because we dropped first swipes to calculate the angle\\n\\n self.startPoints = self.newPoints;\\n $.each(instance.slides, function (index, slide) {\\n var slidePos, stagePos;\\n $.fancybox.stop(slide.$slide);\\n slidePos = $.fancybox.getTranslate(slide.$slide);\\n stagePos = $.fancybox.getTranslate(instance.$refs.stage);\\n slide.$slide.css({\\n transform: \"\",\\n opacity: \"\",\\n \"transition-duration\": \"\"\\n }).removeClass(\"fancybox-animated\").removeClass(function (index, className) {\\n return (className.match(/(^|\\\\s)fancybox-fx-\\\\S+/g) || []).join(\" \");\\n });\\n\\n if (slide.pos === instance.current.pos) {\\n self.sliderStartPos.top = slidePos.top - stagePos.top;\\n self.sliderStartPos.left = slidePos.left - stagePos.left;\\n }\\n\\n $.fancybox.setTranslate(slide.$slide, {\\n top: slidePos.top - stagePos.top,\\n left: slidePos.left - stagePos.left\\n });\\n }); // Stop slideshow\\n\\n if (instance.SlideShow && instance.SlideShow.isActive) {\\n instance.SlideShow.stop();\\n }\\n }\\n\\n return;\\n } // Sticky edges\\n\\n\\n if (swiping == \"x\") {\\n if (self.distanceX > 0 && (self.instance.group.length < 2 || self.instance.current.index === 0 && !self.instance.current.opts.loop)) {\\n left = left + Math.pow(self.distanceX, 0.8);\\n } else if (self.distanceX < 0 && (self.instance.group.length < 2 || self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop)) {\\n left = left - Math.pow(-self.distanceX, 0.8);\\n } else {\\n left = left + self.distanceX;\\n }\\n }\\n\\n self.sliderLastPos = {\\n top: swiping == \"x\" ? 0 : self.sliderStartPos.top + self.distanceY,\\n left: left\\n };\\n\\n if (self.requestId) {\\n cancelAFrame(self.requestId);\\n self.requestId = null;\\n }\\n\\n self.requestId = requestAFrame(function () {\\n if (self.sliderLastPos) {\\n $.each(self.instance.slides, function (index, slide) {\\n var pos = slide.pos - self.instance.currPos;\\n $.fancybox.setTranslate(slide.$slide, {\\n top: self.sliderLastPos.top,\\n left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter\\n });\\n });\\n self.$container.addClass(\"fancybox-is-sliding\");\\n }\\n });\\n };\\n\\n Guestures.prototype.onPan = function () {\\n var self = this; // Prevent accidental movement (sometimes, when tapping casually, finger can move a bit)\\n\\n if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) {\\n self.startPoints = self.newPoints;\\n return;\\n }\\n\\n self.canTap = false;\\n self.contentLastPos = self.limitMovement();\\n\\n if (self.requestId) {\\n cancelAFrame(self.requestId);\\n }\\n\\n self.requestId = requestAFrame(function () {\\n $.fancybox.setTranslate(self.$content, self.contentLastPos);\\n });\\n }; // Make panning sticky to the edges\\n\\n\\n Guestures.prototype.limitMovement = function () {\\n var self = this;\\n var canvasWidth = self.canvasWidth;\\n var canvasHeight = self.canvasHeight;\\n var distanceX = self.distanceX;\\n var distanceY = self.distanceY;\\n var contentStartPos = self.contentStartPos;\\n var currentOffsetX = contentStartPos.left;\\n var currentOffsetY = contentStartPos.top;\\n var currentWidth = contentStartPos.width;\\n var currentHeight = contentStartPos.height;\\n var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY;\\n\\n if (currentWidth > canvasWidth) {\\n newOffsetX = currentOffsetX + distanceX;\\n } else {\\n newOffsetX = currentOffsetX;\\n }\\n\\n newOffsetY = currentOffsetY + distanceY; // Slow down proportionally to traveled distance\\n\\n minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5);\\n minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5);\\n maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5);\\n maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5); // ->\\n\\n if (distanceX > 0 && newOffsetX > minTranslateX) {\\n newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;\\n } // <-\\n\\n\\n if (distanceX < 0 && newOffsetX < maxTranslateX) {\\n newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;\\n } // \\\\/\\n\\n\\n if (distanceY > 0 && newOffsetY > minTranslateY) {\\n newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;\\n } // /\\\\\\n\\n\\n if (distanceY < 0 && newOffsetY < maxTranslateY) {\\n newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;\\n }\\n\\n return {\\n top: newOffsetY,\\n left: newOffsetX\\n };\\n };\\n\\n Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) {\\n var self = this;\\n var canvasWidth = self.canvasWidth;\\n var canvasHeight = self.canvasHeight;\\n\\n if (newWidth > canvasWidth) {\\n newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;\\n newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;\\n } else {\\n // Center horizontally\\n newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);\\n }\\n\\n if (newHeight > canvasHeight) {\\n newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;\\n newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;\\n } else {\\n // Center vertically\\n newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);\\n }\\n\\n return {\\n top: newOffsetY,\\n left: newOffsetX\\n };\\n };\\n\\n Guestures.prototype.onZoom = function () {\\n var self = this; // Calculate current distance between points to get pinch ratio and new width and height\\n\\n var contentStartPos = self.contentStartPos;\\n var currentWidth = contentStartPos.width;\\n var currentHeight = contentStartPos.height;\\n var currentOffsetX = contentStartPos.left;\\n var currentOffsetY = contentStartPos.top;\\n var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);\\n var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;\\n var newWidth = Math.floor(currentWidth * pinchRatio);\\n var newHeight = Math.floor(currentHeight * pinchRatio); // This is the translation due to pinch-zooming\\n\\n var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;\\n var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY; // Point between the two touches\\n\\n var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft();\\n var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop(); // And this is the translation due to translation of the centerpoint\\n // between the two fingers\\n\\n var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;\\n var translateFromTranslatingY = centerPointEndY - self.centerPointStartY; // The new offset is the old/current one plus the total translation\\n\\n var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);\\n var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);\\n var newPos = {\\n top: newOffsetY,\\n left: newOffsetX,\\n scaleX: pinchRatio,\\n scaleY: pinchRatio\\n };\\n self.canTap = false;\\n self.newWidth = newWidth;\\n self.newHeight = newHeight;\\n self.contentLastPos = newPos;\\n\\n if (self.requestId) {\\n cancelAFrame(self.requestId);\\n }\\n\\n self.requestId = requestAFrame(function () {\\n $.fancybox.setTranslate(self.$content, self.contentLastPos);\\n });\\n };\\n\\n Guestures.prototype.ontouchend = function (e) {\\n var self = this;\\n var swiping = self.isSwiping;\\n var panning = self.isPanning;\\n var zooming = self.isZooming;\\n var scrolling = self.isScrolling;\\n self.endPoints = getPointerXY(e);\\n self.dMs = Math.max(new Date().getTime() - self.startTime, 1);\\n self.$container.removeClass(\"fancybox-is-grabbing\");\\n $(document).off(\".fb.touch\");\\n document.removeEventListener(\"scroll\", self.onscroll, true);\\n\\n if (self.requestId) {\\n cancelAFrame(self.requestId);\\n self.requestId = null;\\n }\\n\\n self.isSwiping = false;\\n self.isPanning = false;\\n self.isZooming = false;\\n self.isScrolling = false;\\n self.instance.isDragging = false;\\n\\n if (self.canTap) {\\n return self.onTap(e);\\n }\\n\\n self.speed = 100; // Speed in px/ms\\n\\n self.velocityX = self.distanceX / self.dMs * 0.5;\\n self.velocityY = self.distanceY / self.dMs * 0.5;\\n\\n if (panning) {\\n self.endPanning();\\n } else if (zooming) {\\n self.endZooming();\\n } else {\\n self.endSwiping(swiping, scrolling);\\n }\\n\\n return;\\n };\\n\\n Guestures.prototype.endSwiping = function (swiping, scrolling) {\\n var self = this,\\n ret = false,\\n len = self.instance.group.length,\\n distanceX = Math.abs(self.distanceX),\\n canAdvance = swiping == \"x\" && len > 1 && (self.dMs > 130 && distanceX > 10 || distanceX > 50),\\n speedX = 300;\\n self.sliderLastPos = null; // Close if swiped vertically / navigate if horizontally\\n\\n if (swiping == \"y\" && !scrolling && Math.abs(self.distanceY) > 50) {\\n // Continue vertical movement\\n $.fancybox.animate(self.instance.current.$slide, {\\n top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150,\\n opacity: 0\\n }, 200);\\n ret = self.instance.close(true, 250);\\n } else if (canAdvance && self.distanceX > 0) {\\n ret = self.instance.previous(speedX);\\n } else if (canAdvance && self.distanceX < 0) {\\n ret = self.instance.next(speedX);\\n }\\n\\n if (ret === false && (swiping == \"x\" || swiping == \"y\")) {\\n self.instance.centerSlide(200);\\n }\\n\\n self.$container.removeClass(\"fancybox-is-sliding\");\\n }; // Limit panning from edges\\n // ========================\\n\\n\\n Guestures.prototype.endPanning = function () {\\n var self = this,\\n newOffsetX,\\n newOffsetY,\\n newPos;\\n\\n if (!self.contentLastPos) {\\n return;\\n }\\n\\n if (self.opts.momentum === false || self.dMs > 350) {\\n newOffsetX = self.contentLastPos.left;\\n newOffsetY = self.contentLastPos.top;\\n } else {\\n // Continue movement\\n newOffsetX = self.contentLastPos.left + self.velocityX * 500;\\n newOffsetY = self.contentLastPos.top + self.velocityY * 500;\\n }\\n\\n newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);\\n newPos.width = self.contentStartPos.width;\\n newPos.height = self.contentStartPos.height;\\n $.fancybox.animate(self.$content, newPos, 366);\\n };\\n\\n Guestures.prototype.endZooming = function () {\\n var self = this;\\n var current = self.instance.current;\\n var newOffsetX, newOffsetY, newPos, reset;\\n var newWidth = self.newWidth;\\n var newHeight = self.newHeight;\\n\\n if (!self.contentLastPos) {\\n return;\\n }\\n\\n newOffsetX = self.contentLastPos.left;\\n newOffsetY = self.contentLastPos.top;\\n reset = {\\n top: newOffsetY,\\n left: newOffsetX,\\n width: newWidth,\\n height: newHeight,\\n scaleX: 1,\\n scaleY: 1\\n }; // Reset scalex/scaleY values; this helps for perfomance and does not break animation\\n\\n $.fancybox.setTranslate(self.$content, reset);\\n\\n if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {\\n self.instance.scaleToFit(150);\\n } else if (newWidth > current.width || newHeight > current.height) {\\n self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);\\n } else {\\n newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);\\n $.fancybox.animate(self.$content, newPos, 150);\\n }\\n };\\n\\n Guestures.prototype.onTap = function (e) {\\n var self = this;\\n var $target = $(e.target);\\n var instance = self.instance;\\n var current = instance.current;\\n var endPoints = e && getPointerXY(e) || self.startPoints;\\n var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0;\\n var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0;\\n var where;\\n\\n var process = function process(prefix) {\\n var action = current.opts[prefix];\\n\\n if ($.isFunction(action)) {\\n action = action.apply(instance, [current, e]);\\n }\\n\\n if (!action) {\\n return;\\n }\\n\\n switch (action) {\\n case \"close\":\\n instance.close(self.startEvent);\\n break;\\n\\n case \"toggleControls\":\\n instance.toggleControls();\\n break;\\n\\n case \"next\":\\n instance.next();\\n break;\\n\\n case \"nextOrClose\":\\n if (instance.group.length > 1) {\\n instance.next();\\n } else {\\n instance.close(self.startEvent);\\n }\\n\\n break;\\n\\n case \"zoom\":\\n if (current.type == \"image\" && (current.isLoaded || current.$ghost)) {\\n if (instance.canPan()) {\\n instance.scaleToFit();\\n } else if (instance.isScaledDown()) {\\n instance.scaleToActual(tapX, tapY);\\n } else if (instance.group.length < 2) {\\n instance.close(self.startEvent);\\n }\\n }\\n\\n break;\\n }\\n }; // Ignore right click\\n\\n\\n if (e.originalEvent && e.originalEvent.button == 2) {\\n return;\\n } // Skip if clicked on the scrollbar\\n\\n\\n if (!$target.is(\"img\") && tapX > $target[0].clientWidth + $target.offset().left) {\\n return;\\n } // Check where is clicked\\n\\n\\n if ($target.is(\".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container\")) {\\n where = \"Outside\";\\n } else if ($target.is(\".fancybox-slide\")) {\\n where = \"Slide\";\\n } else if (instance.current.$content && instance.current.$content.find($target).addBack().filter($target).length) {\\n where = \"Content\";\\n } else {\\n return;\\n } // Check if this is a double tap\\n\\n\\n if (self.tapped) {\\n // Stop previously created single tap\\n clearTimeout(self.tapped);\\n self.tapped = null; // Skip if distance between taps is too big\\n\\n if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) {\\n return this;\\n } // OK, now we assume that this is a double-tap\\n\\n\\n process(\"dblclick\" + where);\\n } else {\\n // Single tap will be processed if user has not clicked second time within 300ms\\n // or there is no need to wait for double-tap\\n self.tapX = tapX;\\n self.tapY = tapY;\\n\\n if (current.opts[\"dblclick\" + where] && current.opts[\"dblclick\" + where] !== current.opts[\"click\" + where]) {\\n self.tapped = setTimeout(function () {\\n self.tapped = null;\\n\\n if (!instance.isAnimating) {\\n process(\"click\" + where);\\n }\\n }, 500);\\n } else {\\n process(\"click\" + where);\\n }\\n }\\n\\n return this;\\n };\\n\\n $(document).on(\"onActivate.fb\", function (e, instance) {\\n if (instance && !instance.Guestures) {\\n instance.Guestures = new Guestures(instance);\\n }\\n }).on(\"beforeClose.fb\", function (e, instance) {\\n if (instance && instance.Guestures) {\\n instance.Guestures.destroy();\\n }\\n });\\n})(window, document, jQuery); // ==========================================================================\\n//\\n// SlideShow\\n// Enables slideshow functionality\\n//\\n// Example of usage:\\n// $.fancybox.getInstance().SlideShow.start()\\n//\\n// ==========================================================================\\n\\n\\n(function (document, $) {\\n \"use strict\";\\n\\n $.extend(true, $.fancybox.defaults, {\\n btnTpl: {\\n slideShow: \\'\"\\n },\\n slideShow: {\\n autoStart: false,\\n speed: 3000,\\n progress: true\\n }\\n });\\n\\n var SlideShow = function SlideShow(instance) {\\n this.instance = instance;\\n this.init();\\n };\\n\\n $.extend(SlideShow.prototype, {\\n timer: null,\\n isActive: false,\\n $button: null,\\n init: function init() {\\n var self = this,\\n instance = self.instance,\\n opts = instance.group[instance.currIndex].opts.slideShow;\\n self.$button = instance.$refs.toolbar.find(\"[data-fancybox-play]\").on(\"click\", function () {\\n self.toggle();\\n });\\n\\n if (instance.group.length < 2 || !opts) {\\n self.$button.hide();\\n } else if (opts.progress) {\\n self.$progress = $(\\'\\').appendTo(instance.$refs.inner);\\n }\\n },\\n set: function set(force) {\\n var self = this,\\n instance = self.instance,\\n current = instance.current; // Check if reached last element\\n\\n if (current && (force === true || current.opts.loop || instance.currIndex < instance.group.length - 1)) {\\n if (self.isActive && current.contentType !== \"video\") {\\n if (self.$progress) {\\n $.fancybox.animate(self.$progress.show(), {\\n scaleX: 1\\n }, current.opts.slideShow.speed);\\n }\\n\\n self.timer = setTimeout(function () {\\n if (!instance.current.opts.loop && instance.current.index == instance.group.length - 1) {\\n instance.jumpTo(0);\\n } else {\\n instance.next();\\n }\\n }, current.opts.slideShow.speed);\\n }\\n } else {\\n self.stop();\\n instance.idleSecondsCounter = 0;\\n instance.showControls();\\n }\\n },\\n clear: function clear() {\\n var self = this;\\n clearTimeout(self.timer);\\n self.timer = null;\\n\\n if (self.$progress) {\\n self.$progress.removeAttr(\"style\").hide();\\n }\\n },\\n start: function start() {\\n var self = this,\\n current = self.instance.current;\\n\\n if (current) {\\n self.$button.attr(\"title\", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_STOP).removeClass(\"fancybox-button--play\").addClass(\"fancybox-button--pause\");\\n self.isActive = true;\\n\\n if (current.isComplete) {\\n self.set(true);\\n }\\n\\n self.instance.trigger(\"onSlideShowChange\", true);\\n }\\n },\\n stop: function stop() {\\n var self = this,\\n current = self.instance.current;\\n self.clear();\\n self.$button.attr(\"title\", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_START).removeClass(\"fancybox-button--pause\").addClass(\"fancybox-button--play\");\\n self.isActive = false;\\n self.instance.trigger(\"onSlideShowChange\", false);\\n\\n if (self.$progress) {\\n self.$progress.removeAttr(\"style\").hide();\\n }\\n },\\n toggle: function toggle() {\\n var self = this;\\n\\n if (self.isActive) {\\n self.stop();\\n } else {\\n self.start();\\n }\\n }\\n });\\n $(document).on({\\n \"onInit.fb\": function onInitFb(e, instance) {\\n if (instance && !instance.SlideShow) {\\n instance.SlideShow = new SlideShow(instance);\\n }\\n },\\n \"beforeShow.fb\": function beforeShowFb(e, instance, current, firstRun) {\\n var SlideShow = instance && instance.SlideShow;\\n\\n if (firstRun) {\\n if (SlideShow && current.opts.slideShow.autoStart) {\\n SlideShow.start();\\n }\\n } else if (SlideShow && SlideShow.isActive) {\\n SlideShow.clear();\\n }\\n },\\n \"afterShow.fb\": function afterShowFb(e, instance, current) {\\n var SlideShow = instance && instance.SlideShow;\\n\\n if (SlideShow && SlideShow.isActive) {\\n SlideShow.set();\\n }\\n },\\n \"afterKeydown.fb\": function afterKeydownFb(e, instance, current, keypress, keycode) {\\n var SlideShow = instance && instance.SlideShow; // \"P\" or Spacebar\\n\\n if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is(\"button,a,input\")) {\\n keypress.preventDefault();\\n SlideShow.toggle();\\n }\\n },\\n \"beforeClose.fb onDeactivate.fb\": function beforeCloseFbOnDeactivateFb(e, instance) {\\n var SlideShow = instance && instance.SlideShow;\\n\\n if (SlideShow) {\\n SlideShow.stop();\\n }\\n }\\n }); // Page Visibility API to pause slideshow when window is not active\\n\\n $(document).on(\"visibilitychange\", function () {\\n var instance = $.fancybox.getInstance(),\\n SlideShow = instance && instance.SlideShow;\\n\\n if (SlideShow && SlideShow.isActive) {\\n if (document.hidden) {\\n SlideShow.clear();\\n } else {\\n SlideShow.set();\\n }\\n }\\n });\\n})(document, jQuery); // ==========================================================================\\n//\\n// FullScreen\\n// Adds fullscreen functionality\\n//\\n// ==========================================================================\\n\\n\\n(function (document, $) {\\n \"use strict\"; // Collection of methods supported by user browser\\n\\n var fn = function () {\\n var fnMap = [[\"requestFullscreen\", \"exitFullscreen\", \"fullscreenElement\", \"fullscreenEnabled\", \"fullscreenchange\", \"fullscreenerror\"], // new WebKit\\n [\"webkitRequestFullscreen\", \"webkitExitFullscreen\", \"webkitFullscreenElement\", \"webkitFullscreenEnabled\", \"webkitfullscreenchange\", \"webkitfullscreenerror\"], // old WebKit (Safari 5.1)\\n [\"webkitRequestFullScreen\", \"webkitCancelFullScreen\", \"webkitCurrentFullScreenElement\", \"webkitCancelFullScreen\", \"webkitfullscreenchange\", \"webkitfullscreenerror\"], [\"mozRequestFullScreen\", \"mozCancelFullScreen\", \"mozFullScreenElement\", \"mozFullScreenEnabled\", \"mozfullscreenchange\", \"mozfullscreenerror\"], [\"msRequestFullscreen\", \"msExitFullscreen\", \"msFullscreenElement\", \"msFullscreenEnabled\", \"MSFullscreenChange\", \"MSFullscreenError\"]];\\n var ret = {};\\n\\n for (var i = 0; i < fnMap.length; i++) {\\n var val = fnMap[i];\\n\\n if (val && val[1] in document) {\\n for (var j = 0; j < val.length; j++) {\\n ret[fnMap[0][j]] = val[j];\\n }\\n\\n return ret;\\n }\\n }\\n\\n return false;\\n }();\\n\\n if (fn) {\\n var FullScreen = {\\n request: function request(elem) {\\n elem = elem || document.documentElement;\\n elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);\\n },\\n exit: function exit() {\\n document[fn.exitFullscreen]();\\n },\\n toggle: function toggle(elem) {\\n elem = elem || document.documentElement;\\n\\n if (this.isFullscreen()) {\\n this.exit();\\n } else {\\n this.request(elem);\\n }\\n },\\n isFullscreen: function isFullscreen() {\\n return Boolean(document[fn.fullscreenElement]);\\n },\\n enabled: function enabled() {\\n return Boolean(document[fn.fullscreenEnabled]);\\n }\\n };\\n $.extend(true, $.fancybox.defaults, {\\n btnTpl: {\\n fullScreen: \\'\"\\n },\\n fullScreen: {\\n autoStart: false\\n }\\n });\\n $(document).on(fn.fullscreenchange, function () {\\n var isFullscreen = FullScreen.isFullscreen(),\\n instance = $.fancybox.getInstance();\\n\\n if (instance) {\\n // If image is zooming, then force to stop and reposition properly\\n if (instance.current && instance.current.type === \"image\" && instance.isAnimating) {\\n instance.isAnimating = false;\\n instance.update(true, true, 0);\\n\\n if (!instance.isComplete) {\\n instance.complete();\\n }\\n }\\n\\n instance.trigger(\"onFullscreenChange\", isFullscreen);\\n instance.$refs.container.toggleClass(\"fancybox-is-fullscreen\", isFullscreen);\\n instance.$refs.toolbar.find(\"[data-fancybox-fullscreen]\").toggleClass(\"fancybox-button--fsenter\", !isFullscreen).toggleClass(\"fancybox-button--fsexit\", isFullscreen);\\n }\\n });\\n }\\n\\n $(document).on({\\n \"onInit.fb\": function onInitFb(e, instance) {\\n var $container;\\n\\n if (!fn) {\\n instance.$refs.toolbar.find(\"[data-fancybox-fullscreen]\").remove();\\n return;\\n }\\n\\n if (instance && instance.group[instance.currIndex].opts.fullScreen) {\\n $container = instance.$refs.container;\\n $container.on(\"click.fb-fullscreen\", \"[data-fancybox-fullscreen]\", function (e) {\\n e.stopPropagation();\\n e.preventDefault();\\n FullScreen.toggle();\\n });\\n\\n if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {\\n FullScreen.request();\\n } // Expose API\\n\\n\\n instance.FullScreen = FullScreen;\\n } else if (instance) {\\n instance.$refs.toolbar.find(\"[data-fancybox-fullscreen]\").hide();\\n }\\n },\\n \"afterKeydown.fb\": function afterKeydownFb(e, instance, current, keypress, keycode) {\\n // \"F\"\\n if (instance && instance.FullScreen && keycode === 70) {\\n keypress.preventDefault();\\n instance.FullScreen.toggle();\\n }\\n },\\n \"beforeClose.fb\": function beforeCloseFb(e, instance) {\\n if (instance && instance.FullScreen && instance.$refs.container.hasClass(\"fancybox-is-fullscreen\")) {\\n FullScreen.exit();\\n }\\n }\\n });\\n})(document, jQuery); // ==========================================================================\\n//\\n// Thumbs\\n// Displays thumbnails in a grid\\n//\\n// ==========================================================================\\n\\n\\n(function (document, $) {\\n \"use strict\";\\n\\n var CLASS = \"fancybox-thumbs\",\\n CLASS_ACTIVE = CLASS + \"-active\"; // Make sure there are default values\\n\\n $.fancybox.defaults = $.extend(true, {\\n btnTpl: {\\n thumbs: \\'\"\\n },\\n thumbs: {\\n autoStart: false,\\n // Display thumbnails on opening\\n hideOnClose: true,\\n // Hide thumbnail grid when closing animation starts\\n parentEl: \".fancybox-container\",\\n // Container is injected into this element\\n axis: \"y\" // Vertical (y) or horizontal (x) scrolling\\n\\n }\\n }, $.fancybox.defaults);\\n\\n var FancyThumbs = function FancyThumbs(instance) {\\n this.init(instance);\\n };\\n\\n $.extend(FancyThumbs.prototype, {\\n $button: null,\\n $grid: null,\\n $list: null,\\n isVisible: false,\\n isActive: false,\\n init: function init(instance) {\\n var self = this,\\n group = instance.group,\\n enabled = 0;\\n self.instance = instance;\\n self.opts = group[instance.currIndex].opts.thumbs;\\n instance.Thumbs = self;\\n self.$button = instance.$refs.toolbar.find(\"[data-fancybox-thumbs]\"); // Enable thumbs if at least two group items have thumbnails\\n\\n for (var i = 0, len = group.length; i < len; i++) {\\n if (group[i].thumb) {\\n enabled++;\\n }\\n\\n if (enabled > 1) {\\n break;\\n }\\n }\\n\\n if (enabled > 1 && !!self.opts) {\\n self.$button.removeAttr(\"style\").on(\"click\", function () {\\n self.toggle();\\n });\\n self.isActive = true;\\n } else {\\n self.$button.hide();\\n }\\n },\\n create: function create() {\\n var self = this,\\n instance = self.instance,\\n parentEl = self.opts.parentEl,\\n list = [],\\n src;\\n\\n if (!self.$grid) {\\n // Create main element\\n self.$grid = $(\\'\\').appendTo(instance.$refs.container.find(parentEl).addBack().filter(parentEl)); // Add \"click\" event that performs gallery navigation\\n\\n self.$grid.on(\"click\", \"a\", function () {\\n instance.jumpTo($(this).attr(\"data-index\"));\\n });\\n } // Build the list\\n\\n\\n if (!self.$list) {\\n self.$list = $(\\'
\\').appendTo(self.$grid);\\n }\\n\\n $.each(instance.group, function (i, item) {\\n src = item.thumb;\\n\\n if (!src && item.type === \"image\") {\\n src = item.src;\\n }\\n\\n list.push(\\'\");\\n });\\n self.$list[0].innerHTML = list.join(\"\");\\n\\n if (self.opts.axis === \"x\") {\\n // Set fixed width for list element to enable horizontal scrolling\\n self.$list.width(parseInt(self.$grid.css(\"padding-right\"), 10) + instance.group.length * self.$list.children().eq(0).outerWidth(true));\\n }\\n },\\n focus: function focus(duration) {\\n var self = this,\\n $list = self.$list,\\n $grid = self.$grid,\\n thumb,\\n thumbPos;\\n\\n if (!self.instance.current) {\\n return;\\n }\\n\\n thumb = $list.children().removeClass(CLASS_ACTIVE).filter(\\'[data-index=\"\\' + self.instance.current.index + \\'\"]\\').addClass(CLASS_ACTIVE);\\n thumbPos = thumb.position(); // Check if need to scroll to make current thumb visible\\n\\n if (self.opts.axis === \"y\" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) {\\n $list.stop().animate({\\n scrollTop: $list.scrollTop() + thumbPos.top\\n }, duration);\\n } else if (self.opts.axis === \"x\" && (thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth()))) {\\n $list.parent().stop().animate({\\n scrollLeft: thumbPos.left\\n }, duration);\\n }\\n },\\n update: function update() {\\n var that = this;\\n that.instance.$refs.container.toggleClass(\"fancybox-show-thumbs\", this.isVisible);\\n\\n if (that.isVisible) {\\n if (!that.$grid) {\\n that.create();\\n }\\n\\n that.instance.trigger(\"onThumbsShow\");\\n that.focus(0);\\n } else if (that.$grid) {\\n that.instance.trigger(\"onThumbsHide\");\\n } // Update content position\\n\\n\\n that.instance.update();\\n },\\n hide: function hide() {\\n this.isVisible = false;\\n this.update();\\n },\\n show: function show() {\\n this.isVisible = true;\\n this.update();\\n },\\n toggle: function toggle() {\\n this.isVisible = !this.isVisible;\\n this.update();\\n }\\n });\\n $(document).on({\\n \"onInit.fb\": function onInitFb(e, instance) {\\n var Thumbs;\\n\\n if (instance && !instance.Thumbs) {\\n Thumbs = new FancyThumbs(instance);\\n\\n if (Thumbs.isActive && Thumbs.opts.autoStart === true) {\\n Thumbs.show();\\n }\\n }\\n },\\n \"beforeShow.fb\": function beforeShowFb(e, instance, item, firstRun) {\\n var Thumbs = instance && instance.Thumbs;\\n\\n if (Thumbs && Thumbs.isVisible) {\\n Thumbs.focus(firstRun ? 0 : 250);\\n }\\n },\\n \"afterKeydown.fb\": function afterKeydownFb(e, instance, current, keypress, keycode) {\\n var Thumbs = instance && instance.Thumbs; // \"G\"\\n\\n if (Thumbs && Thumbs.isActive && keycode === 71) {\\n keypress.preventDefault();\\n Thumbs.toggle();\\n }\\n },\\n \"beforeClose.fb\": function beforeCloseFb(e, instance) {\\n var Thumbs = instance && instance.Thumbs;\\n\\n if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) {\\n Thumbs.$grid.hide();\\n }\\n }\\n });\\n})(document, jQuery); //// ==========================================================================\\n//\\n// Share\\n// Displays simple form for sharing current url\\n//\\n// ==========================================================================\\n\\n\\n(function (document, $) {\\n \"use strict\";\\n\\n $.extend(true, $.fancybox.defaults, {\\n btnTpl: {\\n share: \\'\"\\n },\\n share: {\\n url: function url(instance, item) {\\n return (!instance.currentHash && !(item.type === \"inline\" || item.type === \"html\") ? item.origSrc || item.src : false) || window.location;\\n },\\n tpl: \\'