PageSourceSearch

https://alpinesoftit.com/public/assets/js/jquery.magnific-popup.js

js alpinesoftit.com collected 2026-09-24 12:56:51 UTC 64,156 bytes, 1,860 lines download raw bytes

vendor: 64,156 bytes, lines 1-1860
1/*! Magnific Popup - v1.1.0 - 2016-02-20
2* http://dimsemenov.com/plugins/magnific-popup/
3* Copyright (c) 2016 Dmitry Semenov; */
4;(function (factory) { 
5    if (typeof define === 'function' && define.amd) { 
6     // AMD. Register as an anonymous module. 
7     define(['jquery'], factory); 
8     } else if (typeof exports === 'object') { 
9     // Node/CommonJS 
10     factory(require('jquery')); 
11     } else { 
12     // Browser globals 
13     factory(window.jQuery || window.Zepto); 
14     } 
15     }(function($) { 
16    
17    /*>>core*/
18    /**
19     * 
20     * Magnific Popup Core JS file
21     * 
22     */
23    
24    
25    /**
26     * Private static constants
27     */
28    var CLOSE_EVENT = 'Close',
29        BEFORE_CLOSE_EVENT = 'BeforeClose',
30        AFTER_CLOSE_EVENT = 'AfterClose',
31        BEFORE_APPEND_EVENT = 'BeforeAppend',
32        MARKUP_PARSE_EVENT = 'MarkupParse',
33        OPEN_EVENT = 'Open',
34        CHANGE_EVENT = 'Change',
35        NS = 'mfp',
36        EVENT_NS = '.' + NS,
37        READY_CLASS = 'mfp-ready',
38        REMOVING_CLASS = 'mfp-removing',
39        PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
40    
41    
42    /**
43     * Private vars 
44     */
45    /*jshint -W079 */
46    var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'
47        MagnificPopup = function(){},
48        _isJQ = !!(window.jQuery),
49        _prevStatus,
50        _window = $(window),
51        _document,
52        _prevContentType,
53        _wrapClasses,
54        _currPopupType;
55    
56    
57    /**
58     * Private functions
59     */
60    var _mfpOn = function(name, f) {
61            mfp.ev.on(NS + name + EVENT_NS, f);
62        },
63        _getEl = function(className, appendTo, html, raw) {
64            var el = document.createElement('div');
65            el.className = 'mfp-'+className;
66            if(html) {
67                el.innerHTML = html;
68            }
69            if(!raw) {
70                el = $(el);
71                if(appendTo) {
72                    el.appendTo(appendTo);
73                }
74            } else if(appendTo) {
75                appendTo.appendChild(el);
76            }
77            return el;
78        },
79        _mfpTrigger = function(e, data) {
80            mfp.ev.triggerHandler(NS + e, data);
81    
82            if(mfp.st.callbacks) {
83                // converts "mfpEventName" to "eventName" callback and triggers it if it's present
84                e = e.charAt(0).toLowerCase() + e.slice(1);
85                if(mfp.st.callbacks[e]) {
86                    mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);
87                }
88            }
89        },
90        _getCloseBtn = function(type) {
91            if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
92                mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );
93                _currPopupType = type;
94            }
95            return mfp.currTemplate.closeBtn;
96        },
97        // Initialize Magnific Popup only when called at least once
98        _checkInstance = function() {
99            if(!$.magnificPopup.instance) {
100                /*jshint -W020 */
101                mfp = new MagnificPopup();
102                mfp.init();
103                $.magnificPopup.instance = mfp;
104            }
105        },
106        // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
107        supportsTransitions = function() {
108            var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist
109                v = ['ms','O','Moz','Webkit']; // 'v' for vendor
110    
111            if( s['transition'] !== undefined ) {
112                return true; 
113            }
114                
115            while( v.length ) {
116                if( v.pop() + 'Transition' in s ) {
117                    return true;
118                }
119            }
120                    
121            return false;
122        };
123    
124    
125    
126    /**
127     * Public functions
128     */
129    MagnificPopup.prototype = {
130    
131        constructor: MagnificPopup,
132    
133        /**
134         * Initializes Magnific Popup plugin. 
135         * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed
136         */
137        init: function() {
138            var appVersion = navigator.appVersion;
139            mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;
140            mfp.isAndroid = (/android/gi).test(appVersion);
141            mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
142            mfp.supportsTransition = supportsTransitions();
143    
144            // We disable fixed positioned lightbox on devices that don't handle it nicely.
145            // If you know a better way of detecting this - let me know.
146            mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
147            _document = $(document);
148    
149            mfp.popupsCache = {};
150        },
151    
152        /**
153         * Opens popup
154         * @param  data [description]
155         */
156        open: function(data) {
157    
158            var i;
159    
160            if(data.isObj === false) { 
161                // convert jQuery collection to array to avoid conflicts later
162                mfp.items = data.items.toArray();
163    
164                mfp.index = 0;
165                var items = data.items,
166                    item;
167                for(i = 0; i < items.length; i++) {
168                    item = items[i];
169                    if(item.parsed) {
170                        item = item.el[0];
171                    }
172                    if(item === data.el[0]) {
173                        mfp.index = i;
174                        break;
175                    }
176                }
177            } else {
178                mfp.items = $.isArray(data.items) ? data.items : [data.items];
179                mfp.index = data.index || 0;
180            }
181    
182            // if popup is already opened - we just update the content
183            if(mfp.isOpen) {
184                mfp.updateItemHTML();
185                return;
186            }
187            
188            mfp.types = []; 
189            _wrapClasses = '';
190            if(data.mainEl && data.mainEl.length) {
191                mfp.ev = data.mainEl.eq(0);
192            } else {
193                mfp.ev = _document;
194            }
195    
196            if(data.key) {
197                if(!mfp.popupsCache[data.key]) {
198                    mfp.popupsCache[data.key] = {};
199                }
200                mfp.currTemplate = mfp.popupsCache[data.key];
201            } else {
202                mfp.currTemplate = {};
203            }
204    
205    
206    
207            mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); 
208            mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
209    
210            if(mfp.st.modal) {
211                mfp.st.closeOnContentClick = false;
212                mfp.st.closeOnBgClick = false;
213                mfp.st.showCloseBtn = false;
214                mfp.st.enableEscapeKey = false;
215            }
216            
217    
218            // Building markup
219            // main containers are created only once
220            if(!mfp.bgOverlay) {
221    
222                // Dark overlay
223                mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
224                    mfp.close();
225                });
226    
227                mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {
228                    if(mfp._checkIfClose(e.target)) {
229                        mfp.close();
230                    }
231                });
232    
233                mfp.container = _getEl('container', mfp.wrap);
234            }
235    
236            mfp.contentContainer = _getEl('content');
237            if(mfp.st.preloader) {
238                mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
239            }
240    
241    
242            // Initializing modules
243            var modules = $.magnificPopup.modules;
244            for(i = 0; i < modules.length; i++) {
245                var n = modules[i];
246                n = n.charAt(0).toUpperCase() + n.slice(1);
247                mfp['init'+n].call(mfp);
248            }
249            _mfpTrigger('BeforeOpen');
250    
251    
252            if(mfp.st.showCloseBtn) {
253                // Close button
254                if(!mfp.st.closeBtnInside) {
255                    mfp.wrap.append( _getCloseBtn() );
256                } else {
257                    _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
258                        values.close_replaceWith = _getCloseBtn(item.type);
259                    });
260                    _wrapClasses += ' mfp-close-btn-in';
261                }
262            }
263    
264            if(mfp.st.alignTop) {
265                _wrapClasses += ' mfp-align-top';
266            }
267    
268        
269    
270            if(mfp.fixedContentPos) {
271                mfp.wrap.css({
272                    overflow: mfp.st.overflowY,
273                    overflowX: 'hidden',
274                    overflowY: mfp.st.overflowY
275                });
276            } else {
277                mfp.wrap.css({ 
278                    top: _window.scrollTop(),
279                    position: 'absolute'
280                });
281            }
282            if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
283                mfp.bgOverlay.css({
284                    height: _document.height(),
285                    position: 'absolute'
286                });
287            }
288    
289            
290    
291            if(mfp.st.enableEscapeKey) {
292                // Close on ESC key
293                _document.on('keyup' + EVENT_NS, function(e) {
294                    if(e.keyCode === 27) {
295                        mfp.close();
296                    }
297                });
298            }
299    
300            _window.on('resize' + EVENT_NS, function() {
301                mfp.updateSize();
302            });
303    
304    
305            if(!mfp.st.closeOnContentClick) {
306                _wrapClasses += ' mfp-auto-cursor';
307            }
308            
309            if(_wrapClasses)
310                mfp.wrap.addClass(_wrapClasses);
311    
312    
313            // this triggers recalculation of layout, so we get it once to not to trigger twice
314            var windowHeight = mfp.wH = _window.height();
315    
316            
317            var windowStyles = {};
318    
319            if( mfp.fixedContentPos ) {
320                if(mfp._hasScrollBar(windowHeight)){
321                    var s = mfp._getScrollbarSize();
322                    if(s) {
323                        windowStyles.marginRight = s;
324                    }
325                }
326            }
327    
328            if(mfp.fixedContentPos) {
329                if(!mfp.isIE7) {
330                    windowStyles.overflow = 'hidden';
331                } else {
332                    // ie7 double-scroll bug
333                    $('body, html').css('overflow', 'hidden');
334                }
335            }
336    
337            
338            
339            var classesToadd = mfp.st.mainClass;
340            if(mfp.isIE7) {
341                classesToadd += ' mfp-ie7';
342            }
343            if(classesToadd) {
344                mfp._addClassToMFP( classesToadd );
345            }
346    
347            // add content
348            mfp.updateItemHTML();
349    
350            _mfpTrigger('BuildControls');
351    
352            // remove scrollbar, add margin e.t.c
353            $('html').css(windowStyles);
354            
355            // add everything to DOM
356            mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
357    
358            // Save last focused element
359            mfp._lastFocusedEl = document.activeElement;
360            
361            // Wait for next cycle to allow CSS transition
362            setTimeout(function() {
363                
364                if(mfp.content) {
365                    mfp._addClassToMFP(READY_CLASS);
366                    mfp._setFocus();
367                } else {
368                    // if content is not defined (not loaded e.t.c) we add class only for BG
369                    mfp.bgOverlay.addClass(READY_CLASS);
370                }
371                
372                // Trap the focus in popup
373                _document.on('focusin' + EVENT_NS, mfp._onFocusIn);
374    
375            }, 16);
376    
377            mfp.isOpen = true;
378            mfp.updateSize(windowHeight);
379            _mfpTrigger(OPEN_EVENT);
380    
381            return data;
382        },
383    
384        /**
385         * Closes the popup
386         */
387        close: function() {
388            if(!mfp.isOpen) return;
389            _mfpTrigger(BEFORE_CLOSE_EVENT);
390    
391            mfp.isOpen = false;
392            // for CSS3 animation
393            if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {
394                mfp._addClassToMFP(REMOVING_CLASS);
395                setTimeout(function() {
396                    mfp._close();
397                }, mfp.st.removalDelay);
398            } else {
399                mfp._close();
400            }
401        },
402    
403        /**
404         * Helper for close() function
405         */
406        _close: function() {
407            _mfpTrigger(CLOSE_EVENT);
408    
409            var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
410    
411            mfp.bgOverlay.detach();
412            mfp.wrap.detach();
413            mfp.container.empty();
414    
415            if(mfp.st.mainClass) {
416                classesToRemove += mfp.st.mainClass + ' ';
417            }
418    
419            mfp._removeClassFromMFP(classesToRemove);
420    
421            if(mfp.fixedContentPos) {
422                var windowStyles = {marginRight: ''};
423                if(mfp.isIE7) {
424                    $('body, html').css('overflow', '');
425                } else {
426                    windowStyles.overflow = '';
427                }
428                $('html').css(windowStyles);
429            }
430            
431            _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
432            mfp.ev.off(EVENT_NS);
433    
434            // clean up DOM elements that aren't removed
435            mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
436            mfp.bgOverlay.attr('class', 'mfp-bg');
437            mfp.container.attr('class', 'mfp-container');
438    
439            // remove close button from target element
440            if(mfp.st.showCloseBtn &&
441            (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
442                if(mfp.currTemplate.closeBtn)
443                    mfp.currTemplate.closeBtn.detach();
444            }
445    
446    
447            if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
448                $(mfp._lastFocusedEl).focus(); // put tab focus back
449            }
450            mfp.currItem = null;	
451            mfp.content = null;
452            mfp.currTemplate = null;
453            mfp.prevHeight = 0;
454    
455            _mfpTrigger(AFTER_CLOSE_EVENT);
456        },
457        
458        updateSize: function(winHeight) {
459    
460            if(mfp.isIOS) {
461                // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
462                var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
463                var height = window.innerHeight * zoomLevel;
464                mfp.wrap.css('height', height);
465                mfp.wH = height;
466            } else {
467                mfp.wH = winHeight || _window.height();
468            }
469            // Fixes #84: popup incorrectly positioned with position:relative on body
470            if(!mfp.fixedContentPos) {
471                mfp.wrap.css('height', mfp.wH);
472            }
473    
474            _mfpTrigger('Resize');
475    
476        },
477    
478        /**
479         * Set content of popup based on current index
480         */
481        updateItemHTML: function() {
482            var item = mfp.items[mfp.index];
483    
484            // Detach and perform modifications
485            mfp.contentContainer.detach();
486    
487            if(mfp.content)
488                mfp.content.detach();
489    
490            if(!item.parsed) {
491                item = mfp.parseEl( mfp.index );
492            }
493    
494            var type = item.type;
495    
496            _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
497            // BeforeChange event works like so:
498            // _mfpOn('BeforeChange', function(e, prevType, newType) { });
499    
500            mfp.currItem = item;
501    
502            if(!mfp.currTemplate[type]) {
503                var markup = mfp.st[type] ? mfp.st[type].markup : false;
504    
505                // allows to modify markup
506                _mfpTrigger('FirstMarkupParse', markup);
507    
508                if(markup) {
509                    mfp.currTemplate[type] = $(markup);
510                } else {
511                    // if there is no markup found we just define that template is parsed
512                    mfp.currTemplate[type] = true;
513                }
514            }
515    
516            if(_prevContentType && _prevContentType !== item.type) {
517                mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
518            }
519    
520            var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
521            mfp.appendContent(newContent, type);
522    
523            item.preloaded = true;
524    
525            _mfpTrigger(CHANGE_EVENT, item);
526            _prevContentType = item.type;
527    
528            // Append container back after its content changed
529            mfp.container.prepend(mfp.contentContainer);
530    
531            _mfpTrigger('AfterChange');
532        },
533    
534    
535        /**
536         * Set HTML content of popup
537         */
538        appendContent: function(newContent, type) {
539            mfp.content = newContent;
540    
541            if(newContent) {
542                if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
543                    mfp.currTemplate[type] === true) {
544                    // if there is no markup, we just append close button element inside
545                    if(!mfp.content.find('.mfp-close').length) {
546                        mfp.content.append(_getCloseBtn());
547                    }
548                } else {
549                    mfp.content = newContent;
550                }
551            } else {
552                mfp.content = '';
553            }
554    
555            _mfpTrigger(BEFORE_APPEND_EVENT);
556            mfp.container.addClass('mfp-'+type+'-holder');
557    
558            mfp.contentContainer.append(mfp.content);
559        },
560    
561    
562        /**
563         * Creates Magnific Popup data object based on given data
564         * @param  {int} index Index of item to parse
565         */
566        parseEl: function(index) {
567            var item = mfp.items[index],
568                type;
569    
570            if(item.tagName) {
571                item = { el: $(item) };
572            } else {
573                type = item.type;
574                item = { data: item, src: item.src };
575            }
576    
577            if(item.el) {
578                var types = mfp.types;
579    
580                // check for 'mfp-TYPE' class
581                for(var i = 0; i < types.length; i++) {
582                    if( item.el.hasClass('mfp-'+types[i]) ) {
583                        type = types[i];
584                        break;
585                    }
586                }
587    
588                item.src = item.el.attr('data-mfp-src');
589                if(!item.src) {
590                    item.src = item.el.attr('href');
591                }
592            }
593    
594            item.type = type || mfp.st.type || 'inline';
595            item.index = index;
596            item.parsed = true;
597            mfp.items[index] = item;
598            _mfpTrigger('ElementParse', item);
599    
600            return mfp.items[index];
601        },
602    
603    
604        /**
605         * Initializes single popup or a group of popups
606         */
607        addGroup: function(el, options) {
608            var eHandler = function(e) {
609                e.mfpEl = this;
610                mfp._openClick(e, el, options);
611            };
612    
613            if(!options) {
614                options = {};
615            }
616    
617            var eName = 'click.magnificPopup';
618            options.mainEl = el;
619    
620            if(options.items) {
621                options.isObj = true;
622                el.off(eName).on(eName, eHandler);
623            } else {
624                options.isObj = false;
625                if(options.delegate) {
626                    el.off(eName).on(eName, options.delegate , eHandler);
627                } else {
628                    options.items = el;
629                    el.off(eName).on(eName, eHandler);
630                }
631            }
632        },
633        _openClick: function(e, el, options) {
634            var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
635    
636    
637            if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
638                return;
639            }
640    
641            var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
642    
643            if(disableOn) {
644                if($.isFunction(disableOn)) {
645                    if( !disableOn.call(mfp) ) {
646                        return true;
647                    }
648                } else { // else it's number
649                    if( _window.width() < disableOn ) {
650                        return true;
651                    }
652                }
653            }
654    
655            if(e.type) {
656                e.preventDefault();
657    
658                // This will prevent popup from closing if element is inside and popup is already opened
659                if(mfp.isOpen) {
660                    e.stopPropagation();
661                }
662            }
663    
664            options.el = $(e.mfpEl);
665            if(options.delegate) {
666                options.items = el.find(options.delegate);
667            }
668            mfp.open(options);
669        },
670    
671    
672        /**
673         * Updates text on preloader
674         */
675        updateStatus: function(status, text) {
676    
677            if(mfp.preloader) {
678                if(_prevStatus !== status) {
679                    mfp.container.removeClass('mfp-s-'+_prevStatus);
680                }
681    
682                if(!text && status === 'loading') {
683                    text = mfp.st.tLoading;
684                }
685    
686                var data = {
687                    status: status,
688                    text: text
689                };
690                // allows to modify status
691                _mfpTrigger('UpdateStatus', data);
692    
693                status = data.status;
694                text = data.text;
695    
696                mfp.preloader.html(text);
697    
698                mfp.preloader.find('a').on('click', function(e) {
699                    e.stopImmediatePropagation();
700                });
701    
702                mfp.container.addClass('mfp-s-'+status);
703                _prevStatus = status;
704            }
705        },
706    
707    
708        /*
709            "Private" helpers that aren't private at all
710         */
711        // Check to close popup or not
712        // "target" is an element that was clicked
713        _checkIfClose: function(target) {
714    
715            if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
716                return;
717            }
718    
719            var closeOnContent = mfp.st.closeOnContentClick;
720            var closeOnBg = mfp.st.closeOnBgClick;
721    
722            if(closeOnContent && closeOnBg) {
723                return true;
724            } else {
725    
726                // We close the popup if click is on close button or on preloader. Or if there is no content.
727                if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
728                    return true;
729                }
730    
731                // if click is outside the content
732                if(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {
733                    if(closeOnBg) {
734                        // last check, if the clicked element is in DOM, (in case it's removed onclick)
735                        if( $.contains(document, target) ) {
736                            return true;
737                        }
738                    }
739                } else if(closeOnContent) {
740                    return true;
741                }
742    
743            }
744            return false;
745        },
746        _addClassToMFP: function(cName) {
747            mfp.bgOverlay.addClass(cName);
748            mfp.wrap.addClass(cName);
749        },
750        _removeClassFromMFP: function(cName) {
751            this.bgOverlay.removeClass(cName);
752            mfp.wrap.removeClass(cName);
753        },
754        _hasScrollBar: function(winHeight) {
755            return (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
756        },
757        _setFocus: function() {
758            (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
759        },
760        _onFocusIn: function(e) {
761            if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
762                mfp._setFocus();
763                return false;
764            }
765        },
766        _parseMarkup: function(template, values, item) {
767            var arr;
768            if(item.data) {
769                values = $.extend(item.data, values);
770            }
771            _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
772    
773            $.each(values, function(key, value) {
774                if(value === undefined || value === false) {
775                    return true;
776                }
777                arr = key.split('_');
778                if(arr.length > 1) {
779                    var el = template.find(EVENT_NS + '-'+arr[0]);
780    
781                    if(el.length > 0) {
782                        var attr = arr[1];
783                        if(attr === 'replaceWith') {
784                            if(el[0] !== value[0]) {
785                                el.replaceWith(value);
786                            }
787                        } else if(attr === 'img') {
788                            if(el.is('img')) {
789                                el.attr('src', value);
790                            } else {
791                                el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) );
792                            }
793                        } else {
794                            el.attr(arr[1], value);
795                        }
796                    }
797    
798                } else {
799                    template.find(EVENT_NS + '-'+key).html(value);
800                }
801            });
802        },
803    
804        _getScrollbarSize: function() {
805            // thx David
806            if(mfp.scrollbarSize === undefined) {
807                var scrollDiv = document.createElement("div");
808                scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
809                document.body.appendChild(scrollDiv);
810                mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
811                document.body.removeChild(scrollDiv);
812            }
813            return mfp.scrollbarSize;
814        }
815    
816    }; /* MagnificPopup core prototype end */
817    
818    
819    
820    
821    /**
822     * Public static functions
823     */
824    $.magnificPopup = {
825        instance: null,
826        proto: MagnificPopup.prototype,
827        modules: [],
828    
829        open: function(options, index) {
830            _checkInstance();
831    
832            if(!options) {
833                options = {};
834            } else {
835                options = $.extend(true, {}, options);
836            }
837    
838            options.isObj = true;
839            options.index = index || 0;
840            return this.instance.open(options);
841        },
842    
843        close: function() {
844            return $.magnificPopup.instance && $.magnificPopup.instance.close();
845        },
846    
847        registerModule: function(name, module) {
848            if(module.options) {
849                $.magnificPopup.defaults[name] = module.options;
850            }
851            $.extend(this.proto, module.proto);
852            this.modules.push(name);
853        },
854    
855        defaults: {
856    
857            // Info about options is in docs:
858            // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
859    
860            disableOn: 0,
861    
862            key: null,
863    
864            midClick: false,
865    
866            mainClass: '',
867    
868            preloader: true,
869    
870            focus: '', // CSS selector of input to focus after popup is opened
871    
872            closeOnContentClick: false,
873    
874            closeOnBgClick: true,
875    
876            closeBtnInside: true,
877    
878            showCloseBtn: true,
879    
880            enableEscapeKey: true,
881    
882            modal: false,
883    
884            alignTop: false,
885    
886            removalDelay: 0,
887    
888            prependTo: null,
889    
890            fixedContentPos: 'auto',
891    
892            fixedBgPos: 'auto',
893    
894            overflowY: 'auto',
895    
896            closeMarkup: '<button title="%title%" type="button" class="mfp-close">&#215;</button>',
897    
898            tClose: 'Close (Esc)',
899    
900            tLoading: 'Loading...',
901    
902            autoFocusLast: true
903    
904        }
905    };
906    
907    
908    
909    $.fn.magnificPopup = function(options) {
910        _checkInstance();
911    
912        var jqEl = $(this);
913    
914        // We call some API method of first param is a string
915        if (typeof options === "string" ) {
916    
917            if(options === 'open') {
918                var items,
919                    itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
920                    index = parseInt(arguments[1], 10) || 0;
921    
922                if(itemOpts.items) {
923                    items = itemOpts.items[index];
924                } else {
925                    items = jqEl;
926                    if(itemOpts.delegate) {
927                        items = items.find(itemOpts.delegate);
928                    }
929                    items = items.eq( index );
930                }
931                mfp._openClick({mfpEl:items}, jqEl, itemOpts);
932            } else {
933                if(mfp.isOpen)
934                    mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
935            }
936    
937        } else {
938            // clone options obj
939            options = $.extend(true, {}, options);
940    
941            /*
942             * As Zepto doesn't support .data() method for objects
943             * and it works only in normal browsers
944             * we assign "options" object directly to the DOM element. FTW!
945             */
946            if(_isJQ) {
947                jqEl.data('magnificPopup', options);
948            } else {
949                jqEl[0].magnificPopup = options;
950            }
951    
952            mfp.addGroup(jqEl, options);
953    
954        }
955        return jqEl;
956    };
957    
958    /*>>core*/
959    
960    /*>>inline*/
961    
962    var INLINE_NS = 'inline',
963        _hiddenClass,
964        _inlinePlaceholder,
965        _lastInlineElement,
966        _putInlineElementsBack = function() {
967            if(_lastInlineElement) {
968                _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
969                _lastInlineElement = null;
970            }
971        };
972    
973    $.magnificPopup.registerModule(INLINE_NS, {
974        options: {
975            hiddenClass: 'hide', // will be appended with `mfp-` prefix
976            markup: '',
977            tNotFound: 'Content not found'
978        },
979        proto: {
980    
981            initInline: function() {
982                mfp.types.push(INLINE_NS);
983    
984                _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
985                    _putInlineElementsBack();
986                });
987            },
988    
989            getInline: function(item, template) {
990    
991                _putInlineElementsBack();
992    
993                if(item.src) {
994                    var inlineSt = mfp.st.inline,
995                        el = $(item.src);
996    
997                    if(el.length) {
998    
999                        // If target element has parent - we replace it with placeholder and put it back after popup is closed
1000                        var parent = el[0].parentNode;
1001                        if(parent && parent.tagName) {
1002                            if(!_inlinePlaceholder) {
1003                                _hiddenClass = inlineSt.hiddenClass;
1004                                _inlinePlaceholder = _getEl(_hiddenClass);
1005                                _hiddenClass = 'mfp-'+_hiddenClass;
1006                            }
1007                            // replace target inline element with placeholder
1008                            _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
1009                        }
1010    
1011                        mfp.updateStatus('ready');
1012                    } else {
1013                        mfp.updateStatus('error', inlineSt.tNotFound);
1014                        el = $('<div>');
1015                    }
1016    
1017                    item.inlineElement = el;
1018                    return el;
1019                }
1020    
1021                mfp.updateStatus('ready');
1022                mfp._parseMarkup(template, {}, item);
1023                return template;
1024            }
1025        }
1026    });
1027    
1028    /*>>inline*/
1029    
1030    /*>>ajax*/
1031    var AJAX_NS = 'ajax',
1032        _ajaxCur,
1033        _removeAjaxCursor = function() {
1034            if(_ajaxCur) {
1035                $(document.body).removeClass(_ajaxCur);
1036            }
1037        },
1038        _destroyAjaxRequest = function() {
1039            _removeAjaxCursor();
1040            if(mfp.req) {
1041                mfp.req.abort();
1042            }
1043        };
1044    
1045    $.magnificPopup.registerModule(AJAX_NS, {
1046    
1047        options: {
1048            settings: null,
1049            cursor: 'mfp-ajax-cur',
1050            tError: '<a href="%url%">The content</a> could not be loaded.'
1051        },
1052    
1053        proto: {
1054            initAjax: function() {
1055                mfp.types.push(AJAX_NS);
1056                _ajaxCur = mfp.st.ajax.cursor;
1057    
1058                _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
1059                _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
1060            },
1061            getAjax: function(item) {
1062    
1063                if(_ajaxCur) {
1064                    $(document.body).addClass(_ajaxCur);
1065                }
1066    
1067                mfp.updateStatus('loading');
1068    
1069                var opts = $.extend({
1070                    url: item.src,
1071                    success: function(data, textStatus, jqXHR) {
1072                        var temp = {
1073                            data:data,
1074                            xhr:jqXHR
1075                        };
1076    
1077                        _mfpTrigger('ParseAjax', temp);
1078    
1079                        mfp.appendContent( $(temp.data), AJAX_NS );
1080    
1081                        item.finished = true;
1082    
1083                        _removeAjaxCursor();
1084    
1085                        mfp._setFocus();
1086    
1087                        setTimeout(function() {
1088                            mfp.wrap.addClass(READY_CLASS);
1089                        }, 16);
1090    
1091                        mfp.updateStatus('ready');
1092    
1093                        _mfpTrigger('AjaxContentAdded');
1094                    },
1095                    error: function() {
1096                        _removeAjaxCursor();
1097                        item.finished = item.loadError = true;
1098                        mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));
1099                    }
1100                }, mfp.st.ajax.settings);
1101    
1102                mfp.req = $.ajax(opts);
1103    
1104                return '';
1105            }
1106        }
1107    });
1108    
1109    /*>>ajax*/
1110    
1111    /*>>image*/
1112    var _imgInterval,
1113        _getTitle = function(item) {
1114            if(item.data && item.data.title !== undefined)
1115                return item.data.title;
1116    
1117            var src = mfp.st.image.titleSrc;
1118    
1119            if(src) {
1120                if($.isFunction(src)) {
1121                    return src.call(mfp, item);
1122                } else if(item.el) {
1123                    return item.el.attr(src) || '';
1124                }
1125            }
1126            return '';
1127        };
1128    
1129    $.magnificPopup.registerModule('image', {
1130    
1131        options: {
1132            markup: '<div class="mfp-figure">'+
1133                        '<div class="mfp-close"></div>'+
1134                        '<figure>'+
1135                            '<div class="mfp-img"></div>'+
1136                            '<figcaption>'+
1137                                '<div class="mfp-bottom-bar">'+
1138                                    '<div class="mfp-title"></div>'+
1139                                    '<div class="mfp-counter"></div>'+
1140                                '</div>'+
1141                            '</figcaption>'+
1142                        '</figure>'+
1143                    '</div>',
1144            cursor: 'mfp-zoom-out-cur',
1145            titleSrc: 'title',
1146            verticalFit: true,
1147            tError: '<a href="%url%">The image</a> could not be loaded.'
1148        },
1149    
1150        proto: {
1151            initImage: function() {
1152                var imgSt = mfp.st.image,
1153                    ns = '.image';
1154    
1155                mfp.types.push('image');
1156    
1157                _mfpOn(OPEN_EVENT+ns, function() {
1158                    if(mfp.currItem.type === 'image' && imgSt.cursor) {
1159                        $(document.body).addClass(imgSt.cursor);
1160                    }
1161                });
1162    
1163                _mfpOn(CLOSE_EVENT+ns, function() {
1164                    if(imgSt.cursor) {
1165                        $(document.body).removeClass(imgSt.cursor);
1166                    }
1167                    _window.off('resize' + EVENT_NS);
1168                });
1169    
1170                _mfpOn('Resize'+ns, mfp.resizeImage);
1171                if(mfp.isLowIE) {
1172                    _mfpOn('AfterChange', mfp.resizeImage);
1173                }
1174            },
1175            resizeImage: function() {
1176                var item = mfp.currItem;
1177                if(!item || !item.img) return;
1178    
1179                if(mfp.st.image.verticalFit) {
1180                    var decr = 0;
1181                    // fix box-sizing in ie7/8
1182                    if(mfp.isLowIE) {
1183                        decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
1184                    }
1185                    item.img.css('max-height', mfp.wH-decr);
1186                }
1187            },
1188            _onImageHasSize: function(item) {
1189                if(item.img) {
1190    
1191                    item.hasSize = true;
1192    
1193                    if(_imgInterval) {
1194                        clearInterval(_imgInterval);
1195                    }
1196    
1197                    item.isCheckingImgSize = false;
1198    
1199                    _mfpTrigger('ImageHasSize', item);
1200    
1201                    if(item.imgHidden) {
1202                        if(mfp.content)
1203                            mfp.content.removeClass('mfp-loading');
1204    
1205                        item.imgHidden = false;
1206                    }
1207    
1208                }
1209            },
1210    
1211            /**
1212             * Function that loops until the image has size to display elements that rely on it asap
1213             */
1214            findImageSize: function(item) {
1215    
1216                var counter = 0,
1217                    img = item.img[0],
1218                    mfpSetInterval = function(delay) {
1219    
1220                        if(_imgInterval) {
1221                            clearInterval(_imgInterval);
1222                        }
1223                        // decelerating interval that checks for size of an image
1224                        _imgInterval = setInterval(function() {
1225                            if(img.naturalWidth > 0) {
1226                                mfp._onImageHasSize(item);
1227                                return;
1228                            }
1229    
1230                            if(counter > 200) {
1231                                clearInterval(_imgInterval);
1232                            }
1233    
1234                            counter++;
1235                            if(counter === 3) {
1236                                mfpSetInterval(10);
1237                            } else if(counter === 40) {
1238                                mfpSetInterval(50);
1239                            } else if(counter === 100) {
1240                                mfpSetInterval(500);
1241                            }
1242                        }, delay);
1243                    };
1244    
1245                mfpSetInterval(1);
1246            },
1247    
1248            getImage: function(item, template) {
1249    
1250                var guard = 0,
1251    
1252                    // image load complete handler
1253                    onLoadComplete = function() {
1254                        if(item) {
1255                            if (item.img[0].complete) {
1256                                item.img.off('.mfploader');
1257    
1258                                if(item === mfp.currItem){
1259                                    mfp._onImageHasSize(item);
1260    
1261                                    mfp.updateStatus('ready');
1262                                }
1263    
1264                                item.hasSize = true;
1265                                item.loaded = true;
1266    
1267                                _mfpTrigger('ImageLoadComplete');
1268    
1269                            }
1270                            else {
1271                                // if image complete check fails 200 times (20 sec), we assume that there was an error.
1272                                guard++;
1273                                if(guard < 200) {
1274                                    setTimeout(onLoadComplete,100);
1275                                } else {
1276                                    onLoadError();
1277                                }
1278                            }
1279                        }
1280                    },
1281    
1282                    // image error handler
1283                    onLoadError = function() {
1284                        if(item) {
1285                            item.img.off('.mfploader');
1286                            if(item === mfp.currItem){
1287                                mfp._onImageHasSize(item);
1288                                mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
1289                            }
1290    
1291                            item.hasSize = true;
1292                            item.loaded = true;
1293                            item.loadError = true;
1294                        }
1295                    },
1296                    imgSt = mfp.st.image;
1297    
1298    
1299                var el = template.find('.mfp-img');
1300                if(el.length) {
1301                    var img = document.createElement('img');
1302                    img.className = 'mfp-img';
1303                    if(item.el && item.el.find('img').length) {
1304                        img.alt = item.el.find('img').attr('alt');
1305                    }
1306                    item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
1307                    img.src = item.src;
1308    
1309                    // without clone() "error" event is not firing when IMG is replaced by new IMG
1310                    // TODO: find a way to avoid such cloning
1311                    if(el.is('img')) {
1312                        item.img = item.img.clone();
1313                    }
1314    
1315                    img = item.img[0];
1316                    if(img.naturalWidth > 0) {
1317                        item.hasSize = true;
1318                    } else if(!img.width) {
1319                        item.hasSize = false;
1320                    }
1321                }
1322    
1323                mfp._parseMarkup(template, {
1324                    title: _getTitle(item),
1325                    img_replaceWith: item.img
1326                }, item);
1327    
1328                mfp.resizeImage();
1329    
1330                if(item.hasSize) {
1331                    if(_imgInterval) clearInterval(_imgInterval);
1332    
1333                    if(item.loadError) {
1334                        template.addClass('mfp-loading');
1335                        mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
1336                    } else {
1337                        template.removeClass('mfp-loading');
1338                        mfp.updateStatus('ready');
1339                    }
1340                    return template;
1341                }
1342    
1343                mfp.updateStatus('loading');
1344                item.loading = true;
1345    
1346                if(!item.hasSize) {
1347                    item.imgHidden = true;
1348                    template.addClass('mfp-loading');
1349                    mfp.findImageSize(item);
1350                }
1351    
1352                return template;
1353            }
1354        }
1355    });
1356    
1357    /*>>image*/
1358    
1359    /*>>zoom*/
1360    var hasMozTransform,
1361        getHasMozTransform = function() {
1362            if(hasMozTransform === undefined) {
1363                hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
1364            }
1365            return hasMozTransform;
1366        };
1367    
1368    $.magnificPopup.registerModule('zoom', {
1369    
1370        options: {
1371            enabled: false,
1372            easing: 'ease-in-out',
1373            duration: 300,
1374            opener: function(element) {
1375                return element.is('img') ? element : element.find('img');
1376            }
1377        },
1378    
1379        proto: {
1380    
1381            initZoom: function() {
1382                var zoomSt = mfp.st.zoom,
1383                    ns = '.zoom',
1384                    image;
1385    
1386                if(!zoomSt.enabled || !mfp.supportsTransition) {
1387                    return;
1388                }
1389    
1390                var duration = zoomSt.duration,
1391                    getElToAnimate = function(image) {
1392                        var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
1393                            transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
1394                            cssObj = {
1395                                position: 'fixed',
1396                                zIndex: 9999,
1397                                left: 0,
1398                                top: 0,
1399                                '-webkit-backface-visibility': 'hidden'
1400                            },
1401                            t = 'transition';
1402    
1403                        cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
1404    
1405                        newImg.css(cssObj);
1406                        return newImg;
1407                    },
1408                    showMainContent = function() {
1409                        mfp.content.css('visibility', 'visible');
1410                    },
1411                    openTimeout,
1412                    animatedImg;
1413    
1414                _mfpOn('BuildControls'+ns, function() {
1415                    if(mfp._allowZoom()) {
1416    
1417                        clearTimeout(openTimeout);
1418                        mfp.content.css('visibility', 'hidden');
1419    
1420                        // Basically, all code below does is clones existing image, puts in on top of the current one and animated it
1421    
1422                        image = mfp._getItemToZoom();
1423    
1424                        if(!image) {
1425                            showMainContent();
1426                            return;
1427                        }
1428    
1429                        animatedImg = getElToAnimate(image);
1430    
1431                        animatedImg.css( mfp._getOffset() );
1432    
1433                        mfp.wrap.append(animatedImg);
1434    
1435                        openTimeout = setTimeout(function() {
1436                            animatedImg.css( mfp._getOffset( true ) );
1437                            openTimeout = setTimeout(function() {
1438    
1439                                showMainContent();
1440    
1441                                setTimeout(function() {
1442                                    animatedImg.remove();
1443                                    image = animatedImg = null;
1444                                    _mfpTrigger('ZoomAnimationEnded');
1445                                }, 16); // avoid blink when switching images
1446    
1447                            }, duration); // this timeout equals animation duration
1448    
1449                        }, 16); // by adding this timeout we avoid short glitch at the beginning of animation
1450    
1451    
1452                        // Lots of timeouts...
1453                    }
1454                });
1455                _mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
1456                    if(mfp._allowZoom()) {
1457    
1458                        clearTimeout(openTimeout);
1459    
1460                        mfp.st.removalDelay = duration;
1461    
1462                        if(!image) {
1463                            image = mfp._getItemToZoom();
1464                            if(!image) {
1465                                return;
1466                            }
1467                            animatedImg = getElToAnimate(image);
1468                        }
1469    
1470                        animatedImg.css( mfp._getOffset(true) );
1471                        mfp.wrap.append(animatedImg);
1472                        mfp.content.css('visibility', 'hidden');
1473    
1474                        setTimeout(function() {
1475                            animatedImg.css( mfp._getOffset() );
1476                        }, 16);
1477                    }
1478    
1479                });
1480    
1481                _mfpOn(CLOSE_EVENT+ns, function() {
1482                    if(mfp._allowZoom()) {
1483                        showMainContent();
1484                        if(animatedImg) {
1485                            animatedImg.remove();
1486                        }
1487                        image = null;
1488                    }
1489                });
1490            },
1491    
1492            _allowZoom: function() {
1493                return mfp.currItem.type === 'image';
1494            },
1495    
1496            _getItemToZoom: function() {
1497                if(mfp.currItem.hasSize) {
1498                    return mfp.currItem.img;
1499                } else {
1500                    return false;
1501                }
1502            },
1503    
1504            // Get element postion relative to viewport
1505            _getOffset: function(isLarge) {
1506                var el;
1507                if(isLarge) {
1508                    el = mfp.currItem.img;
1509                } else {
1510                    el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
1511                }
1512    
1513                var offset = el.offset();
1514                var paddingTop = parseInt(el.css('padding-top'),10);
1515                var paddingBottom = parseInt(el.css('padding-bottom'),10);
1516                offset.top -= ( $(window).scrollTop() - paddingTop );
1517    
1518    
1519                /*
1520    
1521                Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
1522    
1523                 */
1524                var obj = {
1525                    width: el.width(),
1526                    // fix Zepto height+padding issue
1527                    height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
1528                };
1529    
1530                // I hate to do this, but there is no another option
1531                if( getHasMozTransform() ) {
1532                    obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
1533                } else {
1534                    obj.left = offset.left;
1535                    obj.top = offset.top;
1536                }
1537                return obj;
1538            }
1539    
1540        }
1541    });
1542    
1543    
1544    
1545    /*>>zoom*/
1546    
1547    /*>>iframe*/
1548    
1549    var IFRAME_NS = 'iframe',
1550        _emptyPage = '//about:blank',
1551    
1552        _fixIframeBugs = function(isShowing) {
1553            if(mfp.currTemplate[IFRAME_NS]) {
1554                var el = mfp.currTemplate[IFRAME_NS].find('iframe');
1555                if(el.length) {
1556                    // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
1557                    if(!isShowing) {
1558                        el[0].src = _emptyPage;
1559                    }
1560    
1561                    // IE8 black screen bug fix
1562                    if(mfp.isIE8) {
1563                        el.css('display', isShowing ? 'block' : 'none');
1564                    }
1565                }
1566            }
1567        };
1568    
1569    $.magnificPopup.registerModule(IFRAME_NS, {
1570    
1571        options: {
1572            markup: '<div class="mfp-iframe-scaler">'+
1573                        '<div class="mfp-close"></div>'+
1574                        '<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
1575                    '</div>',
1576    
1577            srcAction: 'iframe_src',
1578    
1579            // we don't care and support only one default type of URL by default
1580            patterns: {
1581                youtube: {
1582                    index: 'youtube.com',
1583                    id: 'v=',
1584                    src: '//www.youtube.com/embed/%id%?autoplay=1'
1585                },
1586                vimeo: {
1587                    index: 'vimeo.com/',
1588                    id: '/',
1589                    src: '//player.vimeo.com/video/%id%?autoplay=1'
1590                },
1591                gmaps: {
1592                    index: '//maps.google.',
1593                    src: '%id%&output=embed'
1594                }
1595            }
1596        },
1597    
1598        proto: {
1599            initIframe: function() {
1600                mfp.types.push(IFRAME_NS);
1601    
1602                _mfpOn('BeforeChange', function(e, prevType, newType) {
1603                    if(prevType !== newType) {
1604                        if(prevType === IFRAME_NS) {
1605                            _fixIframeBugs(); // iframe if removed
1606                        } else if(newType === IFRAME_NS) {
1607                            _fixIframeBugs(true); // iframe is showing
1608                        }
1609                    }// else {
1610                        // iframe source is switched, don't do anything
1611                    //}
1612                });
1613    
1614                _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
1615                    _fixIframeBugs();
1616                });
1617            },
1618    
1619            getIframe: function(item, template) {
1620                var embedSrc = item.src;
1621                var iframeSt = mfp.st.iframe;
1622    
1623                $.each(iframeSt.patterns, function() {
1624                    if(embedSrc.indexOf( this.index ) > -1) {
1625                        if(this.id) {
1626                            if(typeof this.id === 'string') {
1627                                embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
1628                            } else {
1629                                embedSrc = this.id.call( this, embedSrc );
1630                            }
1631                        }
1632                        embedSrc = this.src.replace('%id%', embedSrc );
1633                        return false; // break;
1634                    }
1635                });
1636    
1637                var dataObj = {};
1638                if(iframeSt.srcAction) {
1639                    dataObj[iframeSt.srcAction] = embedSrc;
1640                }
1641                mfp._parseMarkup(template, dataObj, item);
1642    
1643                mfp.updateStatus('ready');
1644    
1645                return template;
1646            }
1647        }
1648    });
1649    
1650    
1651    
1652    /*>>iframe*/
1653    
1654    /*>>gallery*/
1655    /**
1656     * Get looped index depending on number of slides
1657     */
1658    var _getLoopedId = function(index) {
1659            var numSlides = mfp.items.length;
1660            if(index > numSlides - 1) {
1661                return index - numSlides;
1662            } else  if(index < 0) {
1663                return numSlides + index;
1664            }
1665            return index;
1666        },
1667        _replaceCurrTotal = function(text, curr, total) {
1668            return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
1669        };
1670    
1671    $.magnificPopup.registerModule('gallery', {
1672    
1673        options: {
1674            enabled: false,
1675            arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
1676            preload: [0,2],
1677            navigateByImgClick: true,
1678            arrows: true,
1679    
1680            tPrev: 'Previous (Left arrow key)',
1681            tNext: 'Next (Right arrow key)',
1682            tCounter: '%curr% of %total%'
1683        },
1684    
1685        proto: {
1686            initGallery: function() {
1687    
1688                var gSt = mfp.st.gallery,
1689                    ns = '.mfp-gallery';
1690    
1691                mfp.direction = true; // true - next, false - prev
1692    
1693                if(!gSt || !gSt.enabled ) return false;
1694    
1695                _wrapClasses += ' mfp-gallery';
1696    
1697                _mfpOn(OPEN_EVENT+ns, function() {
1698    
1699                    if(gSt.navigateByImgClick) {
1700                        mfp.wrap.on('click'+ns, '.mfp-img', function() {
1701                            if(mfp.items.length > 1) {
1702                                mfp.next();
1703                                return false;
1704                            }
1705                        });
1706                    }
1707    
1708                    _document.on('keydown'+ns, function(e) {
1709                        if (e.keyCode === 37) {
1710                            mfp.prev();
1711                        } else if (e.keyCode === 39) {
1712                            mfp.next();
1713                        }
1714                    });
1715                });
1716    
1717                _mfpOn('UpdateStatus'+ns, function(e, data) {
1718                    if(data.text) {
1719                        data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
1720                    }
1721                });
1722    
1723                _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
1724                    var l = mfp.items.length;
1725                    values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
1726                });
1727    
1728                _mfpOn('BuildControls' + ns, function() {
1729                    if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
1730                        var markup = gSt.arrowMarkup,
1731                            arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),
1732                            arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);
1733    
1734                        arrowLeft.click(function() {
1735                            mfp.prev();
1736                        });
1737                        arrowRight.click(function() {
1738                            mfp.next();
1739                        });
1740    
1741                        mfp.container.append(arrowLeft.add(arrowRight));
1742                    }
1743                });
1744    
1745                _mfpOn(CHANGE_EVENT+ns, function() {
1746                    if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
1747    
1748                    mfp._preloadTimeout = setTimeout(function() {
1749                        mfp.preloadNearbyImages();
1750                        mfp._preloadTimeout = null;
1751                    }, 16);
1752                });
1753    
1754    
1755                _mfpOn(CLOSE_EVENT+ns, function() {
1756                    _document.off(ns);
1757                    mfp.wrap.off('click'+ns);
1758                    mfp.arrowRight = mfp.arrowLeft = null;
1759                });
1760    
1761            },
1762            next: function() {
1763                mfp.direction = true;
1764                mfp.index = _getLoopedId(mfp.index + 1);
1765                mfp.updateItemHTML();
1766            },
1767            prev: function() {
1768                mfp.direction = false;
1769                mfp.index = _getLoopedId(mfp.index - 1);
1770                mfp.updateItemHTML();
1771            },
1772            goTo: function(newIndex) {
1773                mfp.direction = (newIndex >= mfp.index);
1774                mfp.index = newIndex;
1775                mfp.updateItemHTML();
1776            },
1777            preloadNearbyImages: function() {
1778                var p = mfp.st.gallery.preload,
1779                    preloadBefore = Math.min(p[0], mfp.items.length),
1780                    preloadAfter = Math.min(p[1], mfp.items.length),
1781                    i;
1782    
1783                for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
1784                    mfp._preloadItem(mfp.index+i);
1785                }
1786                for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
1787                    mfp._preloadItem(mfp.index-i);
1788                }
1789            },
1790            _preloadItem: function(index) {
1791                index = _getLoopedId(index);
1792    
1793                if(mfp.items[index].preloaded) {
1794                    return;
1795                }
1796    
1797                var item = mfp.items[index];
1798                if(!item.parsed) {
1799                    item = mfp.parseEl( index );
1800                }
1801    
1802                _mfpTrigger('LazyLoad', item);
1803    
1804                if(item.type === 'image') {
1805                    item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
1806                        item.hasSize = true;
1807                    }).on('error.mfploader', function() {
1808                        item.hasSize = true;
1809                        item.loadError = true;
1810                        _mfpTrigger('LazyLoadError', item);
1811                    }).attr('src', item.src);
1812                }
1813    
1814    
1815                item.preloaded = true;
1816            }
1817        }
1818    });
1819    
1820    /*>>gallery*/
1821    
1822    /*>>retina*/
1823    
1824    var RETINA_NS = 'retina';
1825    
1826    $.magnificPopup.registerModule(RETINA_NS, {
1827        options: {
1828            replaceSrc: function(item) {
1829                return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
1830            },
1831            ratio: 1 // Function or number.  Set to 1 to disable.
1832        },
1833        proto: {
1834            initRetina: function() {
1835                if(window.devicePixelRatio > 1) {
1836    
1837                    var st = mfp.st.retina,
1838                        ratio = st.ratio;
1839    
1840                    ratio = !isNaN(ratio) ? ratio : ratio();
1841    
1842                    if(ratio > 1) {
1843                        _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
1844                            item.img.css({
1845                                'max-width': item.img[0].naturalWidth / ratio,
1846                                'width': '100%'
1847                            });
1848                        });
1849                        _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
1850                            item.src = st.replaceSrc(item, ratio);
1851                        });
1852                    }
1853                }
1854    
1855            }
1856        }
1857    });
1858    
1859    /*>>retina*/
1860     _checkInstance(); }));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.