weather-apps-jekyll 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -0
  3. data/README.md +19 -0
  4. data/_config.yml +19 -0
  5. data/_includes/app-download.html +28 -0
  6. data/_includes/featured.html +72 -0
  7. data/_includes/footer.html +54 -0
  8. data/_includes/head.html +29 -0
  9. data/_includes/home.html +35 -0
  10. data/_includes/navbar.html +38 -0
  11. data/_includes/people.html +54 -0
  12. data/_includes/screen.html +104 -0
  13. data/_includes/scripts.html +15 -0
  14. data/_layouts/default.html +49 -0
  15. data/assets/css/animate.css +3303 -0
  16. data/assets/css/bootsnav.css +1474 -0
  17. data/assets/css/bootstrap.css.map +1 -0
  18. data/assets/css/bootstrap.min.css +5 -0
  19. data/assets/css/bootstrap.min.css.map +1 -0
  20. data/assets/css/font-awesome.min.css +4 -0
  21. data/assets/css/fonts/slick.eot +0 -0
  22. data/assets/css/fonts/slick.svg +14 -0
  23. data/assets/css/fonts/slick.ttf +0 -0
  24. data/assets/css/fonts/slick.woff +0 -0
  25. data/assets/css/iconfont.css +1838 -0
  26. data/assets/css/magnific-popup.css +391 -0
  27. data/assets/css/plugins.css +123 -0
  28. data/assets/css/responsive.css +200 -0
  29. data/assets/css/style.css +1309 -0
  30. data/assets/css/swiper.min.css +15 -0
  31. data/assets/fonts/FontAwesome.otf +0 -0
  32. data/assets/fonts/bootstrapThemesCo-icon.eot +0 -0
  33. data/assets/fonts/bootstrapThemesCo-icon.svg +631 -0
  34. data/assets/fonts/bootstrapThemesCo-icon.ttf +0 -0
  35. data/assets/fonts/bootstrapThemesCo-icon.woff +0 -0
  36. data/assets/fonts/fontawesome-webfont.eot +0 -0
  37. data/assets/fonts/fontawesome-webfont.svg +2671 -0
  38. data/assets/fonts/fontawesome-webfont.ttf +0 -0
  39. data/assets/fonts/fontawesome-webfont.woff +0 -0
  40. data/assets/fonts/fontawesome-webfont.woff2 +0 -0
  41. data/assets/images/appdownload.png +0 -0
  42. data/assets/images/appdownload1.png +0 -0
  43. data/assets/images/appstor.png +0 -0
  44. data/assets/images/bodybg.png +0 -0
  45. data/assets/images/cloud1.png +0 -0
  46. data/assets/images/downloadbg.png +0 -0
  47. data/assets/images/drag1.png +0 -0
  48. data/assets/images/drag2.png +0 -0
  49. data/assets/images/drag3.png +0 -0
  50. data/assets/images/footer-logo.png +0 -0
  51. data/assets/images/googleplay.png +0 -0
  52. data/assets/images/homebg.png +0 -0
  53. data/assets/images/logo.png +0 -0
  54. data/assets/images/phone01.png +0 -0
  55. data/assets/images/phone1.png +0 -0
  56. data/assets/images/rainy1.png +0 -0
  57. data/assets/images/screen01.png +0 -0
  58. data/assets/images/screen02.png +0 -0
  59. data/assets/images/screen03.png +0 -0
  60. data/assets/images/sun1.png +0 -0
  61. data/assets/images/test1.png +0 -0
  62. data/assets/js/bootsnav.js +578 -0
  63. data/assets/js/jquery.collapse.js +176 -0
  64. data/assets/js/jquery.easing.1.3.js +205 -0
  65. data/assets/js/jquery.magnific-popup.js +2062 -0
  66. data/assets/js/main.js +107 -0
  67. data/assets/js/plugins.js +85 -0
  68. data/assets/js/swiper.min.js +18 -0
  69. data/assets/js/vendor/bootstrap.min.js +7 -0
  70. data/assets/js/vendor/jquery-1.11.2.min.js +4 -0
  71. data/assets/js/vendor/modernizr-2.8.3-respond-1.4.2.min.js +11 -0
  72. metadata +72 -2
