// ==================================================
// fancyBox v3.0.47
//
// Licensed GPLv3 for open source use
// or fancyBox Commercial License for commercial use
//
// http://fancyapps.com/fancybox/
// Copyright 2017 fancyApps
//
// ==================================================
export default function(){
    ;(function (window, document, $, undefined) {
        //'use strict';

        // If there's no jQuery, fancyBox can't work
        // =========================================

        if ( !$ ) {
            return undefined;
        }

        // Private default settings
        // ========================

        var defaults = {

            // Animation duration in ms
            speed : 330,

            // Enable infinite gallery navigation
            loop : true,

            // Should zoom animation change opacity, too
            // If opacity is 'auto', then fade-out if image and thumbnail have different aspect ratios
            opacity : 'auto',

            // Space around image, ignored if zoomed-in or viewport smaller than 800px
            margin : [44, 0],

            // Horizontal space between slides
            gutter : 30,

            // Should display toolbars
            infobar : true,
            buttons : true,

            // What buttons should appear in the toolbar
            slideShow  : true,
            fullScreen : true,
            thumbs     : true,
            closeBtn   : true,

            // Should apply small close button at top right corner of the content
            // If 'auto' - will be set for content having type 'html', 'inline' or 'ajax'
            smallBtn : 'auto',

            image : {

                // Wait for images to load before displaying
                // Requires predefined image dimensions
                // If 'auto' - will zoom in thumbnail if 'width' and 'height' attributes are found
                preload : "auto",

                // Protect an image from downloading by right-click
                protect : false

            },

            ajax : {

                // Object containing settings for ajax request
                settings : {

                    // This helps to indicate that request comes from the modal
                    // Feel free to change naming
                    data : {
                        fancybox : true
                    }
                }

            },

            iframe : {

                // Iframe template
                tpl : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen allowtransparency="true" src=""></iframe>',

                // Preload iframe before displaying it
                // This allows to calculate iframe content width and height
                // (note: Due to "Same Origin Policy", you can't get cross domain data).
                preload : true,

                // Scrolling attribute for iframe tag
                scrolling : 'no',

                // Custom CSS styling for iframe wrapping element
                css : {}

            },

            // Custom CSS class for layout
            baseClass : '',

            // Custom CSS class for slide element
            slideClass : '',

            // Base template for layout
            baseTpl	: '<div class="fancybox-container" role="dialog" tabindex="-1">' +
            '<div class="fancybox-bg"></div>' +
            '<div class="fancybox-controls">' +
            '<div class="fancybox-infobar">' +
            '<button data-fancybox-previous class="fancybox-button fancybox-button--left" title="Previous"></button>' +
            '<div class="fancybox-infobar__body">' +
            '<span class="js-fancybox-index"></span>&nbsp;/&nbsp;<span class="js-fancybox-count"></span>' +
            '</div>' +
            '<button data-fancybox-next class="fancybox-button fancybox-button--right" title="Next"></button>' +
            '</div>' +
            '<div class="fancybox-buttons">' +
            '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="Close (Esc)"></button>' +
            '</div>' +
            '</div>' +
            '<div class="fancybox-slider-wrap">' +
            '<div class="fancybox-slider"></div>' +
            '</div>' +
            '<div class="fancybox-caption-wrap"><div class="fancybox-caption"></div></div>' +
            '</div>',

            // Loading indicator template
            spinnerTpl : '<div class="fancybox-loading"></div>',

            // Error message template
            errorTpl : '<div class="fancybox-error"><p>The requested content cannot be loaded. <br /> Please try again later.<p></div>',

            // This will be appended to html content, if "smallBtn" option is not set to false
            closeTpl : '<button data-fancybox-close class="fancybox-close-small"></button>',

            // Container is injected into this element
            parentEl : 'body',

            // Enable gestures (tap, zoom, pan and pinch)
            touch : true,

            // Enable keyboard navigation
            keyboard : true,

            // Try to focus on first focusable element after opening
            focus : true,

            // Close when clicked outside of the content
            closeClickOutside : true,

            // Callbacks
            beforeLoad	 : $.noop,
            afterLoad    : $.noop,
            beforeMove 	 : $.noop,
            afterMove    : $.noop,
            onComplete	 : $.noop,

            onInit       : $.noop,
            beforeClose	 : $.noop,
            afterClose	 : $.noop,
            onActivate   : $.noop,
            onDeactivate : $.noop

        };

        var $W = $(window);
        var $D = $(document);

        var called = 0;

        // Check if an object is a jQuery object and not a native JavaScript object
        // ========================================================================

        var isQuery = function (obj) {
            return obj && obj.hasOwnProperty && obj instanceof $;
        };

        // Handle multiple browsers for requestAnimationFrame()
        // ====================================================

        var requestAFrame = (function() {
            return  window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                function( callback ) {
                    window.setTimeout(callback, 1000 / 60); };
        })();


        // Check if element is inside the viewport by at least 1 pixel
        // ===========================================================

        var isElementInViewport = function( el ) {
            var rect;

            if ( typeof $ === "function" && el instanceof $ ) {
                el = el[0];
            }

            rect = el.getBoundingClientRect();

            return rect.bottom > 0 && rect.right > 0 &&
                rect.left < (window.innerWidth || document.documentElement.clientWidth)  &&
                rect.top < (window.innerHeight || document.documentElement.clientHeight);
        };


        // Class definition
        // ================

        var FancyBox = function( content, opts, index ) {
            var self = this;

            self.opts  = $.extend( true, { index : index }, defaults, opts || {} );
            self.id    = self.opts.id || ++called;
            self.group = [];

            self.currIndex = parseInt( self.opts.index, 10 ) || 0;
            self.prevIndex = null;

            self.prevPos = null;
            self.currPos = 0;

            self.firstRun = null;

            // Create group elements from original item collection
            self.createGroup( content );

            if ( !self.group.length ) {
                return;
            }

            // Save last active element and current scroll position
            self.$lastFocus = $(document.activeElement).blur();

            // Collection of gallery objects
            self.slides = {};

            self.init( content );

        };

        $.extend(FancyBox.prototype, {

            // Create DOM structure
            // ====================

            init : function() {
                var self = this;

                var galleryHasHtml = false;

                var testWidth;
                var $container;

                self.scrollTop  = $D.scrollTop();
                self.scrollLeft = $D.scrollLeft();

                if ( !$.fancybox.getInstance() ) {
                    testWidth = $( 'body' ).width();

                    $( 'html' ).addClass( 'fancybox-enabled' );

                    if ( $.fancybox.isTouch ) {

                        // Ugly workaround for iOS page shifting issue (when inputs get focus)
                        // Do not apply for images, otherwise top/bottom bars will appear
                        $.each( self.group, function( key, item ) {
                            if ( item.type !== 'image' && item.type !== 'iframe' ) {
                                galleryHasHtml = true;
                                return false;
                            }
                        });

                        if ( galleryHasHtml ) {
                            $('body').css({
                                position : 'fixed',
                                width    : testWidth,
                                top      : self.scrollTop * -1
                            });
                        }

                    } else {

                        // Compare page width after adding "overflow:hidden"
                        testWidth = $( 'body' ).width() - testWidth;

                        // Width has changed - compensate missing scrollbars
                        if ( testWidth > 1 ) {
                            $( '<style id="fancybox-noscroll" type="text/css">' ).html( '.compensate-for-scrollbar, .fancybox-enabled body { margin-right: ' + testWidth + 'px; }' ).appendTo( 'head' );
                        }

                    }
                }

                $container = $( self.opts.baseTpl )
                    .attr('id', 'fancybox-container-' + self.id)
                    .data( 'FancyBox', self )
                    .addClass( self.opts.baseClass )
                    .hide()
                    .prependTo( self.opts.parentEl );

                // Create object holding references to jQuery wrapped nodes
                self.$refs = {
                    container   : $container,
                    bg          : $container.find('.fancybox-bg'),
                    controls    : $container.find('.fancybox-controls'),
                    buttons     : $container.find('.fancybox-buttons'),
                    slider_wrap : $container.find('.fancybox-slider-wrap'),
                    slider      : $container.find('.fancybox-slider'),
                    caption     : $container.find('.fancybox-caption')
                };

                self.trigger( 'onInit' );

                // Bring to front and enable events
                self.activate();

                // Try to avoid running multiple times
                if ( self.current ) {
                    return;
                }

                self.jumpTo( self.currIndex );

            },


            // Create array of gally item objects
            // Check if each object has valid type and content
            // ===============================================

            createGroup : function ( content ) {
                var self  = this;
                var items = $.makeArray( content );

                $.each(items, function( i, item ) {
                    var obj  = {},
                        opts = {},
                        data = [],
                        $item,
                        type,
                        src,
                        srcParts;

                    // Step 1 - Make sure we have an object

                    if ( $.isPlainObject( item ) ) {

                        obj  = item;
                        opts = item.opts || {};

                    } else if ( $.type( item ) === 'object' && $( item ).length ) {

                        $item = $( item );
                        data  = $item.data();

                        opts = 'options' in data ? data.options : {};

                        opts = $.type( opts ) === 'object' ? opts : {};

                        obj.type = 'type' in data ? data.type : opts.type;
                        obj.src  = 'src'  in data ? data.src  : ( opts.src || $item.attr( 'href' ) );

                        opts.width   = 'width'   in data ? data.width   : opts.width;
                        opts.height  = 'height'  in data ? data.height  : opts.height;
                        opts.thumb   = 'thumb'   in data ? data.thumb   : opts.thumb;

                        opts.selector = 'selector'  in data ? data.selector  : opts.selector;

                        if ( 'srcset' in data ) {
                            opts.image = { srcset : data.srcset };
                        }

                        opts.$orig = $item;

                    } else {

                        obj = {
                            type    : 'html',
                            content : item + ''
                        };

                    }

                    obj.opts = $.extend( true, {}, self.opts, opts );

                    // Step 2 - Make sure we have supported content type

                    type = obj.type;
                    src  = obj.src || '';

                    if ( !type ) {

                        if ( obj.content ) {
                            type = 'html';

                        } else if ( src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i) ) {
                            type = 'image';

                        } else if ( src.match(/\.(pdf)((\?|#).*)?$/i) ) {
                            type = 'pdf';

                        } else if ( src.charAt(0) === '#' ) {
                            type = 'inline';

                        }

                        obj.type = type;

                    }

                    // Step 3 - Some adjustments

                    obj.index = self.group.length;

                    // Check if $orig and $thumb objects exist
                    if ( obj.opts.$orig && !obj.opts.$orig.length ) {
                        delete obj.opts.$orig;
                    }

                    if ( !obj.opts.$thumb && obj.opts.$orig ) {
                        obj.opts.$thumb = obj.opts.$orig.find( 'img:first' );
                    }

                    if ( obj.opts.$thumb && !obj.opts.$thumb.length ) {
                        delete obj.opts.$thumb;
                    }

                    // Caption is a "special" option, it can be passed as a method
                    if ( $.type( obj.opts.caption ) === 'function' ) {
                        obj.opts.caption = obj.opts.caption.apply( item, [ self, obj ] );

                    } else if ( 'caption' in data ) {
                        obj.opts.caption = data.caption;

                    } else if ( opts.$orig ) {
                        obj.opts.caption = $item.attr( 'title' );
                    }

                    // Make sure we have caption as a string
                    obj.opts.caption = obj.opts.caption === undefined ? '' : obj.opts.caption + '';

                    // Check if url contains selector used to filter the content
                    // Example: "ajax.html #something"
                    if ( type === 'ajax' ) {
                        srcParts = src.split(/\s+/, 2);

                        if ( srcParts.length > 1 ) {
                            obj.src = srcParts.shift();

                            obj.opts.selector = srcParts.shift();
                        }
                    }

                    if ( obj.opts.smallBtn == 'auto' ) {

                        if ( $.inArray( type, ['html', 'inline', 'ajax'] ) > -1 ) {
                            obj.opts.buttons  = false;
                            obj.opts.smallBtn = true;

                        } else {
                            obj.opts.smallBtn = false;
                        }

                    }

                    if ( type === 'pdf' ) {

                        obj.type = 'iframe';

                        obj.opts.closeBtn = true;
                        obj.opts.smallBtn = false;

                        obj.opts.iframe.preload = false;

                    }

                    if ( obj.opts.modal ) {

                        $.extend(true, obj.opts, {
                            infobar		: 0,
                            buttons		: 0,
                            keyboard	: 0,
                            slideShow	: 0,
                            fullScreen	: 0,
                            closeClickOutside	: 0
                        });

                    }

                    self.group.push( obj );

                });

            },


            // Attach an event handler functions for:
            //   - navigation elements
            //   - browser scrolling, resizing;
            //   - focusing
            //   - keyboard
            // =================

            addEvents : function() {
                var self = this;

                self.removeEvents();

                // Make navigation elements clickable

                self.$refs.container.on('click.fb-close', '[data-fancybox-close]', function(e) {
                    e.stopPropagation();
                    e.preventDefault();

                    self.close( e );

                }).on('click.fb-previous', '[data-fancybox-previous]', function(e) {
                    e.stopPropagation();
                    e.preventDefault();

                    self.previous();

                }).on('click.fb-next', '[data-fancybox-next]', function(e) {
                    e.stopPropagation();
                    e.preventDefault();

                    self.next();
                });


                // Handle page scrolling and browser resizing

                $( window ).on('orientationchange.fb resize.fb', function(e) {
                    requestAFrame(function() {

                        if ( e && e.originalEvent && e.originalEvent.type === "resize" ) {
                            self.update();

                        } else {
                            self.$refs.slider_wrap.hide();

                            requestAFrame(function () {
                                self.$refs.slider_wrap.show();

                                self.update();
                            });

                        }

                    });
                });


                // Trap focus

                $D.on('focusin.fb', function(e) {
                    var instance = $.fancybox ? $.fancybox.getInstance() : null;

                    if ( instance && !$( e.target ).hasClass( 'fancybox-container' ) && !$.contains( instance.$refs.container[0], e.target ) ) {
                        e.stopPropagation();

                        instance.focus();

                        // Sometimes page gets scrolled, set it back
                        $W.scrollTop( self.scrollTop ).scrollLeft( self.scrollLeft );
                    }

                });

                // Enable keyboard navigation

                $D.on('keydown.fb', function (e) {
                    var current = self.current,
                        keycode = e.keyCode || e.which;

                    if ( !current || !current.opts.keyboard ) {
                        return;
                    }

                    if ( $(e.target).is('input') || $(e.target).is('textarea') ) {
                        return;
                    }

                    // Backspace and Esc keys
                    if ( keycode === 8 || keycode === 27 ) {
                        e.preventDefault();

                        self.close( e );

                        return;
                    }

                    switch ( keycode ) {

                        case 37: // Left arrow
                        case 38: // Up arrow

                            e.preventDefault();

                            self.previous();

                            break;

                        case 39: // Right arrow
                        case 40: // Down arrow

                            e.preventDefault();

                            self.next();

                            break;

                        case 80: // "P"
                        case 32: // Spacebar

                            e.preventDefault();

                            if ( self.SlideShow ) {
                                e.preventDefault();

                                self.SlideShow.toggle();
                            }

                            break;

                        case 70: // "F"

                            if ( self.FullScreen ) {
                                e.preventDefault();

                                self.FullScreen.toggle();
                            }

                            break;

                        case 71: // "G"

                            if ( self.Thumbs ) {
                                e.preventDefault();

                                self.Thumbs.toggle();
                            }

                            break;
                    }
                });


            },


            // Remove events added by the core
            // ===============================

            removeEvents : function () {

                $W.off( 'scroll.fb resize.fb orientationchange.fb' );
                $D.off( 'keydown.fb focusin.fb click.fb-close' );

                this.$refs.container.off('click.fb-close click.fb-previous click.fb-next');
            },


            // Slide to left
            // ==================

            previous : function( duration ) {
                this.jumpTo( this.currIndex - 1, duration );
            },


            // Slide to right
            // ===================

            next : function( duration ) {
                this.jumpTo( this.currIndex + 1, duration );
            },


            // Display current gallery item, move slider to current position
            // =============================================================

            jumpTo : function ( to, duration ) {
                var self = this,
                    firstRun,
                    index,
                    pos,
                    loop;

                firstRun = self.firstRun = ( self.firstRun === null );

                index = pos = to = parseInt( to, 10 );
                loop  = self.current ? self.current.opts.loop : false;

                if ( self.isAnimating || ( index == self.currIndex && !firstRun ) ) {
                    return;
                }

                if ( self.group.length > 1 && loop ) {

                    index = index % self.group.length;
                    index = index < 0 ? self.group.length + index : index;

                    // Calculate closest position of upcoming item from the current one
                    if ( self.group.length == 2 ) {
                        pos = to - self.currIndex + self.currPos;

                    } else {
                        pos = index - self.currIndex + self.currPos;

                        if ( Math.abs( self.currPos - ( pos + self.group.length ) ) < Math.abs( self.currPos - pos ) ) {
                            pos = pos + self.group.length;

                        } else if ( Math.abs( self.currPos - ( pos - self.group.length ) ) < Math.abs( self.currPos - pos ) ) {
                            pos = pos - self.group.length;

                        }
                    }

                } else if ( !self.group[ index ] ) {
                    self.update( false, false, duration );

                    return;
                }

                if ( self.current ) {
                    self.current.$slide.removeClass('fancybox-slide--current fancybox-slide--complete');

                    self.updateSlide( self.current, true );
                }

                self.prevIndex = self.currIndex;
                self.prevPos   = self.currPos;

                self.currIndex = index;
                self.currPos   = pos;

                // Create slides

                self.current = self.createSlide( pos );

                if ( self.group.length > 1 ) {

                    if ( self.opts.loop || pos - 1 >= 0 ) {
                        self.createSlide( pos - 1 );
                    }

                    if ( self.opts.loop || pos + 1 < self.group.length ) {
                        self.createSlide( pos + 1 );
                    }
                }

                self.current.isMoved    = false;
                self.current.isComplete = false;

                duration = parseInt( duration === undefined ? self.current.opts.speed * 1.5 : duration, 10 );

                // Move slider to the next position
                // Note: the content might still be loading
                self.trigger( 'beforeMove' );

                self.updateControls();

                if ( firstRun ) {
                    self.current.$slide.addClass('fancybox-slide--current');

                    self.$refs.container.show();

                    requestAFrame(function() {
                        self.$refs.bg.css('transition-duration', self.current.opts.speed + 'ms');

                        self.$refs.container.addClass( 'fancybox-container--ready' );
                    });
                }

                // Set position immediately on first opening
                self.update( true, false, firstRun ? 0 : duration, function() {
                    self.afterMove();
                });

                self.loadSlide( self.current );

                if ( !( firstRun && self.current.$ghost ) ) {
                    self.preload();
                }

            },


            // Create new "slide" element
            // These are gallery items  that are actually added to DOM
            // =======================================================

            createSlide : function( pos ) {

                var self = this;
                var $slide;
                var index;
                var found;

                index = pos % self.group.length;
                index = index < 0 ? self.group.length + index : index;

                if ( !self.slides[ pos ] && self.group[ index ] ) {

                    // If we are looping and slide with that index already exists, then reuse it
                    if ( self.opts.loop && self.group.length > 2 ) {
                        for (var key in self.slides) {
                            if ( self.slides[ key ].index === index ) {
                                found = self.slides[ key ];
                                found.pos = pos;

                                self.slides[ pos ] = found;

                                delete self.slides[ key ];

                                self.updateSlide( found );

                                return found;
                            }
                        }
                    }

                    $slide = $('<div class="fancybox-slide"></div>').appendTo( self.$refs.slider );

                    self.slides[ pos ] = $.extend( true, {}, self.group[ index ], {
                        pos      : pos,
                        $slide   : $slide,
                        isMoved  : false,
                        isLoaded : false
                    });

                }

                return self.slides[ pos ];

            },

            zoomInOut : function( type, duration, callback ) {

                var self     = this;
                var current  = self.current;
                var $what    = current.$placeholder;
                var opacity  = current.opts.opacity;
                var $thumb   = current.opts.$thumb;
                var thumbPos = $thumb ? $thumb.offset() : 0;
                var slidePos = current.$slide.offset();
                var props;
                var start;
                var end;

                if ( !$what || !current.isMoved || !thumbPos || !isElementInViewport( $thumb ) ) {
                    return false;
                }

                if ( type === 'In' && !self.firstRun ) {
                    return false;
                }

                $.fancybox.stop( $what );

                self.isAnimating = true;

                props = {
                    top    : thumbPos.top  - slidePos.top  + parseFloat( $thumb.css( "border-top-width" ) || 0 ),
                    left   : thumbPos.left - slidePos.left + parseFloat( $thumb.css( "border-left-width" ) || 0 ),
                    width  : $thumb.width(),
                    height : $thumb.height(),
                    scaleX : 1,
                    scaleY : 1
                };

                // Check if we need to animate opacity
                if ( opacity == 'auto' ) {
                    opacity = Math.abs( current.width / current.height - props.width / props.height ) > 0.1;
                }

                if ( type === 'In' ) {
                    start = props;
                    end   = self.getFitPos( current );

                    end.scaleX = end.width  / start.width;
                    end.scaleY = end.height / start.height;

                    if ( opacity ) {
                        start.opacity = 0.1;
                        end.opacity   = 1;
                    }

                } else {

                    start = $.fancybox.getTranslate( $what );
                    end   = props;

                    // Switch to thumbnail image to improve animation performance
                    if ( current.$ghost ) {
                        current.$ghost.show();

                        if ( current.$image ) {
                            current.$image.remove();
                        }
                    }

                    start.scaleX = start.width  / end.width;
                    start.scaleY = start.height / end.height;

                    start.width  = end.width;
                    start.height = end.height;

                    if ( opacity ) {
                        end.opacity = 0;
                    }

                }

                self.updateCursor( end.width, end.height );

                // There is no need to animate width/height properties
                delete end.width;
                delete end.height;

                $.fancybox.setTranslate( $what, start );

                $what.show();

                self.trigger( 'beforeZoom' + type );

                $what.css( 'transition', 'all ' + duration + 'ms' );

                $.fancybox.setTranslate( $what, end );

                setTimeout(function() {
                    var reset;

                    $what.css( 'transition', 'none' );

                    reset = $.fancybox.getTranslate( $what );

                    reset.scaleX = 1;
                    reset.scaleY = 1;

                    // Reset scalex/scaleY values; this helps for perfomance
                    $.fancybox.setTranslate( $what, reset );

                    self.trigger( 'afterZoom' + type );

                    callback.apply( self );

                    self.isAnimating = false;

                }, duration);


                return true;

            },

            // Check if image dimensions exceed parent element
            // ===============================================

            canPan : function() {

                var self = this;

                var current = self.current;
                var $what   = current.$placeholder;

                var rez = false;

                if ( $what ) {
                    rez = self.getFitPos( current );
                    rez = Math.abs( $what.width() - rez.width ) > 1  || Math.abs( $what.height() - rez.height ) > 1;

                }

                return rez;

            },


            // Check if current image dimensions are smaller than actual
            // =========================================================

            isScaledDown : function() {

                var self = this;

                var current = self.current;
                var $what   = current.$placeholder;

                var rez = false;

                if ( $what ) {
                    rez = $.fancybox.getTranslate( $what );
                    rez = rez.width < current.width || rez.height < current.height;
                }

                return rez;

            },


            // Scale image to the actual size of the image
            // ===========================================

            scaleToActual : function( x, y, duration ) {

                var self = this;

                var current = self.current;
                var $what   = current.$placeholder;

                var imgPos, posX, posY, scaleX, scaleY;

                var canvasWidth  = parseInt( current.$slide.width(), 10 );
                var canvasHeight = parseInt( current.$slide.height(), 10 );

                var newImgWidth  = current.width;
                var newImgHeight = current.height;

                if ( !$what ) {
                    return;
                }

                self.isAnimating = true;

                x = x === undefined ? canvasWidth  * 0.5  : x;
                y = y === undefined ? canvasHeight * 0.5  : y;

                imgPos = $.fancybox.getTranslate( $what );

                scaleX  = newImgWidth  / imgPos.width;
                scaleY  = newImgHeight / imgPos.height;

                // Get center position for original image
                posX = ( canvasWidth * 0.5  - newImgWidth * 0.5 );
                posY = ( canvasHeight * 0.5 - newImgHeight * 0.5 );

                // Make sure image does not move away from edges

                if ( newImgWidth > canvasWidth ) {
                    posX = imgPos.left * scaleX - ( ( x * scaleX ) - x );

                    if ( posX > 0 ) {
                        posX = 0;
                    }

                    if ( posX <  canvasWidth - newImgWidth ) {
                        posX = canvasWidth - newImgWidth;
                    }
                }

                if ( newImgHeight > canvasHeight) {
                    posY = imgPos.top  * scaleY - ( ( y * scaleY ) - y );

                    if ( posY > 0 ) {
                        posY = 0;
                    }

                    if ( posY <  canvasHeight - newImgHeight ) {
                        posY = canvasHeight - newImgHeight;
                    }
                }

                self.updateCursor( newImgWidth, newImgHeight );

                $.fancybox.animate( $what, null, {
                    top    : posY,
                    left   : posX,
                    scaleX : scaleX,
                    scaleY : scaleY
                }, duration || current.opts.speed, function() {
                    self.isAnimating = false;
                });

            },


            // Scale image to fit inside parent element
            // ========================================

            scaleToFit : function( duration ) {

                var self = this;

                var current = self.current;
                var $what   = current.$placeholder;
                var end;

                if ( !$what ) {
                    return;
                }

                self.isAnimating = true;

                end = self.getFitPos( current );

                self.updateCursor( end.width, end.height );

                $.fancybox.animate( $what, null, {
                    top    : end.top,
                    left   : end.left,
                    scaleX : end.width  / $what.width(),
                    scaleY : end.height / $what.height()
                }, duration || current.opts.speed, function() {
                    self.isAnimating = false;
                });

            },

            // Calculate image size to fit inside viewport
            // ===========================================

            getFitPos : function( slide ) {
                var $what = slide.$placeholder || slide.$content;

                var imgWidth  = slide.width;
                var imgHeight = slide.height;

                var margin = slide.opts.margin;

                var canvasWidth, canvasHeight, minRatio, top, left, width, height;

                if ( !$what || !$what.length || ( !imgWidth && !imgHeight) ) {
                    return false;
                }

                // Convert "margin to CSS style: [ top, right, bottom, left ]
                if ( $.type( margin ) === "number" ) {
                    margin = [ margin, margin ];
                }

                if ( margin.length == 2 ) {
                    margin = [ margin[0], margin[1], margin[0], margin[1] ];
                }

                if ( $W.width() < 800 ) {
                    margin = [0, 0, 0, 0];
                }

                canvasWidth  = parseInt( slide.$slide.width(), 10 )  - ( margin[ 1 ] + margin[ 3 ] );
                canvasHeight = parseInt( slide.$slide.height(), 10 ) - ( margin[ 0 ] + margin[ 2 ] );

                minRatio = Math.min(1, canvasWidth / imgWidth, canvasHeight / imgHeight );

                // Use floor rounding to make sure it really fits

                width  = Math.floor( minRatio * imgWidth );
                height = Math.floor( minRatio * imgHeight );

                top  = Math.floor( ( canvasHeight - height ) * 0.5 ) + margin[ 0 ];
                left = Math.floor( ( canvasWidth  - width )  * 0.5 ) + margin[ 3 ];

                return {
                    top    : top,
                    left   : left,
                    width  : width,
                    height : height
                };

            },

            // Move slider to current position
            // Update all slides (and their content)
            // =====================================

            update : function( andSlides, andContent, duration, callback ) {

                var self = this;
                var leftValue;

                if ( self.isAnimating === true || !self.current ) {
                    return;
                }

                leftValue = ( self.current.pos * Math.floor( self.current.$slide.width() ) * -1 ) - ( self.current.pos * self.current.opts.gutter );
                duration  = parseInt( duration, 10 ) || 0;

                $.fancybox.stop( self.$refs.slider );

                if ( andSlides === false ) {
                    self.updateSlide( self.current, andContent );

                } else {

                    $.each( self.slides, function( key, slide ) {
                        self.updateSlide( slide, andContent );
                    });

                }

                if ( duration ) {

                    $.fancybox.animate( self.$refs.slider, null, {
                        top  : 0,
                        left : leftValue
                    }, duration, function() {
                        self.current.isMoved = true;

                        if ( $.type( callback ) === 'function' ) {
                            callback.apply( self );
                        }

                    });

                } else {

                    $.fancybox.setTranslate( self.$refs.slider, { top : 0, left : leftValue } );

                    self.current.isMoved = true;

                    if ( $.type( callback ) === 'function' ) {
                        callback.apply( self );
                    }

                }

            },


            // Update slide position and scale content to fit
            // ==============================================

            updateSlide : function( slide, andContent ) {

                var self  = this;
                var $what = slide.$placeholder;
                var leftPos;

                slide = slide || self.current;

                if ( !slide || self.isClosing ) {
                    return;
                }

                leftPos = ( slide.pos * Math.floor( slide.$slide.width() )  ) + ( slide.pos * slide.opts.gutter);

                if ( leftPos !== slide.leftPos ) {
                    $.fancybox.setTranslate( slide.$slide, { top: 0, left : leftPos } );

                    slide.leftPos = leftPos;
                }

                if ( andContent !== false && $what ) {
                    $.fancybox.setTranslate( $what, self.getFitPos( slide ) );

                    if ( slide.pos === self.currPos ) {
                        self.updateCursor();
                    }
                }

                slide.$slide.trigger( 'refresh' );

                self.trigger( 'onUpdate', slide );
            },

            // Update cursor style depending if content can be zoomed
            // ======================================================

            updateCursor : function( nextWidth, nextHeight ) {

                var self = this;
                var canScale;

                var $container = self.$refs.container.removeClass('fancybox-controls--canzoomIn fancybox-controls--canzoomOut fancybox-controls--canGrab');

                if ( self.isClosing || !self.opts.touch ) {
                    return;
                }

                if ( nextWidth !== undefined && nextHeight !== undefined ) {
                    canScale = nextWidth < self.current.width && nextHeight < self.current.height;

                } else {
                    canScale = self.isScaledDown();
                }

                if ( canScale ) {
                    $container.addClass('fancybox-controls--canzoomIn');

                } else if ( self.group.length < 2 ) {
                    $container.addClass('fancybox-controls--canzoomOut');

                } else {
                    $container.addClass('fancybox-controls--canGrab');
                }

            },

            // Load content into the slide
            // ===========================

            loadSlide : function( slide ) {

                var self = this, type, $slide;
                var ajaxLoad;

                if ( !slide || slide.isLoaded || slide.isLoading ) {
                    return;
                }

                slide.isLoading = true;

                self.trigger( 'beforeLoad', slide );

                type   = slide.type;
                $slide = slide.$slide;

                $slide
                    .off( 'refresh' )
                    .trigger( 'onReset' )
                    .addClass( 'fancybox-slide--' + ( type || 'unknown' ) )
                    .addClass( slide.opts.slideClass );

                // Create content depending on the type

                switch ( type ) {

                    case 'image':

                        self.setImage( slide );

                        break;

                    case 'iframe':

                        self.setIframe( slide );

                        break;

                    case 'html':

                        self.setContent( slide, slide.content );

                        break;

                    case 'inline':

                        if ( $( slide.src ).length ) {
                            self.setContent( slide, $( slide.src ) );

                        } else {
                            self.setError( slide );
                        }

                        break;

                    case 'ajax':

                        self.showLoading( slide );

                        ajaxLoad = $.ajax( $.extend( {}, slide.opts.ajax.settings, {

                            url: slide.src,

                            success: function ( data, textStatus ) {

                                if ( textStatus === 'success' ) {
                                    self.setContent( slide, data );
                                }

                            },

                            error: function ( jqXHR, textStatus ) {

                                if ( jqXHR && textStatus !== 'abort' ) {
                                    self.setError( slide );
                                }

                            }

                        }));

                        $slide.one( 'onReset', function () {
                            ajaxLoad.abort();
                        });

                        break;

                    default:

                        self.setError( slide );

                        break;

                }

                return true;

            },


            // Use thumbnail image, if possible
            // ================================

            setImage : function( slide ) {

                var self   = this;
                var srcset = slide.opts.image.srcset;

                var found, temp, pxRatio, windowWidth;

                if ( slide.isLoaded && !slide.hasError ) {
                    self.afterLoad( slide );

                    return;
                }

                // If we have "srcset", then we need to find matching "src" value.
                // This is necessary, because when you set an src attribute, the browser will preload the image
                // before any javascript or even CSS is applied.
                if ( srcset ) {
                    pxRatio     = window.devicePixelRatio || 1;
                    windowWidth = window.innerWidth  * pxRatio;

                    temp = srcset.split(',').map(function (el) {
                        var ret = {};

                        el.trim().split(/\s+/).forEach(function (el, i) {
                            var value = parseInt(el.substring(0, el.length - 1), 10);

                            if ( i === 0 ) {
                                return (ret.url = el);
                            }

                            if ( value ) {
                                ret.value   = value;
                                ret.postfix = el[el.length - 1];
                            }

                        });

                        return ret;
                    });

                    // Sort by value
                    temp.sort(function (a, b) {
                        return a.value - b.value;
                    });

                    // Ok, now we have an array of all srcset values
                    for ( var j = 0; j < temp.length; j++ ) {
                        var el = temp[ j ];

                        if ( ( el.postfix === 'w' && el.value >= windowWidth ) || ( el.postfix === 'x' && el.value >= pxRatio ) ) {
                            found = el;
                            break;
                        }
                    }

                    // If not found, take the last one
                    if ( !found && temp.length ) {
                        found = temp[ temp.length - 1 ];
                    }

                    if ( found ) {
                        slide.src = found.url;

                        // If we have default width/height values, we can calculate height for matching source
                        if ( slide.width && slide.height && found.postfix == 'w' ) {
                            slide.height = ( slide.width / slide.height ) * found.value;
                            slide.width  = found.value;
                        }
                    }
                }

                slide.$placeholder = $('<div class="fancybox-placeholder"></div>')
                    .hide()
                    .appendTo( slide.$slide );

                if ( slide.opts.preload !== false && slide.opts.width && slide.opts.height && ( slide.opts.thumb || slide.opts.$thumb ) ) {

                    slide.width  = slide.opts.width;
                    slide.height = slide.opts.height;

                    slide.$ghost = $('<img />')
                        .one('load error', function() {

                            if ( self.isClosing ) {
                                return;
                            }

                            // Start preloading full size image
                            $('<img/>')[0].src = slide.src;

                            // zoomIn or just show
                            self.revealImage( slide, function() {

                                self.setBigImage( slide );

                                if ( self.firstRun && slide.index === self.currIndex ) {
                                    self.preload();
                                }
                            });

                        })
                        .addClass( 'fancybox-image' )
                        .appendTo( slide.$placeholder )
                        .attr( 'src', slide.opts.thumb || slide.opts.$thumb.attr( 'src' ) );

                } else {

                    self.setBigImage( slide );

                }

            },


            // Create full-size image
            // ======================

            setBigImage : function ( slide ) {
                var self = this;
                var $img = $('<img />');

                slide.$image = $img
                    .one('error', function() {

                        self.setError( slide );

                    })
                    .one('load', function() {

                        // Clear timeout that checks if loading icon needs to be displayed
                        clearTimeout( slide.timouts );

                        slide.timouts = null;

                        if ( self.isClosing ) {
                            return;
                        }

                        slide.width  = this.naturalWidth;
                        slide.height = this.naturalHeight;

                        if ( slide.opts.image.srcset ) {
                            $img.attr('sizes', '100vw').attr('srcset', slide.opts.image.srcset);
                        }

                        self.afterLoad( slide );

                        if ( slide.$ghost ) {
                            slide.timouts = setTimeout(function() {
                                slide.$ghost.hide();

                            }, 350);
                        }

                    })
                    .addClass('fancybox-image')
                    .attr('src', slide.src)
                    .appendTo( slide.$placeholder );

                if ( $img[0].complete ) {
                    $img.trigger('load');

                } else if( $img[0].error ) {
                    $img.trigger('error');

                } else {

                    slide.timouts = setTimeout(function() {
                        if ( !$img[0].complete && !slide.hasError ) {
                            self.showLoading( slide );
                        }

                    }, 150);

                }

                if ( slide.opts.image.protect ) {
                    $('<div class="fancybox-spaceball"></div>').appendTo( slide.$placeholder ).on('contextmenu.fb',function(e){
                        if ( e.button == 2 ) {
                            e.preventDefault();
                        }

                        return true;
                    });
                }

            },

            // Simply show image holder without animation
            // It has been hidden initially to avoid flickering
            // ================================================

            revealImage : function( slide, callback ) {

                var self = this;

                callback = callback || $.noop;

                if ( slide.type !== 'image' || slide.hasError || slide.isRevealed === true ) {

                    callback.apply( self );

                    return;
                }

                slide.isRevealed = true;

                if ( !( slide.pos === self.currPos && self.zoomInOut( 'In', slide.opts.speed, callback ) ) ) {

                    if ( slide.$ghost && !slide.isLoaded ) {
                        self.updateSlide( slide, true );
                    }

                    if ( slide.pos === self.currPos ) {
                        $.fancybox.animate( slide.$placeholder, { opacity: 0 }, { opacity: 1 }, 300, callback );

                    } else {
                        slide.$placeholder.show();
                    }

                    callback.apply( self );

                }

            },

            // Create iframe wrapper, iframe and bindings
            // ==========================================

            setIframe : function( slide ) {
                var self	= this,
                    opts    = slide.opts.iframe,
                    $slide	= slide.$slide,
                    $iframe;

                slide.$content = $('<div class="fancybox-content"></div>')
                    .css( opts.css )
                    .appendTo( $slide );

                $iframe = $( opts.tpl.replace(/\{rnd\}/g, new Date().getTime()) )
                    .attr('scrolling', $.fancybox.isTouch ? 'auto' : opts.scrolling)
                    .appendTo( slide.$content );

                if ( opts.preload ) {
                    slide.$content.addClass( 'fancybox-tmp' );

                    self.showLoading( slide );

                    // Unfortunately, it is not always possible to determine if iframe is successfully loaded
                    // (due to browser security policy)

                    $iframe.on('load.fb error.fb', function(e) {
                        this.isReady = 1;

                        slide.$slide.trigger( 'refresh' );

                        self.afterLoad( slide );

                    });

                    // Recalculate iframe content size

                    $slide.on('refresh.fb', function() {
                        var $wrap = slide.$content,
                            $contents,
                            $body,
                            scrollWidth,
                            frameWidth,
                            frameHeight;

                        if ( $iframe[0].isReady !== 1 ) {
                            return;
                        }

                        // Check if content is accessible,
                        // it will fail if frame is not with the same origin

                        try {
                            $contents = $iframe.contents();
                            $body     = $contents.find('body');

                        } catch (ignore) {}

                        // Calculate dimensions for the wrapper

                        if ( $body && $body.length && !( opts.css.width !== undefined && opts.css.height !== undefined ) ) {

                            scrollWidth = $iframe[0].contentWindow.document.documentElement.scrollWidth;

                            frameWidth	= Math.ceil( $body.outerWidth(true) + ( $wrap.width() - scrollWidth ) );
                            frameHeight	= Math.ceil( $body.outerHeight(true) );

                            // Resize wrapper to fit iframe content

                            $wrap.css({
                                'width'  : opts.css.width  === undefined ? frameWidth  + ( $wrap.outerWidth()  - $wrap.innerWidth() )  : opts.css.width,
                                'height' : opts.css.height === undefined ? frameHeight + ( $wrap.outerHeight() - $wrap.innerHeight() ) : opts.css.height
                            });

                        }

                        $wrap.removeClass( 'fancybox-tmp' );

                    });

                } else {

                    this.afterLoad( slide );

                }

                $iframe.attr( 'src', slide.src );

                if ( slide.opts.smallBtn ) {
                    slide.$content.prepend( slide.opts.closeTpl );
                }

                // Remove iframe if closing or changing gallery item

                $slide.one('onReset', function () {

                    // This helps IE not to throw errors when closing

                    try {

                        $(this).find('iframe').hide().attr('src', '//about:blank');

                    } catch (ignore) {}

                    $(this).empty();

                    slide.isLoaded = false;

                });

            },


            // Wrap and append content to the slide
            // ======================================

            setContent : function ( slide, content ) {

                var self = this;

                if ( self.isClosing ) {
                    return;
                }

                self.hideLoading( slide );

                slide.$slide.empty();

                if ( isQuery( content ) && content.parent().length ) {

                    // If it is a jQuery object, then it will be moved to the box.
                    // The placeholder is created so we will know where to put it back.
                    // If user is navigating gallery fast, then the content might be already moved to the box

                    if ( content.data( 'placeholder' ) ) {
                        content.parents('.fancybox-slide').trigger( 'onReset' );
                    }

                    content.data({'placeholder' : $('<div></div>' ).hide().insertAfter( content ) }).css('display', 'inline-block');

                } else {

                    if ( $.type( content ) === 'string' ) {

                        content = $('<div>').append( content ).contents();

                        if ( content[0].nodeType === 3 ) {
                            content = $('<div>').html( content );
                        }

                    }

                    if ( slide.opts.selector ) {
                        content = $('<div>').html( content ).find( slide.opts.selector );
                    }

                }

                slide.$slide.one('onReset', function () {
                    var placeholder = isQuery( content ) ? content.data('placeholder') : 0;

                    if ( placeholder ) {
                        content.hide().replaceAll( placeholder );

                        content.data( 'placeholder', null );
                    }

                    if ( !slide.hasError ) {
                        $(this).empty();

                        slide.isLoaded = false;
                    }

                });

                slide.$content = $( content ).appendTo( slide.$slide );

                if ( slide.opts.smallBtn === true ) {
                    slide.$content.find( '.fancybox-close-small' ).remove().end().eq(0).append( slide.opts.closeTpl );
                }

                this.afterLoad( slide );

            },

            // Display error message
            // =====================

            setError : function ( slide ) {

                slide.hasError = true;

                this.setContent( slide, slide.opts.errorTpl );

            },


            showLoading : function( slide ) {
                var self = this;

                slide = slide || self.current;

                if ( slide && !slide.$spinner ) {
                    slide.$spinner = $( self.opts.spinnerTpl ).appendTo( slide.$slide );
                }

            },

            hideLoading : function( slide ) {

                var self = this;

                slide = slide || self.current;

                if ( slide && slide.$spinner ) {
                    slide.$spinner.remove();

                    delete slide.$spinner;
                }

            },

            afterMove : function() {

                var self    = this;
                var current = self.current;
                var slides  = {};

                if ( !current ) {
                    return;
                }

                current.$slide.siblings().trigger( 'onReset' );

                // Remove unnecessary slides
                $.each( self.slides, function( key, slide ) {

                    if (  slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1 ) {
                        slides[ slide.pos ] = slide;

                    } else if ( slide ) {
                        slide.$slide.remove();
                    }

                });

                self.slides = slides;

                self.trigger( 'afterMove' );

                if ( current.isLoaded ) {
                    self.complete();
                }

            },

            // Adjustments after slide has been loaded
            // =======================================

            afterLoad : function( slide ) {

                var self = this;

                if ( self.isClosing ) {
                    return;
                }

                slide.isLoading = false;
                slide.isLoaded  = true;

                self.trigger( 'afterLoad', slide );

                self.hideLoading( slide );

                // Resize content to fit inside slide
                // Skip if slide has an $ghost element, because then it has been already processed
                if ( !slide.$ghost ) {
                    self.updateSlide( slide, true );
                }

                if ( slide.index === self.currIndex && slide.isMoved ) {
                    self.complete();

                } else if ( !slide.$ghost ) {
                    self.revealImage( slide );
                }

            },


            // Final adjustments after current gallery item is moved to position
            // and it`s content is loaded
            // ==================================================================

            complete : function() {

                var self = this;

                var current = self.current;

                self.revealImage( current, function() {
                    current.isComplete = true;

                    current.$slide.addClass('fancybox-slide--complete');

                    self.updateCursor();

                    self.trigger( 'onComplete' );

                    // Try to focus on the first focusable element, skip for images and iframes
                    if ( current.opts.focus && !( current.type === 'image' || current.type === 'iframe' ) ) {
                        self.focus();
                    }

                });

            },


            // Preload next and previous slides
            // ================================

            preload : function() {
                var self = this;
                var next, prev;

                if ( self.group.length < 2 ) {
                    return;
                }

                next  = self.slides[ self.currPos + 1 ];
                prev  = self.slides[ self.currPos - 1 ];

                if ( next && next.type === 'image' ) {
                    self.loadSlide( next );
                }

                if ( prev && prev.type === 'image' ) {
                    self.loadSlide( prev );
                }

            },


            // Try to find and focus on the first focusable element
            // ====================================================

            focus : function() {
                var current = this.current;
                var $el;

                $el = current && current.isComplete ? current.$slide.find('button,:input,[tabindex],a:not(".disabled")').filter(':visible:first') : null;

                if ( !$el || !$el.length ) {
                    $el = this.$refs.container;
                }

                $el.focus();

                // Scroll position of wrapper element sometimes changes after focusing (IE)
                this.$refs.slider_wrap.scrollLeft(0);

                // And the same goes for slide element
                if ( current ) {
                    current.$slide.scrollTop(0);
                }

            },


            // Activates current instance - brings container to the front and enables keyboard,
            // notifies other instances about deactivating
            // =================================================================================

            activate : function () {
                var self = this;

                // Deactivate all instances

                $( '.fancybox-container' ).each(function () {
                    var instance = $(this).data( 'FancyBox' );

                    // Skip self and closing instances

                    if (instance && instance.uid !== self.uid && !instance.isClosing) {
                        instance.trigger( 'onDeactivate' );
                    }

                });

                if ( self.current ) {

                    if ( self.$refs.container.index() > 0 ) {
                        self.$refs.container.prependTo( document.body );
                    }

                    self.updateControls();
                }

                self.trigger( 'onActivate' );

                self.addEvents();

            },


            // Start closing procedure
            // This will start "zoom-out" animation if needed and clean everything up afterwards
            // =================================================================================

            close : function( e ) {

                var self     = this;
                var current  = self.current;
                var duration = current.opts.speed;

                var done = $.proxy(function() {

                    self.cleanUp( e );  // Now "this" is again our instance

                }, this);

                if ( self.isAnimating || self.isClosing ) {
                    return false;
                }

                // If beforeClose callback prevents closing, make sure content is centered
                if ( self.trigger( 'beforeClose', e ) === false ) {
                    $.fancybox.stop( self.$refs.slider );

                    requestAFrame(function() {
                        self.update( true, true, 150 );
                    });

                    return;
                }

                self.isClosing = true;

                if ( current.timouts ) {
                    clearTimeout( current.timouts );
                }

                if ( e !== true) {
                    $.fancybox.stop( self.$refs.slider );
                }

                self.$refs.container
                    .removeClass('fancybox-container--active')
                    .addClass('fancybox-container--closing');

                current.$slide
                    .removeClass('fancybox-slide--complete')
                    .siblings()
                    .remove();


                if ( !current.isMoved ) {
                    current.$slide.css('overflow', 'visible');
                }

                // Remove all events
                // If there are multiple instances, they will be set again by "activate" method

                self.removeEvents();

                // Clean up

                self.hideLoading( current );

                self.hideControls();

                self.updateCursor();

                self.$refs.bg.css('transition-duration', duration + 'ms');

                this.$refs.container.removeClass( 'fancybox-container--ready' );

                if ( e === true ) {
                    setTimeout( done, duration );

                } else if ( !self.zoomInOut( 'Out', duration, done ) ) {
                    $.fancybox.animate( self.$refs.container, null, { opacity : 0 }, duration, "easeInSine", done );
                }

            },


            // Final adjustments after removing the instance
            // =============================================

            cleanUp : function( e ) {
                var self = this,
                    instance;

                self.$refs.slider.children().trigger( 'onReset' );

                self.$refs.container.empty().remove();

                self.trigger( 'afterClose', e );

                self.current = null;

                // Check if there are other instances
                instance = $.fancybox.getInstance();

                if ( instance ) {
                    instance.activate();

                } else {

                    $( 'html' ).removeClass( 'fancybox-enabled' );
                    $( 'body' ).removeAttr( 'style' );

                    $W.scrollTop( self.scrollTop ).scrollLeft( self.scrollLeft );

                    $( '#fancybox-noscroll' ).remove();

                }

                // Place back focus
                if ( self.$lastFocus ) {
                    self.$lastFocus.focus();
                }

            },


            // Call callback and trigger an event
            // ==================================

            trigger : function( name, slide ) {
                var args  = Array.prototype.slice.call(arguments, 1),
                    self  = this,
                    obj   = slide && slide.opts ? slide : self.current,
                    rez;

                if ( obj ) {
                    args.unshift( obj );

                } else {
                    obj = self;
                }

                args.unshift( self );

                if ( $.isFunction( obj.opts[ name ] ) ) {
                    rez = obj.opts[ name ].apply( obj, args );
                }

                if ( rez === false ) {
                    return rez;
                }

                if ( name === 'afterClose' ) {
                    $( document ).trigger( name + '.fb', args );

                } else {
                    self.$refs.container.trigger( name + '.fb', args );
                }

            },


            // Toggle toolbar and caption
            // ==========================

            toggleControls : function( force ) {

                if ( this.isHiddenControls ) {
                    this.updateControls( force );

                } else {
                    this.hideControls();
                }


            },


            // Hide toolbar and caption
            // ========================

            hideControls : function () {

                this.isHiddenControls = true;

                this.$refs.container.removeClass('fancybox-show-controls');

                this.$refs.container.removeClass('fancybox-show-caption');

            },


            // Update infobar values, navigation button states and reveal caption
            // ==================================================================

            updateControls : function ( force ) {

                var self = this;

                var $container = self.$refs.container;
                var $caption   = self.$refs.caption;

                // Toggle infobar and buttons

                var current  = self.current;
                var index    = current.index;
                var opts     = current.opts;
                var caption  = opts.caption;

                if ( this.isHiddenControls && force !== true ) {
                    return;
                }

                this.isHiddenControls = false;

                $container
                    .addClass('fancybox-show-controls')
                    .toggleClass('fancybox-show-infobar', !!opts.infobar && self.group.length > 1)
                    .toggleClass('fancybox-show-buttons', !!opts.buttons )
                    .toggleClass('fancybox-is-modal',     !!opts.modal );

                $('.fancybox-button--left',  $container).toggleClass( 'fancybox-button--disabled', (!opts.loop && index <= 0 ) );
                $('.fancybox-button--right', $container).toggleClass( 'fancybox-button--disabled', (!opts.loop && index >= self.group.length - 1) );

                $('.fancybox-button--play',  $container).toggle( !!( opts.slideShow && self.group.length > 1) );
                $('.fancybox-button--close', $container).toggle( !!opts.closeBtn );

                // Update infobar values

                $('.js-fancybox-count', $container).html( self.group.length );
                $('.js-fancybox-index', $container).html( index + 1 );

                // Recalculate content dimensions
                current.$slide.trigger( 'refresh' );

                // Reveal or create new caption
                if ( $caption ) {
                    $caption.empty();
                }

                if ( caption && caption.length ) {
                    $caption.html( caption );

                    this.$refs.container.addClass( 'fancybox-show-caption ');

                    self.$caption = $caption;

                } else {
                    this.$refs.container.removeClass( 'fancybox-show-caption' );
                }

            }

        });


        $.fancybox = {

            version  : "3.0.47",
            defaults : defaults,


            // Get current instance and execute a command.
            //
            // Examples of usage:
            //
            //   $instance = $.fancybox.getInstance();
            //   $.fancybox.getInstance().jumpTo( 1 );
            //   $.fancybox.getInstance( 'jumpTo', 1 );
            //   $.fancybox.getInstance( function() {
            //       console.info( this.currIndex );
            //   });
            // ======================================================

            getInstance : function ( command ) {
                var instance = $('.fancybox-container:not(".fancybox-container--closing"):first').data( 'FancyBox' );
                var args     = Array.prototype.slice.call(arguments, 1);

                if ( instance instanceof FancyBox ) {

                    if ( $.type( command ) === 'string' ) {
                        instance[ command ].apply( instance, args );

                    } else if ( $.type( command ) === 'function' ) {
                        command.apply( instance, args );

                    }

                    return instance;
                }

                return false;

            },


            // Create new instance
            // ===================

            open : function ( items, opts, index ) {
                return new FancyBox( items, opts, index );
            },


            // Close current or all instances
            // ==============================

            close : function ( all ) {
                var instance = this.getInstance();

                if ( instance ) {
                    instance.close();

                    // Try to find and close next instance

                    if ( all === true ) {
                        this.close();
                    }
                }

            },


            // Test for the existence of touch events in the browser
            // Limit to mobile devices
            // ====================================================

            isTouch : document.createTouch !== undefined && /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent),


            // Detect if 'translate3d' support is available
            // ============================================

            use3d : (function() {
                var div = document.createElement('div');

                return window.getComputedStyle( div ).getPropertyValue('transform') && !(document.documentMode && document.documentMode <= 11);
            }()),


            // Helper function to get current visual state of an element
            // returns array[ top, left, horizontal-scale, vertical-scale, opacity ]
            // =====================================================================

            getTranslate : function( $el ) {
                var position, matrix;

                if ( !$el || !$el.length ) {
                    return false;
                }

                position = $el.get( 0 ).getBoundingClientRect();
                matrix   = $el.eq( 0 ).css('transform');

                if ( matrix && matrix.indexOf( 'matrix' ) !== -1 ) {
                    matrix = matrix.split('(')[1];
                    matrix = matrix.split(')')[0];
                    matrix = matrix.split(',');
                } else {
                    matrix = [];
                }

                if ( matrix.length ) {

                    // If IE
                    if ( matrix.length > 10 ) {
                        matrix = [ matrix[13], matrix[12], matrix[0], matrix[5] ];

                    } else {
                        matrix = [ matrix[5], matrix[4], matrix[0], matrix[3]];
                    }

                    matrix = matrix.map(parseFloat);

                } else {
                    matrix = [ 0, 0, 1, 1 ];
                }

                return {
                    top     : matrix[ 0 ],
                    left    : matrix[ 1 ],
                    scaleX  : matrix[ 2 ],
                    scaleY  : matrix[ 3 ],
                    opacity : parseFloat( $el.css('opacity') ),
                    width   : position.width,
                    height  : position.height
                };

            },


            // Shortcut for setting "translate3d" properties for element
            // Can set be used to set opacity, too
            // ========================================================

            setTranslate : function( $el, props ) {
                var str  = '';
                var css  = {};

                if ( !$el || !props ) {
                    return;
                }

                if ( props.left !== undefined || props.top !== undefined ) {

                    str = ( props.left === undefined ? $el.position().top : props.left )  + 'px, ' + ( props.top === undefined ? $el.position().top : props.top ) + 'px';

                    if ( this.use3d ) {
                        str = 'translate3d(' + str + ', 0px)';

                    } else {
                        str = 'translate(' + str + ')';
                    }

                }

                if ( props.scaleX !== undefined && props.scaleY !== undefined ) {
                    str = (str.length ? str + ' ' : '') + 'scale(' + props.scaleX + ', ' + props.scaleY + ')';
                }

                if ( str.length ) {
                    css.transform = str;
                }

                if ( props.opacity !== undefined ) {
                    css.opacity = props.opacity;
                }

                if ( props.width !== undefined ) {
                    css.width = props.width;
                }

                if ( props.height !== undefined ) {
                    css.height = props.height;
                }

                return $el.css( css );

            },


            // Common easings for entrances and exits
            // t: current time, b: begInnIng value, c: change In value, d: duration
            // ====================================================================

            easing : {
                easeOutCubic : function (t, b, c, d) {
                    return c * ((t=t/d-1)*t*t + 1) + b;
                },
                easeInCubic : function (t, b, c, d) {
                    return c * (t/=d)*t*t + b;
                },
                easeOutSine : function (t, b, c, d) {
                    return c * Math.sin(t/d * (Math.PI/2)) + b;
                },
                easeInSine : function (t, b, c, d) {
                    return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
                }
            },


            // Stop fancyBox animation
            // =======================

            stop : function( $el ) {

                $el.removeData( 'animateID' );

            },

            // Animate element using "translate3d"
            // Usage:
            // animate( element, start properties, end properties, duration, easing, callback )
            // or
            // animate( element, start properties, end properties, duration, callback )
            // =================================================================================

            animate : function( $el, from, to, duration, easing, done ) {

                var self = this;

                var lastTime = null;
                var animTime = 0;

                var curr;
                var diff;
                var id;

                var finish = function() {
                    if ( to.scaleX !== undefined && to.scaleY !== undefined && from && from.width !== undefined && from.height !== undefined ) {
                        to.width  = from.width  * to.scaleX;
                        to.height = from.height * to.scaleY;

                        to.scaleX = 1;
                        to.scaleY = 1;
                    }

                    self.setTranslate( $el, to );

                    done();
                };

                var frame = function ( timestamp ) {
                    curr = [];
                    diff = 0;

                    // If "stop" method has been called on this element, then just stop
                    if ( !$el.length || $el.data( 'animateID' ) !== id ) {
                        return;
                    }

                    timestamp = timestamp || Date.now();

                    if ( lastTime ) {
                        diff = timestamp - lastTime;
                    }

                    lastTime = timestamp;
                    animTime += diff;

                    // Are we done?
                    if ( animTime >= duration ) {

                        finish();

                        return;
                    }

                    for ( var prop in to ) {

                        if ( to.hasOwnProperty( prop ) && from[ prop ] !== undefined ) {

                            if ( from[ prop ] == to[ prop ] ) {
                                curr[ prop ] = to[ prop ];

                            } else {
                                curr[ prop ] = self.easing[ easing ]( animTime, from[ prop ], to[ prop ] - from[ prop ], duration );
                            }

                        }
                    }

                    self.setTranslate( $el, curr );

                    requestAFrame( frame );
                };

                self.animateID = id = self.animateID === undefined ? 1 : self.animateID + 1;

                $el.data( 'animateID', id );

                if ( done === undefined && $.type(easing) == 'function' ) {
                    done   = easing;
                    easing = undefined;
                }

                if ( !easing ) {
                    easing = "easeOutCubic";
                }

                done = done || $.noop;

                if ( from ) {
                    this.setTranslate( $el, from );

                } else {

                    // We need current values to calculate change in time
                    from = this.getTranslate( $el );
                }

                if ( duration ) {
                    $el.show();

                    requestAFrame( frame );

                } else {
                    finish();
                }

            }

        };


        // Event handler for click event to "fancyboxed" links
        // ===================================================

        function _run( e ) {
            var target	= e.currentTarget,
                opts	= e.data ? e.data.options : {},
                items	= e.data ? e.data.items : [],
                value	= '',
                index	= 0;

            e.preventDefault();
            e.stopPropagation();

            // Get all related items and find index for clicked one

            if ( $(target).attr( 'data-fancybox' ) ) {
                value = $(target).data( 'fancybox' );
            }

            if ( value ) {
                items = items.length ? items.filter( '[data-fancybox="' + value + '"]' ) : $( '[data-fancybox=' + value + ']' );
                index = items.index( target );

            } else {
                items = [ target ];
            }

            $.fancybox.open( items, opts, index );
        }


        // Create a jQuery plugin
        // ======================

        $.fn.fancybox = function (options) {

            this.off('click.fb-start').on('click.fb-start', {
                items   : this,
                options : options || {}
            }, _run);

            return this;

        };


        // Self initializing plugin
        // ========================

        $(document).on('click.fb-start', '[data-fancybox]', _run);

    }(window, document, window.jQuery));

// ==========================================================================
//
// Media
// Adds additional media type support
//
// ==========================================================================
    ;(function ($) {

        //'use strict';

        // Formats matching url to final form

        var format = function (url, rez, params) {
            if ( !url ) {
                return;
            }

            params = params || '';

            if ( $.type(params) === "object" ) {
                params = $.param(params, true);
            }

            $.each(rez, function (key, value) {
                url = url.replace('$' + key, value || '');
            });

            if (params.length) {
                url += (url.indexOf('?') > 0 ? '&' : '?') + params;
            }

            return url;
        };

        // Object containing properties for each media type

        var media = {
            youtube: {
                matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,
                params: {
                    autoplay: 1,
                    autohide: 1,
                    fs: 1,
                    rel: 0,
                    hd: 1,
                    wmode: 'transparent',
                    enablejsapi: 1,
                    html5: 1
                },
                paramPlace : 8,
                type: 'iframe',
                url: '//www.youtube.com/embed/$4',
                thumb: '//img.youtube.com/vi/$4/hqdefault.jpg'
            },

            vimeo: {
                matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,
                params: {
                    autoplay: 1,
                    hd: 1,
                    show_title: 1,
                    show_byline: 1,
                    show_portrait: 0,
                    fullscreen: 1,
                    api: 1
                },
                paramPlace : 3,
                type: 'iframe',
                url: '//player.vimeo.com/video/$2'
            },

            metacafe: {
                matcher: /metacafe.com\/watch\/(\d+)\/(.*)?/,
                type: 'iframe',
                url: '//www.metacafe.com/embed/$1/?ap=1'
            },

            dailymotion: {
                matcher: /dailymotion.com\/video\/(.*)\/?(.*)/,
                params: {
                    additionalInfos: 0,
                    autoStart: 1
                },
                type: 'iframe',
                url: '//www.dailymotion.com/embed/video/$1'
            },

            vine: {
                matcher: /vine.co\/v\/([a-zA-Z0-9\?\=\-]+)/,
                type: 'iframe',
                url: '//vine.co/v/$1/embed/simple'
            },

            instagram: {
                matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
                type: 'image',
                url: '//$1/p/$2/media/?size=l'
            },

            // Examples:
            // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
            // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
            // https://www.google.lv/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572
            google_maps: {
                matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,
                type: 'iframe',
                url: function (rez) {
                    return '//maps.google.' + rez[2] + '/?ll=' + ( rez[9] ? rez[9] + '&z=' + Math.floor(  rez[10]  ) + ( rez[12] ? rez[12].replace(/^\//, "&") : '' )  : rez[12] ) + '&output=' + ( rez[12] && rez[12].indexOf('layer=c') > 0 ? 'svembed' : 'embed' );
                }
            }
        };

        $(document).on('onInit.fb', function (e, instance) {

            $.each(instance.group, function( i, item ) {

                var url	 = item.src || '',
                    type = false,
                    thumb,
                    rez,
                    params,
                    urlParams,
                    o,
                    provider;

                // Skip items that already have content type
                if ( item.type ) {
                    return;
                }

                // Look for any matching media type

                $.each(media, function ( n, el ) {
                    rez = url.match(el.matcher);
                    o   = {};
                    provider = n;

                    if (!rez) {
                        return;
                    }

                    type = el.type;

                    if ( el.paramPlace && rez[ el.paramPlace ] ) {
                        urlParams = rez[ el.paramPlace ];

                        if ( urlParams[ 0 ] == '?' ) {
                            urlParams = urlParams.substring(1);
                        }

                        urlParams = urlParams.split('&');

                        for ( var m = 0; m < urlParams.length; ++m ) {
                            var p = urlParams[ m ].split('=', 2);

                            if ( p.length == 2 ) {
                                o[ p[0] ] = decodeURIComponent( p[1].replace(/\+/g, " ") );
                            }
                        }
                    }

                    params = $.extend( true, {}, el.params, item.opts[ n ], o );

                    url   = $.type(el.url) === "function" ? el.url.call(this, rez, params, item) : format(el.url, rez, params);
                    thumb = $.type(el.thumb) === "function" ? el.thumb.call(this, rez, params, item) : format(el.thumb, rez);

                    if ( provider === 'vimeo' ) {
                        url = url.replace('&%23', '#');
                    }

                    return false;
                });

                // If it is found, then change content type and update the url

                if ( type ) {
                    item.src  = url;
                    item.type = type;

                    if ( !item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length ) ) {
                        item.opts.thumb = thumb;
                    }

                    if ( type === 'iframe' ) {
                        $.extend(true, item.opts, {
                            iframe : {
                                preload   : false,
                                scrolling : "no"
                            },
                            smallBtn   : false,
                            closeBtn   : true,
                            fullScreen : false,
                            slideShow  : false
                        });

                        item.opts.slideClass += ' fancybox-slide--video';
                    }

                } else {

                    // If no content type is found, then set it to `iframe` as fallback
                    item.type = 'iframe';

                }

            });

        });

    }(window.jQuery));

// ==========================================================================
//
// Guestures
// Adds touch guestures, handles click and tap events
//
// ==========================================================================
    ;(function (window, document, $) {
        //'use strict';

        var requestAFrame = (function() {
            return  window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                function( callback ) {
                    window.setTimeout(callback, 1000 / 60); };
        })();


        var pointers = function( e ) {
            var result = [];

            e = e.originalEvent || e || window.e;
            e = e.touches && e.touches.length ? e.touches : ( e.changedTouches && e.changedTouches.length ? e.changedTouches : [ e ] );

            for ( var key in e ) {

                if ( e[ key ].pageX ) {
                    result.push( { x : e[ key ].pageX, y : e[ key ].pageY } );

                } else if ( e[ key ].clientX ) {
                    result.push( { x : e[ key ].clientX, y : e[ key ].clientY } );
                }
            }

            return result;
        };

        var distance = function( point2, point1, what ) {

            if ( !point1 || !point2 ) {
                return 0;
            }

            if ( what === 'x' ) {
                return point2.x - point1.x;

            } else if ( what === 'y' ) {
                return point2.y - point1.y;
            }

            return Math.sqrt( Math.pow( point2.x - point1.x, 2 ) + Math.pow( point2.y - point1.y, 2 ) );

        };

        var isClickable = function( $el ) {

            return $el.is('a') || $el.is('button') || $el.is('input') || $el.is('select') || $el.is('textarea') || $.isFunction( $el.get(0).onclick );

        };

        var hasScrollbars = function( el ) {
            var overflowY = window.getComputedStyle( el )['overflow-y'];
            var overflowX = window.getComputedStyle( el )['overflow-x'];

            var vertical   = (overflowY === 'scroll' || overflowY === 'auto') && el.scrollHeight > el.clientHeight;
            var horizontal = (overflowX === 'scroll' || overflowX === 'auto') && el.scrollWidth > el.clientWidth;

            return vertical || horizontal;
        };

        var isScrollable = function ( $el ) {

            var rez = false;

            while ( true ) {
                rez	= hasScrollbars( $el.get(0) );

                if ( rez ) {
                    break;
                }

                $el = $el.parent();

                if ( !$el.length || $el.hasClass('fancybox-slider') || $el.is('body') ) {
                    break;
                }

            }

            return rez;

        };


        var Guestures = function ( instance ) {

            var self = this;

            self.instance = instance;

            self.$wrap       = instance.$refs.slider_wrap;
            self.$slider     = instance.$refs.slider;
            self.$container  = instance.$refs.container;

            self.destroy();

            self.$wrap.on('touchstart.fb mousedown.fb', $.proxy(self, "ontouchstart"));

        };

        Guestures.prototype.destroy = function() {

            this.$wrap.off('touchstart.fb mousedown.fb touchmove.fb mousemove.fb touchend.fb touchcancel.fb mouseup.fb mouseleave.fb');

        };

        Guestures.prototype.ontouchstart = function( e ) {

            var self = this;

            var $target  = $( e.target );
            var instance = self.instance;
            var current  = instance.current;
            var $content = current.$content || current.$placeholder;

            self.startPoints = pointers( e );

            self.$target  = $target;
            self.$content = $content;

            self.canvasWidth  = Math.round( current.$slide[0].clientWidth );
            self.canvasHeight = Math.round( current.$slide[0].clientHeight );

            self.startEvent = e;

            // Skip if clicked on the scrollbar
            if ( e.originalEvent.clientX > self.canvasWidth + current.$slide.offset().left ) {
                return true;
            }

            // Ignore taping on links, buttons and scrollable items
            if ( isClickable( $target ) || isClickable( $target.parent() ) || ( isScrollable( $target ) ) ) {
                return;
            }

            // If "touch" is disabled, then handle click event
            if ( !current.opts.touch ) {
                self.endPoints = self.startPoints;

                return self.ontap();
            }

            // Ignore right click
            if ( e.originalEvent && e.originalEvent.button == 2 ) {
                return;
            }

            e.stopPropagation();
            e.preventDefault();

            if ( !current || self.instance.isAnimating || self.instance.isClosing ) {
                return;
            }

            // Prevent zooming if already swiping
            if ( !self.startPoints || ( self.startPoints.length > 1 && !current.isMoved ) ) {
                return;
            }

            self.$wrap.off('touchmove.fb mousemove.fb',  $.proxy(self, "ontouchmove"));
            self.$wrap.off('touchend.fb touchcancel.fb mouseup.fb mouseleave.fb',  $.proxy(self, "ontouchend"));

            self.$wrap.on('touchend.fb touchcancel.fb mouseup.fb mouseleave.fb',  $.proxy(self, "ontouchend"));
            self.$wrap.on('touchmove.fb mousemove.fb',  $.proxy(self, "ontouchmove"));

            self.startTime = new Date().getTime();
            self.distanceX = self.distanceY = self.distance = 0;

            self.canTap    = false;
            self.isPanning = false;
            self.isSwiping = false;
            self.isZooming = false;

            self.sliderStartPos = $.fancybox.getTranslate( self.$slider );

            self.contentStartPos = $.fancybox.getTranslate( self.$content );
            self.contentLastPos  = null;

            if ( self.startPoints.length === 1 && !self.isZooming ) {
                self.canTap = current.isMoved;

                if ( current.type === 'image' && ( self.contentStartPos.width > self.canvasWidth + 1 || self.contentStartPos.height > self.canvasHeight + 1 ) ) {

                    $.fancybox.stop( self.$content );

                    self.isPanning = true;

                } else {

                    $.fancybox.stop( self.$slider );

                    self.isSwiping = true;
                }

                self.$container.addClass('fancybox-controls--isGrabbing');

            }

            if ( self.startPoints.length === 2 && current.isMoved  && !current.hasError && current.type === 'image' && ( current.isLoaded || current.$ghost ) ) {

                self.isZooming = true;

                self.isSwiping = false;
                self.isPanning = false;

                $.fancybox.stop( self.$content );

                self.centerPointStartX = ( ( self.startPoints[0].x + self.startPoints[1].x ) * 0.5 ) - $(window).scrollLeft();
                self.centerPointStartY = ( ( self.startPoints[0].y + self.startPoints[1].y ) * 0.5 ) - $(window).scrollTop();

                self.percentageOfImageAtPinchPointX = ( self.centerPointStartX - self.contentStartPos.left ) / self.contentStartPos.width;
                self.percentageOfImageAtPinchPointY = ( self.centerPointStartY - self.contentStartPos.top  ) / self.contentStartPos.height;

                self.startDistanceBetweenFingers = distance( self.startPoints[0], self.startPoints[1] );
            }

        };

        Guestures.prototype.ontouchmove = function( e ) {

            var self = this;

            e.preventDefault();

            self.newPoints = pointers( e );

            if ( !self.newPoints || !self.newPoints.length ) {
                return;
            }

            self.distanceX = distance( self.newPoints[0], self.startPoints[0], 'x' );
            self.distanceY = distance( self.newPoints[0], self.startPoints[0], 'y' );

            self.distance = distance( self.newPoints[0], self.startPoints[0] );

            // Skip false ontouchmove events (Chrome)
            if ( self.distance > 0 ) {

                if ( self.isSwiping ) {
                    self.onSwipe();

                } else if ( self.isPanning ) {
                    self.onPan();

                } else if ( self.isZooming ) {
                    self.onZoom();
                }

            }

        };

        Guestures.prototype.onSwipe = function() {

            var self = this;

            var swiping = self.isSwiping;
            var left    = self.sliderStartPos.left;
            var angle;

            if ( swiping === true ) {

                if ( Math.abs( self.distance ) > 10 )  {

                    if ( self.instance.group.length < 2 ) {
                        self.isSwiping  = 'y';

                    } else if ( !self.instance.current.isMoved || self.instance.opts.touch.vertical === false || ( self.instance.opts.touch.vertical === 'auto' && $( window ).width() > 800 ) ) {
                        self.isSwiping  = 'x';

                    } else {
                        angle = Math.abs( Math.atan2( self.distanceY, self.distanceX ) * 180 / Math.PI );

                        self.isSwiping = ( angle > 45 && angle < 135 ) ? 'y' : 'x';
                    }

                    self.canTap  = false;

                    self.instance.current.isMoved = false;

                    // Reset points to avoid jumping, because we dropped first swipes to calculate the angle
                    self.startPoints = self.newPoints;
                }

            } else {

                if ( swiping == 'x' ) {

                    // Sticky edges
                    if ( !self.instance.current.opts.loop && self.instance.current.index === 0  && self.distanceX > 0 ) {
                        left = left + Math.pow( self.distanceX, 0.8 );

                    } else if ( !self.instance.current.opts.loop &&self.instance.current.index === self.instance.group.length - 1 && self.distanceX < 0 ) {
                        left = left - Math.pow( -self.distanceX, 0.8 );

                    } else {
                        left = left + self.distanceX;
                    }

                }

                self.sliderLastPos = {
                    top  : swiping == 'x' ? 0 : self.sliderStartPos.top + self.distanceY,
                    left : left
                };

                requestAFrame(function() {
                    $.fancybox.setTranslate( self.$slider, self.sliderLastPos );
                });
            }

        };

        Guestures.prototype.onPan = function() {

            var self = this;

            var newOffsetX, newOffsetY, newPos;

            self.canTap = false;

            if ( self.contentStartPos.width > self.canvasWidth ) {
                newOffsetX = self.contentStartPos.left + self.distanceX;

            } else {
                newOffsetX = self.contentStartPos.left;
            }

            newOffsetY = self.contentStartPos.top + self.distanceY;

            newPos = self.limitMovement( newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height );

            newPos.scaleX = self.contentStartPos.scaleX;
            newPos.scaleY = self.contentStartPos.scaleY;

            self.contentLastPos = newPos;

            requestAFrame(function() {
                $.fancybox.setTranslate( self.$content, self.contentLastPos );
            });
        };

        // Make panning sticky to the edges
        Guestures.prototype.limitMovement = function( newOffsetX, newOffsetY, newWidth, newHeight ) {

            var self = this;

            var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY;

            var canvasWidth  = self.canvasWidth;
            var canvasHeight = self.canvasHeight;

            var currentOffsetX = self.contentStartPos.left;
            var currentOffsetY = self.contentStartPos.top;

            var distanceX = self.distanceX;
            var distanceY = self.distanceY;

            // Slow down proportionally to traveled distance

            minTranslateX = Math.max(0, canvasWidth  * 0.5 - newWidth  * 0.5 );
            minTranslateY = Math.max(0, canvasHeight * 0.5 - newHeight * 0.5 );

            maxTranslateX = Math.min( canvasWidth  - newWidth,  canvasWidth  * 0.5 - newWidth  * 0.5 );
            maxTranslateY = Math.min( canvasHeight - newHeight, canvasHeight * 0.5 - newHeight * 0.5 );

            if ( newWidth > canvasWidth ) {

                //   ->
                if ( distanceX > 0 && newOffsetX > minTranslateX ) {
                    newOffsetX = minTranslateX - 1 + Math.pow( -minTranslateX + currentOffsetX + distanceX, 0.8 ) || 0;
                }

                //    <-
                if ( distanceX  < 0 && newOffsetX < maxTranslateX ) {
                    newOffsetX = maxTranslateX + 1 - Math.pow( maxTranslateX - currentOffsetX - distanceX, 0.8 ) || 0;
                }

            }

            if ( newHeight > canvasHeight ) {

                //   \/
                if ( distanceY > 0 && newOffsetY > minTranslateY ) {
                    newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8 ) || 0;
                }

                //   /\
                if ( distanceY < 0 && newOffsetY < maxTranslateY ) {
                    newOffsetY = maxTranslateY + 1 - Math.pow ( maxTranslateY - currentOffsetY - distanceY, 0.8 ) || 0;
                }

            }

            return {
                top  : newOffsetY,
                left : newOffsetX
            };

        };


        Guestures.prototype.limitPosition = function( newOffsetX, newOffsetY, newWidth, newHeight ) {

            var self = this;

            var canvasWidth  = self.canvasWidth;
            var canvasHeight = self.canvasHeight;

            if ( newWidth > canvasWidth ) {
                newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;
                newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;

            } else {

                // Center horizontally
                newOffsetX = Math.max( 0, canvasWidth / 2 - newWidth / 2 );

            }

            if ( newHeight > canvasHeight ) {
                newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;
                newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;

            } else {

                // Center vertically
                newOffsetY = Math.max( 0, canvasHeight / 2 - newHeight / 2 );

            }

            return {
                top  : newOffsetY,
                left : newOffsetX
            };

        };

        Guestures.prototype.onZoom = function() {

            var self = this;

            // Calculate current distance between points to get pinch ratio and new width and height

            var currentWidth  = self.contentStartPos.width;
            var currentHeight = self.contentStartPos.height;

            var currentOffsetX = self.contentStartPos.left;
            var currentOffsetY = self.contentStartPos.top;

            var endDistanceBetweenFingers = distance( self.newPoints[0], self.newPoints[1] );

            var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;

            var newWidth  = Math.floor( currentWidth  * pinchRatio );
            var newHeight = Math.floor( currentHeight * pinchRatio );

            // This is the translation due to pinch-zooming
            var translateFromZoomingX = (currentWidth  - newWidth)  * self.percentageOfImageAtPinchPointX;
            var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;

            //Point between the two touches

            var centerPointEndX = ((self.newPoints[0].x + self.newPoints[1].x) / 2) - $(window).scrollLeft();
            var centerPointEndY = ((self.newPoints[0].y + self.newPoints[1].y) / 2) - $(window).scrollTop();

            // And this is the translation due to translation of the centerpoint
            // between the two fingers

            var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;
            var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;

            // The new offset is the old/current one plus the total translation

            var newOffsetX = currentOffsetX + ( translateFromZoomingX + translateFromTranslatingX );
            var newOffsetY = currentOffsetY + ( translateFromZoomingY + translateFromTranslatingY );

            var newPos = {
                top    : newOffsetY,
                left   : newOffsetX,
                scaleX : self.contentStartPos.scaleX * pinchRatio,
                scaleY : self.contentStartPos.scaleY * pinchRatio
            };

            self.canTap = false;

            self.newWidth  = newWidth;
            self.newHeight = newHeight;

            self.contentLastPos = newPos;

            requestAFrame(function() {
                $.fancybox.setTranslate( self.$content, self.contentLastPos );
            });

        };

        Guestures.prototype.ontouchend = function( e ) {

            var self = this;

            var current = self.instance.current;

            var dMs = Math.max( (new Date().getTime() ) - self.startTime, 1);

            var swiping = self.isSwiping;
            var panning = self.isPanning;
            var zooming = self.isZooming;

            self.endPoints = pointers( e );

            self.$container.removeClass('fancybox-controls--isGrabbing');

            self.$wrap.off('touchmove.fb mousemove.fb',  $.proxy(this, "ontouchmove"));
            self.$wrap.off('touchend.fb touchcancel.fb mouseup.fb mouseleave.fb',  $.proxy(this, "ontouchend"));

            self.isSwiping = false;
            self.isPanning = false;
            self.isZooming = false;

            if ( self.canTap )  {
                return self.ontap();
            }

            // Speed in px/ms
            self.velocityX = self.distanceX / dMs * 0.5;
            self.velocityY = self.distanceY / dMs * 0.5;

            self.speed = current.opts.speed || 330;

            self.speedX = Math.max( self.speed * 0.75, Math.min( self.speed * 1.5, ( 1 / Math.abs( self.velocityX ) ) * self.speed ) );
            self.speedY = Math.max( self.speed * 0.75, Math.min( self.speed * 1.5, ( 1 / Math.abs( self.velocityY ) ) * self.speed ) );

            if ( panning ) {
                self.endPanning();

            } else if ( zooming ) {
                self.endZooming();

            } else {
                self.endSwiping( swiping );
            }

            return;
        };

        Guestures.prototype.endSwiping = function( swiping ) {

            var self = this;

            // Close if swiped vertically / navigate if horizontally

            if ( swiping == 'y' && Math.abs( self.distanceY ) > 50 ) {

                // Continue vertical movement

                $.fancybox.animate( self.$slider, null, {
                    top     : self.sliderStartPos.top + self.distanceY + self.velocityY * 150,
                    left    : self.sliderStartPos.left,
                    opacity : 0
                }, self.speedY );

                self.instance.close( true );

            } else if ( swiping == 'x' && self.distanceX > 50 ) {
                self.instance.previous( self.speedX );

            } else if ( swiping == 'x' && self.distanceX < -50 ) {
                self.instance.next( self.speedX );

            } else {

                // Move back to center
                self.instance.update( false, true, 150 );

            }

        };

        Guestures.prototype.endPanning = function() {

            var self = this;
            var newOffsetX, newOffsetY, newPos;

            if ( !self.contentLastPos ) {
                return;
            }

            newOffsetX = self.contentLastPos.left + ( self.velocityX * self.speed * 2 );
            newOffsetY = self.contentLastPos.top  + ( self.velocityY * self.speed * 2 );

            newPos = self.limitPosition( newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height );

            newPos.width  = self.contentStartPos.width;
            newPos.height = self.contentStartPos.height;

            $.fancybox.animate( self.$content, null, newPos, self.speed, "easeOutSine" );

        };


        Guestures.prototype.endZooming = function() {

            var self = this;

            var current = self.instance.current;

            var newOffsetX, newOffsetY, newPos, reset;

            var newWidth  = self.newWidth;
            var newHeight = self.newHeight;

            if ( !self.contentLastPos ) {
                return;
            }

            newOffsetX = self.contentLastPos.left;
            newOffsetY = self.contentLastPos.top;

            reset = {
                top    : newOffsetY,
                left   : newOffsetX,
                width  : newWidth,
                height : newHeight,
                scaleX : 1,
                scaleY : 1
            };

            // Reset scalex/scaleY values; this helps for perfomance and does not break animation
            $.fancybox.setTranslate( self.$content, reset );

            if ( newWidth < self.canvasWidth && newHeight < self.canvasHeight ) {
                self.instance.scaleToFit( 150 );

            } else if ( newWidth > current.width || newHeight > current.height ) {
                self.instance.scaleToActual( self.centerPointStartX, self.centerPointStartY, 150 );

            } else {

                newPos = self.limitPosition( newOffsetX, newOffsetY, newWidth, newHeight );

                $.fancybox.animate( self.$content, null, newPos, self.speed, "easeOutSine" );

            }

        };

        Guestures.prototype.ontap = function() {

            var self = this;

            var instance = self.instance;
            var current  = instance.current;

            var x = self.endPoints[0].x;
            var y = self.endPoints[0].y;

            x = x - self.$wrap.offset().left;
            y = y - self.$wrap.offset().top;

            // Stop slideshow
            if ( instance.SlideShow && instance.SlideShow.isActive ) {
                instance.SlideShow.stop();
            }

            if ( !$.fancybox.isTouch ) {

                if ( current.opts.closeClickOutside && self.$target.is('.fancybox-slide') ) {
                    instance.close( self.startEvent );

                    return;
                }

                if ( current.type == 'image' && current.isMoved ) {

                    if ( instance.canPan() ) {
                        instance.scaleToFit();

                    } else if ( instance.isScaledDown() ) {
                        instance.scaleToActual( x, y );

                    } else if ( instance.group.length < 2 ) {
                        instance.close( self.startEvent );
                    }

                }

                return;
            }


            // Double tap
            if ( self.tapped ) {

                clearTimeout( self.tapped );

                self.tapped = null;

                if ( Math.abs( x - self.x ) > 50 || Math.abs( y - self.y ) > 50 || !current.isMoved ) {
                    return this;
                }

                if ( current.type == 'image' && ( current.isLoaded || current.$ghost ) ) {

                    if ( instance.canPan() ) {
                        instance.scaleToFit();

                    } else if ( instance.isScaledDown() ) {
                        instance.scaleToActual( x, y );

                    }

                }

            } else {

                // Single tap

                self.x = x;
                self.y = y;

                self.tapped = setTimeout(function() {
                    self.tapped = null;

                    instance.toggleControls( true );

                }, 300);
            }

            return this;
        };

        $(document).on('onActivate.fb', function (e, instance) {

            if ( instance && !instance.Guestures ) {
                instance.Guestures = new Guestures( instance );
            }

        });

        $(document).on('beforeClose.fb', function (e, instance) {

            if ( instance && instance.Guestures ) {
                instance.Guestures.destroy();
            }

        });


    }(window, document, window.jQuery));

// ==========================================================================
//
// SlideShow
// Enables slideshow functionality
//
// Example of usage:
// $.fancybox.getInstance().slideShow.start()
//
// ==========================================================================
    ;(function (document, $) {
        //'use strict';

        var SlideShow = function( instance ) {

            this.instance = instance;

            this.init();

        };

        $.extend( SlideShow.prototype, {
            timer    : null,
            isActive : false,
            $button  : null,
            speed    : 3000,

            init : function() {
                var self = this;

                self.$button = $('<button data-fancybox-play class="fancybox-button fancybox-button--play" title="Slideshow (P)"></button>')
                    .appendTo( self.instance.$refs.buttons );

                self.instance.$refs.container.on('click', '[data-fancybox-play]', function() {
                    self.toggle();
                });

            },

            set : function() {
                var self = this;

                // Check if reached last element
                if ( self.instance && self.instance.current && (self.instance.current.opts.loop || self.instance.currIndex < self.instance.group.length - 1 )) {

                    self.timer = setTimeout(function() {
                        self.instance.next();

                    }, self.instance.current.opts.slideShow.speed || self.speed);

                } else {
                    self.stop();
                }
            },

            clear : function() {
                var self = this;

                clearTimeout( self.timer );

                self.timer = null;
            },

            start : function() {
                var self = this;

                self.stop();

                if ( self.instance && self.instance.current && ( self.instance.current.opts.loop || self.instance.currIndex < self.instance.group.length - 1 )) {

                    self.instance.$refs.container.on({
                        'beforeLoad.fb.player'	: $.proxy(self, "clear"),
                        'onComplete.fb.player'	: $.proxy(self, "set"),
                    });

                    self.isActive = true;

                    if ( self.instance.current.isComplete ) {
                        self.set();
                    }

                    self.instance.$refs.container.trigger('onPlayStart');

                    self.$button.addClass('fancybox-button--pause');
                }

            },

            stop: function() {
                var self = this;

                self.clear();

                self.instance.$refs.container
                    .trigger('onPlayEnd')
                    .off('.player');

                self.$button.removeClass('fancybox-button--pause');

                self.isActive = false;
            },

            toggle : function() {
                var self = this;

                if ( self.isActive ) {
                    self.stop();

                } else {
                    self.start();
                }
            }

        });

        $(document).on('onInit.fb', function(e, instance) {

            if ( instance && instance.group.length > 1 && !!instance.opts.slideShow && !instance.SlideShow ) {
                instance.SlideShow = new SlideShow( instance );
            }

        });

        $(document).on('beforeClose.fb onDeactivate.fb', function(e, instance) {

            if ( instance && instance.SlideShow ) {
                instance.SlideShow.stop();
            }

        });

    }(document, window.jQuery));

// ==========================================================================
//
// FullScreen
// Adds fullscreen functionality
//
// ==========================================================================
    ;(function (document, $) {
        //'use strict';

        // Collection of methods supported by user browser
        var fn = (function () {

            var fnMap = [
                [
                    'requestFullscreen',
                    'exitFullscreen',
                    'fullscreenElement',
                    'fullscreenEnabled',
                    'fullscreenchange',
                    'fullscreenerror'
                ],
                // new WebKit
                [
                    'webkitRequestFullscreen',
                    'webkitExitFullscreen',
                    'webkitFullscreenElement',
                    'webkitFullscreenEnabled',
                    'webkitfullscreenchange',
                    'webkitfullscreenerror'

                ],
                // old WebKit (Safari 5.1)
                [
                    'webkitRequestFullScreen',
                    'webkitCancelFullScreen',
                    'webkitCurrentFullScreenElement',
                    'webkitCancelFullScreen',
                    'webkitfullscreenchange',
                    'webkitfullscreenerror'

                ],
                [
                    'mozRequestFullScreen',
                    'mozCancelFullScreen',
                    'mozFullScreenElement',
                    'mozFullScreenEnabled',
                    'mozfullscreenchange',
                    'mozfullscreenerror'
                ],
                [
                    'msRequestFullscreen',
                    'msExitFullscreen',
                    'msFullscreenElement',
                    'msFullscreenEnabled',
                    'MSFullscreenChange',
                    'MSFullscreenError'
                ]
            ];

            var val;
            var ret = {};
            var i, j;

            for ( i = 0; i < fnMap.length; i++ ) {
                val = fnMap[ i ];

                if ( val && val[ 1 ] in document ) {
                    for ( j = 0; j < val.length; j++ ) {
                        ret[ fnMap[ 0 ][ j ] ] = val[ j ];
                    }

                    return ret;
                }
            }

            return false;
        })();

        if ( !fn ) {
            return;
        }

        var FullScreen = {
            request : function ( elem ) {

                elem = elem || document.documentElement;

                elem[ fn.requestFullscreen ]( elem.ALLOW_KEYBOARD_INPUT );

            },
            exit : function () {
                document[ fn.exitFullscreen ]();
            },
            toggle : function ( elem ) {

                if ( this.isFullscreen() ) {
                    this.exit();
                } else {
                    this.request( elem );
                }

            },
            isFullscreen : function()  {
                return Boolean( document[ fn.fullscreenElement ] );
            },
            enabled : function()  {
                return Boolean( document[ fn.fullscreenEnabled ] );
            }
        };

        $(document).on({
            'onInit.fb' : function(e, instance) {
                var $container;

                if ( instance && !!instance.opts.fullScreen && !instance.FullScreen) {
                    $container = instance.$refs.container;

                    instance.$refs.button_fs = $('<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fullscreen" title="Full screen (F)"></button>')
                        .appendTo( instance.$refs.buttons );

                    $container.on('click.fb-fullscreen', '[data-fancybox-fullscreen]', function(e) {

                        e.stopPropagation();
                        e.preventDefault();

                        FullScreen.toggle( $container[ 0 ] );

                    });

                    if ( instance.opts.fullScreen.requestOnStart === true ) {
                        FullScreen.request( $container[ 0 ] );
                    }

                }

            }, 'beforeMove.fb' : function(e, instance) {

                if ( instance && instance.$refs.button_fs ) {
                    instance.$refs.button_fs.toggle( !!instance.current.opts.fullScreen );
                }

            }, 'beforeClose.fb':  function() {
                FullScreen.exit();
            }
        });

        $(document).on(fn.fullscreenchange, function() {
            var instance = $.fancybox.getInstance();
            var  $what   = instance ? instance.current.$placeholder : null;

            if ( $what ) {

                // If image is zooming, then this will force it to stop and reposition properly
                $what.css( 'transition', 'none' );

                instance.isAnimating = false;

                instance.update( true, true, 0 );
            }

        });

    }(document, window.jQuery));

// ==========================================================================
//
// Thumbs
// Displays thumbnails in a grid
//
// ==========================================================================
    ;(function (document, $) {
        //'use strict';

        var FancyThumbs = function( instance ) {

            this.instance = instance;

            this.init();

        };

        $.extend( FancyThumbs.prototype, {

            $button		: null,
            $grid		: null,
            $list		: null,
            isVisible	: false,

            init : function() {
                var self = this;

                self.$button = $('<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="Thumbnails (G)"></button>')
                    .appendTo( this.instance.$refs.buttons )
                    .on('touchend click', function(e) {
                        e.stopPropagation();
                        e.preventDefault();

                        self.toggle();
                    });

            },

            create : function() {
                var instance = this.instance,
                    list,
                    src;

                this.$grid = $('<div class="fancybox-thumbs"></div>').appendTo( instance.$refs.container );

                list = '<ul>';

                $.each(instance.group, function( i, item ) {

                    src = item.opts.thumb || ( item.opts.$thumb ? item.opts.$thumb.attr('src') : null );

                    if ( !src && item.type === 'image' ) {
                        src = item.src;
                    }

                    if ( src && src.length ) {
                        list += '<li data-index="' + i + '"  tabindex="0" class="fancybox-thumbs-loading"><img data-src="' + src + '" /></li>';
                    }

                });

                list += '</ul>';

                this.$list = $( list ).appendTo( this.$grid ).on('click touchstart', 'li', function() {

                    instance.jumpTo( $(this).data('index') );

                });

                this.$list.find('img').hide().one('load', function() {

                    var $parent		= $(this).parent().removeClass('fancybox-thumbs-loading'),
                        thumbWidth	= $parent.outerWidth(),
                        thumbHeight	= $parent.outerHeight(),
                        width,
                        height,
                        widthRatio,
                        heightRatio;

                    width  = this.naturalWidth	|| this.width;
                    height = this.naturalHeight	|| this.height;

                    //Calculate thumbnail width/height and center it

                    widthRatio  = width  / thumbWidth;
                    heightRatio = height / thumbHeight;

                    if (widthRatio >= 1 && heightRatio >= 1) {
                        if (widthRatio > heightRatio) {
                            width  = width / heightRatio;
                            height = thumbHeight;

                        } else {
                            width  = thumbWidth;
                            height = height / widthRatio;
                        }
                    }

                    $(this).css({
                        width         : Math.floor(width),
                        height        : Math.floor(height),
                        'margin-top'  : Math.min( 0, Math.floor(thumbHeight * 0.3 - height * 0.3 ) ),
                        'margin-left' : Math.min( 0, Math.floor(thumbWidth  * 0.5 - width  * 0.5 ) )
                    }).show();

                })
                    .each(function() {
                        this.src = $( this ).data( 'src' );
                    });

            },

            focus : function() {

                if ( this.instance.current ) {
                    this.$list
                        .children()
                        .removeClass('fancybox-thumbs-active')
                        .filter('[data-index="' + this.instance.current.index  + '"]')
                        .addClass('fancybox-thumbs-active')
                        .focus();
                }

            },

            close : function() {

                this.$grid.hide();

            },

            update : function() {

                this.instance.$refs.container.toggleClass('fancybox-container--thumbs', this.isVisible);

                if ( this.isVisible ) {

                    if ( !this.$grid ) {
                        this.create();
                    }

                    this.$grid.show();

                    this.focus();

                } else if ( this.$grid ) {
                    this.$grid.hide();
                }

                this.instance.update();

            },

            hide : function() {

                this.isVisible = false;

                this.update();

            },

            show : function() {

                this.isVisible = true;

                this.update();

            },

            toggle : function() {

                if ( this.isVisible ) {
                    this.hide();

                } else {
                    this.show();
                }
            }

        });

        $(document).on('onInit.fb', function(e, instance) {
            var first  = instance.group[0],
                second = instance.group[1];

            if ( !!instance.opts.thumbs && !instance.Thumbs && instance.group.length > 1 && (
                    ( first.type == 'image'  || first.opts.thumb  || first.opts.$thumb ) &&
                    ( second.type == 'image' || second.opts.thumb || second.opts.$thumb )
                )
            ) {

                instance.Thumbs = new FancyThumbs( instance );
            }

        });

        $(document).on('beforeMove.fb', function(e, instance, item) {
            var self = instance && instance.Thumbs;

            if ( !self ) {
                return;
            }

            if ( item.modal ) {

                self.$button.hide();

                self.hide();

            } else {

                if ( instance.opts.thumbs.showOnStart === true && instance.firstRun ) {
                    self.show();

                }

                self.$button.show();

                if ( self.isVisible ) {
                    self.focus();
                }

            }

        });

        $(document).on('beforeClose.fb', function(e, instance) {

            if ( instance && instance.Thumbs) {
                if ( instance.Thumbs.isVisible && instance.opts.thumbs.hideOnClosing !== false ) {
                    instance.Thumbs.close();
                }

                instance.Thumbs = null;
            }

        });

    }(document, window.jQuery));

// ==========================================================================
//
// Hash
// Enables linking to each modal
//
// ==========================================================================
    ;(function (document, window, $) {
        //'use strict';

        // Simple $.escapeSelector polyfill (for jQuery prior v3)
        if ( !$.escapeSelector ) {
            $.escapeSelector = function( sel ) {
                var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
                var fcssescape = function( ch, asCodePoint ) {
                    if ( asCodePoint ) {
                        // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
                        if ( ch === "\0" ) {
                            return "\uFFFD";
                        }

                        // Control characters and (dependent upon position) numbers get escaped as code points
                        return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
                    }

                    // Other potentially-special ASCII characters get backslash-escaped
                    return "\\" + ch;
                };

                return ( sel + "" ).replace( rcssescape, fcssescape );
            };
        }

        // Variable containing last hash value set by fancyBox
        // It will be used to determine if fancyBox needs to close after hash change is detected
        var currentHash = null;

        // Get info about gallery name and current index from url
        function parseUrl() {
            var hash    = window.location.hash.substr( 1 );
            var rez     = hash.split( '-' );
            var index   = rez.length > 1 && /^\+?\d+$/.test( rez[ rez.length - 1 ] ) ? parseInt( rez.pop( -1 ), 10 ) || 1 : 1;
            var gallery = rez.join( '-' );

            // Index is starting from 1
            if ( index < 1 ) {
                index = 1;
            }

            return {
                hash    : hash,
                index   : index,
                gallery : gallery
            };
        }

        // Trigger click evnt on links to open new fancyBox instance
        function triggerFromUrl( url ) {
            var $el;

            if ( url.gallery !== '' ) {

                // If we can find element matching 'data-fancybox' atribute, then trigger click event for that ..
                $el = $( "[data-fancybox='" + $.escapeSelector( url.gallery ) + "']" ).eq( url.index - 1 );

                if ( $el.length ) {
                    $el.trigger( 'click' );

                } else {

                    // .. if not, try finding element by ID
                    $( "#" + $.escapeSelector( url.gallery ) + "" ).trigger( 'click' );

                }

            }
        }

        // Get gallery name from current instance
        function getGallery( instance ) {
            var opts;

            if ( !instance ) {
                return false;
            }

            opts = instance.current ? instance.current.opts : instance.opts;

            return opts.$orig ? opts.$orig.data( 'fancybox' ) : ( opts.hash || '' );
        }

        // Star when DOM becomes ready
        $(function() {

            // Small delay is used to allow other scripts to process "dom ready" event
            setTimeout(function() {

                // Check if this module is not disabled
                if ( $.fancybox.defaults.hash === false ) {
                    return;
                }

                // Check if need to close after url has changed
                $(window).on('hashchange.fb', function() {
                    var url = parseUrl();

                    if ( $.fancybox.getInstance() ) {
                        if ( currentHash && currentHash !== url.gallery + '-' + url.index )  {
                            currentHash = null;

                            $.fancybox.close();
                        }

                    } else if ( url.gallery !== '' ) {
                        triggerFromUrl( url );
                    }

                });

                // Update hash when opening/closing fancyBox
                $(document).on({
                    'onInit.fb' : function( e, instance ) {
                        var url     = parseUrl();
                        var gallery = getGallery( instance );

                        // Make sure gallery start index matches index from hash
                        if ( gallery && url.gallery && gallery == url.gallery ) {
                            instance.currIndex = url.index - 1;
                        }

                    }, 'beforeMove.fb' : function( e, instance, current ) {
                        var gallery = getGallery( instance );

                        // Update window hash
                        if ( gallery && gallery !== '' ) {

                            if ( window.location.hash.indexOf( gallery ) < 0 ) {
                                instance.opts.origHash = window.location.hash;
                            }

                            currentHash = gallery + ( instance.group.length > 1 ? '-' + ( current.index + 1 ) : '' );

                            if ( "pushState" in history ) {
                                history.pushState( '', document.title, window.location.pathname + window.location.search + '#' +  currentHash );

                            } else {
                                window.location.hash = currentHash;
                            }

                        }

                    }, 'beforeClose.fb' : function( e, instance, current ) {
                        var gallery  = getGallery( instance );
                        var origHash = instance && instance.opts.origHash ? instance.opts.origHash : '';

                        // Remove hash from location bar
                        if ( gallery && gallery !== '' ) {
                            if ( "pushState" in history ) {
                                history.pushState( '', document.title, window.location.pathname + window.location.search + origHash );

                            } else {
                                window.location.hash = origHash;
                            }
                        }

                        currentHash = null;
                    }
                });

                // Check current hash and trigger click event on matching element to start fancyBox, if needed
                triggerFromUrl( parseUrl() );

            }, 50);
        });


    }(document, window, window.jQuery));

}