@@ -0,0 +1,176 @@
1
+ /*
2
+ * Collapse plugin for jQuery
3
+ * --
4
+ * source: http://github.com/danielstocks/jQuery-Collapse/
5
+ * site: http://webcloud.se/jQuery-Collapse
6
+ *
7
+ * @author Daniel Stocks (http://webcloud.se)
8
+ * Copyright 2013, Daniel Stocks
9
+ * Released under the MIT, BSD, and GPL Licenses.
10
+ */
11
+
12
+ (function($) {
13
+
14
+ // Constructor
15
+ function Collapse (el, options) {
16
+ options = options || {};
17
+ var _this = this,
18
+ query = options.query || "> :even";
19
+
20
+ $.extend(_this, {
21
+ $el: el,
22
+ options : options,
23
+ sections: [],
24
+ isAccordion : options.accordion || false,
25
+ db : options.persist ? jQueryCollapseStorage(el.get(0).id) : false
26
+ });
27
+
28
+ // Figure out what sections are open if storage is used
29
+ _this.states = _this.db ? _this.db.read() : [];
30
+
31
+ // For every pair of elements in given
32
+ // element, create a section
33
+ _this.$el.find(query).each(function() {
34
+ new jQueryCollapseSection($(this), _this);
35
+ });
36
+
37
+ // Capute ALL the clicks!
38
+ (function(scope) {
39
+ _this.$el.on("click", "[data-collapse-summary] " + (scope.options.clickQuery || ""),
40
+ $.proxy(_this.handleClick, scope));
41
+
42
+ _this.$el.bind("toggle close open",
43
+ $.proxy(_this.handleEvent, scope));
44
+
45
+ }(_this));
46
+ }
47
+
48
+ Collapse.prototype = {
49
+ handleClick: function(e, state) {
50
+ e.preventDefault();
51
+ var state = state || "toggle"
52
+ var sections = this.sections,
53
+ l = sections.length;
54
+ while(l--) {
55
+ if($.contains(sections[l].$summary[0], e.target)) {
56
+ sections[l][state]();
57
+ break;
58
+ }
59
+ }
60
+ },
61
+ handleEvent: function(e) {
62
+ if(e.target == this.$el.get(0)) return this[e.type]();
63
+ this.handleClick(e, e.type);
64
+ },
65
+ open: function(eq) {
66
+ if(isFinite(eq)) return this.sections[eq].open();
67
+ $.each(this.sections, function(i, section) {
68
+ section.open();
69
+ })
70
+ },
71
+ close: function(eq) {
72
+ if(isFinite(eq)) return this.sections[eq].close();
73
+ $.each(this.sections, function(i, section) {
74
+ section.close();
75
+ })
76
+ },
77
+ toggle: function(eq) {
78
+ if(isFinite(eq)) return this.sections[eq].toggle();
79
+ $.each(this.sections, function(i, section) {
80
+ section.toggle();
81
+ })
82
+ }
83
+ };
84
+
85
+ // Section constructor
86
+ function Section($el, parent) {
87
+
88
+ if(!parent.options.clickQuery) $el.wrapInner('<a href="#"/>');
89
+
90
+ $.extend(this, {
91
+ isOpen : false,
92
+ $summary : $el.attr("data-collapse-summary",""),
93
+ $details : $el.next(),
94
+ options: parent.options,
95
+ parent: parent
96
+ });
97
+ parent.sections.push(this);
98
+
99
+ // Check current state of section
100
+ var state = parent.states[this._index()];
101
+
102
+ if(state === 0) {
103
+ this.close(true)
104
+ }
105
+ else if(this.$summary.is(".open") || state === 1) {
106
+ this.open(true);
107
+ } else {
108
+ this.close(true)
109
+ }
110
+ }
111
+
112
+ Section.prototype = {
113
+ toggle : function() {
114
+ this.isOpen ? this.close() : this.open();
115
+ },
116
+ close: function(bypass) {
117
+ this._changeState("close", bypass);
118
+ },
119
+ open: function(bypass) {
120
+ var _this = this;
121
+ if(_this.options.accordion && !bypass) {
122
+ $.each(_this.parent.sections, function(i, section) {
123
+ section.close()
124
+ });
125
+ }
126
+ _this._changeState("open", bypass);
127
+ },
128
+ _index: function() {
129
+ return $.inArray(this, this.parent.sections);
130
+ },
131
+ _changeState: function(state, bypass) {
132
+
133
+ var _this = this;
134
+ _this.isOpen = state == "open";
135
+ if($.isFunction(_this.options[state]) && !bypass) {
136
+ _this.options[state].apply(_this.$details);
137
+ } else {
138
+ _this.$details[_this.isOpen ? "show" : "hide"]();
139
+ }
140
+
141
+ _this.$summary.toggleClass("open", state != "close")
142
+ _this.$details.attr("aria-hidden", state == "close");
143
+ _this.$summary.attr("aria-expanded", state == "open");
144
+ _this.$summary.trigger(state == "open" ? "opened" : "closed", _this);
145
+ if(_this.parent.db) {
146
+ _this.parent.db.write(_this._index(), _this.isOpen);
147
+ }
148
+ }
149
+ };
150
+
151
+ // Expose in jQuery API
152
+ $.fn.extend({
153
+ collapse: function(options, scan) {
154
+ var nodes = (scan) ? $("body").find("[data-collapse]") : $(this);
155
+ return nodes.each(function() {
156
+ var settings = (scan) ? {} : options,
157
+ values = $(this).attr("data-collapse") || "";
158
+ $.each(values.split(" "), function(i,v) {
159
+ if(v) settings[v] = true;
160
+ });
161
+ new Collapse($(this), settings);
162
+ });
163
+ }
164
+ });
165
+
166
+ //jQuery DOM Ready
167
+ $(function() {
168
+ $.fn.collapse(false, true);
169
+ });
170
+
171
+ // Expose constructor to
172
+ // global namespace
173
+ jQueryCollapse = Collapse;
174
+ jQueryCollapseSection = Section;
175
+
176
+ })(window.jQuery);
@@ -0,0 +1,205 @@
1
+ /*
2
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
3
+ *
4
+ * Uses the built in easing capabilities added In jQuery 1.1
5
+ * to offer multiple easing options
6
+ *
7
+ * TERMS OF USE - jQuery Easing
8
+ *
9
+ * Open source under the BSD License.
10
+ *
11
+ * Copyright © 2008 George McGinley Smith
12
+ * All rights reserved.
13
+ *
14
+ * Redistribution and use in source and binary forms, with or without modification,
15
+ * are permitted provided that the following conditions are met:
16
+ *
17
+ * Redistributions of source code must retain the above copyright notice, this list of
18
+ * conditions and the following disclaimer.
19
+ * Redistributions in binary form must reproduce the above copyright notice, this list
20
+ * of conditions and the following disclaimer in the documentation and/or other materials
21
+ * provided with the distribution.
22
+ *
23
+ * Neither the name of the author nor the names of contributors may be used to endorse
24
+ * or promote products derived from this software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
27
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
35
+ *
36
+ */
37
+
38
+ // t: current time, b: begInnIng value, c: change In value, d: duration
39
+ jQuery.easing['jswing'] = jQuery.easing['swing'];
40
+
41
+ jQuery.extend( jQuery.easing,
42
+ {
43
+ def: 'easeOutQuad',
44
+ swing: function (x, t, b, c, d) {
45
+ //alert(jQuery.easing.default);
46
+ return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
47
+ },
48
+ easeInQuad: function (x, t, b, c, d) {
49
+ return c*(t/=d)*t + b;
50
+ },
51
+ easeOutQuad: function (x, t, b, c, d) {
52
+ return -c *(t/=d)*(t-2) + b;
53
+ },
54
+ easeInOutQuad: function (x, t, b, c, d) {
55
+ if ((t/=d/2) < 1) return c/2*t*t + b;
56
+ return -c/2 * ((--t)*(t-2) - 1) + b;
57
+ },
58
+ easeInCubic: function (x, t, b, c, d) {
59
+ return c*(t/=d)*t*t + b;
60
+ },
61
+ easeOutCubic: function (x, t, b, c, d) {
62
+ return c*((t=t/d-1)*t*t + 1) + b;
63
+ },
64
+ easeInOutCubic: function (x, t, b, c, d) {
65
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
66
+ return c/2*((t-=2)*t*t + 2) + b;
67
+ },
68
+ easeInQuart: function (x, t, b, c, d) {
69
+ return c*(t/=d)*t*t*t + b;
70
+ },
71
+ easeOutQuart: function (x, t, b, c, d) {
72
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
73
+ },
74
+ easeInOutQuart: function (x, t, b, c, d) {
75
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
76
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
77
+ },
78
+ easeInQuint: function (x, t, b, c, d) {
79
+ return c*(t/=d)*t*t*t*t + b;
80
+ },
81
+ easeOutQuint: function (x, t, b, c, d) {
82
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
83
+ },
84
+ easeInOutQuint: function (x, t, b, c, d) {
85
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
86
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
87
+ },
88
+ easeInSine: function (x, t, b, c, d) {
89
+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
90
+ },
91
+ easeOutSine: function (x, t, b, c, d) {
92
+ return c * Math.sin(t/d * (Math.PI/2)) + b;
93
+ },
94
+ easeInOutSine: function (x, t, b, c, d) {
95
+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
96
+ },
97
+ easeInExpo: function (x, t, b, c, d) {
98
+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
99
+ },
100
+ easeOutExpo: function (x, t, b, c, d) {
101
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
102
+ },
103
+ easeInOutExpo: function (x, t, b, c, d) {
104
+ if (t==0) return b;
105
+ if (t==d) return b+c;
106
+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
107
+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
108
+ },
109
+ easeInCirc: function (x, t, b, c, d) {
110
+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
111
+ },
112
+ easeOutCirc: function (x, t, b, c, d) {
113
+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
114
+ },
115
+ easeInOutCirc: function (x, t, b, c, d) {
116
+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
117
+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
118
+ },
119
+ easeInElastic: function (x, t, b, c, d) {
120
+ var s=1.70158;var p=0;var a=c;
121
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
122
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
123
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
124
+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
125
+ },
126
+ easeOutElastic: function (x, t, b, c, d) {
127
+ var s=1.70158;var p=0;var a=c;
128
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
129
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
130
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
131
+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
132
+ },
133
+ easeInOutElastic: function (x, t, b, c, d) {
134
+ var s=1.70158;var p=0;var a=c;
135
+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
136
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
137
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
138
+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
139
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
140
+ },
141
+ easeInBack: function (x, t, b, c, d, s) {
142
+ if (s == undefined) s = 1.70158;
143
+ return c*(t/=d)*t*((s+1)*t - s) + b;
144
+ },
145
+ easeOutBack: function (x, t, b, c, d, s) {
146
+ if (s == undefined) s = 1.70158;
147
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
148
+ },
149
+ easeInOutBack: function (x, t, b, c, d, s) {
150
+ if (s == undefined) s = 1.70158;
151
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
152
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
153
+ },
154
+ easeInBounce: function (x, t, b, c, d) {
155
+ return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
156
+ },
157
+ easeOutBounce: function (x, t, b, c, d) {
158
+ if ((t/=d) < (1/2.75)) {
159
+ return c*(7.5625*t*t) + b;
160
+ } else if (t < (2/2.75)) {
161
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
162
+ } else if (t < (2.5/2.75)) {
163
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
164
+ } else {
165
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
166
+ }
167
+ },
168
+ easeInOutBounce: function (x, t, b, c, d) {
169
+ if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
170
+ return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
171
+ }
172
+ });
173
+
174
+ /*
175
+ *
176
+ * TERMS OF USE - EASING EQUATIONS
177
+ *
178
+ * Open source under the BSD License.
179
+ *
180
+ * Copyright © 2001 Robert Penner
181
+ * All rights reserved.
182
+ *
183
+ * Redistribution and use in source and binary forms, with or without modification,
184
+ * are permitted provided that the following conditions are met:
185
+ *
186
+ * Redistributions of source code must retain the above copyright notice, this list of
187
+ * conditions and the following disclaimer.
188
+ * Redistributions in binary form must reproduce the above copyright notice, this list
189
+ * of conditions and the following disclaimer in the documentation and/or other materials
190
+ * provided with the distribution.
191
+ *
192
+ * Neither the name of the author nor the names of contributors may be used to endorse
193
+ * or promote products derived from this software without specific prior written permission.
194
+ *
195
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
196
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
197
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
198
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
199
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
200
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
201
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
202
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
203
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
204
+ *
205
+ */
@@ -0,0 +1,2062 @@
1
+ /*! Magnific Popup - v1.0.1 - 2015-12-30
2
+ * http://dimsemenov.com/plugins/magnific-popup/
3
+ * Copyright (c) 2015 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.isIE7 = appVersion.indexOf("MSIE 7.") !== -1;
140
+ mfp.isIE8 = appVersion.indexOf("MSIE 8.") !== -1;
141
+ mfp.isLowIE = mfp.isIE7 || mfp.isIE8;
142
+ mfp.isAndroid = (/android/gi).test(appVersion);
143
+ mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
144
+ mfp.supportsTransition = supportsTransitions();
145
+
146
+ // We disable fixed positioned lightbox on devices that don't handle it nicely.
147
+ // If you know a better way of detecting this - let me know.
148
+ mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
149
+ _document = $(document);
150
+
151
+ mfp.popupsCache = {};
152
+ },
153
+
154
+ /**
155
+ * Opens popup
156
+ * @param data [description]
157
+ */
158
+ open: function(data) {
159
+
160
+ var i;
161
+
162
+ if(data.isObj === false) {
163
+ // convert jQuery collection to array to avoid conflicts later
164
+ mfp.items = data.items.toArray();
165
+
166
+ mfp.index = 0;
167
+ var items = data.items,
168
+ item;
169
+ for(i = 0; i < items.length; i++) {
170
+ item = items[i];
171
+ if(item.parsed) {
172
+ item = item.el[0];
173
+ }
174
+ if(item === data.el[0]) {
175
+ mfp.index = i;
176
+ break;
177
+ }
178
+ }
179
+ } else {
180
+ mfp.items = $.isArray(data.items) ? data.items : [data.items];
181
+ mfp.index = data.index || 0;
182
+ }
183
+
184
+ // if popup is already opened - we just update the content
185
+ if(mfp.isOpen) {
186
+ mfp.updateItemHTML();
187
+ return;
188
+ }
189
+
190
+ mfp.types = [];
191
+ _wrapClasses = '';
192
+ if(data.mainEl && data.mainEl.length) {
193
+ mfp.ev = data.mainEl.eq(0);
194
+ } else {
195
+ mfp.ev = _document;
196
+ }
197
+
198
+ if(data.key) {
199
+ if(!mfp.popupsCache[data.key]) {
200
+ mfp.popupsCache[data.key] = {};
201
+ }
202
+ mfp.currTemplate = mfp.popupsCache[data.key];
203
+ } else {
204
+ mfp.currTemplate = {};
205
+ }
206
+
207
+
208
+
209
+ mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data );
210
+ mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
211
+
212
+ if(mfp.st.modal) {
213
+ mfp.st.closeOnContentClick = false;
214
+ mfp.st.closeOnBgClick = false;
215
+ mfp.st.showCloseBtn = false;
216
+ mfp.st.enableEscapeKey = false;
217
+ }
218
+
219
+
220
+ // Building markup
221
+ // main containers are created only once
222
+ if(!mfp.bgOverlay) {
223
+
224
+ // Dark overlay
225
+ mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
226
+ mfp.close();
227
+ });
228
+
229
+ mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {
230
+ if(mfp._checkIfClose(e.target)) {
231
+ mfp.close();
232
+ }
233
+ });
234
+
235
+ mfp.container = _getEl('container', mfp.wrap);
236
+ }
237
+
238
+ mfp.contentContainer = _getEl('content');
239
+ if(mfp.st.preloader) {
240
+ mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
241
+ }
242
+
243
+
244
+ // Initializing modules
245
+ var modules = $.magnificPopup.modules;
246
+ for(i = 0; i < modules.length; i++) {
247
+ var n = modules[i];
248
+ n = n.charAt(0).toUpperCase() + n.slice(1);
249
+ mfp['init'+n].call(mfp);
250
+ }
251
+ _mfpTrigger('BeforeOpen');
252
+
253
+
254
+ if(mfp.st.showCloseBtn) {
255
+ // Close button
256
+ if(!mfp.st.closeBtnInside) {
257
+ mfp.wrap.append( _getCloseBtn() );
258
+ } else {
259
+ _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
260
+ values.close_replaceWith = _getCloseBtn(item.type);
261
+ });
262
+ _wrapClasses += ' mfp-close-btn-in';
263
+ }
264
+ }
265
+
266
+ if(mfp.st.alignTop) {
267
+ _wrapClasses += ' mfp-align-top';
268
+ }
269
+
270
+
271
+
272
+ if(mfp.fixedContentPos) {
273
+ mfp.wrap.css({
274
+ overflow: mfp.st.overflowY,
275
+ overflowX: 'hidden',
276
+ overflowY: mfp.st.overflowY
277
+ });
278
+ } else {
279
+ mfp.wrap.css({
280
+ top: _window.scrollTop(),
281
+ position: 'absolute'
282
+ });
283
+ }
284
+ if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
285
+ mfp.bgOverlay.css({
286
+ height: _document.height(),
287
+ position: 'absolute'
288
+ });
289
+ }
290
+
291
+
292
+
293
+ if(mfp.st.enableEscapeKey) {
294
+ // Close on ESC key
295
+ _document.on('keyup' + EVENT_NS, function(e) {
296
+ if(e.keyCode === 27) {
297
+ mfp.close();
298
+ }
299
+ });
300
+ }
301
+
302
+ _window.on('resize' + EVENT_NS, function() {
303
+ mfp.updateSize();
304
+ });
305
+
306
+
307
+ if(!mfp.st.closeOnContentClick) {
308
+ _wrapClasses += ' mfp-auto-cursor';
309
+ }
310
+
311
+ if(_wrapClasses)
312
+ mfp.wrap.addClass(_wrapClasses);
313
+
314
+
315
+ // this triggers recalculation of layout, so we get it once to not to trigger twice
316
+ var windowHeight = mfp.wH = _window.height();
317
+
318
+
319
+ var windowStyles = {};
320
+
321
+ if( mfp.fixedContentPos ) {
322
+ if(mfp._hasScrollBar(windowHeight)){
323
+ var s = mfp._getScrollbarSize();
324
+ if(s) {
325
+ windowStyles.marginRight = s;
326
+ }
327
+ }
328
+ }
329
+
330
+ if(mfp.fixedContentPos) {
331
+ if(!mfp.isIE7) {
332
+ windowStyles.overflow = 'hidden';
333
+ } else {
334
+ // ie7 double-scroll bug
335
+ $('body, html').css('overflow', 'hidden');
336
+ }
337
+ }
338
+
339
+
340
+
341
+ var classesToadd = mfp.st.mainClass;
342
+ if(mfp.isIE7) {
343
+ classesToadd += ' mfp-ie7';
344
+ }
345
+ if(classesToadd) {
346
+ mfp._addClassToMFP( classesToadd );
347
+ }
348
+
349
+ // add content
350
+ mfp.updateItemHTML();
351
+
352
+ _mfpTrigger('BuildControls');
353
+
354
+ // remove scrollbar, add margin e.t.c
355
+ $('html').css(windowStyles);
356
+
357
+ // add everything to DOM
358
+ mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
359
+
360
+ // Save last focused element
361
+ mfp._lastFocusedEl = document.activeElement;
362
+
363
+ // Wait for next cycle to allow CSS transition
364
+ setTimeout(function() {
365
+
366
+ if(mfp.content) {
367
+ mfp._addClassToMFP(READY_CLASS);
368
+ mfp._setFocus();
369
+ } else {
370
+ // if content is not defined (not loaded e.t.c) we add class only for BG
371
+ mfp.bgOverlay.addClass(READY_CLASS);
372
+ }
373
+
374
+ // Trap the focus in popup
375
+ _document.on('focusin' + EVENT_NS, mfp._onFocusIn);
376
+
377
+ }, 16);
378
+
379
+ mfp.isOpen = true;
380
+ mfp.updateSize(windowHeight);
381
+ _mfpTrigger(OPEN_EVENT);
382
+
383
+ return data;
384
+ },
385
+
386
+ /**
387
+ * Closes the popup
388
+ */
389
+ close: function() {
390
+ if(!mfp.isOpen) return;
391
+ _mfpTrigger(BEFORE_CLOSE_EVENT);
392
+
393
+ mfp.isOpen = false;
394
+ // for CSS3 animation
395
+ if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) {
396
+ mfp._addClassToMFP(REMOVING_CLASS);
397
+ setTimeout(function() {
398
+ mfp._close();
399
+ }, mfp.st.removalDelay);
400
+ } else {
401
+ mfp._close();
402
+ }
403
+ },
404
+
405
+ /**
406
+ * Helper for close() function
407
+ */
408
+ _close: function() {
409
+ _mfpTrigger(CLOSE_EVENT);
410
+
411
+ var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
412
+
413
+ mfp.bgOverlay.detach();
414
+ mfp.wrap.detach();
415
+ mfp.container.empty();
416
+
417
+ if(mfp.st.mainClass) {
418
+ classesToRemove += mfp.st.mainClass + ' ';
419
+ }
420
+
421
+ mfp._removeClassFromMFP(classesToRemove);
422
+
423
+ if(mfp.fixedContentPos) {
424
+ var windowStyles = {marginRight: ''};
425
+ if(mfp.isIE7) {
426
+ $('body, html').css('overflow', '');
427
+ } else {
428
+ windowStyles.overflow = '';
429
+ }
430
+ $('html').css(windowStyles);
431
+ }
432
+
433
+ _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
434
+ mfp.ev.off(EVENT_NS);
435
+
436
+ // clean up DOM elements that aren't removed
437
+ mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
438
+ mfp.bgOverlay.attr('class', 'mfp-bg');
439
+ mfp.container.attr('class', 'mfp-container');
440
+
441
+ // remove close button from target element
442
+ if(mfp.st.showCloseBtn &&
443
+ (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
444
+ if(mfp.currTemplate.closeBtn)
445
+ mfp.currTemplate.closeBtn.detach();
446
+ }
447
+
448
+
449
+ if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
450
+ $(mfp._lastFocusedEl).focus(); // put tab focus back
451
+ }
452
+ mfp.currItem = null;
453
+ mfp.content = null;
454
+ mfp.currTemplate = null;
455
+ mfp.prevHeight = 0;
456
+
457
+ _mfpTrigger(AFTER_CLOSE_EVENT);
458
+ },
459
+
460
+ updateSize: function(winHeight) {
461
+
462
+ if(mfp.isIOS) {
463
+ // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
464
+ var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
465
+ var height = window.innerHeight * zoomLevel;
466
+ mfp.wrap.css('height', height);
467
+ mfp.wH = height;
468
+ } else {
469
+ mfp.wH = winHeight || _window.height();
470
+ }
471
+ // Fixes #84: popup incorrectly positioned with position:relative on body
472
+ if(!mfp.fixedContentPos) {
473
+ mfp.wrap.css('height', mfp.wH);
474
+ }
475
+
476
+ _mfpTrigger('Resize');
477
+
478
+ },
479
+
480
+ /**
481
+ * Set content of popup based on current index
482
+ */
483
+ updateItemHTML: function() {
484
+ var item = mfp.items[mfp.index];
485
+
486
+ // Detach and perform modifications
487
+ mfp.contentContainer.detach();
488
+
489
+ if(mfp.content)
490
+ mfp.content.detach();
491
+
492
+ if(!item.parsed) {
493
+ item = mfp.parseEl( mfp.index );
494
+ }
495
+
496
+ var type = item.type;
497
+
498
+ _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
499
+ // BeforeChange event works like so:
500
+ // _mfpOn('BeforeChange', function(e, prevType, newType) { });
501
+
502
+ mfp.currItem = item;
503
+
504
+
505
+
506
+
507
+
508
+ if(!mfp.currTemplate[type]) {
509
+ var markup = mfp.st[type] ? mfp.st[type].markup : false;
510
+
511
+ // allows to modify markup
512
+ _mfpTrigger('FirstMarkupParse', markup);
513
+
514
+ if(markup) {
515
+ mfp.currTemplate[type] = $(markup);
516
+ } else {
517
+ // if there is no markup found we just define that template is parsed
518
+ mfp.currTemplate[type] = true;
519
+ }
520
+ }
521
+
522
+ if(_prevContentType && _prevContentType !== item.type) {
523
+ mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
524
+ }
525
+
526
+ var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
527
+ mfp.appendContent(newContent, type);
528
+
529
+ item.preloaded = true;
530
+
531
+ _mfpTrigger(CHANGE_EVENT, item);
532
+ _prevContentType = item.type;
533
+
534
+ // Append container back after its content changed
535
+ mfp.container.prepend(mfp.contentContainer);
536
+
537
+ _mfpTrigger('AfterChange');
538
+ },
539
+
540
+
541
+ /**
542
+ * Set HTML content of popup
543
+ */
544
+ appendContent: function(newContent, type) {
545
+ mfp.content = newContent;
546
+
547
+ if(newContent) {
548
+ if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
549
+ mfp.currTemplate[type] === true) {
550
+ // if there is no markup, we just append close button element inside
551
+ if(!mfp.content.find('.mfp-close').length) {
552
+ mfp.content.append(_getCloseBtn());
553
+ }
554
+ } else {
555
+ mfp.content = newContent;
556
+ }
557
+ } else {
558
+ mfp.content = '';
559
+ }
560
+
561
+ _mfpTrigger(BEFORE_APPEND_EVENT);
562
+ mfp.container.addClass('mfp-'+type+'-holder');
563
+
564
+ mfp.contentContainer.append(mfp.content);
565
+ },
566
+
567
+
568
+
569
+
570
+ /**
571
+ * Creates Magnific Popup data object based on given data
572
+ * @param {int} index Index of item to parse
573
+ */
574
+ parseEl: function(index) {
575
+ var item = mfp.items[index],
576
+ type;
577
+
578
+ if(item.tagName) {
579
+ item = { el: $(item) };
580
+ } else {
581
+ type = item.type;
582
+ item = { data: item, src: item.src };
583
+ }
584
+
585
+ if(item.el) {
586
+ var types = mfp.types;
587
+
588
+ // check for 'mfp-TYPE' class
589
+ for(var i = 0; i < types.length; i++) {
590
+ if( item.el.hasClass('mfp-'+types[i]) ) {
591
+ type = types[i];
592
+ break;
593
+ }
594
+ }
595
+
596
+ item.src = item.el.attr('data-mfp-src');
597
+ if(!item.src) {
598
+ item.src = item.el.attr('href');
599
+ }
600
+ }
601
+
602
+ item.type = type || mfp.st.type || 'inline';
603
+ item.index = index;
604
+ item.parsed = true;
605
+ mfp.items[index] = item;
606
+ _mfpTrigger('ElementParse', item);
607
+
608
+ return mfp.items[index];
609
+ },
610
+
611
+
612
+ /**
613
+ * Initializes single popup or a group of popups
614
+ */
615
+ addGroup: function(el, options) {
616
+ var eHandler = function(e) {
617
+ e.mfpEl = this;
618
+ mfp._openClick(e, el, options);
619
+ };
620
+
621
+ if(!options) {
622
+ options = {};
623
+ }
624
+
625
+ var eName = 'click.magnificPopup';
626
+ options.mainEl = el;
627
+
628
+ if(options.items) {
629
+ options.isObj = true;
630
+ el.off(eName).on(eName, eHandler);
631
+ } else {
632
+ options.isObj = false;
633
+ if(options.delegate) {
634
+ el.off(eName).on(eName, options.delegate , eHandler);
635
+ } else {
636
+ options.items = el;
637
+ el.off(eName).on(eName, eHandler);
638
+ }
639
+ }
640
+ },
641
+ _openClick: function(e, el, options) {
642
+ var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
643
+
644
+
645
+ if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
646
+ return;
647
+ }
648
+
649
+ var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
650
+
651
+ if(disableOn) {
652
+ if($.isFunction(disableOn)) {
653
+ if( !disableOn.call(mfp) ) {
654
+ return true;
655
+ }
656
+ } else { // else it's number
657
+ if( _window.width() < disableOn ) {
658
+ return true;
659
+ }
660
+ }
661
+ }
662
+
663
+ if(e.type) {
664
+ e.preventDefault();
665
+
666
+ // This will prevent popup from closing if element is inside and popup is already opened
667
+ if(mfp.isOpen) {
668
+ e.stopPropagation();
669
+ }
670
+ }
671
+
672
+
673
+ options.el = $(e.mfpEl);
674
+ if(options.delegate) {
675
+ options.items = el.find(options.delegate);
676
+ }
677
+ mfp.open(options);
678
+ },
679
+
680
+
681
+ /**
682
+ * Updates text on preloader
683
+ */
684
+ updateStatus: function(status, text) {
685
+
686
+ if(mfp.preloader) {
687
+ if(_prevStatus !== status) {
688
+ mfp.container.removeClass('mfp-s-'+_prevStatus);
689
+ }
690
+
691
+ if(!text && status === 'loading') {
692
+ text = mfp.st.tLoading;
693
+ }
694
+
695
+ var data = {
696
+ status: status,
697
+ text: text
698
+ };
699
+ // allows to modify status
700
+ _mfpTrigger('UpdateStatus', data);
701
+
702
+ status = data.status;
703
+ text = data.text;
704
+
705
+ mfp.preloader.html(text);
706
+
707
+ mfp.preloader.find('a').on('click', function(e) {
708
+ e.stopImmediatePropagation();
709
+ });
710
+
711
+ mfp.container.addClass('mfp-s-'+status);
712
+ _prevStatus = status;
713
+ }
714
+ },
715
+
716
+
717
+ /*
718
+ "Private" helpers that aren't private at all
719
+ */
720
+ // Check to close popup or not
721
+ // "target" is an element that was clicked
722
+ _checkIfClose: function(target) {
723
+
724
+ if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
725
+ return;
726
+ }
727
+
728
+ var closeOnContent = mfp.st.closeOnContentClick;
729
+ var closeOnBg = mfp.st.closeOnBgClick;
730
+
731
+ if(closeOnContent && closeOnBg) {
732
+ return true;
733
+ } else {
734
+
735
+ // We close the popup if click is on close button or on preloader. Or if there is no content.
736
+ if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
737
+ return true;
738
+ }
739
+
740
+ // if click is outside the content
741
+ if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) {
742
+ if(closeOnBg) {
743
+ // last check, if the clicked element is in DOM, (in case it's removed onclick)
744
+ if( $.contains(document, target) ) {
745
+ return true;
746
+ }
747
+ }
748
+ } else if(closeOnContent) {
749
+ return true;
750
+ }
751
+
752
+ }
753
+ return false;
754
+ },
755
+ _addClassToMFP: function(cName) {
756
+ mfp.bgOverlay.addClass(cName);
757
+ mfp.wrap.addClass(cName);
758
+ },
759
+ _removeClassFromMFP: function(cName) {
760
+ this.bgOverlay.removeClass(cName);
761
+ mfp.wrap.removeClass(cName);
762
+ },
763
+ _hasScrollBar: function(winHeight) {
764
+ return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
765
+ },
766
+ _setFocus: function() {
767
+ (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
768
+ },
769
+ _onFocusIn: function(e) {
770
+ if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
771
+ mfp._setFocus();
772
+ return false;
773
+ }
774
+ },
775
+ _parseMarkup: function(template, values, item) {
776
+ var arr;
777
+ if(item.data) {
778
+ values = $.extend(item.data, values);
779
+ }
780
+ _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
781
+
782
+ $.each(values, function(key, value) {
783
+ if(value === undefined || value === false) {
784
+ return true;
785
+ }
786
+ arr = key.split('_');
787
+ if(arr.length > 1) {
788
+ var el = template.find(EVENT_NS + '-'+arr[0]);
789
+
790
+ if(el.length > 0) {
791
+ var attr = arr[1];
792
+ if(attr === 'replaceWith') {
793
+ if(el[0] !== value[0]) {
794
+ el.replaceWith(value);
795
+ }
796
+ } else if(attr === 'img') {
797
+ if(el.is('img')) {
798
+ el.attr('src', value);
799
+ } else {
800
+ el.replaceWith( '<img src="'+value+'" class="' + el.attr('class') + '" />' );
801
+ }
802
+ } else {
803
+ el.attr(arr[1], value);
804
+ }
805
+ }
806
+
807
+ } else {
808
+ template.find(EVENT_NS + '-'+key).html(value);
809
+ }
810
+ });
811
+ },
812
+
813
+ _getScrollbarSize: function() {
814
+ // thx David
815
+ if(mfp.scrollbarSize === undefined) {
816
+ var scrollDiv = document.createElement("div");
817
+ scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
818
+ document.body.appendChild(scrollDiv);
819
+ mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
820
+ document.body.removeChild(scrollDiv);
821
+ }
822
+ return mfp.scrollbarSize;
823
+ }
824
+
825
+ }; /* MagnificPopup core prototype end */
826
+
827
+
828
+
829
+
830
+ /**
831
+ * Public static functions
832
+ */
833
+ $.magnificPopup = {
834
+ instance: null,
835
+ proto: MagnificPopup.prototype,
836
+ modules: [],
837
+
838
+ open: function(options, index) {
839
+ _checkInstance();
840
+
841
+ if(!options) {
842
+ options = {};
843
+ } else {
844
+ options = $.extend(true, {}, options);
845
+ }
846
+
847
+
848
+ options.isObj = true;
849
+ options.index = index || 0;
850
+ return this.instance.open(options);
851
+ },
852
+
853
+ close: function() {
854
+ return $.magnificPopup.instance && $.magnificPopup.instance.close();
855
+ },
856
+
857
+ registerModule: function(name, module) {
858
+ if(module.options) {
859
+ $.magnificPopup.defaults[name] = module.options;
860
+ }
861
+ $.extend(this.proto, module.proto);
862
+ this.modules.push(name);
863
+ },
864
+
865
+ defaults: {
866
+
867
+ // Info about options is in docs:
868
+ // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
869
+
870
+ disableOn: 0,
871
+
872
+ key: null,
873
+
874
+ midClick: false,
875
+
876
+ mainClass: '',
877
+
878
+ preloader: true,
879
+
880
+ focus: '', // CSS selector of input to focus after popup is opened
881
+
882
+ closeOnContentClick: false,
883
+
884
+ closeOnBgClick: true,
885
+
886
+ closeBtnInside: true,
887
+
888
+ showCloseBtn: true,
889
+
890
+ enableEscapeKey: true,
891
+
892
+ modal: false,
893
+
894
+ alignTop: false,
895
+
896
+ removalDelay: 0,
897
+
898
+ prependTo: null,
899
+
900
+ fixedContentPos: 'auto',
901
+
902
+ fixedBgPos: 'auto',
903
+
904
+ overflowY: 'auto',
905
+
906
+ closeMarkup: '<button title="%title%" type="button" class="mfp-close">&#215;</button>',
907
+
908
+ tClose: 'Close (Esc)',
909
+
910
+ tLoading: 'Loading...',
911
+
912
+ autoFocusLast: true
913
+
914
+ }
915
+ };
916
+
917
+
918
+
919
+ $.fn.magnificPopup = function(options) {
920
+ _checkInstance();
921
+
922
+ var jqEl = $(this);
923
+
924
+ // We call some API method of first param is a string
925
+ if (typeof options === "string" ) {
926
+
927
+ if(options === 'open') {
928
+ var items,
929
+ itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
930
+ index = parseInt(arguments[1], 10) || 0;
931
+
932
+ if(itemOpts.items) {
933
+ items = itemOpts.items[index];
934
+ } else {
935
+ items = jqEl;
936
+ if(itemOpts.delegate) {
937
+ items = items.find(itemOpts.delegate);
938
+ }
939
+ items = items.eq( index );
940
+ }
941
+ mfp._openClick({mfpEl:items}, jqEl, itemOpts);
942
+ } else {
943
+ if(mfp.isOpen)
944
+ mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
945
+ }
946
+
947
+ } else {
948
+ // clone options obj
949
+ options = $.extend(true, {}, options);
950
+
951
+ /*
952
+ * As Zepto doesn't support .data() method for objects
953
+ * and it works only in normal browsers
954
+ * we assign "options" object directly to the DOM element. FTW!
955
+ */
956
+ if(_isJQ) {
957
+ jqEl.data('magnificPopup', options);
958
+ } else {
959
+ jqEl[0].magnificPopup = options;
960
+ }
961
+
962
+ mfp.addGroup(jqEl, options);
963
+
964
+ }
965
+ return jqEl;
966
+ };
967
+
968
+
969
+ //Quick benchmark
970
+ /*
971
+ var start = performance.now(),
972
+ i,
973
+ rounds = 1000;
974
+
975
+ for(i = 0; i < rounds; i++) {
976
+
977
+ }
978
+ console.log('Test #1:', performance.now() - start);
979
+
980
+ start = performance.now();
981
+ for(i = 0; i < rounds; i++) {
982
+
983
+ }
984
+ console.log('Test #2:', performance.now() - start);
985
+ */
986
+
987
+
988
+ /*>>core*/
989
+
990
+ /*>>inline*/
991
+
992
+ var INLINE_NS = 'inline',
993
+ _hiddenClass,
994
+ _inlinePlaceholder,
995
+ _lastInlineElement,
996
+ _putInlineElementsBack = function() {
997
+ if(_lastInlineElement) {
998
+ _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
999
+ _lastInlineElement = null;
1000
+ }
1001
+ };
1002
+
1003
+ $.magnificPopup.registerModule(INLINE_NS, {
1004
+ options: {
1005
+ hiddenClass: 'hide', // will be appended with `mfp-` prefix
1006
+ markup: '',
1007
+ tNotFound: 'Content not found'
1008
+ },
1009
+ proto: {
1010
+
1011
+ initInline: function() {
1012
+ mfp.types.push(INLINE_NS);
1013
+
1014
+ _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
1015
+ _putInlineElementsBack();
1016
+ });
1017
+ },
1018
+
1019
+ getInline: function(item, template) {
1020
+
1021
+ _putInlineElementsBack();
1022
+
1023
+ if(item.src) {
1024
+ var inlineSt = mfp.st.inline,
1025
+ el = $(item.src);
1026
+
1027
+ if(el.length) {
1028
+
1029
+ // If target element has parent - we replace it with placeholder and put it back after popup is closed
1030
+ var parent = el[0].parentNode;
1031
+ if(parent && parent.tagName) {
1032
+ if(!_inlinePlaceholder) {
1033
+ _hiddenClass = inlineSt.hiddenClass;
1034
+ _inlinePlaceholder = _getEl(_hiddenClass);
1035
+ _hiddenClass = 'mfp-'+_hiddenClass;
1036
+ }
1037
+ // replace target inline element with placeholder
1038
+ _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
1039
+ }
1040
+
1041
+ mfp.updateStatus('ready');
1042
+ } else {
1043
+ mfp.updateStatus('error', inlineSt.tNotFound);
1044
+ el = $('<div>');
1045
+ }
1046
+
1047
+ item.inlineElement = el;
1048
+ return el;
1049
+ }
1050
+
1051
+ mfp.updateStatus('ready');
1052
+ mfp._parseMarkup(template, {}, item);
1053
+ return template;
1054
+ }
1055
+ }
1056
+ });
1057
+
1058
+ /*>>inline*/
1059
+
1060
+ /*>>ajax*/
1061
+ var AJAX_NS = 'ajax',
1062
+ _ajaxCur,
1063
+ _removeAjaxCursor = function() {
1064
+ if(_ajaxCur) {
1065
+ $(document.body).removeClass(_ajaxCur);
1066
+ }
1067
+ },
1068
+ _destroyAjaxRequest = function() {
1069
+ _removeAjaxCursor();
1070
+ if(mfp.req) {
1071
+ mfp.req.abort();
1072
+ }
1073
+ };
1074
+
1075
+ $.magnificPopup.registerModule(AJAX_NS, {
1076
+
1077
+ options: {
1078
+ settings: null,
1079
+ cursor: 'mfp-ajax-cur',
1080
+ tError: '<a href="%url%">The content</a> could not be loaded.'
1081
+ },
1082
+
1083
+ proto: {
1084
+ initAjax: function() {
1085
+ mfp.types.push(AJAX_NS);
1086
+ _ajaxCur = mfp.st.ajax.cursor;
1087
+
1088
+ _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
1089
+ _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
1090
+ },
1091
+ getAjax: function(item) {
1092
+
1093
+ if(_ajaxCur) {
1094
+ $(document.body).addClass(_ajaxCur);
1095
+ }
1096
+
1097
+ mfp.updateStatus('loading');
1098
+
1099
+ var opts = $.extend({
1100
+ url: item.src,
1101
+ success: function(data, textStatus, jqXHR) {
1102
+ var temp = {
1103
+ data:data,
1104
+ xhr:jqXHR
1105
+ };
1106
+
1107
+ _mfpTrigger('ParseAjax', temp);
1108
+
1109
+ mfp.appendContent( $(temp.data), AJAX_NS );
1110
+
1111
+ item.finished = true;
1112
+
1113
+ _removeAjaxCursor();
1114
+
1115
+ mfp._setFocus();
1116
+
1117
+ setTimeout(function() {
1118
+ mfp.wrap.addClass(READY_CLASS);
1119
+ }, 16);
1120
+
1121
+ mfp.updateStatus('ready');
1122
+
1123
+ _mfpTrigger('AjaxContentAdded');
1124
+ },
1125
+ error: function() {
1126
+ _removeAjaxCursor();
1127
+ item.finished = item.loadError = true;
1128
+ mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));
1129
+ }
1130
+ }, mfp.st.ajax.settings);
1131
+
1132
+ mfp.req = $.ajax(opts);
1133
+
1134
+ return '';
1135
+ }
1136
+ }
1137
+ });
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+ /*>>ajax*/
1146
+
1147
+ /*>>image*/
1148
+ var _imgInterval,
1149
+ _getTitle = function(item) {
1150
+ if(item.data && item.data.title !== undefined)
1151
+ return item.data.title;
1152
+
1153
+ var src = mfp.st.image.titleSrc;
1154
+
1155
+ if(src) {
1156
+ if($.isFunction(src)) {
1157
+ return src.call(mfp, item);
1158
+ } else if(item.el) {
1159
+ return item.el.attr(src) || '';
1160
+ }
1161
+ }
1162
+ return '';
1163
+ };
1164
+
1165
+ $.magnificPopup.registerModule('image', {
1166
+
1167
+ options: {
1168
+ markup: '<div class="mfp-figure">'+
1169
+ '<div class="mfp-close"></div>'+
1170
+ '<figure>'+
1171
+ '<div class="mfp-img"></div>'+
1172
+ '<figcaption>'+
1173
+ '<div class="mfp-bottom-bar">'+
1174
+ '<div class="mfp-title"></div>'+
1175
+ '<div class="mfp-counter"></div>'+
1176
+ '</div>'+
1177
+ '</figcaption>'+
1178
+ '</figure>'+
1179
+ '</div>',
1180
+ cursor: 'mfp-zoom-out-cur',
1181
+ titleSrc: 'title',
1182
+ verticalFit: true,
1183
+ tError: '<a href="%url%">The image</a> could not be loaded.'
1184
+ },
1185
+
1186
+ proto: {
1187
+ initImage: function() {
1188
+ var imgSt = mfp.st.image,
1189
+ ns = '.image';
1190
+
1191
+ mfp.types.push('image');
1192
+
1193
+ _mfpOn(OPEN_EVENT+ns, function() {
1194
+ if(mfp.currItem.type === 'image' && imgSt.cursor) {
1195
+ $(document.body).addClass(imgSt.cursor);
1196
+ }
1197
+ });
1198
+
1199
+ _mfpOn(CLOSE_EVENT+ns, function() {
1200
+ if(imgSt.cursor) {
1201
+ $(document.body).removeClass(imgSt.cursor);
1202
+ }
1203
+ _window.off('resize' + EVENT_NS);
1204
+ });
1205
+
1206
+ _mfpOn('Resize'+ns, mfp.resizeImage);
1207
+ if(mfp.isLowIE) {
1208
+ _mfpOn('AfterChange', mfp.resizeImage);
1209
+ }
1210
+ },
1211
+ resizeImage: function() {
1212
+ var item = mfp.currItem;
1213
+ if(!item || !item.img) return;
1214
+
1215
+ if(mfp.st.image.verticalFit) {
1216
+ var decr = 0;
1217
+ // fix box-sizing in ie7/8
1218
+ if(mfp.isLowIE) {
1219
+ decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
1220
+ }
1221
+ item.img.css('max-height', mfp.wH-decr);
1222
+ }
1223
+ },
1224
+ _onImageHasSize: function(item) {
1225
+ if(item.img) {
1226
+
1227
+ item.hasSize = true;
1228
+
1229
+ if(_imgInterval) {
1230
+ clearInterval(_imgInterval);
1231
+ }
1232
+
1233
+ item.isCheckingImgSize = false;
1234
+
1235
+ _mfpTrigger('ImageHasSize', item);
1236
+
1237
+ if(item.imgHidden) {
1238
+ if(mfp.content)
1239
+ mfp.content.removeClass('mfp-loading');
1240
+
1241
+ item.imgHidden = false;
1242
+ }
1243
+
1244
+ }
1245
+ },
1246
+
1247
+ /**
1248
+ * Function that loops until the image has size to display elements that rely on it asap
1249
+ */
1250
+ findImageSize: function(item) {
1251
+
1252
+ var counter = 0,
1253
+ img = item.img[0],
1254
+ mfpSetInterval = function(delay) {
1255
+
1256
+ if(_imgInterval) {
1257
+ clearInterval(_imgInterval);
1258
+ }
1259
+ // decelerating interval that checks for size of an image
1260
+ _imgInterval = setInterval(function() {
1261
+ if(img.naturalWidth > 0) {
1262
+ mfp._onImageHasSize(item);
1263
+ return;
1264
+ }
1265
+
1266
+ if(counter > 200) {
1267
+ clearInterval(_imgInterval);
1268
+ }
1269
+
1270
+ counter++;
1271
+ if(counter === 3) {
1272
+ mfpSetInterval(10);
1273
+ } else if(counter === 40) {
1274
+ mfpSetInterval(50);
1275
+ } else if(counter === 100) {
1276
+ mfpSetInterval(500);
1277
+ }
1278
+ }, delay);
1279
+ };
1280
+
1281
+ mfpSetInterval(1);
1282
+ },
1283
+
1284
+ getImage: function(item, template) {
1285
+
1286
+ var guard = 0,
1287
+
1288
+ // image load complete handler
1289
+ onLoadComplete = function() {
1290
+ if(item) {
1291
+ if (item.img[0].complete) {
1292
+ item.img.off('.mfploader');
1293
+
1294
+ if(item === mfp.currItem){
1295
+ mfp._onImageHasSize(item);
1296
+
1297
+ mfp.updateStatus('ready');
1298
+ }
1299
+
1300
+ item.hasSize = true;
1301
+ item.loaded = true;
1302
+
1303
+ _mfpTrigger('ImageLoadComplete');
1304
+
1305
+ }
1306
+ else {
1307
+ // if image complete check fails 200 times (20 sec), we assume that there was an error.
1308
+ guard++;
1309
+ if(guard < 200) {
1310
+ setTimeout(onLoadComplete,100);
1311
+ } else {
1312
+ onLoadError();
1313
+ }
1314
+ }
1315
+ }
1316
+ },
1317
+
1318
+ // image error handler
1319
+ onLoadError = function() {
1320
+ if(item) {
1321
+ item.img.off('.mfploader');
1322
+ if(item === mfp.currItem){
1323
+ mfp._onImageHasSize(item);
1324
+ mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
1325
+ }
1326
+
1327
+ item.hasSize = true;
1328
+ item.loaded = true;
1329
+ item.loadError = true;
1330
+ }
1331
+ },
1332
+ imgSt = mfp.st.image;
1333
+
1334
+
1335
+ var el = template.find('.mfp-img');
1336
+ if(el.length) {
1337
+ var img = document.createElement('img');
1338
+ img.className = 'mfp-img';
1339
+ if(item.el && item.el.find('img').length) {
1340
+ img.alt = item.el.find('img').attr('alt');
1341
+ }
1342
+ item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
1343
+ img.src = item.src;
1344
+
1345
+ // without clone() "error" event is not firing when IMG is replaced by new IMG
1346
+ // TODO: find a way to avoid such cloning
1347
+ if(el.is('img')) {
1348
+ item.img = item.img.clone();
1349
+ }
1350
+
1351
+ img = item.img[0];
1352
+ if(img.naturalWidth > 0) {
1353
+ item.hasSize = true;
1354
+ } else if(!img.width) {
1355
+ item.hasSize = false;
1356
+ }
1357
+ }
1358
+
1359
+ mfp._parseMarkup(template, {
1360
+ title: _getTitle(item),
1361
+ img_replaceWith: item.img
1362
+ }, item);
1363
+
1364
+ mfp.resizeImage();
1365
+
1366
+ if(item.hasSize) {
1367
+ if(_imgInterval) clearInterval(_imgInterval);
1368
+
1369
+ if(item.loadError) {
1370
+ template.addClass('mfp-loading');
1371
+ mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
1372
+ } else {
1373
+ template.removeClass('mfp-loading');
1374
+ mfp.updateStatus('ready');
1375
+ }
1376
+ return template;
1377
+ }
1378
+
1379
+ mfp.updateStatus('loading');
1380
+ item.loading = true;
1381
+
1382
+ if(!item.hasSize) {
1383
+ item.imgHidden = true;
1384
+ template.addClass('mfp-loading');
1385
+ mfp.findImageSize(item);
1386
+ }
1387
+
1388
+ return template;
1389
+ }
1390
+ }
1391
+ });
1392
+
1393
+
1394
+
1395
+ /*>>image*/
1396
+
1397
+ /*>>zoom*/
1398
+ var hasMozTransform,
1399
+ getHasMozTransform = function() {
1400
+ if(hasMozTransform === undefined) {
1401
+ hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
1402
+ }
1403
+ return hasMozTransform;
1404
+ };
1405
+
1406
+ $.magnificPopup.registerModule('zoom', {
1407
+
1408
+ options: {
1409
+ enabled: false,
1410
+ easing: 'ease-in-out',
1411
+ duration: 300,
1412
+ opener: function(element) {
1413
+ return element.is('img') ? element : element.find('img');
1414
+ }
1415
+ },
1416
+
1417
+ proto: {
1418
+
1419
+ initZoom: function() {
1420
+ var zoomSt = mfp.st.zoom,
1421
+ ns = '.zoom',
1422
+ image;
1423
+
1424
+ if(!zoomSt.enabled || !mfp.supportsTransition) {
1425
+ return;
1426
+ }
1427
+
1428
+ var duration = zoomSt.duration,
1429
+ getElToAnimate = function(image) {
1430
+ var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
1431
+ transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
1432
+ cssObj = {
1433
+ position: 'fixed',
1434
+ zIndex: 9999,
1435
+ left: 0,
1436
+ top: 0,
1437
+ '-webkit-backface-visibility': 'hidden'
1438
+ },
1439
+ t = 'transition';
1440
+
1441
+ cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
1442
+
1443
+ newImg.css(cssObj);
1444
+ return newImg;
1445
+ },
1446
+ showMainContent = function() {
1447
+ mfp.content.css('visibility', 'visible');
1448
+ },
1449
+ openTimeout,
1450
+ animatedImg;
1451
+
1452
+ _mfpOn('BuildControls'+ns, function() {
1453
+ if(mfp._allowZoom()) {
1454
+
1455
+ clearTimeout(openTimeout);
1456
+ mfp.content.css('visibility', 'hidden');
1457
+
1458
+ // Basically, all code below does is clones existing image, puts in on top of the current one and animated it
1459
+
1460
+ image = mfp._getItemToZoom();
1461
+
1462
+ if(!image) {
1463
+ showMainContent();
1464
+ return;
1465
+ }
1466
+
1467
+ animatedImg = getElToAnimate(image);
1468
+
1469
+ animatedImg.css( mfp._getOffset() );
1470
+
1471
+ mfp.wrap.append(animatedImg);
1472
+
1473
+ openTimeout = setTimeout(function() {
1474
+ animatedImg.css( mfp._getOffset( true ) );
1475
+ openTimeout = setTimeout(function() {
1476
+
1477
+ showMainContent();
1478
+
1479
+ setTimeout(function() {
1480
+ animatedImg.remove();
1481
+ image = animatedImg = null;
1482
+ _mfpTrigger('ZoomAnimationEnded');
1483
+ }, 16); // avoid blink when switching images
1484
+
1485
+ }, duration); // this timeout equals animation duration
1486
+
1487
+ }, 16); // by adding this timeout we avoid short glitch at the beginning of animation
1488
+
1489
+
1490
+ // Lots of timeouts...
1491
+ }
1492
+ });
1493
+ _mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
1494
+ if(mfp._allowZoom()) {
1495
+
1496
+ clearTimeout(openTimeout);
1497
+
1498
+ mfp.st.removalDelay = duration;
1499
+
1500
+ if(!image) {
1501
+ image = mfp._getItemToZoom();
1502
+ if(!image) {
1503
+ return;
1504
+ }
1505
+ animatedImg = getElToAnimate(image);
1506
+ }
1507
+
1508
+
1509
+ animatedImg.css( mfp._getOffset(true) );
1510
+ mfp.wrap.append(animatedImg);
1511
+ mfp.content.css('visibility', 'hidden');
1512
+
1513
+ setTimeout(function() {
1514
+ animatedImg.css( mfp._getOffset() );
1515
+ }, 16);
1516
+ }
1517
+
1518
+ });
1519
+
1520
+ _mfpOn(CLOSE_EVENT+ns, function() {
1521
+ if(mfp._allowZoom()) {
1522
+ showMainContent();
1523
+ if(animatedImg) {
1524
+ animatedImg.remove();
1525
+ }
1526
+ image = null;
1527
+ }
1528
+ });
1529
+ },
1530
+
1531
+ _allowZoom: function() {
1532
+ return mfp.currItem.type === 'image';
1533
+ },
1534
+
1535
+ _getItemToZoom: function() {
1536
+ if(mfp.currItem.hasSize) {
1537
+ return mfp.currItem.img;
1538
+ } else {
1539
+ return false;
1540
+ }
1541
+ },
1542
+
1543
+ // Get element postion relative to viewport
1544
+ _getOffset: function(isLarge) {
1545
+ var el;
1546
+ if(isLarge) {
1547
+ el = mfp.currItem.img;
1548
+ } else {
1549
+ el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
1550
+ }
1551
+
1552
+ var offset = el.offset();
1553
+ var paddingTop = parseInt(el.css('padding-top'),10);
1554
+ var paddingBottom = parseInt(el.css('padding-bottom'),10);
1555
+ offset.top -= ( $(window).scrollTop() - paddingTop );
1556
+
1557
+
1558
+ /*
1559
+
1560
+ Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
1561
+
1562
+ */
1563
+ var obj = {
1564
+ width: el.width(),
1565
+ // fix Zepto height+padding issue
1566
+ height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
1567
+ };
1568
+
1569
+ // I hate to do this, but there is no another option
1570
+ if( getHasMozTransform() ) {
1571
+ obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
1572
+ } else {
1573
+ obj.left = offset.left;
1574
+ obj.top = offset.top;
1575
+ }
1576
+ return obj;
1577
+ }
1578
+
1579
+ }
1580
+ });
1581
+
1582
+
1583
+
1584
+ /*>>zoom*/
1585
+
1586
+ /*>>iframe*/
1587
+
1588
+ var IFRAME_NS = 'iframe',
1589
+ _emptyPage = '//about:blank',
1590
+
1591
+ _fixIframeBugs = function(isShowing) {
1592
+ if(mfp.currTemplate[IFRAME_NS]) {
1593
+ var el = mfp.currTemplate[IFRAME_NS].find('iframe');
1594
+ if(el.length) {
1595
+ // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
1596
+ if(!isShowing) {
1597
+ el[0].src = _emptyPage;
1598
+ }
1599
+
1600
+ // IE8 black screen bug fix
1601
+ if(mfp.isIE8) {
1602
+ el.css('display', isShowing ? 'block' : 'none');
1603
+ }
1604
+ }
1605
+ }
1606
+ };
1607
+
1608
+ $.magnificPopup.registerModule(IFRAME_NS, {
1609
+
1610
+ options: {
1611
+ markup: '<div class="mfp-iframe-scaler">'+
1612
+ '<div class="mfp-close"></div>'+
1613
+ '<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
1614
+ '</div>',
1615
+
1616
+ srcAction: 'iframe_src',
1617
+
1618
+ // we don't care and support only one default type of URL by default
1619
+ patterns: {
1620
+ youtube: {
1621
+ index: 'youtube.com',
1622
+ id: 'v=',
1623
+ src: '//www.youtube.com/embed/%id%?autoplay=1'
1624
+ },
1625
+ vimeo: {
1626
+ index: 'vimeo.com/',
1627
+ id: '/',
1628
+ src: '//player.vimeo.com/video/%id%?autoplay=1'
1629
+ },
1630
+ gmaps: {
1631
+ index: '//maps.google.',
1632
+ src: '%id%&output=embed'
1633
+ }
1634
+ }
1635
+ },
1636
+
1637
+ proto: {
1638
+ initIframe: function() {
1639
+ mfp.types.push(IFRAME_NS);
1640
+
1641
+ _mfpOn('BeforeChange', function(e, prevType, newType) {
1642
+ if(prevType !== newType) {
1643
+ if(prevType === IFRAME_NS) {
1644
+ _fixIframeBugs(); // iframe if removed
1645
+ } else if(newType === IFRAME_NS) {
1646
+ _fixIframeBugs(true); // iframe is showing
1647
+ }
1648
+ }// else {
1649
+ // iframe source is switched, don't do anything
1650
+ //}
1651
+ });
1652
+
1653
+ _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
1654
+ _fixIframeBugs();
1655
+ });
1656
+ },
1657
+
1658
+ getIframe: function(item, template) {
1659
+ var embedSrc = item.src;
1660
+ var iframeSt = mfp.st.iframe;
1661
+
1662
+ $.each(iframeSt.patterns, function() {
1663
+ if(embedSrc.indexOf( this.index ) > -1) {
1664
+ if(this.id) {
1665
+ if(typeof this.id === 'string') {
1666
+ embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
1667
+ } else {
1668
+ embedSrc = this.id.call( this, embedSrc );
1669
+ }
1670
+ }
1671
+ embedSrc = this.src.replace('%id%', embedSrc );
1672
+ return false; // break;
1673
+ }
1674
+ });
1675
+
1676
+ var dataObj = {};
1677
+ if(iframeSt.srcAction) {
1678
+ dataObj[iframeSt.srcAction] = embedSrc;
1679
+ }
1680
+ mfp._parseMarkup(template, dataObj, item);
1681
+
1682
+ mfp.updateStatus('ready');
1683
+
1684
+ return template;
1685
+ }
1686
+ }
1687
+ });
1688
+
1689
+
1690
+
1691
+ /*>>iframe*/
1692
+
1693
+ /*>>gallery*/
1694
+ /**
1695
+ * Get looped index depending on number of slides
1696
+ */
1697
+ var _getLoopedId = function(index) {
1698
+ var numSlides = mfp.items.length;
1699
+ if(index > numSlides - 1) {
1700
+ return index - numSlides;
1701
+ } else if(index < 0) {
1702
+ return numSlides + index;
1703
+ }
1704
+ return index;
1705
+ },
1706
+ _replaceCurrTotal = function(text, curr, total) {
1707
+ return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
1708
+ };
1709
+
1710
+ $.magnificPopup.registerModule('gallery', {
1711
+
1712
+ options: {
1713
+ enabled: false,
1714
+ arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
1715
+ preload: [0,2],
1716
+ navigateByImgClick: true,
1717
+ arrows: true,
1718
+
1719
+ tPrev: 'Previous (Left arrow key)',
1720
+ tNext: 'Next (Right arrow key)',
1721
+ tCounter: '%curr% of %total%'
1722
+ },
1723
+
1724
+ proto: {
1725
+ initGallery: function() {
1726
+
1727
+ var gSt = mfp.st.gallery,
1728
+ ns = '.mfp-gallery',
1729
+ supportsFastClick = Boolean($.fn.mfpFastClick);
1730
+
1731
+ mfp.direction = true; // true - next, false - prev
1732
+
1733
+ if(!gSt || !gSt.enabled ) return false;
1734
+
1735
+ _wrapClasses += ' mfp-gallery';
1736
+
1737
+ _mfpOn(OPEN_EVENT+ns, function() {
1738
+
1739
+ if(gSt.navigateByImgClick) {
1740
+ mfp.wrap.on('click'+ns, '.mfp-img', function() {
1741
+ if(mfp.items.length > 1) {
1742
+ mfp.next();
1743
+ return false;
1744
+ }
1745
+ });
1746
+ }
1747
+
1748
+ _document.on('keydown'+ns, function(e) {
1749
+ if (e.keyCode === 37) {
1750
+ mfp.prev();
1751
+ } else if (e.keyCode === 39) {
1752
+ mfp.next();
1753
+ }
1754
+ });
1755
+ });
1756
+
1757
+ _mfpOn('UpdateStatus'+ns, function(e, data) {
1758
+ if(data.text) {
1759
+ data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
1760
+ }
1761
+ });
1762
+
1763
+ _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
1764
+ var l = mfp.items.length;
1765
+ values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
1766
+ });
1767
+
1768
+ _mfpOn('BuildControls' + ns, function() {
1769
+ if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
1770
+ var markup = gSt.arrowMarkup,
1771
+ arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),
1772
+ arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);
1773
+
1774
+ var eName = supportsFastClick ? 'mfpFastClick' : 'click';
1775
+ arrowLeft[eName](function() {
1776
+ mfp.prev();
1777
+ });
1778
+ arrowRight[eName](function() {
1779
+ mfp.next();
1780
+ });
1781
+
1782
+ // Polyfill for :before and :after (adds elements with classes mfp-a and mfp-b)
1783
+ if(mfp.isIE7) {
1784
+ _getEl('b', arrowLeft[0], false, true);
1785
+ _getEl('a', arrowLeft[0], false, true);
1786
+ _getEl('b', arrowRight[0], false, true);
1787
+ _getEl('a', arrowRight[0], false, true);
1788
+ }
1789
+
1790
+ mfp.container.append(arrowLeft.add(arrowRight));
1791
+ }
1792
+ });
1793
+
1794
+ _mfpOn(CHANGE_EVENT+ns, function() {
1795
+ if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
1796
+
1797
+ mfp._preloadTimeout = setTimeout(function() {
1798
+ mfp.preloadNearbyImages();
1799
+ mfp._preloadTimeout = null;
1800
+ }, 16);
1801
+ });
1802
+
1803
+
1804
+ _mfpOn(CLOSE_EVENT+ns, function() {
1805
+ _document.off(ns);
1806
+ mfp.wrap.off('click'+ns);
1807
+
1808
+ if(mfp.arrowLeft && supportsFastClick) {
1809
+ mfp.arrowLeft.add(mfp.arrowRight).destroyMfpFastClick();
1810
+ }
1811
+ mfp.arrowRight = mfp.arrowLeft = null;
1812
+ });
1813
+
1814
+ },
1815
+ next: function() {
1816
+ mfp.direction = true;
1817
+ mfp.index = _getLoopedId(mfp.index + 1);
1818
+ mfp.updateItemHTML();
1819
+ },
1820
+ prev: function() {
1821
+ mfp.direction = false;
1822
+ mfp.index = _getLoopedId(mfp.index - 1);
1823
+ mfp.updateItemHTML();
1824
+ },
1825
+ goTo: function(newIndex) {
1826
+ mfp.direction = (newIndex >= mfp.index);
1827
+ mfp.index = newIndex;
1828
+ mfp.updateItemHTML();
1829
+ },
1830
+ preloadNearbyImages: function() {
1831
+ var p = mfp.st.gallery.preload,
1832
+ preloadBefore = Math.min(p[0], mfp.items.length),
1833
+ preloadAfter = Math.min(p[1], mfp.items.length),
1834
+ i;
1835
+
1836
+ for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
1837
+ mfp._preloadItem(mfp.index+i);
1838
+ }
1839
+ for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
1840
+ mfp._preloadItem(mfp.index-i);
1841
+ }
1842
+ },
1843
+ _preloadItem: function(index) {
1844
+ index = _getLoopedId(index);
1845
+
1846
+ if(mfp.items[index].preloaded) {
1847
+ return;
1848
+ }
1849
+
1850
+ var item = mfp.items[index];
1851
+ if(!item.parsed) {
1852
+ item = mfp.parseEl( index );
1853
+ }
1854
+
1855
+ _mfpTrigger('LazyLoad', item);
1856
+
1857
+ if(item.type === 'image') {
1858
+ item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
1859
+ item.hasSize = true;
1860
+ }).on('error.mfploader', function() {
1861
+ item.hasSize = true;
1862
+ item.loadError = true;
1863
+ _mfpTrigger('LazyLoadError', item);
1864
+ }).attr('src', item.src);
1865
+ }
1866
+
1867
+
1868
+ item.preloaded = true;
1869
+ }
1870
+ }
1871
+ });
1872
+
1873
+ /*
1874
+ Touch Support that might be implemented some day
1875
+
1876
+ addSwipeGesture: function() {
1877
+ var startX,
1878
+ moved,
1879
+ multipleTouches;
1880
+
1881
+ return;
1882
+
1883
+ var namespace = '.mfp',
1884
+ addEventNames = function(pref, down, move, up, cancel) {
1885
+ mfp._tStart = pref + down + namespace;
1886
+ mfp._tMove = pref + move + namespace;
1887
+ mfp._tEnd = pref + up + namespace;
1888
+ mfp._tCancel = pref + cancel + namespace;
1889
+ };
1890
+
1891
+ if(window.navigator.msPointerEnabled) {
1892
+ addEventNames('MSPointer', 'Down', 'Move', 'Up', 'Cancel');
1893
+ } else if('ontouchstart' in window) {
1894
+ addEventNames('touch', 'start', 'move', 'end', 'cancel');
1895
+ } else {
1896
+ return;
1897
+ }
1898
+ _window.on(mfp._tStart, function(e) {
1899
+ var oE = e.originalEvent;
1900
+ multipleTouches = moved = false;
1901
+ startX = oE.pageX || oE.changedTouches[0].pageX;
1902
+ }).on(mfp._tMove, function(e) {
1903
+ if(e.originalEvent.touches.length > 1) {
1904
+ multipleTouches = e.originalEvent.touches.length;
1905
+ } else {
1906
+ //e.preventDefault();
1907
+ moved = true;
1908
+ }
1909
+ }).on(mfp._tEnd + ' ' + mfp._tCancel, function(e) {
1910
+ if(moved && !multipleTouches) {
1911
+ var oE = e.originalEvent,
1912
+ diff = startX - (oE.pageX || oE.changedTouches[0].pageX);
1913
+
1914
+ if(diff > 20) {
1915
+ mfp.next();
1916
+ } else if(diff < -20) {
1917
+ mfp.prev();
1918
+ }
1919
+ }
1920
+ });
1921
+ },
1922
+ */
1923
+
1924
+
1925
+ /*>>gallery*/
1926
+
1927
+ /*>>retina*/
1928
+
1929
+ var RETINA_NS = 'retina';
1930
+
1931
+ $.magnificPopup.registerModule(RETINA_NS, {
1932
+ options: {
1933
+ replaceSrc: function(item) {
1934
+ return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
1935
+ },
1936
+ ratio: 1 // Function or number. Set to 1 to disable.
1937
+ },
1938
+ proto: {
1939
+ initRetina: function() {
1940
+ if(window.devicePixelRatio > 1) {
1941
+
1942
+ var st = mfp.st.retina,
1943
+ ratio = st.ratio;
1944
+
1945
+ ratio = !isNaN(ratio) ? ratio : ratio();
1946
+
1947
+ if(ratio > 1) {
1948
+ _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
1949
+ item.img.css({
1950
+ 'max-width': item.img[0].naturalWidth / ratio,
1951
+ 'width': '100%'
1952
+ });
1953
+ });
1954
+ _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
1955
+ item.src = st.replaceSrc(item, ratio);
1956
+ });
1957
+ }
1958
+ }
1959
+
1960
+ }
1961
+ }
1962
+ });
1963
+
1964
+ /*>>retina*/
1965
+
1966
+ /*>>fastclick*/
1967
+ /**
1968
+ * FastClick event implementation. (removes 300ms delay on touch devices)
1969
+ * Based on https://developers.google.com/mobile/articles/fast_buttons
1970
+ *
1971
+ * You may use it outside the Magnific Popup by calling just:
1972
+ *
1973
+ * $('.your-el').mfpFastClick(function() {
1974
+ * console.log('Clicked!');
1975
+ * });
1976
+ *
1977
+ * To unbind:
1978
+ * $('.your-el').destroyMfpFastClick();
1979
+ *
1980
+ *
1981
+ * Note that it's a very basic and simple implementation, it blocks ghost click on the same element where it was bound.
1982
+ * If you need something more advanced, use plugin by FT Labs https://github.com/ftlabs/fastclick
1983
+ *
1984
+ */
1985
+
1986
+ (function() {
1987
+ var ghostClickDelay = 1000,
1988
+ supportsTouch = 'ontouchstart' in window,
1989
+ unbindTouchMove = function() {
1990
+ _window.off('touchmove'+ns+' touchend'+ns);
1991
+ },
1992
+ eName = 'mfpFastClick',
1993
+ ns = '.'+eName;
1994
+
1995
+
1996
+ // As Zepto.js doesn't have an easy way to add custom events (like jQuery), so we implement it in this way
1997
+ $.fn.mfpFastClick = function(callback) {
1998
+
1999
+ return $(this).each(function() {
2000
+
2001
+ var elem = $(this),
2002
+ lock;
2003
+
2004
+ if( supportsTouch ) {
2005
+
2006
+ var timeout,
2007
+ startX,
2008
+ startY,
2009
+ pointerMoved,
2010
+ point,
2011
+ numPointers;
2012
+
2013
+ elem.on('touchstart' + ns, function(e) {
2014
+ pointerMoved = false;
2015
+ numPointers = 1;
2016
+
2017
+ point = e.originalEvent ? e.originalEvent.touches[0] : e.touches[0];
2018
+ startX = point.clientX;
2019
+ startY = point.clientY;
2020
+
2021
+ _window.on('touchmove'+ns, function(e) {
2022
+ point = e.originalEvent ? e.originalEvent.touches : e.touches;
2023
+ numPointers = point.length;
2024
+ point = point[0];
2025
+ if (Math.abs(point.clientX - startX) > 10 ||
2026
+ Math.abs(point.clientY - startY) > 10) {
2027
+ pointerMoved = true;
2028
+ unbindTouchMove();
2029
+ }
2030
+ }).on('touchend'+ns, function(e) {
2031
+ unbindTouchMove();
2032
+ if(pointerMoved || numPointers > 1) {
2033
+ return;
2034
+ }
2035
+ lock = true;
2036
+ e.preventDefault();
2037
+ clearTimeout(timeout);
2038
+ timeout = setTimeout(function() {
2039
+ lock = false;
2040
+ }, ghostClickDelay);
2041
+ callback();
2042
+ });
2043
+ });
2044
+
2045
+ }
2046
+
2047
+ elem.on('click' + ns, function() {
2048
+ if(!lock) {
2049
+ callback();
2050
+ }
2051
+ });
2052
+ });
2053
+ };
2054
+
2055
+ $.fn.destroyMfpFastClick = function() {
2056
+ $(this).off('touchstart' + ns + ' click' + ns);
2057
+ if(supportsTouch) _window.off('touchmove'+ns+' touchend'+ns);
2058
+ };
2059
+ })();
2060
+
2061
+ /*>>fastclick*/
2062
+ _checkInstance(); }));