PageSourceSearch

https://nashvillecatrescue.org/wp-content/themes/jupiter/assets/js/core-scripts.6.8.0.js?ver=1602714013

js nashvillecatrescue.org collected 2026-10-04 18:41:10 UTC 455,848 bytes, 13,610 lines download raw bytes

1(function($) {// v5 namespace 
2var MK = {
3	api 		: {},
4	ui 			: {},
5	component 	: {},
6};
7
8// Global 
9window.MK = MK;
10'use strict';
11
12
13console.log( 23423 );
14/**
15 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level
16 * directory of this distribution and at
17 * https://github.com/marcj/css-element-queries/blob/master/LICENSE.
18 */
19(function (root, factory) {
20    if (typeof define === "function" && define.amd) {
21        define(factory);
22    } else if (typeof exports === "object") {
23        module.exports = factory();
24    } else {
25        root.ResizeSensor = factory();
26    }
27}(typeof window !== 'undefined' ? window : this, function () {
28
29    // Make sure it does not throw in a SSR (Server Side Rendering) situation
30    if (typeof window === "undefined") {
31        return null;
32    }
33    // Only used for the dirty checking, so the event callback count is limited to max 1 call per fps per sensor.
34    // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and
35    // would generate too many unnecessary events.
36    var requestAnimationFrame = window.requestAnimationFrame ||
37        window.mozRequestAnimationFrame ||
38        window.webkitRequestAnimationFrame ||
39        function (fn) {
40            return window.setTimeout(fn, 20);
41        };
42
43    /**
44     * Iterate over each of the provided element(s).
45     *
46     * @param {HTMLElement|HTMLElement[]} elements
47     * @param {Function}                  callback
48     */
49    function forEachElement(elements, callback){
50        var elementsType = Object.prototype.toString.call(elements);
51        var isCollectionTyped = ('[object Array]' === elementsType
52            || ('[object NodeList]' === elementsType)
53            || ('[object HTMLCollection]' === elementsType)
54            || ('[object Object]' === elementsType)
55            || ('undefined' !== typeof jQuery && elements instanceof jQuery) //jquery
56            || ('undefined' !== typeof Elements && elements instanceof Elements) //mootools
57        );
58        var i = 0, j = elements.length;
59        if (isCollectionTyped) {
60            for (; i < j; i++) {
61                callback(elements[i]);
62            }
63        } else {
64            callback(elements);
65        }
66    }
67
68    /**
69    * Get element size
70    * @param {HTMLElement} element
71    * @returns {Object} {width, height}
72    */
73    function getElementSize(element) {
74        if (!element.getBoundingClientRect) {
75            return {
76                width: element.offsetWidth,
77                height: element.offsetHeight
78            }
79        }
80
81        var rect = element.getBoundingClientRect();
82        return {
83            width: Math.round(rect.width),
84            height: Math.round(rect.height)
85        }
86    }
87
88    /**
89     * Class for dimension change detection.
90     *
91     * @param {Element|Element[]|Elements|jQuery} element
92     * @param {Function} callback
93     *
94     * @constructor
95     */
96    var ResizeSensor = function(element, callback) {
97        /**
98         *
99         * @constructor
100         */
101        function EventQueue() {
102            var q = [];
103            this.add = function(ev) {
104                q.push(ev);
105            };
106
107            var i, j;
108            this.call = function() {
109                for (i = 0, j = q.length; i < j; i++) {
110                    q[i].call();
111                }
112            };
113
114            this.remove = function(ev) {
115                var newQueue = [];
116                for(i = 0, j = q.length; i < j; i++) {
117                    if(q[i] !== ev) newQueue.push(q[i]);
118                }
119                q = newQueue;
120            };
121
122            this.length = function() {
123                return q.length;
124            }
125        }
126
127        /**
128         *
129         * @param {HTMLElement} element
130         * @param {Function}    resized
131         */
132        function attachResizeEvent(element, resized) {
133            if (!element) return;
134            if (element.resizedAttached) {
135                element.resizedAttached.add(resized);
136                return;
137            }
138
139            element.resizedAttached = new EventQueue();
140            element.resizedAttached.add(resized);
141
142            element.resizeSensor = document.createElement('div');
143            element.resizeSensor.dir = 'ltr';
144            element.resizeSensor.className = 'resize-sensor';
145            var style = 'position: absolute; left: -10px; top: -10px; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;';
146            var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
147
148            element.resizeSensor.style.cssText = style;
149            element.resizeSensor.innerHTML =
150                '<div class="resize-sensor-expand" style="' + style + '">' +
151                    '<div style="' + styleChild + '"></div>' +
152                '</div>' +
153                '<div class="resize-sensor-shrink" style="' + style + '">' +
154                    '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
155                '</div>';
156            element.appendChild(element.resizeSensor);
157
158            var position = window.getComputedStyle(element).getPropertyPriority('position');
159            if ('absolute' !== position && 'relative' !== position && 'fixed' !== position) {
160                element.style.position = 'relative';
161            }
162
163            var expand = element.resizeSensor.childNodes[0];
164            var expandChild = expand.childNodes[0];
165            var shrink = element.resizeSensor.childNodes[1];
166            var dirty, rafId, newWidth, newHeight;
167            var size = getElementSize(element);
168            var lastWidth = size.width;
169            var lastHeight = size.height;
170
171            var reset = function() {
172                //set display to block, necessary otherwise hidden elements won't ever work
173                var invisible = element.offsetWidth === 0 && element.offsetHeight === 0;
174
175                if (invisible) {
176                    var saveDisplay = element.style.display;
177                    element.style.display = 'block';
178                }
179
180                expandChild.style.width = '100000px';
181                expandChild.style.height = '100000px';
182
183                expand.scrollLeft = 100000;
184                expand.scrollTop = 100000;
185
186                shrink.scrollLeft = 100000;
187                shrink.scrollTop = 100000;
188
189                if (invisible) {
190                    element.style.display = saveDisplay;
191                }
192            };
193            element.resizeSensor.resetSensor = reset;
194
195            var onResized = function() {
196                rafId = 0;
197
198                if (!dirty) return;
199
200                lastWidth = newWidth;
201                lastHeight = newHeight;
202
203                if (element.resizedAttached) {
204                    element.resizedAttached.call();
205                }
206            };
207
208            var onScroll = function() {
209                var size = getElementSize(element);
210                var newWidth = size.width;
211                var newHeight = size.height;
212                dirty = newWidth != lastWidth || newHeight != lastHeight;
213
214                if (dirty && !rafId) {
215                    rafId = requestAnimationFrame(onResized);
216                }
217
218                reset();
219            };
220
221            var addEvent = function(el, name, cb) {
222                if (el.attachEvent) {
223                    el.attachEvent('on' + name, cb);
224                } else {
225                    el.addEventListener(name, cb);
226                }
227            };
228
229            addEvent(expand, 'scroll', onScroll);
230            addEvent(shrink, 'scroll', onScroll);
231
232			// Fix for custom Elements
233			requestAnimationFrame(reset);
234        }
235
236        forEachElement(element, function(elem){
237            attachResizeEvent(elem, callback);
238        });
239
240        this.detach = function(ev) {
241            ResizeSensor.detach(element, ev);
242        };
243
244        this.reset = function() {
245            element.resizeSensor.resetSensor();
246        };
247    };
248
249    ResizeSensor.reset = function(element, ev) {
250        forEachElement(element, function(elem){
251            elem.resizeSensor.resetSensor();
252        });
253    };
254
255    ResizeSensor.detach = function(element, ev) {
256        forEachElement(element, function(elem){
257            if (!elem) return;
258            if(elem.resizedAttached && typeof ev === "function"){
259                elem.resizedAttached.remove(ev);
260                if(elem.resizedAttached.length()) return;
261            }
262            if (elem.resizeSensor) {
263                if (elem.contains(elem.resizeSensor)) {
264                    elem.removeChild(elem.resizeSensor);
265                }
266                delete elem.resizeSensor;
267                delete elem.resizedAttached;
268            }
269        });
270    };
271
272    return ResizeSensor;
273
274}));
275
276'use strict';
277
278/**
279 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level
280 * directory of this distribution and at
281 * https://github.com/marcj/css-element-queries/blob/master/LICENSE.
282 */
283(function (root, factory) {
284    if (typeof define === "function" && define.amd) {
285        define(['./ResizeSensor.js'], factory);
286    } else if (typeof exports === "object") {
287        module.exports = factory(require('./ResizeSensor.js'));
288    } else {
289        root.ElementQueries = factory(root.ResizeSensor);
290        root.ElementQueries.listen();
291    }
292}(typeof window !== 'undefined' ? window : this, function (ResizeSensor) {
293
294    /**
295     *
296     * @type {Function}
297     * @constructor
298     */
299    var ElementQueries = function () {
300        //<style> element with our dynamically created styles
301        var cssStyleElement;
302
303        //all rules found for element queries
304        var allQueries = {};
305
306        //association map to identify which selector belongs to a element from the animationstart event.
307        var idToSelectorMapping = [];
308
309        /**
310         *
311         * @param element
312         * @returns {Number}
313         */
314        function getEmSize(element) {
315            if (!element) {
316                element = document.documentElement;
317            }
318            var fontSize = window.getComputedStyle(element, null).fontSize;
319            return parseFloat(fontSize) || 16;
320        }
321
322        /**
323         * Get element size
324         * @param {HTMLElement} element
325         * @returns {Object} {width, height}
326         */
327        function getElementSize(element) {
328            if (!element.getBoundingClientRect) {
329                return {
330                    width: element.offsetWidth,
331                    height: element.offsetHeight
332                }
333            }
334
335            var rect = element.getBoundingClientRect();
336            return {
337                width: Math.round(rect.width),
338                height: Math.round(rect.height)
339            }
340        }
341
342        /**
343         *
344         * @copyright https://github.com/Mr0grog/element-query/blob/master/LICENSE
345         *
346         * @param {HTMLElement} element
347         * @param {*} value
348         * @returns {*}
349         */
350        function convertToPx(element, value) {
351            var numbers = value.split(/\d/);
352            var units = numbers[numbers.length - 1];
353            value = parseFloat(value);
354            switch (units) {
355                case "px":
356                    return value;
357                case "em":
358                    return value * getEmSize(element);
359                case "rem":
360                    return value * getEmSize();
361                // Viewport units!
362                // According to http://quirksmode.org/mobile/tableViewport.html
363                // documentElement.clientWidth/Height gets us the most reliable info
364                case "vw":
365                    return value * document.documentElement.clientWidth / 100;
366                case "vh":
367                    return value * document.documentElement.clientHeight / 100;
368                case "vmin":
369                case "vmax":
370                    var vw = document.documentElement.clientWidth / 100;
371                    var vh = document.documentElement.clientHeight / 100;
372                    var chooser = Math[units === "vmin" ? "min" : "max"];
373                    return value * chooser(vw, vh);
374                default:
375                    return value;
376                // for now, not supporting physical units (since they are just a set number of px)
377                // or ex/ch (getting accurate measurements is hard)
378            }
379        }
380
381        /**
382         *
383         * @param {HTMLElement} element
384         * @param {String} id
385         * @constructor
386         */
387        function SetupInformation(element, id) {
388            this.element = element;
389            var key, option, elementSize, value, actualValue, attrValues, attrValue, attrName;
390
391            var attributes = ['min-width', 'min-height', 'max-width', 'max-height'];
392
393            /**
394             * Extracts the computed width/height and sets to min/max- attribute.
395             */
396            this.call = function () {
397                // extract current dimensions
398                elementSize = getElementSize(this.element);
399
400                attrValues = {};
401
402                for (key in allQueries[id]) {
403                    if (!allQueries[id].hasOwnProperty(key)) {
404                        continue;
405                    }
406                    option = allQueries[id][key];
407
408                    value = convertToPx(this.element, option.value);
409
410                    actualValue = option.property === 'width' ? elementSize.width : elementSize.height;
411                    attrName = option.mode + '-' + option.property;
412                    attrValue = '';
413
414                    if (option.mode === 'min' && actualValue >= value) {
415                        attrValue += option.value;
416                    }
417
418                    if (option.mode === 'max' && actualValue <= value) {
419                        attrValue += option.value;
420                    }
421
422                    if (!attrValues[attrName]) attrValues[attrName] = '';
423                    if (attrValue && -1 === (' ' + attrValues[attrName] + ' ').indexOf(' ' + attrValue + ' ')) {
424                        attrValues[attrName] += ' ' + attrValue;
425                    }
426                }
427
428                for (var k in attributes) {
429                    if (!attributes.hasOwnProperty(k)) continue;
430
431                    if (attrValues[attributes[k]]) {
432                        this.element.setAttribute(attributes[k], attrValues[attributes[k]].substr(1));
433                    } else {
434                        this.element.removeAttribute(attributes[k]);
435                    }
436                }
437            };
438        }
439
440        /**
441         * @param {HTMLElement} element
442         * @param {Object}      id
443         */
444        function setupElement(element, id) {
445            if (!element.elementQueriesSetupInformation) {
446                element.elementQueriesSetupInformation = new SetupInformation(element, id);
447            }
448            if (!element.elementQueriesSensor) {
449                element.elementQueriesSensor = new ResizeSensor(element, function () {
450                    element.elementQueriesSetupInformation.call();
451                });
452            }
453
454            element.elementQueriesSetupInformation.call();
455        }
456
457        /**
458         * Stores rules to the selector that should be applied once resized.
459         *
460         * @param {String} selector
461         * @param {String} mode min|max
462         * @param {String} property width|height
463         * @param {String} value
464         */
465        function queueQuery(selector, mode, property, value) {
466            if (typeof(allQueries[selector]) === 'undefined') {
467                allQueries[selector] = [];
468                // add animation to trigger animationstart event, so we know exactly when a element appears in the DOM
469
470                var id = idToSelectorMapping.length;
471                cssStyleElement.innerHTML += '\n' + selector + ' {animation: 0.1s element-queries;}';
472                cssStyleElement.innerHTML += '\n' + selector + ' > .resize-sensor {min-width: '+id+'px;}';
473                idToSelectorMapping.push(selector);
474            }
475
476            allQueries[selector].push({
477                mode: mode,
478                property: property,
479                value: value
480            });
481        }
482
483        function getQuery(container) {
484            var query;
485            if (document.querySelectorAll) query = (container) ? container.querySelectorAll.bind(container) : document.querySelectorAll.bind(document);
486            if (!query && 'undefined' !== typeof $$) query = $$;
487            if (!query && 'undefined' !== typeof jQuery) query = jQuery;
488
489            if (!query) {
490                throw 'No document.querySelectorAll, jQuery or Mootools\'s $$ found.';
491            }
492
493            return query;
494        }
495
496        /**
497         * If animationStart didn't catch a new element in the DOM, we can manually search for it
498         */
499        function findElementQueriesElements(container) {
500            var query = getQuery(container);
501
502            for (var selector in allQueries) if (allQueries.hasOwnProperty(mode)) {
503                // find all elements based on the extract query selector from the element query rule
504                var elements = query(selector, container);
505
506                for (var i = 0, j = elements.length; i < j; i++) {
507                    setupElement(elements[i], selector);
508                }
509            }
510        }
511
512        /**
513         *
514         * @param {HTMLElement} element
515         */
516        function attachResponsiveImage(element) {
517            var children = [];
518            var rules = [];
519            var sources = [];
520            var defaultImageId = 0;
521            var lastActiveImage = -1;
522            var loadedImages = [];
523
524            for (var i in element.children) {
525                if (!element.children.hasOwnProperty(i)) continue;
526
527                if (element.children[i].tagName && element.children[i].tagName.toLowerCase() === 'img') {
528                    children.push(element.children[i]);
529
530                    var minWidth = element.children[i].getAttribute('min-width') || element.children[i].getAttribute('data-min-width');
531                    //var minHeight = element.children[i].getAttribute('min-height') || element.children[i].getAttribute('data-min-height');
532                    var src = element.children[i].getAttribute('data-src') || element.children[i].getAttribute('url');
533
534                    sources.push(src);
535
536                    var rule = {
537                        minWidth: minWidth
538                    };
539
540                    rules.push(rule);
541
542                    if (!minWidth) {
543                        defaultImageId = children.length - 1;
544                        element.children[i].style.display = 'block';
545                    } else {
546                        element.children[i].style.display = 'none';
547                    }
548                }
549            }
550
551            lastActiveImage = defaultImageId;
552
553            function check() {
554                var imageToDisplay = false, i;
555
556                for (i in children) {
557                    if (!children.hasOwnProperty(i)) continue;
558
559                    if (rules[i].minWidth) {
560                        if (element.offsetWidth > rules[i].minWidth) {
561                            imageToDisplay = i;
562                        }
563                    }
564                }
565
566                if (!imageToDisplay) {
567                    //no rule matched, show default
568                    imageToDisplay = defaultImageId;
569                }
570
571                if (lastActiveImage !== imageToDisplay) {
572                    //image change
573
574                    if (!loadedImages[imageToDisplay]) {
575                        //image has not been loaded yet, we need to load the image first in memory to prevent flash of
576                        //no content
577
578                        var image = new Image();
579                        image.onload = function () {
580                            children[imageToDisplay].src = sources[imageToDisplay];
581
582                            children[lastActiveImage].style.display = 'none';
583                            children[imageToDisplay].style.display = 'block';
584
585                            loadedImages[imageToDisplay] = true;
586
587                            lastActiveImage = imageToDisplay;
588                        };
589
590                        image.src = sources[imageToDisplay];
591                    } else {
592                        children[lastActiveImage].style.display = 'none';
593                        children[imageToDisplay].style.display = 'block';
594                        lastActiveImage = imageToDisplay;
595                    }
596                } else {
597                    //make sure for initial check call the .src is set correctly
598                    children[imageToDisplay].src = sources[imageToDisplay];
599                }
600            }
601
602            element.resizeSensor = new ResizeSensor(element, check);
603            check();
604        }
605
606        function findResponsiveImages() {
607            var query = getQuery();
608
609            var elements = query('[data-responsive-image],[responsive-image]');
610            for (var i = 0, j = elements.length; i < j; i++) {
611                attachResponsiveImage(elements[i]);
612            }
613        }
614
615        var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mg
615i;
616        var attrRegex = /\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]/mgi;
617
618        /**
619         * @param {String} css
620         */
621        function extractQuery(css) {
622            var match, smatch, attrs, attrMatch;
623
624            css = css.replace(/'/g, '"');
625            while (null !== (match = regex.exec(css))) {
626                smatch = match[1] + match[3];
627                attrs = match[2];
628
629                while (null !== (attrMatch = attrRegex.exec(attrs))) {
630                    queueQuery(smatch, attrMatch[1], attrMatch[2], attrMatch[3]);
631                }
632            }
633        }
634
635        /**
636         * @param {CssRule[]|String} rules
637         */
638        function readRules(rules) {
639            var selector = '';
640
641            if (!rules) {
642                return;
643            }
644
645            if ('string' === typeof rules) {
646                rules = rules.toLowerCase();
647                if (-1 !== rules.indexOf('min-width') || -1 !== rules.indexOf('max-width')) {
648                    extractQuery(rules);
649                }
650            } else {
651                for (var i = 0, j = rules.length; i < j; i++) {
652                    if (1 === rules[i].type) {
653                        selector = rules[i].selectorText || rules[i].cssText;
654                        if (-1 !== selector.indexOf('min-height') || -1 !== selector.indexOf('max-height')) {
655                            extractQuery(selector);
656                        } else if (-1 !== selector.indexOf('min-width') || -1 !== selector.indexOf('max-width')) {
657                            extractQuery(selector);
658                        }
659                    } else if (4 === rules[i].type) {
660                        readRules(rules[i].cssRules || rules[i].rules);
661                    } else if (3 === rules[i].type) {
662                        readRules(rules[i].styleSheet.cssRules);
663                    }
664                }
665            }
666        }
667
668        var defaultCssInjected = false;
669
670        /**
671         * Searches all css rules and setups the event listener to all elements with element query rules..
672         */
673        this.init = function () {
674            var animationStart = 'animationstart';
675            if (typeof document.documentElement.style['webkitAnimationName'] !== 'undefined') {
676                animationStart = 'webkitAnimationStart';
677            } else if (typeof document.documentElement.style['MozAnimationName'] !== 'undefined') {
678                animationStart = 'mozanimationstart';
679            } else if (typeof document.documentElement.style['OAnimationName'] !== 'undefined') {
680                animationStart = 'oanimationstart';
681            }
682
683            document.body.addEventListener(animationStart, function (e) {
684                var element = e.target;
685                var styles = window.getComputedStyle(element, null);
686
687                if (-1 !== styles.getPropertyValue('animation-name').indexOf('element-queries')) {
688                    element.elementQueriesSensor = new ResizeSensor(element, function () {
689                        if (element.elementQueriesSetupInformation) {
690                            element.elementQueriesSetupInformation.call();
691                        }
692                    });
693
694                    var sensorStyles = window.getComputedStyle(element.resizeSensor, null);
695                    var id = sensorStyles.getPropertyValue('min-width');
696                    id = parseInt(id.replace('px', ''));
697                    setupElement(e.target, idToSelectorMapping[id]);
698                }
699            });
700
701            if (!defaultCssInjected) {
702                cssStyleElement = document.createElement('style');
703                cssStyleElement.type = 'text/css';
704                cssStyleElement.innerHTML = '[responsive-image] > img, [data-responsive-image] {overflow: hidden; padding: 0; } [responsive-image] > img, [data-responsive-image] > img {width: 100%;}';
705
706                //safari wants at least one rule in keyframes to start working
707                cssStyleElement.innerHTML += '\n@keyframes element-queries { 0% { visibility: inherit; } }';
708                document.getElementsByTagName('head')[0].appendChild(cssStyleElement);
709                defaultCssInjected = true;
710            }
711
712            for (var i = 0, j = document.styleSheets.length; i < j; i++) {
713                try {
714                    if (document.styleSheets[i].href && 0 === document.styleSheets[i].href.indexOf('file://')) {
715                        console.log("CssElementQueries: unable to parse local css files, " + document.styleSheets[i].href);
716                    }
717
718                    readRules(document.styleSheets[i].cssRules || document.styleSheets[i].rules || document.styleSheets[i].cssText);
719                } catch (e) {
720                }
721            }
722
723            // findElementQueriesElements();
724            findResponsiveImages();
725        };
726
727        /**
728         * Go through all collected rules (readRules()) and attach the resize-listener.
729         * Not necessary to call it manually, since we detect automatically when new elements
730         * are available in the DOM. However, sometimes handy for dirty DOM modifications.
731         *
732         * @param {HTMLElement} container only elements of the container are considered (document.body if not set)
733         */
734        this.findElementQueriesElements = function (container) {
735            findElementQueriesElements(container);
736        };
737
738        this.update = function () {
739            this.init();
740        };
741    };
742
743    ElementQueries.update = function () {
744        ElementQueries.instance.update();
745    };
746
747    /**
748     * Removes all sensor and elementquery information from the element.
749     *
750     * @param {HTMLElement} element
751     */
752    ElementQueries.detach = function (element) {
753        if (element.elementQueriesSetupInformation) {
754            //element queries
755            element.elementQueriesSensor.detach();
756            delete element.elementQueriesSetupInformation;
757            delete element.elementQueriesSensor;
758
759        } else if (element.resizeSensor) {
760            //responsive image
761
762            element.resizeSensor.detach();
763            delete element.resizeSensor;
764        }
765    };
766
767    ElementQueries.init = function () {
768        if (!ElementQueries.instance) {
769            ElementQueries.instance = new ElementQueries();
770        }
771
772        ElementQueries.instance.init();
773    };
774
775    var domLoaded = function (callback) {
776        /* Mozilla, Chrome, Opera */
777        if (document.addEventListener) {
778            document.addEventListener('DOMContentLoaded', callback, false);
779        }
780        /* Safari, iCab, Konqueror */
781        else if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
782            var DOMLoadTimer = setInterval(function () {
783                if (/loaded|complete/i.test(document.readyState)) {
784                    callback();
785                    clearInterval(DOMLoadTimer);
786                }
787            }, 10);
788        }
789        /* Other web browsers */
790        else window.onload = callback;
791    };
792
793    ElementQueries.findElementQueriesElements = function (container) {
794        ElementQueries.instance.findElementQueriesElements(container);
795    };
796
797    ElementQueries.listen = function () {
798        domLoaded(ElementQueries.init);
799    };
800
801    return ElementQueries;
802
803}));
804
805(function($) {
806	'use strict';
807
808	$.exists = function(selector) {
809	    return ($(selector).length > 0);
810	};
811
812	/**
813	 * Helper to enable caching async scripts
814	 * https://api.jquery.com/jquery.getscript/
815	 * http://www.vrdmn.com/2013/07/overriding-jquerygetscript-to-include.html
816	 * 
817	 * @param  {String}   script url
818	 * @param  {Function} callback     
819	 */
820	$.getCachedScript = function( url ) {
821		var options = {
822			dataType: "script",
823			cache: true,
824			url: url
825		};
826	 
827	    // Use $.ajax() since it is more flexible than $.getScript
828	    // Return the jqXHR object so we can chain callbacks
829	  	return $.ajax( options );
830	};
831
832
833
834	// Fn to allow an event to fire after all images are loaded
835	// usage:
836	// $.ajax({
837	//     cache: false,
838	//     url: 'ajax/content.php',
839	//     success: function(data) {
840	//         $('#divajax').html(data).imagesLoaded().then(function(){
841	//             // do stuff after images are loaded here
842	//         });
843	//     }
844	// });
845	$.fn.mk_imagesLoaded = function () {
846
847	    // Edit: in strict mode, the var keyword is needed
848	    var $imgs = this.find('img[src!=""]');
849	    // if there's no images, just return an already resolved promise
850	    if (!$imgs.length) {return $.Deferred().resolve().promise();}
851
852	    // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails)
853	    var dfds = [];  
854	    $imgs.each(function(){
855	        var dfd = $.Deferred();
856	        dfds.push(dfd);
857	        var img = new Image();
858	        img.onload = function(){dfd.resolve();};
859	        img.onerror = function(){dfd.resolve();};
860	        img.src = this.src;
861	    });
862
863	    // return a master promise object which will resolve when all the deferred objects have resolved
864	    // IE - when all the images are loaded
865	    return $.when.apply($,dfds);
866
867	};
868
869}(jQuery));
870/**
871* Detect Element Resize
872*
873* https://github.com/sdecima/javascript-detect-element-resize
874* Sebastian Decima
875*
876* version: 0.5.3
877**/
878
879(function () {
880	var attachEvent = document.attachEvent,
881		stylesCreated = false;
882	
883	if (!attachEvent) {
884		var requestFrame = (function(){
885			var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
886								function(fn){ return window.setTimeout(fn, 20); };
887			return function(fn){ return raf(fn); };
888		})();
889		
890		var cancelFrame = (function(){
891			var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
892								   window.clearTimeout;
893		  return function(id){ return cancel(id); };
894		})();
895
896		function resetTriggers(element){
897			var triggers = element.__resizeTriggers__,
898				expand = triggers.firstElementChild,
899				contract = triggers.lastElementChild,
900				expandChild = expand.firstElementChild;
901			contract.scrollLeft = contract.scrollWidth;
902			contract.scrollTop = contract.scrollHeight;
903			expandChild.style.width = expand.offsetWidth + 1 + 'px';
904			expandChild.style.height = expand.offsetHeight + 1 + 'px';
905			expand.scrollLeft = expand.scrollWidth;
906			expand.scrollTop = expand.scrollHeight;
907		};
908
909		function checkTriggers(element){
910			return element.offsetWidth != element.__resizeLast__.width ||
911						 element.offsetHeight != element.__resizeLast__.height;
912		}
913		
914		function scrollListener(e){
915			var element = this;
916			resetTriggers(this);
917			if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
918			this.__resizeRAF__ = requestFrame(function(){
919				if (checkTriggers(element)) {
920					element.__resizeLast__.width = element.offsetWidth;
921					element.__resizeLast__.height = element.offsetHeight;
922					element.__resizeListeners__.forEach(function(fn){
923						fn.call(element, e);
924					});
925				}
926			});
927		};
928		
929		/* Detect CSS Animations support to detect element display/re-attach */
930		var animation = false,
931			animationstring = 'animation',
932			keyframeprefix = '',
933			animationstartevent = 'animationstart',
934			domPrefixes = 'Webkit Moz O ms'.split(' '),
935			startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
936			pfx  = '';
937		{
938			var elm = document.createElement('fakeelement');
939			if( elm.style.animationName !== undefined ) { animation = true; }    
940			
941			if( animation === false ) {
942				for( var i = 0; i < domPrefixes.length; i++ ) {
943					if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
944						pfx = domPrefixes[ i ];
945						animationstring = pfx + 'Animation';
946						keyframeprefix = '-' + pfx.toLowerCase() + '-';
947						animationstartevent = startEvents[ i ];
948						animation = true;
949						break;
950					}
951				}
952			}
953		}
954		
955		var animationName = 'resizeanim';
956		var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
957		var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
958	}
959	
960	function createStyles() {
961		if (!stylesCreated) {
962			//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
963			var css = (animationKeyframes ? animationKeyframes : '') +
964					'.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
965					'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
966				head = document.head || document.getElementsByTagName('head')[0],
967				style = document.createElement('style');
968			
969			style.type = 'text/css';
970			if (style.styleSheet) {
971				style.styleSheet.cssText = css;
972			} else {
973				style.appendChild(document.createTextNode(css));
974			}
975
976			head.appendChild(style);
977			stylesCreated = true;
978		}
979	}
980	
981	window.addResizeListener = function(element, fn){
982		if (attachEvent) element.attachEvent('onresize', fn);
983		else {
984			if (!element.__resizeTriggers__) {
985				if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
986				createStyles();
987				element.__resizeLast__ = {};
988				element.__resizeListeners__ = [];
989				(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
990				element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
991																						'<div class="contract-trigger"></div>';
992				element.appendChild(element.__resizeTriggers__);
993				resetTriggers(element);
994				element.addEventListener('scroll', scrollListener, true);
995				
996				/* Listen for a css animation to detect element display/re-attach */
997				animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
998					if(e.animationName == animationName)
999						resetTriggers(element);
1000				});
1001			}
1002			element.__resizeListeners__.push(fn);
1003		}
1004	};
1005	
1006	window.removeResizeListener = function(element, fn){
1007		if (attachEvent) element.detachEvent('onresize', fn);
1008		else {
1009			element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
1010			if (!element.__resizeListeners__.length) {
1011					element.removeEventListener('scroll', scrollListener);
1012					element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
1013			}
1014		}
1015	}
1016})();
1017/**
1018* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
1019*/
1020;(function(window, document) {
1021/*jshint evil:true */
1022  /** version */
1023  var version = '3.7.3';
1024
1025  /** Preset options */
1026  var options = window.html5 || {};
1027
1028  /** Used to skip problem elements */
1029  var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
1030
1031  /** Not all elements can be cloned in IE **/
1032  var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
1033
1034  /** Detect whether the browser supports default html5 styles */
1035  var supportsHtml5Styles;
1036
1037  /** Name of the expando, to work with multiple documents or to re-shiv one document */
1038  var expando = '_html5shiv';
1039
1040  /** The id for the the documents expando */
1041  var expanID = 0;
1042
1043  /** Cached data for each document */
1044  var expandoData = {};
1045
1046  /** Detect whether the browser supports unknown elements */
1047  var supportsUnknownElements;
1048
1049  (function() {
1050    try {
1051        var a = document.createElement('a');
1052        a.innerHTML = '<xyz></xyz>';
1053        //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
1054        supportsHtml5Styles = ('hidden' in a);
1055
1056        supportsUnknownElements = a.childNodes.length == 1 || (function() {
1057          // assign a false positive if unable to shiv
1058          (document.createElement)('a');
1059          var frag = document.createDocumentFragment();
1060          return (
1061            typeof frag.cloneNode == 'undefined' ||
1062            typeof frag.createDocumentFragment == 'undefined' ||
1063            typeof frag.createElement == 'undefined'
1064          );
1065        }());
1066    } catch(e) {
1067      // assign a false positive if detection fails => unable to shiv
1068      supportsHtml5Styles = true;
1069      supportsUnknownElements = true;
1070    }
1071
1072  }());
1073
1074  /*--------------------------------------------------------------------------*/
1075
1076  /**
1077   * Creates a style sheet with the given CSS text and adds it to the document.
1078   * @private
1079   * @param {Document} ownerDocument The document.
1080   * @param {String} cssText The CSS text.
1081   * @returns {StyleSheet} The style element.
1082   */
1083  function addStyleSheet(ownerDocument, cssText) {
1084    var p = ownerDocument.createElement('p'),
1085        parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
1086
1087    p.innerHTML = 'x<style>' + cssText + '</style>';
1088    return parent.insertBefore(p.lastChild, parent.firstChild);
1089  }
1090
1091  /**
1092   * Returns the value of `html5.elements` as an array.
1093   * @private
1094   * @returns {Array} An array of shived element node names.
1095   */
1096  function getElements() {
1097    var elements = html5.elements;
1098    return typeof elements == 'string' ? elements.split(' ') : elements;
1099  }
1100
1101  /**
1102   * Extends the built-in list of html5 elements
1103   * @memberOf html5
1104   * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
1105   * @param {Document} ownerDocument The context document.
1106   */
1107  function addElements(newElements, ownerDocument) {
1108    var elements = html5.elements;
1109    if(typeof elements != 'string'){
1110      elements = elements.join(' ');
1111    }
1112    if(typeof newElements != 'string'){
1113      newElements = newElements.join(' ');
1114    }
1115    html5.elements = elements +' '+ newElements;
1116    shivDocument(ownerDocument);
1117  }
1118
1119   /**
1120   * Returns the data associated to the given document
1121   * @private
1122   * @param {Document} ownerDocument The document.
1123   * @returns {Object} An object of data.
1124   */
1125  function getExpandoData(ownerDocument) {
1126    var data = expandoData[ownerDocument[expando]];
1127    if (!data) {
1128        data = {};
1129        expanID++;
1130        ownerDocument[expando] = expanID;
1131        expandoData[expanID] = data;
1132    }
1133    return data;
1134  }
1135
1136  /**
1137   * returns a shived element for the given nodeName and document
1138   * @memberOf html5
1139   * @param {String} nodeName name of the element
1140   * @param {Document|DocumentFrag
vendor: 6,335 bytes, lines 1140-1342
1140ment} ownerDocument The context document.
1141   * @returns {Object} The shived element.
1142   */
1143  function createElement(nodeName, ownerDocument, data){
1144    if (!ownerDocument) {
1145        ownerDocument = document;
1146    }
1147    if(supportsUnknownElements){
1148        return ownerDocument.createElement(nodeName);
1149    }
1150    if (!data) {
1151        data = getExpandoData(ownerDocument);
1152    }
1153    var node;
1154
1155    if (data.cache[nodeName]) {
1156        node = data.cache[nodeName].cloneNode();
1157    } else if (saveClones.test(nodeName)) {
1158        node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
1159    } else {
1160        node = data.createElem(nodeName);
1161    }
1162
1163    // Avoid adding some elements to fragments in IE < 9 because
1164    // * Attributes like `name` or `type` cannot be set/changed once an element
1165    //   is inserted into a document/fragment
1166    // * Link elements with `src` attributes that are inaccessible, as with
1167    //   a 403 response, will cause the tab/window to crash
1168    // * Script elements appended to fragments will execute when their `src`
1169    //   or `text` property is set
1170    return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
1171  }
1172
1173  /**
1174   * returns a shived DocumentFragment for the given document
1175   * @memberOf html5
1176   * @param {Document} ownerDocument The context document.
1177   * @returns {Object} The shived DocumentFragment.
1178   */
1179  function createDocumentFragment(ownerDocument, data){
1180    if (!ownerDocument) {
1181        ownerDocument = document;
1182    }
1183    if(supportsUnknownElements){
1184        return ownerDocument.createDocumentFragment();
1185    }
1186    data = data || getExpandoData(ownerDocument);
1187    var clone = data.frag.cloneNode(),
1188        i = 0,
1189        elems = getElements(),
1190        l = elems.length;
1191    for(;i<l;i++){
1192        clone.createElement(elems[i]);
1193    }
1194    return clone;
1195  }
1196
1197  /**
1198   * Shivs the `createElement` and `createDocumentFragment` methods of the document.
1199   * @private
1200   * @param {Document|DocumentFragment} ownerDocument The document.
1201   * @param {Object} data of the document.
1202   */
1203  function shivMethods(ownerDocument, data) {
1204    if (!data.cache) {
1205        data.cache = {};
1206        data.createElem = ownerDocument.createElement;
1207        data.createFrag = ownerDocument.createDocumentFragment;
1208        data.frag = data.createFrag();
1209    }
1210
1211
1212    ownerDocument.createElement = function(nodeName) {
1213      //abort shiv
1214      if (!html5.shivMethods) {
1215          return data.createElem(nodeName);
1216      }
1217      return createElement(nodeName, ownerDocument, data);
1218    };
1219
1220    ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
1221      'var n=f.cloneNode(),c=n.createElement;' +
1222      'h.shivMethods&&(' +
1223        // unroll the `createElement` calls
1224        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
1225          data.createElem(nodeName);
1226          data.frag.createElement(nodeName);
1227          return 'c("' + nodeName + '")';
1228        }) +
1229      ');return n}'
1230    )(html5, data.frag);
1231  }
1232
1233  /*--------------------------------------------------------------------------*/
1234
1235  /**
1236   * Shivs the given document.
1237   * @memberOf html5
1238   * @param {Document} ownerDocument The document to shiv.
1239   * @returns {Document} The shived document.
1240   */
1241  function shivDocument(ownerDocument) {
1242    if (!ownerDocument) {
1243        ownerDocument = document;
1244    }
1245    var data = getExpandoData(ownerDocument);
1246
1247    if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
1248      data.hasCSS = !!addStyleSheet(ownerDocument,
1249        // corrects block display not defined in IE6/7/8/9
1250        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
1251        // adds styling not present in IE6/7/8/9
1252        'mark{background:#FF0;color:#000}' +
1253        // hides non-rendered elements
1254        'template{display:none}'
1255      );
1256    }
1257    if (!supportsUnknownElements) {
1258      shivMethods(ownerDocument, data);
1259    }
1260    return ownerDocument;
1261  }
1262
1263  /*--------------------------------------------------------------------------*/
1264
1265  /**
1266   * The `html5` object is exposed so that more elements can be shived and
1267   * existing shiving can be detected on iframes.
1268   * @type Object
1269   * @example
1270   *
1271   * // options can be changed before the script is included
1272   * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
1273   */
1274  var html5 = {
1275
1276    /**
1277     * An array or space separated string of node names of the elements to shiv.
1278     * @memberOf html5
1279     * @type Array|String
1280     */
1281    'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
1282
1283    /**
1284     * current version of html5shiv
1285     */
1286    'version': version,
1287
1288    /**
1289     * A flag to indicate that the HTML5 style sheet should be inserted.
1290     * @memberOf html5
1291     * @type Boolean
1292     */
1293    'shivCSS': (options.shivCSS !== false),
1294
1295    /**
1296     * Is equal to true if a browser supports creating unknown/HTML5 elements
1297     * @memberOf html5
1298     * @type boolean
1299     */
1300    'supportsUnknownElements': supportsUnknownElements,
1301
1302    /**
1303     * A flag to indicate that the document's `createElement` and `createDocumentFragment`
1304     * methods should be overwritten.
1305     * @memberOf html5
1306     * @type Boolean
1307     */
1308    'shivMethods': (options.shivMethods !== false),
1309
1310    /**
1311     * A string to describe the type of `html5` object ("default" or "default print").
1312     * @memberOf html5
1313     * @type String
1314     */
1315    'type': 'default',
1316
1317    // shivs the document according to the specified `html5` object options
1318    'shivDocument': shivDocument,
1319
1320    //creates a shived element
1321    createElement: createElement,
1322
1323    //creates a shived documentFragment
1324    createDocumentFragment: createDocumentFragment,
1325
1326    //extends list of elements
1327    addElements: addElements
1328  };
1329
1330  /*--------------------------------------------------------------------------*/
1331
1332  // expose html5
1333  window.html5 = html5;
1334
1335  // shiv the document
1336  shivDocument(document);
1337
1338  if(typeof module == 'object' && module.exports){
1339    module.exports = html5;
1340  }
1341
1342}(typeof window !== "undefined" ? window : this, document));
1343/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
1344
1345window.matchMedia || (window.matchMedia = function() {
1346    "use strict";
1347
1348    // For browsers that support matchMedium api such as IE 9 and webkit
1349    var styleMedia = (window.styleMedia || window.media);
1350
1351    // For those that don't support matchMedium
1352    if (!styleMedia) {
1353        var style       = document.createElement('style'),
1354            script      = document.getElementsByTagName('script')[0],
1355            info        = null;
1356
1357        style.type  = 'text/css';
1358        style.id    = 'matchmediajs-test';
1359
1360        script.parentNode.insertBefore(style, script);
1361
1362        // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
1363        info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
1364
1365        styleMedia = {
1366            matchMedium: function(media) {
1367                var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
1368
1369                // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
1370                if (style.styleSheet) {
1371                    style.styleSheet.cssText = text;
1372                } else {
1373                    style.textContent = text;
1374                }
1375
1376                // Test if media query is true or false
1377                return info.width === '1px';
1378            }
1379        };
1380    }
1381
1382    return function(media) {
1383        return {
1384            matches: styleMedia.matchMedium(media || 'all'),
1385            media: media || 'all'
1386        };
1387    };
1388}());
1389
1390/*!
1391 * The MIT License
1392 *
1393 * Copyright (c) 2012 James Allardice
1394 *
1395 * Permission is hereby granted, free of charge, to any person obtaining a copy
1396 * of this software and associated documentation files (the "Software"), to
1397 * deal in the Software without restriction, including without limitation the
1398 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1399 * sell copies of the Software, and to permit persons to whom the Software is
1400 * furnished to do so, subject to the following conditions:
1401 *
1402 * The above copyright notice and this permission notice shall be included in
1403 * all copies or substantial portions of the Software.
1404 *
1405 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1406 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1407 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1408 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1409 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1410 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1411 * IN THE SOFTWARE.
1412 */
1413
1414( function ( global ) {
1415
1416  'use strict';
1417
1418  //
1419  // Test for support. We do this as early as possible to optimise for browsers
1420  // that have native support for the attribute.
1421  //
1422
1423  var test = document.createElement('input');
1424  var nativeSupport = test.placeholder !== void 0;
1425
1426  global.Placeholders = {
1427    nativeSupport: nativeSupport,
1428    disable: nativeSupport ? noop : disablePlaceholders,
1429    enable: nativeSupport ? noop : enablePlaceholders
1430  };
1431
1432  if ( nativeSupport ) {
1433    return;
1434  }
1435
1436  //
1437  // If we reach this point then the browser does not have native support for
1438  // the attribute.
1439  //
1440
1441  // The list of input element types that support the placeholder attribute.
1442  var validTypes = [
1443    'text',
1444    'search',
1445    'url',
1446    'tel',
1447    'email',
1448    'password',
1449    'number',
1450    'textarea'
1451  ];
1452
1453  // The list of keycodes that are not allowed when the polyfill is configured
1454  // to hide-on-input.
1455  var badKeys = [
1456
1457    // The following keys all cause the caret to jump to the end of the input
1458    // value.
1459
1460    27, // Escape
1461    33, // Page up
1462    34, // Page down
1463    35, // End
1464    36, // Home
1465
1466    // Arrow keys allow you to move the caret manually, which should be
1467    // prevented when the placeholder is visible.
1468
1469    37, // Left
1470    38, // Up
1471    39, // Right
1472    40, // Down
1473
1474    // The following keys allow you to modify the placeholder text by removing
1475    // characters, which should be prevented when the placeholder is visible.
1476
1477    8, // Backspace
1478    46 // Delete
1479  ];
1480
1481  // Styling variables.
1482  var placeholderStyleColor = '#ccc';
1483  var placeholderClassName = 'placeholdersjs';
1484  var classNameRegExp = new RegExp('(?:^|\\s)' + placeholderClassName + '(?!\\S)');
1485
1486  // The various data-* attributes used by the polyfill.
1487  var ATTR_CURRENT_VAL = 'data-placeholder-value';
1488  var ATTR_ACTIVE = 'data-placeholder-active';
1489  var ATTR_INPUT_TYPE = 'data-placeholder-type';
1490  var ATTR_FORM_HANDLED = 'data-placeholder-submit';
1491  var ATTR_EVENTS_BOUND = 'data-placeholder-bound';
1492  var ATTR_OPTION_FOCUS = 'data-placeholder-focus';
1493  var ATTR_OPTION_LIVE = 'data-placeholder-live';
1494  var ATTR_MAXLENGTH = 'data-placeholder-maxlength';
1495
1496  // Various other variables used throughout the rest of the script.
1497  var UPDATE_INTERVAL = 100;
1498  var head = document.getElementsByTagName('head')[ 0 ];
1499  var root = document.documentElement;
1500  var Placeholders = global.Placeholders;
1501  var keydownVal;
1502
1503  // Get references to all the input and textarea elements currently in the DOM
1504  // (live NodeList objects to we only need to do this once).
1505  var inputs = document.getElementsByTagName('input');
1506  var textareas = document.getElementsByTagName('textarea');
1507
1508  // Get any settings declared as data-* attributes on the root element.
1509  // Currently the only options are whether to hide the placeholder on focus
1510  // or input and whether to auto-update.
1511  var hideOnInput = root.getAttribute(ATTR_OPTION_FOCUS) === 'false';
1512  var liveUpdates = root.getAttribute(ATTR_OPTION_LIVE) !== 'false';
1513
1514  // Create style element for placeholder styles (instead of directly setting
1515  // style properties on elements - allows for better flexibility alongside
1516  // user-defined styles).
1517  var styleElem = document.createElement('style');
1518  styleElem.type = 'text/css';
1519
1520  // Create style rules as text node.
1521  var styleRules = document.createTextNode(
1522    '.' + placeholderClassName + ' {' +
1523      'color:' + placeholderStyleColor + ';' +
1524    '}'
1525  );
1526
1527  // Append style rules to newly created stylesheet.
1528  if ( styleElem.styleSheet ) {
1529    styleElem.styleSheet.cssText = styleRules.nodeValue;
1530  } else {
1531    styleElem.appendChild(styleRules);
1532  }
1533
1534  // Prepend new style element to the head (before any existing stylesheets,
1535  // so user-defined rules take precedence).
1536  head.insertBefore(styleElem, head.firstChild);
1537
1538  // Set up the placeholders.
1539  var placeholder;
1540  var elem;
1541
1542  for ( var i = 0, len = inputs.length + textareas.length; i < len; i++ ) {
1543
1544    // Find the next element. If we've already done all the inputs we move on
1545    // to the textareas.
1546    elem = i < inputs.length ? inputs[ i ] : textareas[ i - inputs.length ];
1547
1548    // Get the value of the placeholder attribute, if any. IE10 emulating IE7
1549    // fails with getAttribute, hence the use of the attributes node.
1550    placeholder = elem.attributes.placeholder;
1551
1552    // If the element has a placeholder attribute we need to modify it.
1553    if ( placeholder ) {
1554
1555      // IE returns an empty object instead of undefined if the attribute is
1556      // not present.
1557      placeholder = placeholder.nodeValue;
1558
1559      // Only apply the polyfill if this element is of a type that supports
1560      // placeholders and has a placeholder attribute with a non-empty value.
1561      if ( placeholder && inArray(validTypes, elem.type) ) {
1562        newElement(elem);
1563      }
1564    }
1565  }
1566
1567  // If enabled, the polyfill will repeatedly check for changed/added elements
1568  // and apply to those as well.
1569  var timer = setInterval(function () {
1570    for ( var i = 0, len = inputs.length + textareas.length; i < len; i++ ) {
1571      elem = i < inputs.length ? inputs[ i ] : textareas[ i - inputs.length ];
1572
1573      // Only apply the polyfill if this element is of a type that supports
1574      // placeholders, and has a placeholder attribute with a non-empty value.
1575      placeholder = elem.attributes.placeholder;
1576
1577      if ( placeholder ) {
1578
1579        placeholder = placeholder.nodeValue;
1580
1581        if ( placeholder && inArray(validTypes, elem.type) ) {
1582
1583          // If the element hasn't had event handlers bound to it then add
1584          // them.
1585          if ( !elem.getAttribute(ATTR_EVENTS_BOUND) ) {
1586            newElement(elem);
1587          }
1588
1589          // If the placeholder value has changed or not been initialised yet
1590          // we need to update the display.
1591          if (
1592            placeholder !== elem.getAttribute(ATTR_CURRENT_VAL) ||
1593            ( elem.type === 'password' && !elem.getAttribute(ATTR_INPUT_TYPE) )
1594          ) {
1595
1596            // Attempt to change the type of password inputs (fails in IE < 9).
1597            if (
1598              elem.type === 'password' &&
1599              !elem.getAttribute(ATTR_INPUT_TYPE) &&
1600              changeType(elem, 'text')
1601            ) {
1602              elem.setAttribute(ATTR_INPUT_TYPE, 'password');
1603            }
1604
1605            // If the placeholder value has changed and the placeholder is
1606            // currently on display we need to change it.
1607            if ( elem.value === elem.getAttribute(ATTR_CURRENT_VAL) ) {
1608              elem.value = placeholder;
1609            }
1610
1611            // Keep a reference to the current placeholder value in case it
1612            // changes via another script.
1613            elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
1614          }
1615        }
1616      } else if ( elem.getAttribute(ATTR_ACTIVE) ) {
1617        hidePlaceholder(elem);
1618        elem.removeAttribute(ATTR_CURRENT_VAL);
1619      }
1620    }
1621
1622    // If live updates are not enabled cancel the timer.
1623    if ( !liveUpdates ) {
1624      clearInterval(timer);
1625    }
1626  }, UPDATE_INTERVAL);
1627
1628  // Disabling placeholders before unloading the page prevents flash of
1629  // unstyled placeholders on load if the page was refreshed.
1630  addEventListener(global, 'beforeunload', function () {
1631    Placeholders.disable();
1632  });
1633
1634  //
1635  // Utility functions
1636  //
1637
1638  // No-op (used in place of public methods when native support is detected).
1639  function noop() {}
1640
1641  // Avoid IE9 activeElement of death when an iframe is used.
1642  //
1643  // More info:
1644  //  - http://bugs.jquery.com/ticket/13393
1645  //  - https://github.com/jquery/jquery/commit/85fc5878b3c6af73f42d61eedf73013e7faae408
1646  function safeActiveElement() {
1647    try {
1648      return document.activeElement;
1649    } catch ( err ) {}
1650  }
1651
1652  // Check whether an item is in an array. We don't use Array.prototype.indexOf
1653  // so we don't clobber any existing polyfills. This is a really simple
1654  // alternative.
1655  function inArray( arr, item ) {
1656    for ( var i = 0, len = arr.length; i < len; i++ ) {
1657      if ( arr[ i ] === item ) {
1658        return true;
1659      }
1660    }
1661    return false;
1662  }
1663
1664  // Cross-browser DOM event binding
1665  function addEventListener( elem, event, fn ) {
1666    if ( elem.addEventListener ) {
1667      return elem.addEventListener(event, fn, false);
1668    }
1669    if ( elem.attachEvent ) {
1670      return elem.attachEvent('on' + event, fn);
1671    }
1672  }
1673
1674  // Move the caret to the index position specified. Assumes that the element
1675  // has focus.
1676  function moveCaret( elem, index ) {
1677    var range;
1678    if ( elem.createTextRange ) {
1679      range = elem.createTextRange();
1680      range.move('character', index);
1681      range.select();
1682    } else if ( elem.selectionStart ) {
1683      elem.focus();
1684      elem.setSelectionRange(index, index);
1685    }
1686  }
1687
1688  // Attempt to change the type property of an input element.
1689  function changeType( elem, type ) {
1690    try {
1691      elem.type = type;
1692      return true;
1693    } catch ( e ) {
1694      // You can't change input type in IE8 and below.
1695      return false;
1696    }
1697  }
1698
1699  function handleElem( node, callback ) {
1700
1701    // Check if the passed in node is an input/textarea (in which case it can't
1702    // have any affected descendants).
1703    if ( node && node.getAttribute(ATTR_CURRENT_VAL) ) {
1704      callback(node);
1705    } else {
1706
1707      // If an element was passed in, get all affected descendants. Otherwise,
1708      // get all affected elements in document.
1709      var handleInputs = node ? node.getElementsByTagName('input') : input
1709s;
1710      var handleTextareas = node ? node.getElementsByTagName('textarea') : textareas;
1711
1712      var handleInputsLength = handleInputs ? handleInputs.length : 0;
1713      var handleTextareasLength = handleTextareas ? handleTextareas.length : 0;
1714
1715      // Run the callback for each element.
1716      var len = handleInputsLength + handleTextareasLength;
1717      var elem;
1718      for ( var i = 0; i < len; i++ ) {
1719
1720        elem = i < handleInputsLength ?
1721          handleInputs[ i ] :
1722          handleTextareas[ i - handleInputsLength ];
1723
1724        callback(elem);
1725      }
1726    }
1727  }
1728
1729  // Return all affected elements to their normal state (remove placeholder
1730  // value if present).
1731  function disablePlaceholders( node ) {
1732    handleElem(node, hidePlaceholder);
1733  }
1734
1735  // Show the placeholder value on all appropriate elements.
1736  function enablePlaceholders( node ) {
1737    handleElem(node, showPlaceholder);
1738  }
1739
1740  // Hide the placeholder value on a single element. Returns true if the
1741  // placeholder was hidden and false if it was not (because it wasn't visible
1742  // in the first place).
1743  function hidePlaceholder( elem, keydownValue ) {
1744
1745    var valueChanged = !!keydownValue && elem.value !== keydownValue;
1746    var isPlaceholderValue = elem.value === elem.getAttribute(ATTR_CURRENT_VAL);
1747
1748    if (
1749      ( valueChanged || isPlaceholderValue ) &&
1750      elem.getAttribute(ATTR_ACTIVE) === 'true'
1751    ) {
1752
1753      elem.removeAttribute(ATTR_ACTIVE);
1754      elem.value = elem.value.replace(elem.getAttribute(ATTR_CURRENT_VAL), '');
1755      elem.className = elem.className.replace(classNameRegExp, '');
1756
1757      // Restore the maxlength value. Old FF returns -1 if attribute not set.
1758      // See GH-56.
1759      var maxLength = elem.getAttribute(ATTR_MAXLENGTH);
1760      if ( parseInt(maxLength, 10) >= 0 ) {
1761        elem.setAttribute('maxLength', maxLength);
1762        elem.removeAttribute(ATTR_MAXLENGTH);
1763      }
1764
1765      // If the polyfill has changed the type of the element we need to change
1766      // it back.
1767      var type = elem.getAttribute(ATTR_INPUT_TYPE);
1768      if ( type ) {
1769        elem.type = type;
1770      }
1771
1772      return true;
1773    }
1774
1775    return false;
1776  }
1777
1778  // Show the placeholder value on a single element. Returns true if the
1779  // placeholder was shown and false if it was not (because it was already
1780  // visible).
1781  function showPlaceholder( elem ) {
1782
1783    var val = elem.getAttribute(ATTR_CURRENT_VAL);
1784
1785    if ( elem.value === '' && val ) {
1786
1787      elem.setAttribute(ATTR_ACTIVE, 'true');
1788      elem.value = val;
1789      elem.className += ' ' + placeholderClassName;
1790
1791      // Store and remove the maxlength value.
1792      var maxLength = elem.getAttribute(ATTR_MAXLENGTH);
1793      if ( !maxLength ) {
1794        elem.setAttribute(ATTR_MAXLENGTH, elem.maxLength);
1795        elem.removeAttribute('maxLength');
1796      }
1797
1798      // If the type of element needs to change, change it (e.g. password
1799      // inputs).
1800      var type = elem.getAttribute(ATTR_INPUT_TYPE);
1801      if ( type ) {
1802        elem.type = 'text';
1803      } else if ( elem.type === 'password' && changeType(elem, 'text') ) {
1804        elem.setAttribute(ATTR_INPUT_TYPE, 'password');
1805      }
1806
1807      return true;
1808    }
1809
1810    return false;
1811  }
1812
1813  // Returns a function that is used as a focus event handler.
1814  function makeFocusHandler( elem ) {
1815    return function () {
1816
1817      // Only hide the placeholder value if the (default) hide-on-focus
1818      // behaviour is enabled.
1819      if (
1820        hideOnInput &&
1821        elem.value === elem.getAttribute(ATTR_CURRENT_VAL) &&
1822        elem.getAttribute(ATTR_ACTIVE) === 'true'
1823      ) {
1824
1825        // Move the caret to the start of the input (this mimics the behaviour
1826        // of all browsers that do not hide the placeholder on focus).
1827        moveCaret(elem, 0);
1828      } else {
1829
1830        // Remove the placeholder.
1831        hidePlaceholder(elem);
1832      }
1833    };
1834  }
1835
1836  // Returns a function that is used as a blur event handler.
1837  function makeBlurHandler( elem ) {
1838    return function () {
1839      showPlaceholder(elem);
1840    };
1841  }
1842
1843  // Returns a function that is used as a submit event handler on form elements
1844  // that have children affected by this polyfill.
1845  function makeSubmitHandler( form ) {
1846    return function () {
1847
1848        // Turn off placeholders on all appropriate descendant elements.
1849        disablePlaceholders(form);
1850    };
1851  }
1852
1853  // Functions that are used as a event handlers when the hide-on-input
1854  // behaviour has been activated - very basic implementation of the 'input'
1855  // event.
1856  function makeKeydownHandler( elem ) {
1857    return function ( e ) {
1858      keydownVal = elem.value;
1859
1860      // Prevent the use of the arrow keys (try to keep the cursor before the
1861      // placeholder).
1862      if (
1863        elem.getAttribute(ATTR_ACTIVE) === 'true' &&
1864        keydownVal === elem.getAttribute(ATTR_CURRENT_VAL) &&
1865        inArray(badKeys, e.keyCode)
1866      ) {
1867        if ( e.preventDefault ) {
1868            e.preventDefault();
1869        }
1870        return false;
1871      }
1872    };
1873  }
1874
1875  function makeKeyupHandler(elem) {
1876    return function () {
1877      hidePlaceholder(elem, keydownVal);
1878
1879      // If the element is now empty we need to show the placeholder
1880      if ( elem.value === '' ) {
1881        elem.blur();
1882        moveCaret(elem, 0);
1883      }
1884    };
1885  }
1886
1887  function makeClickHandler(elem) {
1888    return function () {
1889      if (
1890        elem === safeActiveElement() &&
1891        elem.value === elem.getAttribute(ATTR_CURRENT_VAL) &&
1892        elem.getAttribute(ATTR_ACTIVE) === 'true'
1893      ) {
1894        moveCaret(elem, 0);
1895      }
1896    };
1897  }
1898
1899  // Bind event handlers to an element that we need to affect with the
1900  // polyfill.
1901  function newElement( elem ) {
1902
1903    // If the element is part of a form, make sure the placeholder string is
1904    // not submitted as a value.
1905    var form = elem.form;
1906    if ( form && typeof form === 'string' ) {
1907
1908      // Get the real form.
1909      form = document.getElementById(form);
1910
1911      // Set a flag on the form so we know it's been handled (forms can contain
1912      // multiple inputs).
1913      if ( !form.getAttribute(ATTR_FORM_HANDLED) ) {
1914        addEventListener(form, 'submit', makeSubmitHandler(form));
1915        form.setAttribute(ATTR_FORM_HANDLED, 'true');
1916      }
1917    }
1918
1919    // Bind event handlers to the element so we can hide/show the placeholder
1920    // as appropriate.
1921    addEventListener(elem, 'focus', makeFocusHandler(elem));
1922    addEventListener(elem, 'blur', makeBlurHandler(elem));
1923
1924    // If the placeholder should hide on input rather than on focus we need
1925    // additional event handlers
1926    if (hideOnInput) {
1927      addEventListener(elem, 'keydown', makeKeydownHandler(elem));
1928      addEventListener(elem, 'keyup', makeKeyupHandler(elem));
1929      addEventListener(elem, 'click', makeClickHandler(elem));
1930    }
1931
1932    // Remember that we've bound event handlers to this element.
1933    elem.setAttribute(ATTR_EVENTS_BOUND, 'true');
1934    elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
1935
1936    // If the element doesn't have a value and is not focussed, set it to the
1937    // placeholder string.
1938    if ( hideOnInput || elem !== safeActiveElement() ) {
1939      showPlaceholder(elem);
1940    }
1941  }
1942
1943}(this) );
1944// IE spupport comes in IE10
1945(function rAFPolyfill() {
1946    var lastTime, vendors, x;
1947    lastTime = 0;
1948    vendors = ["webkit", "moz"];
1949    x = 0;
1950    while (x < vendors.length && !window.requestAnimationFrame) {
1951      window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
1952      window.cancelAnimationFrame = window[vendors[x] + "CancelAnimationFrame"] || window[vendors[x] + "CancelRequestAnimationFrame"];
1953      ++x;
1954    }
1955    if (!window.requestAnimationFrame) {
1956      window.requestAnimationFrame = function(callback, element) {
1957        var currTime, id, timeToCall;
1958        currTime = new Date().getTime();
1959        timeToCall = Math.max(0, 16 - (currTime - lastTime));
1960        id = window.setTimeout(function() {
1961          callback(currTime + timeToCall);
1962        }, timeToCall);
1963        lastTime = currTime + timeToCall;
1964        return id;
1965      };
1966    }
1967    if (!window.cancelAnimationFrame) {
1968      window.cancelAnimationFrame = function(id) {
1969        clearTimeout(id);
1970      };
1971    }
1972})();
1973
1974
1975
1976(function($) {
1977	'use strict';
1978
1979	var MK = window.MK || {};
1980
1981	/**
1982	 * MK.core holds most important methods that bootstraps whole application
1983	 * 
1984	 * @type {Object}
1985	 */
1986	MK.core = {};
1987
1988
1989
1990	/**
1991	 * State for referance of already loaded script files
1992	 * @type {Array}
1993	 */
1994	var _loadedDependencies = [];
1995
1996	/**
1997	 * State of queue represented as pairs of script ref => callback
1998	 * @type {Object}
1999	 */
2000	var _inQueue = {};
2001	
2002	/**
2003	 * Initializes all components in given scope (object or DOM reference) based on data attribute and 'pointer' css class '.js-el'.
2004	 * DOM work is reduced by single traversing for pointer class and later filtering through cached object. It expects init() method
2005	 * on every component. Component itself should be defined in MK.component namespace and assign to DOM element via data-mk-component.
2006	 * Use it once on DOM ready with document as a scope. For partial initialization after aja
2006x operations pass as a scope element
2007	 * where new DOM was inserted.
2008	 * 
2009	 * @param  {string|object}
2010	 */
2011	MK.core.initAll = function( scope ) {
2012		var $el = $( scope ).find( '.js-el' ), // single traversing
2013			$components = $el.filter( '[data-mk-component]' ),
2014			component = null;
2015
2016
2017		// initialize  component
2018		var init = function init(name, el) {
2019			var $el = $(el);
2020
2021			if ( $el.data('init-' + name) ) return; // do not initialize the same module twice
2022
2023			if ( typeof MK.component[ name ] !== 'function' ) console.log('Component init error: ', name);
2024			else {
2025				component = new MK.component[ name ]( el );
2026				component.init();
2027				$el.data('init-' + name, true); // mark as initialised
2028				// TODO add name
2029				MK.utils.eventManager.publish('component-inited');
2030			}
2031		};
2032
2033		$components.each( function() {
2034			var self = this,
2035				$this = $( this ),
2036				names = $this.data( 'mk-component' );
2037
2038			if( typeof names === 'string' ) {
2039				var name = names; // containes only single name. Keep it transparent.
2040				init(name, self);
2041			} else {
2042				names.forEach( function( name ) {
2043					init(name, self);
2044				});
2045			} 
2046		}); 
2047	};
2048
2049	/**
2050	 * Async loader for 3rd party plugins available from within theme or external CDNs / APIs.
2051	 * Take one argument as callback which is run when loading is finished. Also keeps track of already loaded scripts 
2052	 * and prevent duplication. Holds in queue multiple callbacks that where defined in different places but depend on the 
2053	 * same plugin.
2054	 *
2055	 * TODO: heavy test for multiple dependencies and crosssharing one dependency and different one dependency in queue, 
2056	 * bulletproof with single dependency
2057	 *
2058	 * @example MK.core.loadDependencies([MK.core.path.plugins + 'plugin.js'], function() {
2059	 *          	// do something when plugin is loaded
2060	 * 			})
2061	 * 
2062	 * @param  {array}
2063	 * @param  {function}
2064	 */
2065	MK.core.loadDependencies = function( dependencies, callback ) {
2066		var _callback = callback || function() {};
2067
2068        if( !dependencies ) {
2069        	// If no dependencies defined then run _callback imidietelly
2070        	_callback(); 
2071        	return;
2072        }
2073
2074		// Check for new dependencies
2075        var newDeps = dependencies.map( function( dep ) {
2076            if( _loadedDependencies.indexOf( dep ) === -1 ) {
2077            	 if( typeof _inQueue[ dep ] === 'undefined' ) {
2078        			// console.log( dep );
2079                	return dep;
2080                } else {
2081                	_inQueue[ dep ].push( _callback );
2082                	return true;
2083                }
2084            } else {
2085            	return false;
2086            }
2087        });
2088
2089        // The dependency is not new but it's not resolved yet
2090        // Callback is added to queue that will be run after the script is loaded
2091        // Don't run callback just yet.
2092        if( newDeps[0] === true ) {
2093        	// console.log('Waiting for ' + dependencies[0]);
2094        	return;
2095        }
2096
2097        // Dependency was loaded previously. We can run callback safely
2098        if( newDeps[0] === false ) {
2099        	_callback();
2100        	return;
2101        }
2102
2103        // Create queue and relationship script -> callback array to track
2104        // all callbacks that waits for ths script
2105        var queue = newDeps.map( function( script ) {
2106        	// console.log( script );
2107        	_inQueue[ script ] = [ _callback ];
2108            return $.getCachedScript( script );
2109        });
2110
2111        // Callbacks invoking
2112        var onLoad = function onLoad() {
2113        	var index;
2114        	newDeps.map( function( loaded ) {
2115        		_inQueue[ loaded ].forEach( function( callback ) {
2116        			callback();
2117        		});
2118        		delete _inQueue[ loaded ];
2119                _loadedDependencies.push( loaded );
2120        	});
2121        };
2122
2123        // Run callbacks when promise is resolved
2124        $.when.apply( null, queue ).done( onLoad );
2125	};
2126
2127	/**
2128	 * Single namespace for all paths recuired in application.
2129	 * @type {Object}
2130	 */
2131	MK.core.path = {
2132		theme   : mk_theme_dir,
2133		plugins : mk_theme_js_path + '/plugins/async/min/',
2134		ajaxUrl : window.PHP.ajax
2135	};
2136
2137
2138})(jQuery);
2139(function($) {
2140	'use strict';
2141
2142    var MK = window.MK || {};
2143	MK.utils = window.MK.utils || {};
2144
2145    /**
2146     * Enables to evaluate common methods through DOM JSON references by invoking from object with bracket notation MK.utils[var][var]
2147     * @type {Object}
2148     */
2149    MK.utils.actions = {};
2150
2151    MK.utils.actions.activate = function (el) {
2152        $(el).addClass('is-active');
2153    };
2154        
2155    MK.utils.actions.deactivate = function (el) {
2156        $(el).removeClass('is-active');
2157    };
2158
2159}(jQuery));
2160(function($) {
2161	'use strict';
2162
2163    var MK = window.MK || {};
2164	MK.utils = window.MK.utils || {};
2165
2166    /**
2167     * Gets user browser and its version
2168     * @return {Object} => {name, version}
2169     */
2170	MK.utils.browser = (function() {
2171        var dataBrowser = [
2172            {string: navigator.userAgent, subString: "Edge", identity: "Edge"},
2173            {string: navigator.userAgent, subString: "Chrome", identity: "Chrome"},
2174            {string: navigator.userAgent, subString: "MSIE", identity: "IE"},
2175            {string: navigator.userAgent, subString: "Trident", identity: "IE"},
2176            {string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
2177            {string: navigator.userAgent, subString: "Safari", identity: "Safari"},
2178            {string: navigator.userAgent, subString: "Opera", identity: "Opera"}
2179        ];
2180
2181		var versionSearchString = null;
2182        var searchString = function (data) {
2183            for (var i = 0; i < data.length; i++) {
2184                var dataString = data[i].string;
2185                versionSearchString = data[i].subString;
2186
2187                if (dataString.indexOf(data[i].subString) !== -1) {
2188                    return data[i].identity;
2189                }
2190            }
2191        };
2192        
2193        var searchVersion = function (dataString) {
2194            var index = dataString.indexOf(versionSearchString);
2195            if (index === -1) {
2196                return;
2197            }
2198
2199            var rv = dataString.indexOf("rv:");
2200            if (versionSearchString === "Trident" && rv !== -1) {
2201                return parseFloat(dataString.substring(rv + 3));
2202            } else {
2203                return parseFloat(dataString.substring(index + versionSearchString.length + 1));
2204            }
2205        };
2206
2207        var name = searchString(dataBrowser) || "Other";
2208        var version = searchVersion(navigator.userAgent) || searchVersion(navigator.appVersion) || "Unknown";
2209
2210        // Expose for css
2211        $('html').addClass(name).addClass(name + version);
2212
2213
2214        return {
2215        	name : name,
2216        	version : version
2217        };
2218        
2219	})();
2220
2221    /**
2222     * Gets user operating system
2223     * @return {String}
2224     */
2225	MK.utils.OS = (function() {
2226		if (navigator.appVersion.indexOf("Win")!=-1) return "Windows";
2227		if (navigator.appVersion.indexOf("Mac")!=-1) return "OSX";
2228		if (navigator.appVersion.indexOf("X11")!=-1) return "UNIX";
2229		if (navigator.appVersion.indexOf("Linux")!=-1) return "Linux";
2230	})();
2231	
2232    /**
2233     * Check if mobile device.
2234     * @return {Boolean}
2235     */
2236	MK.utils.isMobile = function() {
2237        // Problems with bigger tablets as users raport differences with behaviour. Switch to navigator sniffing
2238		// return ('ontouchstart' in document.documentElement) && matchMedia( '(max-width: 1024px)' ).matches;
2239     
2240        // http://www.abeautifulsite.net/detecting-mobile-devices-with-javascript/
2241        // if it still brings problem try to move to more sophisticated solution like
2242        // apachemobilefilter.org
2243        // detectright.com
2244        // web.wurfl.io
2245        // 
2246        // Seems as best solution here:
2247        // hgoebl.github.io/mobile-detect.js
2248
2249        function android() {
2250            return navigator.userAgent.match(/Android/i);
2251        }
2252
2253        function blackBerry() {
2254            return navigator.userAgent.match(/BlackBerry/i);
2255        }
2256
2257        function iOS() {
2258            return navigator.userAgent.match(/iPhone|iPad|iPod/i);
2259        }
2260
2261        function opera() {
2262            return navigator.userAgent.match(/Opera Mini/i);
2263        }
2264
2265        function windows() {
2266            return navigator.userAgent.match(/IEMobile/i);
2267        }
2268
2269        return (android() || blackBerry() || iOS() || opera() || windows() || matchMedia( '(max-width: 1024px)' ).matches); 
2270            
2271	};
2272
2273    /**
2274     * Check if menu is switched to responsive state based on user width settings
2275     * @return {Boolean} 
2276     */
2277    MK.utils.isResponsiveMenuState = function() {
2278        return window.matchMedia( '(max-width: '+ mk_responsive_nav_width +'px)').matches;
2279    };
2280
2281
2282
2283    MK.utils.getUrlParameter = function getUrlParameter(sParam) {
2284        var sPageURL = decodeURIComponent(window.location.search.substring(1)),
2285            sURLVariables = sPageURL.split('&'),
2286            sParameterName,
2287            i;
2288
2289        for (i = 0; i < sURLVariables.length; i++) {
2290            sParameterName = sURLVariables[i].split('=');
2291
2292            if (sParameterName[0] === sParam) {
2293                return sParameterName[1] === undefined ? true : sParameterName[1];
2294            }
2295        }
2296    };
2297
2298
2299    MK.utils.isSmoothScroll = (function() {
2300        var isUserChoice = (mk_smooth_scroll === 'true');
2301
2302        // We notify our app about smooth scroll option when user choose it from admin panel.
2303        return isUserChoice;
2304    }());
2305
2306}(jQuery));
2307(function($) {
2308	'use strict';
2309
2310    var MK = window.MK || {};
2311	MK.utils = window.MK.utils || {};
2312
2313	/**
2314	 * Basic implementation of pub / sub pattern to avoid tight coupling with direct module communication
2315	 * @type {Object}
2316	 */
2317	MK.utils.eventManager = {};
2318
2319	/**
2320	 * Subscribe to custom event and run callbacks
2321	 * @param  {String}
2322	 * @param  {Function}
2323	 *
2324	 * @usage MK.utils.eventManager.subscribe('event', function(e, params) {} )
2325	 */
2326	MK.utils.eventManager.subscribe = function(evt, func) {
2327		$(this).on(evt, func);
2328	};
2329
2330	/**
2331	 * Unsubscribe from custom event
2332	 * @param  {String}
2333	 * @param  {Function}
2334	 */
2335	MK.utils.eventManager.unsubscribe = function(evt, func) {
2336		$(this).off(evt, func);
2337	};
2338
2339	/**
2340	 * Publish custom event to notify appliaction about state change
2341	 * @param  {String}
2342	 * 
2343	 * @usage MK.utils.eventManager.publish('event', {
2344	 *        	param: val
2345	 *        })
2346	 */
2347	MK.utils.eventManager.publish = function(evt, params) {
2348		$(this).trigger(evt, [params]);
2349	};
2350
2351}(jQuery));
2352(function($) {
2353	'use strict';
2354
2355    var MK = window.MK || {};
2356	MK.utils = window.MK.utils || {};
2357
2358	/**
2359	 * Control browser fullscreen mode
2360	 * @type {Object}
2361	 */
2362	MK.utils.fullscreen = {};
2363
2364	// TODO: move to namespace
2365	MK.utils.launchIntoFullscreen = function ( element ) {
2366	    if(element.requestFullscreen) {
2367	     	element.requestFullscreen();
2368	  	} else if(element.mozRequestFullScreen) {
2369	    	element.mozRequestFullScreen();
2370	  	} else if(element.webkitRequestFullscreen) {
2371	    	element.webkitRequestFullscreen();
2372	  	} else if(element.msRequestFullscreen) {
2373	    	element.msRequestFullscreen();
2374	  	}
2375	};
2376
2377	MK.utils.exitFullscreen = function () {
2378	  	if(document.exitFullscreen) {
2379	    	document.exitFullscreen();
2380	  	} else if(document.mozCancelFullScreen) {
2381	    	document.mozCancelFullScreen();
2382	  	} else if(document.webkitExitFullscreen) {
2383	    	document.webkitExitFullscreen();
2384	  	}
2385	};
2386
2387}(jQuery));
2388(function($) {
2389	'use strict';
2390
2391    var MK = window.MK || {};
2392	MK.utils = window.MK.utils || {};
2393
2394	MK.utils.misc = {};
2395	// TODO: move to namespace
2396
2397	/**
2398	 * Get all top offsets from jQuery collection
2399	 * 
2400	 * @param  {$Objects}
2401	 * @return {Aray}
2402	 */
2403	MK.utils.offsets = function( $els ) {
2404		return $.map( $els, function( el ) {
2405			return $( el ).offset().top;
2406		});
2407	};
2408
2409	/**
2410	 * Retrive from array of numbers first number that is higher than given parameter
2411	 * 
2412	 * @param  {Number}
2413	 * @param  {Array}
2414	 * @return {Number}
2415	 */
2416	MK.utils.nextHigherVal = function( val, arr ) {
2417		var i = 0,
2418			higher = null;
2419
2420		var check = function() {
2421			if( val > arr[ i ]) {
2422				i += 1;
2423				check();
2424			} else {
2425				higher = arr[ i ];
2426			}
2427		};
2428		check();
2429
2430		return higher;
2431	};
2432
2433
2434    MK.utils.throttle = function( delay, fn ) {
2435        var last;
2436        var deferTimer;
2437
2438        return function() {
2439            var context = this;
2440            var args = arguments;
2441            var now = +new Date;
2442            if( last && now < last + delay ) {
2443            	clearTimeout( deferTimer );
2444            	deferTimer = setTimeout( function() { 
2445            		last = now; fn.apply( context, args ); 
2446            	}, delay );
2447          	} else {
2448            	last = now;
2449            	fn.apply( context, args );
2450          	}
2451        };
2452    };
2453
2454    MK.utils.isElementInViewport = function( el ) {
2455        var elemTop = el.getBoundingClientRect().top;
2456	    var isVisible = (elemTop < window.innerHeight);
2457	    return isVisible;
2458    };
2459
2460})(jQuery); 
2461(function($) {
2462	'use strict';
2463
2464    var MK = window.MK || {};
2465	MK.utils = window.MK.utils || {};
2466
2467	/**
2468	 * Scrolls page to static pixel offset
2469	 * @param  {Number}
2470	 */
2471	MK.utils.scrollTo = function( offset ) {
2472		$('html, body').stop().animate({
2473			scrollTop: offset
2474			}, {
2475	  		duration: 1200,
2476	  		easing: "easeInOutExpo"
2477		});
2478	};
2479
2480	/**
2481	 * Scrolls to element passed in as object or DOM reference
2482	 * @param  {String|Object}
2483	 */
2484	MK.utils.scrollToAnchor = function( hash ) {
2485		// Escape meta-chars from hash name only.
2486		hash = hash.substring(1).replace(/[!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g, "\\$&");
2487		hash = "#" + hash;
2488		var $target = $( hash );
2489		// console.log( hash );
2490
2491		if( ! $target.length ) return;
2492
2493		var offset  = $target.offset().top;
2494		offset = offset - MK.val.offsetHeaderHeight( offset );
2495
2496		if( hash === '#top-of-page' ) window.history.replaceState( undefined, undefined, ' ' );
2497		else window.history.replaceState( undefined, undefined, hash );
2498
2499		MK.utils.scrollTo( offset );
2500	};
2501
2502	/**
2503	 * Controls native scroll behaviour
2504	 * @return {Object} => {disable, enable}
2505	 */
2506	MK.utils.scroll = (function() {
2507        // 37 - left arror, 38 - up arrow, 39 right arrow, 40 down arrow
2508	    var keys = [38, 40];
2509
2510        function preventDefault(e) {
2511          e = e || window.event;
2512          e.preventDefault();
2513          e.returnValue = false;  
2514        }
2515
2516        function wheel(e) {
2517          preventDefault(e);
2518        }
2519
2520        function keydown(e) {
2521            for (var i = keys.length; i--;) {
2522                if (e.keyCode === keys[i]) {
2523                    preventDefault(e);
2524                    return;
2525                }
2526            }
2527        }
2528
2529        function disableScroll() {
2530            if (window.addEventListener) {
2531                window.addEventListener('DOMMouseScroll', wheel, false);
2532            }
2533          	window.onmousewheel = document.onmousewheel = wheel;
2534          	document.onkeydown = keydown;
2535        }
2536
2537        function enableScroll() {            
2538          	if (window.removeEventListener) {
2539                window.removeEventListener('DOMMouseScroll', wheel, false);
2540            }
2541            window.onmousewheel = document.onmousewheel = document.onkeydown = null; 
2542        }	
2543
2544        return {
2545        	disable : disableScroll,
2546        	enable  : enableScroll
2547        };
2548
2549	})();
2550
2551	/**
2552	 * Checks if passed link element has anchor inside current page. Returns string like '#anchor' if so or false
2553	 * @param  {String|Object}
2554	 * @return {String|Boolean}
2555	 */
2556	MK.utils.detectAnchor = function( el ) {
2557		var $this = $( el ),
2558			loc = window.location,
2559			currentPage = loc.origin + loc.pathname,
2560			href = $this.attr( 'href' ),
2561			linkSplit = (href) ? href.split( '#' ) : '',
2562			hrefPage  = linkSplit[0] ? linkSplit[0] : '', 
2563			hrefHash  = linkSplit[1] ? linkSplit[1] : '';
2564
2565		if( typeof hrefHash !== 'undefined' && hrefHash !== '' ) {
2566			return '#' + hrefHash;
2567		} else {
2568			return false;
2569		}
2570	};
2571
2572	/**
2573	 * This should be invoked only on page load. 
2574	 * Scrolls to anchor from  address bar
2575	 */
2576	MK.utils.scrollToURLHash = function() {
2577		var loc = window.location,
2578			hash = loc.hash;
2579
2580		if ( hash.length && hash.substring(1).length ) {
2581			// !loading is added early after DOM is ready to prevent native jump to anchor
2582			hash = hash.replace( '!loading', '' );
2583
2584			// Wait for one second before animating 
2585			// Most of UI animations should be done by then and async operations complited
2586			setTimeout( function() {
2587				MK.utils.scrollToAnchor( hash );
2588			}, 1000 ); 
2589
2590			// Right after reset back address bar
2591			setTimeout( function() {
2592				window.history.replaceState(undefined, undefined, hash);
2593			}, 1001);
2594		}
2595	};
2596
2597	/**
2598	 * Scroll Spy implementation. Spy dynamic offsets of elements or static pixel offset
2599	 * @param  {Number|Element}
2600	 * @param  {Object} => callback object {before, active, after}
2601	 */
2602	MK.utils.scrollSpy = function( toSpy, config ) {
2603		var $window   = $( window ),
2604	        container = document.getElementById( 'mk-theme-container' ),
2605	        isObj     = ( typeof toSpy === 'object' ),
2606	        offset    = (isObj) ? MK.val.dynamicOffset( toSpy, config.position, config.threshold ) : function() { return toSpy; },
2607	        height    = (isObj) ? MK.val.dynamicHeight( toSpy ) : function() { return 0; },
2608	        cacheVals = {},
2609	        _p 		  = 'before'; // current position
2610
2611		var checkPosition = function() {
2612	    	var s = MK.val.scroll(), 
2613	    		o = offset(),
2614	    		h = height();
2615
2616	        if( s < o && _p !== 'before' ) {
2617	        	// console.log( toSpy, 'before' );
2618	        	if( config.before ) config.before();
2619	        	_p = 'before';
2620	        } 
2621	        else if( s >= o && s <= o + h && _p !== 'active' ) {
2622	        	// console.log( toSpy, 'active' );
2623	        	if( config.active ) config.active( o );
2624	        	_p = 'active';
2625	        }
2626	        else if( s > o + h && _p !== 'after' ) {
2627	        	// console.log( toSpy, 'after' );
2628	        	if( config.after) config.after( o + h );
2629	        	_p = 'after';
2630	        }
2631		};
2632
2633		var rAF = function() {
2634			window.requestAnimationFrame( checkPosition );
2635		};
2636
2637		var exportVals = function() {
2638			return cacheVals;    
2639		};
2640
2641		var updateCache = function() {
2642	    	var o = offset(),
2643	    		h = height();
2644	    		
2645	        cacheVals = {
2646	        	before : o - $window.height(),
2647	        	active : o,
2648	        	after : o + h
2649	        };
2650		};
2651
2652		if( config.cache ) {
2653			config.cache( exportVals );
2654		}
2655
2656	    checkPosition();
2657	    $window.on( 'load', checkPosition );
2658	    $window.on( 'resize', checkPosition );
2659	    $window.on( 'mouseup', checkPosition );
2660   		window.addResizeListener( container, checkPosition );
2661
2662	    $window.on( 'scroll', rAF ); 
2663
2664   		updateCache();
2665	    $window.on( 'load', updateCache );
2666	    $window.on( 'resize', updateCache );
2667   		window.addResizeListener( container, updateCache );
2668	};
2669
2670}(jQuery));
2671(function($) {
2672    'use strict';
2673
2674    // Create delagation event handler to behave as "live" listener. We may provide new elements with ajax etc later
2675    // Just add js-taphover class whatever element you'd like to immidietely bring hover on touch devices
2676    $("body").on("click touchend", '.js-taphover', function (e) {
2677        var $link = $(e.currentTarget); // grab target
2678        var $target = $(e.target);
2679
2680        // Rather than ":hover" state we operate on ".hover" class which gives us more control and chance to emulate it on click
2681        // yet it is easy to reason about in our CSS
2682        if ($link.hasClass('hover')) {
2683            return true;
2684        } else if ( MK.utils.isMobile() ) {
2685            if ( ($target.hasClass('hover-icon') || $target.closest('.hover-icon').length) && !$target.closest('.js-taphover').hasClass('hover') ) {
2686                e.preventDefault();
2687            }
2688            $link.addClass('hover');
2689            $('.js-taphover').not(e.currentTarget).removeClass('hover'); // remove it from previous element
2690            e.stopPropagation(); // do not leak to document root if expected element was touched
2691        }
2692    });
2693
2694    // Whenever click leaks to the root romve all hover classes
2695    $(document).on("click", function(e) {
2696        $('.js-taphover').removeClass('hover');
2697    });
2698
2699}(jQuery));
2700// (function() {
2701//     'use strict';
2702
2703//     // Make sure the video behaves like background-size: cover
2704//     window.videoCover = function( holderSelector, videoSelector ) {
2705//         var videos = document.querySelectorAll( videoSelector ),
2706//             holder = document.querySelectorAll( holderSelector )[0];
2707
2708//         [].forEach.call(videos, function(video) {
2709
2710//             var videoAspectRatio;
2711
2712//             resizeBackground(); 
2713
2714//             video.onloadedmetadata = function() {
2715//                 // get images aspect ratio
2716//                 videoAspectRatio = this.height / this.width;
2717//                 // attach resize event and fire it once
2718//                 window.onresize = resizeBackground;
2719//                 resizeBackground();
2720//             };
2721
2722//             function resizeBackground() {
2723//                 // get window size and aspect ratio
2724//                 var holderWidth = holder.innerWidth,
2725//                     holderHeight = holder.innerHeight,
2726//                     holderAspectRatio = holderHeight / holderWidth;
2727
2728//                 //compare holder ratio to image ratio so you know which way the image should fill
2729//                 if ( holderAspectRatio < videoAspectRatio ) {
2730//                     // we are fill width
2731//                     video.style.width = holderWidth + "px";
2732//                     // and applying the correct aspect to the height now
2733//                     video.style.height = (holderWidth * videoAspectRatio) + "px"; // this can be margin if your element is not positioned relatively, absolutely or fixed
2734//                     // make sure image is always centered
2735//                     video.style.left = "0px";
2736//                     video.style.top = (holderHeight - (holderWidth * videoAspectRatio)) / 2 + "px";
2737//                 } else { // same thing as above but filling height instead
2738//                     video.style.height = holderHeight + "px";
2739//                     video.style.width = (holderHeight / videoAspectRatio) + "px";
2740//                     video.style.left = (holderWidth - (holderHeight / videoAspectRatio)) / 2 + "px";
2741//                     video.style.top = "0px";
2742//                 }
2743//             }
2744
2745//         });
2746//     };
2747
2748// }());
2749// 
2750// 
2751// 
2752// TODO it is temp only. make it as a plugin
2753
2754(function($) {
2755    'use strict';
2756
2757    var $videoHolder = $('.mk-center-video'),
2758        $wrapper = $videoHolder.parent(),
2759        baseAspectRatio = 56.25;
2760
2761    var wrapperHeight,
2762        wrapperWidth,
2763        wrapperAspectRatio;
2764
2765    function calc() {
2766        wrapperHeight = $wrapper.height();
2767        wrapperWidth = $wrapper.width();
2768        wrapperAspectRatio = (wrapperHeight / wrapperWidth) * 100;
2769    } 
2770
2771    function apply() {        
2772        var width = (wrapperAspectRatio / baseAspectRatio) * 100,
2773            widthOverflow = (width - 100);
2774
2775        $videoHolder.css({
2776            'padding-top': wrapperAspectRatio + '%',
2777            'width': width + '%',
2778            'left': -(widthOverflow / 2) + '%'
2779        }); 
2780    }
2781
2782    function reset() {
2783        $videoHolder.css({
2784            'padding-top': baseAspectRatio + '%',
2785            'width': 100 + '%',
2786            'left': 0
2787        });
2788    }
2789
2790    function setCover() {
2791        reset();
2792        calc();
2793        if(wrapperAspectRatio > baseAspectRatio) apply();
2794    }
2795
2796    $(window).on('load', setCover);
2797    $(window).on('resize', setCover);
2798
2799
2800}(jQuery));
2801(function($) {
2802	'use strict';
2803
2804	var MK = window.MK || {};
2805
2806	/**
2807	* 	MK.val is collection of Lambdas responsible for returning up to date values of method type like scrollY or el offset.
2808	* 	The Lambda is responsible for keeping track of value of a particular property, usually takes as argument an object
2809	* 	(or DOM reference) and internally creates and updates data that is returned as primitive value - through variable reference.
2810	*
2811	*  Benefits of this approach:
2812	*  - reduced DOM reads
2813	*  - auto-updating values without need for additional logic where methods are called
2814	*  - updating values when needed to be updated not read
2815	*
2816	*  Downsides:
2817	*  - Memory overhead with closures and keeping state in memory ( still beter than read state from DOM, but use wisely -
2818	*    do not use it when you really need static value on runtime )
2819	*/
2820	MK.val = {};
2821
2822	/**
2823	* Current window offsetY position
2824	*
2825	* @uses   MK.val.scroll()
2826	* @return {number}
2827	*/
2828	MK.val.scroll = (function() {
2829		var offset = 0,
2830		$window = $(window),
2831		hasPageYOffset = (window.pageYOffset !== undefined),
2832		body = (document.documentElement || document.body.parentNode || document.body); // cross browser handling
2833
2834		var update = function() {
2835			offset = hasPageYOffset ? window.pageYOffset : body.scrollTop;
2836		};
2837
2838		var rAF = function() {
2839			window.requestAnimationFrame(update);
2840		};
2841
2842		update();
2843		$window.on('load', update);
2844		$window.on('resize', update);
2845		$window.on('scroll', rAF);
2846
2847		return function() {
2848			return offset;
2849		};
2850	})();
2851
2852
2853	/**
2854	* Changes number of percent to pixels based on viewport height
2855	*
2856	* @uses   MK.val.viewportPercentHeight({percent val})
2857	* @param  {number}
2858	* @return {number}
2859	*/
2860	MK.val.viewportPercentHeight = function(percent) {
2861		return $(window).height() * (percent / 100);
2862	};
2863
2864
2865	/**
2866	* Wordpress adminbar height based on wp media queries
2867	* @return {Number}
2868	*/
2869	MK.val.adminbarHeight = function() {
2870		if (php.hasAdminbar) {
2871			// apply WP native media-query and sizes
2872			return (window.matchMedia('( max-width: 782px )').matches) ? 46 : 32;
2873		} else {
2874			return 0;
2875		}
2876	};
2877
2878
2879	/**
2880	* Offset when header becomes sticky. Evaluates viewport % and header height to pixels for according options
2881	* @return {Number}
2882	*/
2883	MK.val.stickyOffset = (function() {
2884		var $header = $('.mk-header').not('.js-header-shortcode').first();
2885
2886		// We need to have returning function even when header is disabled
2887		if (!$header.length) {
2888			return function() {
2889				return 0;
2890			};
2891		}
2892
2893
2894
2895		var $toolbar = $header.find('.mk-header-toolbar'),
2896		config = $header.data(),
2897		hasToolbar = $toolbar.length,
2898		toolbarHeight = (hasToolbar) ? $toolbar.height() : 0,
2899		isVertical = (config.headerStyle === 4),
2900		headerHeight = (isVertical) ? 0 : config.height;
2901
2902		var type = ((typeof config.stickyOffset === 'number') ? 'number' : false) ||
2903		((config.stickyOffset === 'header') ? 'header' : false) ||
2904		'percent';
2905
2906		var stickyOffset = 0;
2907		var setOffset = function() {
2908
2909			//we calculate toolbar height for When the device is changed Size
2910			//Toolbar height in responsive state is 0
2911			toolbarHeight = (hasToolbar) ? $toolbar.height() : 0;
2912
2913			if (MK.utils.isResponsiveMenuState()) {
2914				headerHeight = config.responsiveHeight;
2915
2916				if (hasToolbar) {
2917					if ($toolbar.is(':hidden')) {
2918						toolbarHeight = 0;
2919					}
2920				}
2921			}
2922
2923			if (type === 'number') {
2924				stickyOffset = config.stickyOffset;
2925			} else if (type === 'header') {
2926
2927				stickyOffset = headerHeight + toolbarHeight + MK.val.adminbarHeight(); // add all header components here, make them 0 if needed
2928
2929			} else if (type === 'percent') {
2930				stickyOffset = MK.val.viewportPercentHeight(parseInt(config.stickyOffset));
2931			}
2932		};
2933
2934		setOffset();
2935		$(window).on('resize', setOffset);
2936
2937		return function() {
2938			return stickyOffset;
2939		};
2940	}());
2941
2942
2943
2944	/**
2945	* Gets header height on particular offsetY position. Use to determine logic for fullHeight, smooth scroll etc.
2946	* Takes one parameter which is offset position we're interested in.
2947	*
2948	* @uses   MK.val.offsetHeaderHeight({offset val})
2949	* @param  {number}
2950	* @return {number}
2951	*/
2952	MK.val.offsetHeaderHeight = (function() { // Closure avoids multiple DOM reads. We need to fetch header config only once.
2953		var $header = $('.mk-header').not('.js-header-shortcode').first();
2954
2955		// We need to have returning function even when header is disabled
2956		if (!$header.length) {
2957			return function() {
2958				return 0;
2959			};
2960		}
2961
2962		var $toolbar = $header.find('.mk-header-toolbar'),
2963		config = $header.data(),
2964		stickyHeight = config.stickyHeight,
2965		desktopHeight = config.height,
2966		mobileHeight = config.responsiveHeight,
2967		isTransparent = $header.hasClass('transparent-header'),
2968		isSticky = config.stickyStyle.length,
2969		isStickyLazy = config.stickyStyle === 'lazy',
2970		isVertical = config.headerStyle === 4,
2971		hasToolbar = $toolbar.length,
2972		toolbarHeight = hasToolbar ? $toolbar.height() : 0,
2973		bufor = 5;
2974
2975		/**
2976		 * The sticky section of header style 2 has fixed height.
2977		 * The stickey height option does not affect this header style.
2978		 */
2979		if ( config.headerStyle === 2 ) {
2980			stickyHeight = $header.find( '.mk-header-nav-container' ).outerHeight();
2981		}
2982
2983		// if header has border bottom we can calculate that (for responsive state)
2984		var $innerHeader = $header.find('.mk-header-inner');
2985		var hasInnerHeader = $innerHeader.length;
2986
2987		var headerHeight = function(offset) {
2988
2989			toolbarHeight = hasToolbar ? $toolbar.height() : 0
2990			var stickyOffset = MK.val.stickyOffset();
2991
2992
2993			if (MK.utils.isResponsiveMenuState()) { //  Header avaible only on top for mobile
2994
2995				if (hasToolbar && $toolbar.is(':hidden')) {
2996					toolbarHeight = 0;
2997				}
2998
2999				//in responsive state , .mk-header-holder position's changed to "relative"
3000				//and header's border affected to offset,so borders must be calculated
3001				var headerBorder = 0;
3002				headerBorder = parseInt($innerHeader.css('border-bottom-width'));
3003
3004				var totalHeight = mobileHeight + MK.val.adminbarHeight() + toolbarHeight + headerBorder;
3005
3006				if (offset <= totalHeight) return totalHeight;
3007				else return MK.val.adminbarHeight();
3008			} else {
3009				if (offset <= stickyOffset) {
3010					if (isVertical) {
3011						if (hasToolbar) {
3012							return toolbarHeight + MK.val.adminbarHeight();
3013						} else {
3014							return MK.val.adminbarHeight();
3015						}
3016					} else if (isTransparent) {
3017						return MK.val.adminbarHeight();
3018					} else {
3019						return desktopHeight + toolbarHeight + MK.val.adminbarHeight();
3020					} // For any other return regular desktop height
3021				} else if (offset > stickyOffset) {
3022					if (isVertical) {
3023						return MK.val.adminbarHeight();
3024					} else if (!isSticky) {
3025						return MK.val.adminbarHeight();
3026					} else if (isStickyLazy) {
3027						return MK.val.adminbarHeight();
3028					} else if (isSticky) {
3029						return stickyHeight + MK.val.adminbarHeight();
3030					}
3031				}
3032			}
3033			// default to 0 to prevent errors ( need to return number )
3034			// Anyway make sure all scenarios are covered in IFs
3035			return 0;
3036		};
3037
3038		return function(offset) {
3039			return headerHeight(offset - MK.val.adminbarHeight());
3040		};
3041	})();
3042
3043
3044	/**
3045	* Gets current offset of given element (passed as object or DOM reference) from top or bottom (default to top)
3046	* of screen  with possible threshold (default to 0)
3047	*
3048	* @uses   MK.val.dynamicOffset({obj reference}, {'top'|'bottom'}, {threshold val})
3049	* @param  {string|object}
3050	* @param  {string}
3051	* @param  {number}
3052	* @return {number}
3053	*/
3054	MK.val.dynamicOffset = function(el, position, threshold) {
3055		var $window = $(window),
3056		$el = $(el),
3057		pos = position || 'top',
3058		thr = threshold || 0,
3059		container = document.getElementById('mk-theme-container'),
3060		currentPos = 0;
3061
3062		var offset = 0,
3063		winH = 0,
3064		rect = 0,
3065		x = 0;
3066
3067		var update = function() {
3068			winH = $window.height();
3069			rect = $el[0].getBoundingClientRect();
3070			offset = (rect.top + MK.val.scroll());
3071			x = (pos === 'top') ? MK.val.offsetHeaderHeight(offset) : winH + (rect.height - thr);
3072			currentPos = offset - x - 1;
3073		};
3074
3075		update();
3076		$window.on('load', update);
3077		$window.on('resize', update);
3078		window.addResizeListener(container, update);
3079
3080		return function() {
3081			return currentPos;
3082		};
3083	};
3084
3085	/**
3086	* Gets current height of given element (passed as object or DOM reference)
3087	*
3088	* @uses   MK.val.dynamicHeight({obj reference})
3089	* @param  {string|object}
3090	* @return {number}
3091	*/
3092	MK.val.dynamicHeight = function(el) {
3093		var $window = $(window),
3094		$el = $(el),
3095		container = document.getElementById('mk-theme-container'),
3096		currentHeight = 0;
3097
3098		var update = function() {
3099			currentHeight = $el.outerHeight();
3100		};
3101
3102		update();
3103		$window.on('load', update);
3104		$window.on('resize', update);
3105		window.addResizeListener(container, update);
3106
3107		return function() {
3108			return currentHeight;
3109		};
3110	};
3111
3112})(jQuery);
3113
3114/*
3115 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
3116 *
3117 */
3118jQuery.easing["jswing"] = jQuery.easing["swing"];
3119jQuery.extend(jQuery.easing, {
3120        def: "easeOutQuad",
3121        swing: function (a, b, c, d, e) {
3122                return jQuery.easing[jQuery.easing.def](a, b, c, d, e)
3123        },
3124        easeInQuad: function (a, b, c, d, e) {
3125                return d * (b /= e) * b + c
3126        },
3127        easeOutQuad: function (a, b, c, d, e) {
3128                return -d * (b /= e) * (b - 2) + c
3129        },
3130        easeInOutQuad: function (a, b, c, d, e) {
3131                if ((b /= e / 2) < 1) return d / 2 * b * b + c;
3132                return -d / 2 * (--b * (b - 2) - 1) + c
3133        },
3134        easeInCubic: function (a, b, c, d, e) {
3135                return d * (b /= e) * b * b + c
3136        },
3137        easeOutCubic: function (a, b, c, d, e) {
3138                return d * ((b = b / e - 1) * b * b + 1) + c
3139        },
3140        easeInOutCubic: function (a, b, c, d, e) {
3141                if ((b /= e / 2) < 1) return d / 2 * b * b * b + c;
3142                return d / 2 * ((b -= 2) * b * b + 2) + c
3143        },
3144        easeInQuart: function (a, b, c, d, e) {
3145                return d * (b /= e) * b * b * b + c
3146        },
3147        easeOutQuart: function (a, b, c, d, e) {
3148                return -d * ((b = b / e - 1) * b * b * b - 1) + c
3149        },
3150        easeInOutQuart: function (a, b, c, d, e) {
3151                if ((b /= e / 2) < 1) return d / 2 * b * b * b * b + c;
3152                return -d / 2 * ((b -= 2) * b * b * b - 2) + c
3153        },
3154        easeInQuint: function (a, b, c, d, e) {
3155                return d * (b /= e) * b * b * b * b + c
3156        },
3157        easeOutQuint: function (a, b, c, d, e) {
3158                return d * ((b = b / e - 1) * b * b * b * b + 1) + c
3159        },
3160        easeInOutQuint: function (a, b, c, d, e) {
3161                if ((b /= e / 2) < 1) return d / 2 * b * b * b * b * b + c;
3162                return d / 2 * ((b -= 2) * b * b * b * b + 2) + c
3163        },
3164        easeInSine: function (a, b, c, d, e) {
3165                return -d * Math.cos(b / e * (Math.PI / 2)) + d + c
3166        },
3167        easeOutSine: function (a, b, c, d, e) {
3168                return d * Math.sin(b / e * (Math.PI / 2)) + c
3169        },
3170        easeInOutSine: function (a, b, c, d, e) {
3171                return -d / 2 * (Math.cos(Math.PI * b / e) - 1) + c
3172        },
3173        easeInExpo: function (a, b, c, d, e) {
3174                return b == 0 ? c : d * Math.pow(2, 10 * (b / e - 1)) + c
3175        },
3176        easeOutExpo: function (a, b, c, d, e) {
3177                return b == e ? c + d : d * (-Math.pow(2, -10 * b / e) + 1) + c
3178        },
3179        easeInOutExpo: function (a, b, c, d, e) {
3180                if (b == 0) return c;
3181                if (b == e) return c + d;
3182                if ((b /= e / 2) < 1) return d / 2 * Math.pow(2, 10 * (b - 1)) + c;
3183                return d / 2 * (-Math.pow(2, -10 * --b) + 2) + c
3184        },
3185        easeInCirc: function (a, b, c, d, e) {
3186                return -d * (Math.sqrt(1 - (b /= e) * b) - 1) + c
3187        },
3188        easeOutCirc: function (a, b, c, d, e) {
3189                return d * Math.sqrt(1 - (b = b / e - 1) * b) + c
3190        },
3191        easeInOutCirc: function (a, b, c, d, e) {
3192                if ((b /= e / 2) < 1) return -d / 2 * (Math.sqrt(1 - b * b) - 1) + c;
3193                return d / 2 * (Math.sqrt(1 - (b -= 2) * b) + 1) + c
3194        },
3195        easeInElastic: function (a, b, c, d, e) {
3196                var f = 1.70158;
3197                var g = 0;
3198                var h = d;
3199                if (b == 0) return c;
3200                if ((b /= e) == 1) return c + d;
3201                if (!g) g = e * .3;
3202                if (h < Math.abs(d)) {
3203                        h = d;
3204                        var f = g / 4
3205                } else var f = g / (2 * Math.PI) * Math.asin(d / h);
3206                return -(h * Math.pow(2, 10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g)) + c
3207        },
3208        easeOutElastic: function (a, b, c, d, e) {
3209                var f = 1.70158;
3210                var g = 0;
3211                var h = d;
3212                if (b == 0) return c;
3213                if ((b /= e) == 1) return c + d;
3214                if (!g) g = e * .3;
3215                if (h < Math.abs(d)) {
3216                        h = d;
3217                        var f = g / 4
3218                } else var f = g / (2 * Math.PI) * Math.asin(d / h);
3219                return h * Math.pow(2, -10 * b) * Math.sin((b * e - f) * 2 * Math.PI / g) + d + c
3220        },
3221        easeInOutElastic: function (a, b, c, d, e) {
3222                var f = 1.70158;
3223                var g = 0;
3224                var h = d;
3225                if (b == 0) return c;
3226                if ((b /= e / 2) == 2) return c + d;
3227                if (!g) g = e * .3 * 1.5;
3228                if (h < Math.abs(d)) {
3229                        h = d;
3230                        var f = g / 4
3231                } else var f = g / (2 * Math.PI) * Math.asin(d / h);
3232                if (b < 1) return -.5 * h * Math.pow(2, 10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g) + c;
3233                return h * Math.pow(2, -10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g) * .5 + d + c
3234        },
3235        easeInBack: function (a, b, c, d, e, f) {
3236                if (f == undefined) f = 1.70158;
3237                return d * (b /= e) * b * ((f + 1) * b - f) + c
3238        },
3239        easeOutBack: function (a, b, c, d, e, f) {
3240                if (f == undefined) f = 1.70158;
3241                return d * ((b = b / e - 1) * b * ((f + 1) * b + f) + 1) + c
3242        },
3243        easeInOutBack: function (a, b, c, d, e, f) {
3244                if (f == undefined) f = 1.70158;
3245                if ((b /= e / 2) < 1) return d / 2 * b * b * (((f *= 1.525) + 1) * b - f) + c;
3246                return d / 2 * ((b -= 2) * b * (((f *= 1.525) + 1) * b + f) + 2) + c
3247        },
3248        easeInBounce: function (a, b, c, d, e) {
3249                return d - jQuery.easing.easeOutBounce(a, e - b, 0, d, e) + c
3250        },
3251        easeOutBounce: function (a, b, c, d, e) {
3252                if ((b /= e) < 1 / 2.75) {
3253                        return d * 7.5625 * b * b + c
3254                } else if (b < 2 / 2.75) {
3255                        return d * (7.5625 * (b -= 1.5 / 2.75) * b + .75) + c
3256                } else if (b < 2.5 / 2.75) {
3257                        return d * (7.5625 * (b -= 2.25 / 2.75) * b + .9375) + c
3258                } else {
3259                        return d * (7.5625 * (b -= 2.625 / 2.75) * b + .984375) + c
3260                }
3261        },
3262        easeInOutBounce: function (a, b, c, d, e) {
3263                if (b < e / 2) return jQuery.easing.easeInBounce(a, b * 2, 0, d, e) * .5 + c;
3264                return jQuery.easing.easeOutBounce(a, b * 2 - e, 0, d, e) * .5 + d * .5 + c
3265        }
3266});
3267
3268/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */
3269(function(s, H, f, w) {
3270    var K = f("html"),
3271        q = f(s),
3272        p = f(H),
3273        b = f.fancybox = function() {
3274            b.open.apply(this, arguments)
3275        },
3276        J = navigator.userAgent.match(/msie/i),
3277        C = null,
3278        t = H.createTouch !== w,
3279        u = function(a) {
3280            return a && a.hasOwnProperty && a instanceof f
3281        },
3282        r = function(a) {
3283            return a && "string" === f.type(a)
3284        },
3285        F = function(a) {
3286            return r(a) && 0 < a.indexOf("%")
3287        },
3288        m = function(a, d) {
3289            var e = parseInt(a, 10) || 0;
3290            d && F(a) && (e *= b.getViewport()[d] / 100);
3291            return Math.ceil(e)
3292        },
3293        x = function(a, b) {
3294            return m(a, b) + "px"
3295        };
3296    f.extend(b, {
3297        version: "2.1.5",
3298        defaults: {
3299            padding: 15,
3300            margin: 20,
3301            width: 800,
3302            height: 600,
3303            minWidth: 100,
3304            minHeight: 100,
3305            maxWidth: 9999,
3306            maxHeight: 9999,
3307            pixelRatio: 1,
3308            autoSize: !0,
3309            autoHeight: !1,
3310            autoWidth: !1,
3311            autoResize: !0,
3312            autoCenter: !t,
3313            fitToView: !0,
3314            aspectRatio: !1,
3315            topRatio: 0.5,
3316            leftRatio: 0.5,
3317            scrolling: "auto",
3318            wrapCSS: "",
3319            arrows: !0,
3320            closeBtn: !0,
3321            closeClick: !1,
3322            nextClick: !1,
3323            mouseWheel: !0,
3324            autoPlay: !1,
3325            playSpeed: 3E3,
3326            preload: 3,
3327            modal: !1,
3328            loop: !0,
3329            ajax: {
3330                dataType: "html",
3331                headers: {
3332                    "X-fancyBox": !0
3333                }
3334            },
3335            iframe: {
3336                scrolling: "auto",
3337                preload: !0
3338            },
3339            swf: {
3340                wmode: "transparent",
3341                allowfullscreen: "true",
3342                allowscriptaccess: "always"
3343            },
3344            keys: {
3345                next: {
3346                    13: "left",
3347                    34: "up",
3348                    39: "left",
3349                    40: "up"
3350                },
3351                prev: {
3352                    8: "right",
3353                    33: "down",
3354                    37: "right",
3355                    38: "down"
3356                },
3357                close: [27],
3358                play: [32],
3359                toggle: [70]
3360            },
3361            direction: {
3362                next: "left",
3363                prev: "right"
3364            },
3365            scrollOutside: !0,
3366            index: 0,
3367            type: null,
3368            href: null,
3369            content: null,
3370            title: null,
3371            tpl: {
3372                wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
3373                image: '<img class="fancybox-image" src="{href}" alt="" />',
3374                iframe: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' +
3375                    (J ? ' allowtransparency="true"' : "") + "></iframe>",
3376                error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
3377                closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
3378                next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
3379                prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
3380            },
3381            openEffect: "fade",
3382            openSpeed: 250,
3383            openEasing: "swing",
3384            openOpacity: !0,
3385            openMethod: "zoomIn",
3386            closeEffect: "fade",
3387            closeSpeed: 250,
3388            closeEasing: "swing",
3389            closeOpacity: !0,
3390            closeMethod: "zoomOut",
3391            nextEffect: "elastic",
3392            nextSpeed: 250,
3393            nextEasing: "swing",
3394            nextMethod: "changeIn",
3395            prevEffect: "elastic",
3396            prevSpeed: 250,
3397            prevEasing: "swing",
3398            prevMethod: "changeOut",
3399            helpers: {
3400                overlay: !0,
3401                title: !0
3402            },
3403            onCancel: f.noop,
3404            beforeLoad: f.noop,
3405            afterLoad: f.noop,
3406            beforeShow: f.noop,
3407            afterShow: f.noop,
3408            beforeChange: f.noop,
3409            beforeClose: f.noop,
3410            afterClose: f.noop
3411        },
3412        group: {},
3413        opts: {},
3414        previous: null,
3415        coming: null,
3416        current: null,
3417        isActive: !1,
3418        isOpen: !1,
3419        isOpened: !1,
3420        wrap: null,
3421        skin: null,
3422        outer: null,
3423        inner: null,
3424        player: {
3425            timer: null,
3426            isActive: !1
3427        },
3428        ajaxLoad: null,
3429        imgPreload: null,
3430        transitions: {},
3431        helpers: {},
3432        open: function(a, d) {
3433            if (a && (f.isPlainObject(d) || (d = {}), !1 !== b.close(!0))) return f.isArray(a) || (a = u(a) ? f(a).get() : [a]), f.each(a, function(e, 
vendor: 34,462 bytes, lines 3433-4183
3433c) {
3434                var l = {},
3435                    g, h, k, n, m;
3436                "object" === f.type(c) && (c.nodeType && (c = f(c)), u(c) ? (l = {
3437                        href: c.data("fancybox-href") || c.attr("href"),
3438                        title: f("<div/>").text(c.data("fancybox-title") || c.attr("title")).html(),
3439                        isDom: !0,
3440                        element: c
3441                    },
3442                    f.metadata && f.extend(!0, l, c.metadata())) : l = c);
3443                g = d.href || l.href || (r(c) ? c : null);
3444                h = d.title !== w ? d.title : l.title || "";
3445                n = (k = d.content || l.content) ? "html" : d.type || l.type;
3446                !n && l.isDom && (n = c.data("fancybox-type"), n || (n = (n = c.prop("class").match(/fancybox\.(\w+)/)) ? n[1] : null));
3447                r(g) && (n || (b.isImage(g) ? n = "image" : b.isSWF(g) ? n = "swf" : "#" === g.charAt(0) ? n = "inline" : r(c) && (n = "html", k = c)), "ajax" === n && (m = g.split(/\s+/, 2), g = m.shift(), m = m.shift()));
3448                k || ("inline" === n ? g ? k = f(r(g) ? g.replace(/.*(?=#[^\s]+$)/, "") : g) : l.isDom && (k = c) :
3449                    "html" === n ? k = g : n || g || !l.isDom || (n = "inline", k = c));
3450                f.extend(l, {
3451                    href: g,
3452                    type: n,
3453                    content: k,
3454                    title: h,
3455                    selector: m
3456                });
3457                a[e] = l
3458            }), b.opts = f.extend(!0, {}, b.defaults, d), d.keys !== w && (b.opts.keys = d.keys ? f.extend({}, b.defaults.keys, d.keys) : !1), b.group = a, b._start(b.opts.index)
3459        },
3460        cancel: function() {
3461            var a = b.coming;
3462            a && !1 === b.trigger("onCancel") || (b.hideLoading(), a && (b.ajaxLoad && b.ajaxLoad.abort(), b.ajaxLoad = null, b.imgPreload && (b.imgPreload.onload = b.imgPreload.onerror = null), a.wrap && a.wrap.stop(!0, !0).trigger("onReset").remove(),
3463                b.coming = null, b.current || b._afterZoomOut(a)))
3464        },
3465        close: function(a) {
3466            b.cancel();
3467            !1 !== b.trigger("beforeClose") && (b.unbindEvents(), b.isActive && (b.isOpen && !0 !== a ? (b.isOpen = b.isOpened = !1, b.isClosing = !0, f(".fancybox-item, .fancybox-nav").remove(), b.wrap.stop(!0, !0).removeClass("fancybox-opened"), b.transitions[b.current.closeMethod]()) : (f(".fancybox-wrap").stop(!0).trigger("onReset").remove(), b._afterZoomOut())))
3468        },
3469        play: function(a) {
3470            var d = function() {
3471                    clearTimeout(b.player.timer)
3472                },
3473                e = function() {
3474                    d();
3475                    b.current && b.player.isActive &&
3476                        (b.player.timer = setTimeout(b.next, b.current.playSpeed))
3477                },
3478                c = function() {
3479                    d();
3480                    p.unbind(".player");
3481                    b.player.isActive = !1;
3482                    b.trigger("onPlayEnd")
3483                };
3484            !0 === a || !b.player.isActive && !1 !== a ? b.current && (b.current.loop || b.current.index < b.group.length - 1) && (b.player.isActive = !0, p.bind({
3485                "onCancel.player beforeClose.player": c,
3486                "onUpdate.player": e,
3487                "beforeLoad.player": d
3488            }), e(), b.trigger("onPlayStart")) : c()
3489        },
3490        next: function(a) {
3491            var d = b.current;
3492            d && (r(a) || (a = d.direction.next), b.jumpto(d.index + 1, a, "next"))
3493        },
3494        prev: function(a) {
3495            var d =
3496                b.current;
3497            d && (r(a) || (a = d.direction.prev), b.jumpto(d.index - 1, a, "prev"))
3498        },
3499        jumpto: function(a, d, e) {
3500            var c = b.current;
3501            c && (a = m(a), b.direction = d || c.direction[a >= c.index ? "next" : "prev"], b.router = e || "jumpto", c.loop && (0 > a && (a = c.group.length + a % c.group.length), a %= c.group.length), c.group[a] !== w && (b.cancel(), b._start(a)))
3502        },
3503        reposition: function(a, d) {
3504            var e = b.current,
3505                c = e ? e.wrap : null,
3506                l;
3507            c && (l = b._getPosition(d), a && "scroll" === a.type ? (delete l.position, c.stop(!0, !0).animate(l, 200)) : (c.css(l), e.pos = f.extend({}, e.dim, l)))
3508        },
3509        update: function(a) {
3510            var d = a && a.originalEvent && a.originalEvent.type,
3511                e = !d || "orientationchange" === d;
3512            e && (clearTimeout(C), C = null);
3513            b.isOpen && !C && (C = setTimeout(function() {
3514                var c = b.current;
3515                c && !b.isClosing && (b.wrap.removeClass("fancybox-tmp"), (e || "load" === d || "resize" === d && c.autoResize) && b._setDimension(), "scroll" === d && c.canShrink || b.reposition(a), b.trigger("onUpdate"), C = null)
3516            }, e && !t ? 0 : 300))
3517        },
3518        toggle: function(a) {
3519            b.isOpen && (b.current.fitToView = "boolean" === f.type(a) ? a : !b.current.fitToView, t && (b.wrap.removeAttr("style").addClass("fancybox-tmp"),
3520                b.trigger("onUpdate")), b.update())
3521        },
3522        hideLoading: function() {
3523            p.unbind(".loading");
3524            f("#fancybox-loading").remove()
3525        },
3526        showLoading: function() {
3527            var a, d;
3528            b.hideLoading();
3529            a = f('<div id="fancybox-loading"><div></div></div>').click(b.cancel).appendTo("body");
3530            p.bind("keydown.loading", function(a) {
3531                27 === (a.which || a.keyCode) && (a.preventDefault(), b.cancel())
3532            });
3533            b.defaults.fixed || (d = b.getViewport(), a.css({
3534                position: "absolute",
3535                top: 0.5 * d.h + d.y,
3536                left: 0.5 * d.w + d.x
3537            }));
3538            b.trigger("onLoading")
3539        },
3540        getViewport: function() {
3541            var a = b.current &&
3542                b.current.locked || !1,
3543                d = {
3544                    x: q.scrollLeft(),
3545                    y: q.scrollTop()
3546                };
3547            a && a.length ? (d.w = a[0].clientWidth, d.h = a[0].clientHeight) : (d.w = t && s.innerWidth ? s.innerWidth : q.width(), d.h = t && s.innerHeight ? s.innerHeight : q.height());
3548            return d
3549        },
3550        unbindEvents: function() {
3551            b.wrap && u(b.wrap) && b.wrap.unbind(".fb");
3552            p.unbind(".fb");
3553            q.unbind(".fb")
3554        },
3555        bindEvents: function() {
3556            var a = b.current,
3557                d;
3558            a && (q.bind("orientationchange.fb" + (t ? "" : " resize.fb") + (a.autoCenter && !a.locked ? " scroll.fb" : ""), b.update), (d = a.keys) && p.bind("keydown.fb", function(e) {
3559                var c =
3560                    e.which || e.keyCode,
3561                    l = e.target || e.srcElement;
3562                if (27 === c && b.coming) return !1;
3563                e.ctrlKey || e.altKey || e.shiftKey || e.metaKey || l && (l.type || f(l).is("[contenteditable]")) || f.each(d, function(d, l) {
3564                    if (1 < a.group.length && l[c] !== w) return b[d](l[c]), e.preventDefault(), !1;
3565                    if (-1 < f.inArray(c, l)) return b[d](), e.preventDefault(), !1
3566                })
3567            }), f.fn.mousewheel && a.mouseWheel && b.wrap.bind("mousewheel.fb", function(d, c, l, g) {
3568                for (var h = f(d.target || null), k = !1; h.length && !(k || h.is(".fancybox-skin") || h.is(".fancybox-wrap"));) k = h[0] && !(h[0].style.overflow &&
3569                    "hidden" === h[0].style.overflow) && (h[0].clientWidth && h[0].scrollWidth > h[0].clientWidth || h[0].clientHeight && h[0].scrollHeight > h[0].clientHeight), h = f(h).parent();
3570                0 !== c && !k && 1 < b.group.length && !a.canShrink && (0 < g || 0 < l ? b.prev(0 < g ? "down" : "left") : (0 > g || 0 > l) && b.next(0 > g ? "up" : "right"), d.preventDefault())
3571            }))
3572        },
3573        trigger: function(a, d) {
3574            var e, c = d || b.coming || b.current;
3575            if (c) {
3576                f.isFunction(c[a]) && (e = c[a].apply(c, Array.prototype.slice.call(arguments, 1)));
3577                if (!1 === e) return !1;
3578                c.helpers && f.each(c.helpers, function(d, e) {
3579                    if (e &&
3580                        b.helpers[d] && f.isFunction(b.helpers[d][a])) b.helpers[d][a](f.extend(!0, {}, b.helpers[d].defaults, e), c)
3581                })
3582            }
3583            p.trigger(a)
3584        },
3585        isImage: function(a) {
3586            return r(a) && a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)
3587        },
3588        isSWF: function(a) {
3589            return r(a) && a.match(/\.(swf)((\?|#).*)?$/i)
3590        },
3591        _start: function(a) {
3592            var d = {},
3593                e, c;
3594            a = m(a);
3595            e = b.group[a] || null;
3596            if (!e) return !1;
3597            d = f.extend(!0, {}, b.opts, e);
3598            e = d.margin;
3599            c = d.padding;
3600            "number" === f.type(e) && (d.margin = [e, e, e, e]);
3601            "number" === f.type(c) && (d.padding = [c, c,
3602                c, c
3603            ]);
3604            d.modal && f.extend(!0, d, {
3605                closeBtn: !1,
3606                closeClick: !1,
3607                nextClick: !1,
3608                arrows: !1,
3609                mouseWheel: !1,
3610                keys: null,
3611                helpers: {
3612                    overlay: {
3613                        closeClick: !1
3614                    }
3615                }
3616            });
3617            d.autoSize && (d.autoWidth = d.autoHeight = !0);
3618            "auto" === d.width && (d.autoWidth = !0);
3619            "auto" === d.height && (d.autoHeight = !0);
3620            d.group = b.group;
3621            d.index = a;
3622            b.coming = d;
3623            if (!1 === b.trigger("beforeLoad")) b.coming = null;
3624            else {
3625                c = d.type;
3626                e = d.href;
3627                if (!c) return b.coming = null, b.current && b.router && "jumpto" !== b.router ? (b.current.index = a, b[b.router](b.direction)) : !1;
3628                b.isActive = !0;
3629                if ("image" ===
3630                    c || "swf" === c) d.autoHeight = d.autoWidth = !1, d.scrolling = "visible";
3631                "image" === c && (d.aspectRatio = !0);
3632                "iframe" === c && t && (d.scrolling = "scroll");
3633                d.wrap = f(d.tpl.wrap).addClass("fancybox-" + (t ? "mobile" : "desktop") + " fancybox-type-" + c + " fancybox-tmp " + d.wrapCSS).appendTo(d.parent || "body");
3634                f.extend(d, {
3635                    skin: f(".fancybox-skin", d.wrap),
3636                    outer: f(".fancybox-outer", d.wrap),
3637                    inner: f(".fancybox-inner", d.wrap)
3638                });
3639                f.each(["Top", "Right", "Bottom", "Left"], function(a, b) {
3640                    d.skin.css("padding" + b, x(d.padding[a]))
3641                });
3642                b.trigger("onReady");
3643                if ("inline" === c || "html" === c) {
3644                    if (!d.content || !d.content.length) return b._error("content")
3645                } else if (!e) return b._error("href");
3646                "image" === c ? b._loadImage() : "ajax" === c ? b._loadAjax() : "iframe" === c ? b._loadIframe() : b._afterLoad()
3647            }
3648        },
3649        _error: function(a) {
3650            f.extend(b.coming, {
3651                type: "html",
3652                autoWidth: !0,
3653                autoHeight: !0,
3654                minWidth: 0,
3655                minHeight: 0,
3656                scrolling: "no",
3657                hasError: a,
3658                content: b.coming.tpl.error
3659            });
3660            b._afterLoad()
3661        },
3662        _loadImage: function() {
3663            var a = b.imgPreload = new Image;
3664            a.onload = function() {
3665                this.onload = this.onerror = null;
3666                b.coming.width =
3667                    this.width / b.opts.pixelRatio;
3668                b.coming.height = this.height / b.opts.pixelRatio;
3669                b._afterLoad()
3670            };
3671            a.onerror = function() {
3672                this.onload = this.onerror = null;
3673                b._error("image")
3674            };
3675            a.src = b.coming.href;
3676            !0 !== a.complete && b.showLoading()
3677        },
3678        _loadAjax: function() {
3679            var a = b.coming;
3680            b.showLoading();
3681            b.ajaxLoad = f.ajax(f.extend({}, a.ajax, {
3682                url: a.href,
3683                error: function(a, e) {
3684                    b.coming && "abort" !== e ? b._error("ajax", a) : b.hideLoading()
3685                },
3686                success: function(d, e) {
3687                    "success" === e && (a.content = d, b._afterLoad())
3688                }
3689            }))
3690        },
3691        _loadIframe: function() {
3692            var a = b.coming,
3693                d = f(a.tpl.iframe.replace(/\{rnd\}/g, (new Date).getTime())).attr("scrolling", t ? "auto" : a.iframe.scrolling).attr("src", a.href);
3694            f(a.wrap).bind("onReset", function() {
3695                try {
3696                    f(this).find("iframe").hide().attr("src", "//about:blank").end().empty()
3697                } catch (a) {}
3698            });
3699            a.iframe.preload && (b.showLoading(), d.one("load", function() {
3700                f(this).data("ready", 1);
3701                t || f(this).bind("load.fb", b.update);
3702                f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();
3703                b._afterLoad()
3704            }));
3705            a.content = d.appendTo(a.inner);
3706            a.iframe.preload ||
3707                b._afterLoad()
3708        },
3709        _preloadImages: function() {
3710            var a = b.group,
3711                d = b.current,
3712                e = a.length,
3713                c = d.preload ? Math.min(d.preload, e - 1) : 0,
3714                f, g;
3715            for (g = 1; g <= c; g += 1) f = a[(d.index + g) % e], "image" === f.type && f.href && ((new Image).src = f.href)
3716        },
3717        _afterLoad: function() {
3718            var a = b.coming,
3719                d = b.current,
3720                e, c, l, g, h;
3721            b.hideLoading();
3722            if (a && !1 !== b.isActive)
3723                if (!1 === b.trigger("afterLoad", a, d)) a.wrap.stop(!0).trigger("onReset").remove(), b.coming = null;
3724                else {
3725                    d && (b.trigger("beforeChange", d), d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove());
3726                    b.unbindEvents();
3727                    e = a.content;
3728                    c = a.type;
3729                    l = a.scrolling;
3730                    f.extend(b, {
3731                        wrap: a.wrap,
3732                        skin: a.skin,
3733                        outer: a.outer,
3734                        inner: a.inner,
3735                        current: a,
3736                        previous: d
3737                    });
3738                    g = a.href;
3739                    switch (c) {
3740                        case "inline":
3741                        case "ajax":
3742                        case "html":
3743                            a.selector ? e = f("<div>").html(e).find(a.selector) : u(e) && (e.data("fancybox-placeholder") || e.data("fancybox-placeholder", f('<div class="fancybox-placeholder"></div>').insertAfter(e).hide()), e = e.show().detach(), a.wrap.bind("onReset", function() {
3744                                f(this).find(e).length && e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder", !1)
3745                            }));
3746                            break;
3747                        case "image":
3748                            e = a.tpl.image.replace(/\{href\}/g, g);
3749                            break;
3750                        case "swf":
3751                            e = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + g + '"></param>', h = "", f.each(a.swf, function(a, b) {
3752                                e += '<param name="' + a + '" value="' + b + '"></param>';
3753                                h += " " + a + '="' + b + '"'
3754                            }), e += '<embed src="' + g + '" type="application/x-shockwave-flash" width="100%" height="100%"' + h + "></embed></object>"
3755                    }
3756                    u(e) && e.parent().is(a.inner) || a.inner.append(e);
3757                    b.trigger("beforeShow");
3758                    a.inner.css("overflow", "yes" === l ? "scroll" : "no" === l ? "hidden" : l);
3759                    b._setDimension();
3760                    b.reposition();
3761                    b.isOpen = !1;
3762                    b.coming = null;
3763                    b.bindEvents();
3764                    if (!b.isOpened) f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();
3765                    else if (d.prevMethod) b.transitions[d.prevMethod]();
3766                    b.transitions[b.isOpened ? a.nextMethod : a.openMethod]();
3767                    b._preloadImages()
3768                }
3769        },
3770        _setDimension: function() {
3771            var a = b.getViewport(),
3772                d = 0,
3773                e = !1,
3774                c = !1,
3775                e = b.wrap,
3776                l = b.skin,
3777                g = b.inner,
3778                h = b.current,
3779                c = h.width,
3780                k = h.height,
3781                n = h.minWidth,
3782                v = h.minHeight,
3783                p = h.maxWidth,
3784                q = h.maxHeight,
3785                t = h.scrolling,
3786                r = h.scrollOutside ? h.scrollbarWidth : 0,
3787                y = h.margin,
3788                z = m(y[1] + y[3]),
3789                s = m(y[0] + y[2]),
3790                w, A, u, D, B, G, C, E, I;
3791            e.add(l).add(g).width("auto").height("auto").removeClass("fancybox-tmp");
3792            y = m(l.outerWidth(!0) - l.width());
3793            w = m(l.outerHeight(!0) - l.height());
3794            A = z + y;
3795            u = s + w;
3796            D = F(c) ? (a.w - A) * m(c) / 100 : c;
3797            B = F(k) ? (a.h - u) * m(k) / 100 : k;
3798            if ("iframe" === h.type) {
3799                if (I = h.content, h.autoHeight && 1 === I.data("ready")) try {
3800                    I[0].contentWindow.document.location && (g.width(D).height(9999), G = I.contents().find("body"), r && G.css("overflow-x",
3801                        "hidden"), B = G.outerHeight(!0))
3802                } catch (H) {}
3803            } else if (h.autoWidth || h.autoHeight) g.addClass("fancybox-tmp"), h.autoWidth || g.width(D), h.autoHeight || g.height(B), h.autoWidth && (D = g.width()), h.autoHeight && (B = g.height()), g.removeClass("fancybox-tmp");
3804            c = m(D);
3805            k = m(B);
3806            E = D / B;
3807            n = m(F(n) ? m(n, "w") - A : n);
3808            p = m(F(p) ? m(p, "w") - A : p);
3809            v = m(F(v) ? m(v, "h") - u : v);
3810            q = m(F(q) ? m(q, "h") - u : q);
3811            G = p;
3812            C = q;
3813            h.fitToView && (p = Math.min(a.w - A, p), q = Math.min(a.h - u, q));
3814            A = a.w - z;
3815            s = a.h - s;
3816            h.aspectRatio ? (c > p && (c = p, k = m(c / E)), k > q && (k = q, c = m(k * E)), c < n && (c = n, k = m(c /
3817                E)), k < v && (k = v, c = m(k * E))) : (c = Math.max(n, Math.min(c, p)), h.autoHeight && "iframe" !== h.type && (g.width(c), k = g.height()), k = Math.max(v, Math.min(k, q)));
3818            if (h.fitToView)
3819                if (g.width(c).height(k), e.width(c + y), a = e.width(), z = e.height(), h.aspectRatio)
3820                    for (;
3821                        (a > A || z > s) && c > n && k > v && !(19 < d++);) k = Math.max(v, Math.min(q, k - 10)), c = m(k * E), c < n && (c = n, k = m(c / E)), c > p && (c = p, k = m(c / E)), g.width(c).height(k), e.width(c + y), a = e.width(), z = e.height();
3822                else c = Math.max(n, Math.min(c, c - (a - A))), k = Math.max(v, Math.min(k, k - (z - s)));
3823            r && "auto" === t && k < B &&
3824                c + y + r < A && (c += r);
3825            g.width(c).height(k);
3826            e.width(c + y);
3827            a = e.width();
3828            z = e.height();
3829            e = (a > A || z > s) && c > n && k > v;
3830            c = h.aspectRatio ? c < G && k < C && c < D && k < B : (c < G || k < C) && (c < D || k < B);
3831            f.extend(h, {
3832                dim: {
3833                    width: x(a),
3834                    height: x(z)
3835                },
3836                origWidth: D,
3837                origHeight: B,
3838                canShrink: e,
3839                canExpand: c,
3840                wPadding: y,
3841                hPadding: w,
3842                wrapSpace: z - l.outerHeight(!0),
3843                skinSpace: l.height() - k
3844            });
3845            !I && h.autoHeight && k > v && k < q && !c && g.height("auto")
3846        },
3847        _getPosition: function(a) {
3848            var d = b.current,
3849                e = b.getViewport(),
3850                c = d.margin,
3851                f = b.wrap.width() + c[1] + c[3],
3852                g = b.wrap.height() + c[0] + c[2],
3853                c = {
3854                    position: "absolute",
3855                    top: c[0],
3856                    left: c[3]
3857                };
3858            d.autoCenter && d.fixed && !a && g <= e.h && f <= e.w ? c.position = "fixed" : d.locked || (c.top += e.y, c.left += e.x);
3859            c.top = x(Math.max(c.top, c.top + (e.h - g) * d.topRatio));
3860            c.left = x(Math.max(c.left, c.left + (e.w - f) * d.leftRatio));
3861            return c
3862        },
3863        _afterZoomIn: function() {
3864            var a = b.current;
3865            a && ((b.isOpen = b.isOpened = !0, b.wrap.css("overflow", "visible").addClass("fancybox-opened"), b.update(), (a.closeClick || a.nextClick && 1 < b.group.length) && b.inner.css("cursor", "pointer").bind("click.fb", function(d) {
3866                f(d.target).is("a") || f(d.target).parent().is("a") ||
3867                    (d.preventDefault(), b[a.closeClick ? "close" : "next"]())
3868            }), a.closeBtn && f(a.tpl.closeBtn).appendTo(b.skin).bind("click.fb", function(a) {
3869                a.preventDefault();
3870                b.close()
3871            }), a.arrows && 1 < b.group.length && ((a.loop || 0 < a.index) && f(a.tpl.prev).appendTo(b.outer).bind("click.fb", b.prev), (a.loop || a.index < b.group.length - 1) && f(a.tpl.next).appendTo(b.outer).bind("click.fb", b.next)), b.trigger("afterShow"), a.loop || a.index !== a.group.length - 1) ? b.opts.autoPlay && !b.player.isActive && (b.opts.autoPlay = !1, b.play(!0)) : b.play(!1))
3872        },
3873        _afterZoomOut: function(a) {
3874            a = a || b.current;
3875            f(".fancybox-wrap").trigger("onReset").remove();
3876            f.extend(b, {
3877                group: {},
3878                opts: {},
3879                router: !1,
3880                current: null,
3881                isActive: !1,
3882                isOpened: !1,
3883                isOpen: !1,
3884                isClosing: !1,
3885                wrap: null,
3886                skin: null,
3887                outer: null,
3888                inner: null
3889            });
3890            b.trigger("afterClose", a)
3891        }
3892    });
3893    b.transitions = {
3894        getOrigPosition: function() {
3895            var a = b.current,
3896                d = a.element,
3897                e = a.orig,
3898                c = {},
3899                f = 50,
3900                g = 50,
3901                h = a.hPadding,
3902                k = a.wPadding,
3903                n = b.getViewport();
3904            !e && a.isDom && d.is(":visible") && (e = d.find("img:first"), e.length || (e = d));
3905            u(e) ? (c = e.offset(), e.is("img") &&
3906                (f = e.outerWidth(), g = e.outerHeight())) : (c.top = n.y + (n.h - g) * a.topRatio, c.left = n.x + (n.w - f) * a.leftRatio);
3907            if ("fixed" === b.wrap.css("position") || a.locked) c.top -= n.y, c.left -= n.x;
3908            return c = {
3909                top: x(c.top - h * a.topRatio),
3910                left: x(c.left - k * a.leftRatio),
3911                width: x(f + k),
3912                height: x(g + h)
3913            }
3914        },
3915        step: function(a, d) {
3916            var e, c, f = d.prop;
3917            c = b.current;
3918            var g = c.wrapSpace,
3919                h = c.skinSpace;
3920            if ("width" === f || "height" === f) e = d.end === d.start ? 1 : (a - d.start) / (d.end - d.start), b.isClosing && (e = 1 - e), c = "width" === f ? c.wPadding : c.hPadding, c = a - c, b.skin[f](m("width" ===
3921                f ? c : c - g * e)), b.inner[f](m("width" === f ? c : c - g * e - h * e))
3922        },
3923        zoomIn: function() {
3924            var a = b.current,
3925                d = a.pos,
3926                e = a.openEffect,
3927                c = "elastic" === e,
3928                l = f.extend({
3929                    opacity: 1
3930                }, d);
3931            delete l.position;
3932            c ? (d = this.getOrigPosition(), a.openOpacity && (d.opacity = 0.1)) : "fade" === e && (d.opacity = 0.1);
3933            b.wrap.css(d).animate(l, {
3934                duration: "none" === e ? 0 : a.openSpeed,
3935                easing: a.openEasing,
3936                step: c ? this.step : null,
3937                complete: b._afterZoomIn
3938            })
3939        },
3940        zoomOut: function() {
3941            var a = b.current,
3942                d = a.closeEffect,
3943                e = "elastic" === d,
3944                c = {
3945                    opacity: 0.1
3946                };
3947            e && (c = this.getOrigPosition(), a.closeOpacity &&
3948                (c.opacity = 0.1));
3949            b.wrap.animate(c, {
3950                duration: "none" === d ? 0 : a.closeSpeed,
3951                easing: a.closeEasing,
3952                step: e ? this.step : null,
3953                complete: b._afterZoomOut
3954            })
3955        },
3956        changeIn: function() {
3957            var a = b.current,
3958                d = a.nextEffect,
3959                e = a.pos,
3960                c = {
3961                    opacity: 1
3962                },
3963                f = b.direction,
3964                g;
3965            e.opacity = 0.1;
3966            "elastic" === d && (g = "down" === f || "up" === f ? "top" : "left", "down" === f || "right" === f ? (e[g] = x(m(e[g]) - 200), c[g] = "+=200px") : (e[g] = x(m(e[g]) + 200), c[g] = "-=200px"));
3967            "none" === d ? b._afterZoomIn() : b.wrap.css(e).animate(c, {
3968                duration: a.nextSpeed,
3969                easing: a.nextEasing,
3970                complete: b._afterZoomIn
3971            })
3972        },
3973        changeOut: function() {
3974            var a = b.previous,
3975                d = a.prevEffect,
3976                e = {
3977                    opacity: 0.1
3978                },
3979                c = b.direction;
3980            "elastic" === d && (e["down" === c || "up" === c ? "top" : "left"] = ("up" === c || "left" === c ? "-" : "+") + "=200px");
3981            a.wrap.animate(e, {
3982                duration: "none" === d ? 0 : a.prevSpeed,
3983                easing: a.prevEasing,
3984                complete: function() {
3985                    f(this).trigger("onReset").remove()
3986                }
3987            })
3988        }
3989    };
3990    b.helpers.overlay = {
3991        defaults: {
3992            closeClick: !0,
3993            speedOut: 200,
3994            showEarly: !0,
3995            css: {},
3996            locked: !t,
3997            fixed: !0
3998        },
3999        overlay: null,
4000        fixed: !1,
4001        el: f("html"),
4002        create: function(a) {
4003            var d;
4004            a = f.extend({}, this.defaults, a);
4005            this.overlay &&
4006                this.close();
4007            d = b.coming ? b.coming.parent : a.parent;
4008            this.overlay = f('<div class="fancybox-overlay"></div>').appendTo(d && d.lenth ? d : "body");
4009            this.fixed = !1;
4010            a.fixed && b.defaults.fixed && (this.overlay.addClass("fancybox-overlay-fixed"), this.fixed = !0)
4011        },
4012        open: function(a) {
4013            var d = this;
4014            a = f.extend({}, this.defaults, a);
4015            this.overlay ? this.overlay.unbind(".overlay").width("auto").height("auto") : this.create(a);
4016            this.fixed || (q.bind("resize.overlay", f.proxy(this.update, this)), this.update());
4017            a.closeClick && this.overlay.bind("click.overlay",
4018                function(a) {
4019                    if (f(a.target).hasClass("fancybox-overlay")) return b.isActive ? b.close() : d.close(), !1
4020                });
4021            this.overlay.css(a.css).show()
4022        },
4023        close: function() {
4024            q.unbind("resize.overlay");
4025            this.el.hasClass("fancybox-lock") && (f(".fancybox-margin").removeClass("fancybox-margin"), this.el.removeClass("fancybox-lock"), q.scrollTop(this.scrollV).scrollLeft(this.scrollH));
4026            f(".fancybox-overlay").remove().hide();
4027            f.extend(this, {
4028                overlay: null,
4029                fixed: !1
4030            })
4031        },
4032        update: function() {
4033            var a = "100%",
4034                b;
4035            this.overlay.width(a).height("100%");
4036            J ? (b = Math.max(H.documentElement.offsetWidth, H.body.offsetWidth), p.width() > b && (a = p.width())) : p.width() > q.width() && (a = p.width());
4037            this.overlay.width(a).height(p.height())
4038        },
4039        onReady: function(a, b) {
4040            var e = this.overlay;
4041            f(".fancybox-overlay").stop(!0, !0);
4042            e || this.create(a);
4043            a.locked && this.fixed && b.fixed && (b.locked = this.overlay.append(b.wrap), b.fixed = !1);
4044            !0 === a.showEarly && this.beforeShow.apply(this, arguments)
4045        },
4046        beforeShow: function(a, b) {
4047            b.locked && !this.el.hasClass("fancybox-lock") && (!1 !== this.fixPosition && f("*").filter(function() {
4048                return "fixed" ===
4049                    f(this).css("position") && !f(this).hasClass("fancybox-overlay") && !f(this).hasClass("fancybox-wrap")
4050            }).addClass("fancybox-margin"), this.el.addClass("fancybox-margin"), this.scrollV = q.scrollTop(), this.scrollH = q.scrollLeft(), this.el.addClass("fancybox-lock"), q.scrollTop(this.scrollV).scrollLeft(this.scrollH));
4051            this.open(a)
4052        },
4053        onUpdate: function() {
4054            this.fixed || this.update()
4055        },
4056        afterClose: function(a) {
4057            this.overlay && !b.coming && this.overlay.fadeOut(a.speedOut, f.proxy(this.close, this))
4058        }
4059    };
4060    b.helpers.title = {
4061        defaults: {
4062            type: "float",
4063            position: "bottom"
4064        },
4065        beforeShow: function(a) {
4066            var d = b.current,
4067                e = d.title,
4068                c = a.type;
4069            f.isFunction(e) && (e = e.call(d.element, d));
4070            if (r(e) && "" !== f.trim(e)) {
4071                d = f('<div class="fancybox-title fancybox-title-' + c + '-wrap">' + e + "</div>");
4072                switch (c) {
4073                    case "inside":
4074                        c = b.skin;
4075                        break;
4076                    case "outside":
4077                        c = b.wrap;
4078                        break;
4079                    case "over":
4080                        c = b.inner;
4081                        break;
4082                    default:
4083                        c = b.skin, d.appendTo("body"), J && d.width(d.width()), d.wrapInner('<span class="child"></span>'), b.current.margin[2] += Math.abs(m(d.css("margin-bottom")))
4084                }
4085                d["top" === a.position ? "prependTo" :
4086                    "appendTo"](c)
4087            }
4088        }
4089    };
4090    f.fn.fancybox = function(a) {
4091        var d, e = f(this),
4092            c = this.selector || "",
4093            l = function(g) {
4094                var h = f(this).blur(),
4095                    k = d,
4096                    l, m;
4097                g.ctrlKey || g.altKey || g.shiftKey || g.metaKey || h.is(".fancybox-wrap") || (l = a.groupAttr || "data-fancybox-group", m = h.attr(l), m || (l = "rel", m = h.get(0)[l]), m && "" !== m && "nofollow" !== m && (h = c.length ? f(c) : e, h = h.filter("[" + l + '="' + m + '"]'), k = h.index(this)), a.index = k, !1 !== b.open(h, a) && g.preventDefault())
4098            };
4099        a = a || {};
4100        d = a.index || 0;
4101        c && !1 !== a.live ? p.undelegate(c, "click.fb-start").delegate(c + ":not('.fancybox-item, .fancybox-nav')",
4102            "click.fb-start", l) : e.unbind("click.fb-start").bind("click.fb-start", l);
4103        this.filter("[data-fancybox-start=1]").trigger("click");
4104        return this
4105    };
4106    p.ready(function() {
4107        var a, d;
4108        f.scrollbarWidth === w && (f.scrollbarWidth = function() {
4109            var a = f('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),
4110                b = a.children(),
4111                b = b.innerWidth() - b.height(99).innerWidth();
4112            a.remove();
4113            return b
4114        });
4115        f.support.fixedPosition === w && (f.support.fixedPosition = function() {
4116            var a = f('<div style="position:fixed;top:20px;"></div>').appendTo("body"),
4117                b = 20 === a[0].offsetTop || 15 === a[0].offsetTop;
4118            a.remove();
4119            return b
4120        }());
4121        f.extend(b.defaults, {
4122            scrollbarWidth: f.scrollbarWidth(),
4123            fixed: f.support.fixedPosition,
4124            parent: f("body")
4125        });
4126        a = f(s).width();
4127        K.addClass("fancybox-lock-test");
4128        d = f(s).width();
4129        K.removeClass("fancybox-lock-test");
4130        f("<style type='text/css'>.fancybox-margin{margin-right:" + (d - a) + "px;}</style>").appendTo("head")
4131    })
4132})(window, document, jQuery);
4133
4134
4135
4136
4137
4138
4139/*!
4140 * Media helper for fancyBox
4141 * version: 1.0.6 (Fri, 14 Jun 2013)
4142 * @requires fancyBox v2.0 or later
4143 *
4144 * Usage:
4145 *     $(".fancybox").fancybox({
4146 *         helpers : {
4147 *             media: true
4148 *         }
4149 *     });
4150 *
4151 * Set custom URL parameters:
4152 *     $(".fancybox").fancybox({
4153 *         helpers : {
4154 *             media: {
4155 *                 youtube : {
4156 *                     params : {
4157 *                         autoplay : 0
4158 *                     }
4159 *                 }
4160 *             }
4161 *         }
4162 *     });
4163 *
4164 * Or:
4165 *     $(".fancybox").fancybox({,
4166 *         helpers : {
4167 *             media: true
4168 *         },
4169 *         youtube : {
4170 *             autoplay: 0
4171 *         }
4172 *     });
4173 *
4174 *  Supports:
4175 *
4176 *      Youtube
4177 *          http://www.youtube.com/watch?v=opj24KnzrWo
4178 *          http://www.youtube.com/embed/opj24KnzrWo
4179 *          http://youtu.be/opj24KnzrWo
4180 *          http://www.youtube-nocookie.com/embed/opj24KnzrWo
4181 *      Vimeo
4182 *          http://vimeo.com/40648169
4183 *          http://vimeo.com/channels/staffpicks/38843628
vendor: 5,535 bytes, lines 4184-4332
4184 *          http://vimeo.com/groups/surrealism/videos/36516384
4185 *          http://player.vimeo.com/video/45074303
4186 *      Metacafe
4187 *          http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/
4188 *          http://www.metacafe.com/watch/7635964/
4189 *      Dailymotion
4190 *          http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people
4191 *      Twitvid
4192 *          http://twitvid.com/QY7MD
4193 *      Twitpic
4194 *          http://twitpic.com/7p93st
4195 *      Instagram
4196 *          http://instagr.am/p/IejkuUGxQn/
4197 *          http://instagram.com/p/IejkuUGxQn/
4198 *      Google maps
4199 *          http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17
4200 *          http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
4201 *          http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56
4202 */
4203(function ($) {
4204    "use strict";
4205
4206    //Shortcut for fancyBox object
4207    var F = $.fancybox,
4208        format = function( url, rez, params ) {
4209            params = params || '';
4210
4211            if ( $.type( params ) === "object" ) {
4212                params = $.param(params, true);
4213            }
4214
4215            $.each(rez, function(key, value) {
4216                url = url.replace( '$' + key, value || '' );
4217            });
4218
4219            if (params.length) {
4220                url += ( url.indexOf('?') > 0 ? '&' : '?' ) + params;
4221            }
4222
4223            return url;
4224        };
4225
4226    //Add helper object
4227    F.helpers.media = {
4228        defaults : {
4229            youtube : {
4230                matcher : /(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i,
4231                params  : {
4232                    autoplay    : 1,
4233                    autohide    : 1,
4234                    fs          : 1,
4235                    rel         : 0,
4236                    hd          : 1,
4237                    wmode       : 'opaque',
4238                    enablejsapi : 1
4239                },
4240                type : 'iframe',
4241                url  : '//www.youtube.com/embed/$3'
4242            },
4243            vimeo : {
4244                matcher : /(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/,
4245                params  : {
4246                    autoplay      : 1,
4247                    hd            : 1,
4248                    show_title    : 1,
4249                    show_byline   : 1,
4250                    show_portrait : 0,
4251                    fullscreen    : 1
4252                },
4253                type : 'iframe',
4254                url  : '//player.vimeo.com/video/$1'
4255            },
4256            metacafe : {
4257                matcher : /metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/,
4258                params  : {
4259                    autoPlay : 'yes'
4260                },
4261                type : 'swf',
4262                url  : function( rez, params, obj ) {
4263                    obj.swf.flashVars = 'playerVars=' + $.param( params, true );
4264
4265                    return '//www.metacafe.com/fplayer/' + rez[1] + '/.swf';
4266                }
4267            },
4268            dailymotion : {
4269                matcher : /dailymotion.com\/video\/(.*)\/?(.*)/,
4270                params  : {
4271                    additionalInfos : 0,
4272                    autoStart : 1
4273                },
4274                type : 'swf',
4275                url  : '//www.dailymotion.com/swf/video/$1'
4276            },
4277            twitvid : {
4278                matcher : /twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i,
4279                params  : {
4280                    autoplay : 0
4281                },
4282                type : 'iframe',
4283                url  : '//www.twitvid.com/embed.php?guid=$1'
4284            },
4285            twitpic : {
4286                matcher : /twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i,
4287                type : 'image',
4288                url  : '//twitpic.com/show/full/$1/'
4289            },
4290            instagram : {
4291                matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
4292                type : 'image',
4293                url  : '//$1/p/$2/media/?size=l'
4294            },
4295            google_maps : {
4296                matcher : /maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i,
4297                type : 'iframe',
4298                url  : function( rez ) {
4299                    return '//maps.google.' + rez[1] + '/' + rez[3] + '' + rez[4] + '&output=' + (rez[4].indexOf('layer=c') > 0 ? 'svembed' : 'embed');
4300                }
4301            }
4302        },
4303
4304        beforeLoad : function(opts, obj) {
4305            var url   = obj.href || '',
4306                type  = false,
4307                what,
4308                item,
4309                rez,
4310                params;
4311
4312            for (what in opts) {
4313                if (opts.hasOwnProperty(what)) {
4314                    item = opts[ what ];
4315                    rez  = url.match( item.matcher );
4316
4317                    if (rez) {
4318                        type   = item.type;
4319                        params = $.extend(true, {}, item.params, obj[ what ] || ($.isPlainObject(opts[ what ]) ? opts[ what ].params : null));
4320
4321                        url = $.type( item.url ) === "function" ? item.url.call( this, rez, params, obj ) : format( item.url, rez, params );
4322
4323                        break;
4324                    }
4325                }
4326            }
4327
4328            if (type) {
4329                obj.href = url;
4330                obj.type = type;
4331
4332                obj.autoHeight = false;
4333            }
4334        }
4335    };
4336
4337}(jQuery));
4338;
4339(function ($, window, document, undefined) {
4340
4341  var pluginName = "MegaMenu",
4342    defaults = {
4343      propertyName: "value"
4344    };
4345
4346  // Set delay time for mouseout
4347  var delayOut = 400; // Default delay time is 200
4348
4349  // the list of menus
4350  var menus = [];
4351
4352  function CustomMenu(element, options) {
4353    this.element = element;
4354
4355    this.options = $.extend({}, defaults, options);
4356
4357    this._defaults = defaults;
4358    this._name = pluginName;
4359
4360    this.init();
4361  }
4362
4363  CustomMenu.prototype = {
4364    isOpen: false,
4365    timeout: null,
4366    init: function () {
4367
4368      var that = this;
4369
4370      $(this).each(function(index, menu) {
4371        that.node = menu.element; 
4372        that.addListeners(menu.element);
4373
4374        var $menu = $(menu.element);
4375        $menu.addClass("dropdownJavascript");
4376        menus.push(menu.element);
4377
4378        $menu.find('ul > li').each(function(index, submenu) {
4379          if ($(submenu).find('ul').length > 0 ) {
4380            $(submenu).addClass('with-menu');
4381          }
4382        });
4383      });
4384    },
4385    addListeners: function(menu) {
4386      var that = this;
4387      $(menu).mouseover(function(e) {
4388        that.handleMouseOver.call(that, e);
4389      }).mouseout(function(e) {
4390          that.handleMouseOut.call(that, e);
4391        });
4392    },
4393    handleMouseOver: function (e) {
4394      var that = this;
4395      // clear the timeout
4396      this.clearTimeout();
4397
4398      // find the parent list item
4399      //var item = ('target' in e ? e.target : e.srcElement);
4400      var item = e.target || e.srcElement;
4401      while (item.nodeName != 'LI' && item != this.node) {
4402        item = item.parentNode;
4403      }
4404
4405      // if the target is within a list item, set the timeout
4406      if (item.nodeName == 'LI') {
4407        this.toOpen = item;
4408        this.timeout = setTimeout(function() {
4409          that.open.call(that);
4410        }, this.options.delay);
4411      }
4412
4413    },
4414    handleMouseOut: function () {
4415      var that = this;
4416      // clear the timeout
4417      this.clearTimeout();
4418
4419      // Check mouseout delay overriding
4420      var _delayOut = this.options.delay;
4421      if ( delayOut ) {
4422        _delayOut = delayOut;
4423      }
4424
4425      this.timeout = setTimeout(function() {
4426        that.close.call(that);
4427      }, _delayOut );
4428
4429    },
4430    clearTimeout: function () {
4431
4432      // clear the timeout
4433      if (this.timeout) {
4434        clearTimeout(this.timeout);
4435        this.timeout = null;
4436      }
4437
4438    },
4439    open: function () {
4440
4441      var that = this;
4442      // store that the menu is open
4443      this.isOpen = true;
4444
4445      // loop over the list items with the same parent
4446      var items = $(this.toOpen).parent().children('li');
4447      $(items).each(function(index, item) {
4448        $(item).find("ul").each(function(index, submenu) {
4449          if (item != that.toOpen) {
4450            // close the submenu
4451            $(item).removeClass("dropdownOpen");
4452            that.close(item);
4453
4454          } else if (!$(item).hasClass('dropdownOpen')) {
4455
4456            // open the submenu
4457            //if ( !$(item).parents('li').hasClass('has-mega-menu') ) {
4458              $(item).addClass("dropdownOpen");
4459            //}
4460
4461
4462            // determine the location of the edges of the submenu
4463            var left = 0;
4464            var node = submenu;
4465            while (node) {
4466              //abs is because when you make menus right to left
4467              //the offsetLeft would be negative
4468              left += Math.abs(node.offsetLeft);
4469              node = node.offsetParent;
4470            }
4471            var right = left + submenu.offsetWidth;
4472
4473
4474            //We should refactor this code to execute only when menu is vertical
4475            var menuHeight = $(submenu).outerHeight();
4476            var parentTop = $(submenu).offset().top - $(window).scrollTop();
4477            var totalHeight = menuHeight + parentTop;
4478            var windowHeight = window.innerHeight;
4479
4480           /* if (totalHeight > windowHeight) {
4481              var bestTop = (windowHeight - totalHeight) - 20;
4482              $(submenu).css('margin-top', bestTop + "px");
4483            }*/
4484
4485            //remove any previous classes
4486            $(item).removeClass('dropdownRightToLeft');
4487
4488            // move the submenu to the right of the item if appropriate
4489            if (left < 0) $(item).addClass('dropdownLeftToRight');
4490
4491            // move the submenu to the left of the item if appropriate
4492            if (right > document.body.clientWidth) {
4493              $(item).addClass('dropdownRightToLeft');
4494            }
4495
4496          }
4497        });
4498      });
4499
4500    },
4501
4502
4503    close: function (node) {
4504
4505      // if no node was specified, close all menus
4506      if (!node) {
4507        this.isOpen = false;
4508        node = this.node;
4509      }
4510
4511      // loop over the items, closing their submenus
4512      $(node).find('li').each(function(index, item) {
4513        $(item).removeClass('dropdownOpen');
4514      });
4515
4516    }
4517  };
4518
4519  $.fn[pluginName] = function (options) {
4520    return this.each(function () {
4521      if (!$.data(this, "plugin_" + pluginName)) {
4522        $.data(this, "plugin_" + pluginName,
4523          new CustomMenu(this, options));
4524      }
4525    });
4526  };
4527
4528})(jQuery, window, document);
4529
4530/*!
4531 * modernizr v3.3.1
4532 * Build https://modernizr.com/download?-cssanimations-csstransitions-touchevents-domprefixes-prefixed-prefixes-setclasses-shiv-testallprops-testprop-teststyles-dontmin
4533 *
4534 * Copyright (c)
4535 *  Faruk Ates
4536 *  Paul Irish
4537 *  Alex Sexton
4538 *  Ryan Seddon
4539 *  Patrick Kettner
4540 *  Stu Cox
4541 *  Richard Herrera
4542
4543 * MIT License
4544 */
4545
4546/*
4547 * Modernizr tests which native CSS3 and HTML5 features are available in the
4548 * current UA and makes the results available to you in two ways: as properties on
4549 * a global `Modernizr` object, and as classes on the `<html>` element. This
4550 * information allows you to progressively enhance your pages with a granular level
4551 * of control over the experience.
4552*/
4553
4554;(function(window, document, undefined){
4555  var classes = [];
4556  
4557
4558  var tests = [];
4559  
4560
4561  /**
4562   *
4563   * ModernizrProto is the constructor for Modernizr
4564   *
4565   * @class
4566   * @access public
4567   */
4568
4569  var ModernizrProto = {
4570    // The current version, dummy
4571    _version: '3.3.1',
4572
4573    // Any settings that don't work as separate modules
4574    // can go in here as configuration.
4575    _config: {
4576      'classPrefix': '',
4577      'enableClasses': true,
4578      'enableJSClass': true,
4579      'usePrefixes': true
4580    },
4581
4582    // Queue of tests
4583    _q: [],
4584
4585    // Stub these for people who are listening
4586    on: function(test, cb) {
4587      // I don't really think people should do this, but we can
4588      // safe guard it a bit.
4589      // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.
4590      // This is in case people listen to synchronous tests. I would leave it out,
4591      // but the code to *disallow* sync tests in the real version of this
4592      // function is actually larger than this.
4593      var self = this;
4594      setTimeout(function() {
4595        cb(self[test]);
4596      }, 0);
4597    },
4598
4599    addTest: function(name, fn, options) {
4600      tests.push({name: name, fn: fn, options: options});
4601    },
4602
4603    addAsyncTest: function(fn) {
4604      tests.push({name: null, fn: fn});
4605    }
4606  };
4607
4608  
4609
4610  // Fake some of Object.create so we can force non test results to be non "own" properties.
4611  var Modernizr = function() {};
4612  Modernizr.prototype = ModernizrProto;
4613
4614  // Leak modernizr globally when you `require` it rather than force it here.
4615  // Overwrite name so constructor name is nicer :D
4616  Modernizr = new Modernizr();
4617
4618  
4619
4620  /**
4621   * List of property values to set for css tests. See ticket #21
4622   * http://git.io/vUGl4
4623   *
4624   * @memberof Modernizr
4625   * @name Modernizr._prefixes
4626   * @optionName Modernizr._prefixes
4627   * @optionProp prefixes
4628   * @access public
4629   * @example
4630   *
4631   * Modernizr._prefixes is the internal list of prefixes that we test against
4632   * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply
4633   * an array of kebab-case vendor prefixes you can use within your code.
4634   *
4635   * Some common use cases include
4636   *
4637   * Generating all possible prefixed version of a CSS property
4638   * ```js
4639   * var rule = Modernizr._prefixes.join('transform: rotate(20deg); ');
4640   *
4641   * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);'
4642   * ```
4643   *
4644   * Generating all possible prefixed version of a CSS value
4645   * ```js
4646   * rule = 'display:' +  Modernizr._prefixes.join('flex; display:') + 'flex';
4647   *
4648   * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex'
4649   * ```
4650   */
4651
4652  // we use ['',''] rather than an empty array in order to allow a pattern of .`join()`ing prefixes to test
4653  // values in feature detects to continue to work
4654  var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : ['','']);
4655
4656  // expose these for the plugin API. Look in the source for how to join() them against your input
4657  ModernizrProto._prefixes = prefixes;
4658
4659  
4660
4661  /**
4662   * is returns a boolean if the typeof an obj is exactly type.
4663   *
4664   * @access private
4665   * @function is
4666   * @param {*} obj - A thing we want to check the type of
4667   * @param {string} type - A string to compare the typeof against
4668   * @returns {boolean}
4669   */
4670
4671  function is(obj, type) {
4672    return typeof obj === type;
4673  }
4674  ;
4675
4676  /**
4677   * Run through all tests and detect their support in the current UA.
4678   *
4679   * @access private
4680   */
4681
4682  function testRunner() {
4683    var featureNames;
4684    var feature;
4685    var aliasIdx;
4686    var result;
4687    var nameIdx;
4688    var featureName;
4689    var featureNameSplit;
4690
4691    for (var featureIdx in tests) {
4692      if (tests.hasOwnProperty(featureIdx)) {
4693        featureNames = [];
4694        feature = tests[featureIdx];
4695        // run the test, throw the return value into the Modernizr,
4696        // then based on that boolean, define an appropriate className
4697        // and push it into an array of classes we'll join later.
4698        //
4699        // If there is no name, it's an 'async' test that is run,
4700        // but not directly added to the object. That should
4701        // be done with a post-run addTest call.
4702        if (feature.name) {
4703          featureNames.push(feature.name.toLowerCase());
4704
4705          if (feature.options && feature.options.aliases && feature.options.aliases.length) {
4706            // Add all the aliases into the names list
4707            for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {
4708              featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
4709            }
4710          }
4711        }
4712
4713        // Run the test, or use the raw value if it's not a function
4714        result = is(feature.fn, 'function') ? feature.fn() : feature.fn;
4715
4716
4717        // Set each of the names on the Modernizr object
4718        for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
4719          featureName = featureNames[nameIdx];
4720          // Support dot properties as sub tests. We don't do checking to make sure
4721          // that the implied parent tests have been added. You must call them in
4722          // order (either in the test, or make the parent test a dependency).
4723          //
4724          // Cap it to TWO to make the logic simple and because who needs that kind of subtesting
4725          // hashtag famous last words
4726          featureNameSplit = featureName.split('.');
4727
4728          if (featureNameSplit.length === 1) {
4729            Modernizr[featureNameSplit[0]] = result;
4730          } else {
4731            // cast to a Boolean, if not one already
4732            /* jshint -W053 */
4733            if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
4734              Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
4735            }
4736
4737            Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
4738          }
4739
4740          classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
4741        }
4742      }
4743    }
4744  }
4745  ;
4746
4747  /**
4748   * docElement is a convenience wrapper to grab the root element of the document
4749   *
4750   * @access private
4751   * @returns {HTMLElement|SVGElement} The root element of the document
4752   */
4753
4754  var docElement = document.documentElement;
4755  
4756
4757  /**
4758   * A convenience helper to check if the document we are running in is an SVG document
4759   *
4760   * @access private
4761   * @returns {boolean}
4762   */
4763
4764  var isSVG = docElement.nodeName.toLowerCase() === 'svg';
4765  
4766
4767  /**
4768   * setClasses takes an array of class names and adds them to the root element
4769   *
4770   * @access private
4771   * @function setClasses
4772   * @param {string[]} classes - Array of class names
4773   */
4774
4775  // Pass in an and array of class names, e.g.:
4776  //  ['no-webp', 'borderradius', ...]
4777  function setClasses(classes) {
4778    var className = docElement.className;
4779    var classPrefix = Modernizr._config.classPrefix || '';
4780
4781    if (isSVG) {
4782      className = className.baseVal;
4783    }
4784
4785    // Change `no-js` to `js` (independently of the `enableClasses` option)
4786    // Handle classPrefix on this too
4787    if (Modernizr._config.enableJSClass) {
4788      var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
4789      className = className.replace(reJS, '$1' + classPrefix + 'js$2');
4790    }
4791
4792    if (Modernizr._config.enableClasses) {
4793      // Add the new classes
4794      className += ' ' + classPrefix + classes.join(' ' + classPrefix);
4795      isSVG ? docElement.className.baseVal = className : docElement.className = className;
4796    }
4797
4798  }
4799
4800  ;
4801
4802/**
4803  * @optionName html5shiv
4804  * @optionProp html5shiv
4805  */
4806
4807  // Take the html5 variable out of the html5shiv scope so we can return it.
4808  var html5;
4809  if (!isSVG) {
4810    /**
4811     * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
4812     */
4813    ;(function(window, document) {
4814      /*jshint evil:true */
4815      /** version */
4816      var version = '3.7.3';
4817
4818      /** Preset options */
4819      var options = window.html5 || {};
4820
4821      /** Used to skip problem elements */
4822      var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
4823
4824      /** Not all elements can be cloned in IE **/
4825      var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
4826
4827      /** Detect whether the browser supports default html5 styles */
4828      var supportsHtml5Styles;
4829
4830      /** Name of the expando, to work with multiple documents or to re-shiv one document */
4831      var expando = '_html5shiv';
4832
4833      /** The id for the the documents expando */
4834      var expanID = 0;
4835
4836      /** Cached data for each document */
4837      var expandoData = {};
4838
4839      /** Detect whether the browser supports unknown elements */
4840      var supportsUnknownElements;
4841
4842      (function() {
4843        try {
4844          var a = document.createElement('a');
4845          a.innerHTML = '<xyz></xyz>';
4846          //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
4847          supportsHtml5Styles = ('hidden' in a);
4848
4849          supportsUnknownElements = a.childNodes.length == 1 || (function() {
4850            // assign a false positive if unable to shiv
4851            (document.createElement)('a');
4852            var frag = document.createDocumentFragment();
4853            return (
4854              typeof frag.cloneNode == 'undefined' ||
4855                typeof frag.createDocumentFragment == 'undefined' ||
4856                typeof frag.createElement == 'undefined'
4857            );
4858          }());
4859        } catch(e) {
4860          // assign a false positive if detection fails => unable to shiv
4861          supportsHtml5Styles = true;
4862          supportsUnknownElements = true;
4863        }
4864
4865      }());
4866
4867      /*--------------------------------------------------------------------------*/
4868
4869      /**
4870       * Creates a style sheet with the given CSS text and adds it to the document.
4871       * @private
4872       * @param {Document} ownerDocument The document.
4873       * @param {String} cssText The CSS text.
4874       * @returns {StyleSheet} The style element.
4875       */
4876      function addStyleSheet(ownerDocument, cssText) {
4877        var p = ownerDocument.createElement('p'),
4878          parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
4879
4880        p.innerHTML = 'x<style>' + cssText + '</style>';
4881        return parent.insertBefore(p.lastChild, parent.firstChild);
4882      }
4883
4884      /**
4885       * Returns the value of `html5.elements` as an array.
4886       * @private
4887       * @returns {Array} An array of shived element node names.
4888       */
4889      function getElements() {
4890        var elements = html5.elements;
4891        return typeof elements == 'string' ? elements.split(' ') : elements;
4892      }
4893
4894      /**
4895       * Extends the built-in list of html5 elements
4896       * @memberOf html5
4897       * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
4898       * @param {Document} ownerDocument The context document.
4899       */
4900      function addElements(newElements, ownerDocument) {
4901        var elements = html5.elements;
4902        if(typeof elements != 'string'){
4903          elements = elements.join(' ');
4904        }
4905        if(typeof newElements != 'string'){
4906          newElements = newElements.join(' ');
4907        }
4908        html5.elements = elements +' '+ newElements;
4909        shivDocument(ownerDocument);
4910      }
4911
4912      /**
4913       * Returns the data associated to the given document
4914       * @private
4915       * @param {Document} ownerDocument The document.
4916       * @returns {Object} An object of data.
4917       */
4918      function getExpandoData(ownerDocument) {
4919        var data = expandoData[ownerDocument[expando]];
4920        if (!data) {
4921          data = {};
4922          expanID++;
4923          ownerDocument[expando] = expanID;
4924          expandoData[expanID] = data;
4925        }
4926        return data;
4927      }
4928
4929      /**
4930       * returns a shived element for the given nodeName and document
4931       * @memberOf html5
4932       * @param {String}
vendor: 4,418 bytes, lines 4932-5043
4932 nodeName name of the element
4933       * @param {Document|DocumentFragment} ownerDocument The context document.
4934       * @returns {Object} The shived element.
4935       */
4936      function createElement(nodeName, ownerDocument, data){
4937        if (!ownerDocument) {
4938          ownerDocument = document;
4939        }
4940        if(supportsUnknownElements){
4941          return ownerDocument.createElement(nodeName);
4942        }
4943        if (!data) {
4944          data = getExpandoData(ownerDocument);
4945        }
4946        var node;
4947
4948        if (data.cache[nodeName]) {
4949          node = data.cache[nodeName].cloneNode();
4950        } else if (saveClones.test(nodeName)) {
4951          node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
4952        } else {
4953          node = data.createElem(nodeName);
4954        }
4955
4956        // Avoid adding some elements to fragments in IE < 9 because
4957        // * Attributes like `name` or `type` cannot be set/changed once an element
4958        //   is inserted into a document/fragment
4959        // * Link elements with `src` attributes that are inaccessible, as with
4960        //   a 403 response, will cause the tab/window to crash
4961        // * Script elements appended to fragments will execute when their `src`
4962        //   or `text` property is set
4963        return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
4964      }
4965
4966      /**
4967       * returns a shived DocumentFragment for the given document
4968       * @memberOf html5
4969       * @param {Document} ownerDocument The context document.
4970       * @returns {Object} The shived DocumentFragment.
4971       */
4972      function createDocumentFragment(ownerDocument, data){
4973        if (!ownerDocument) {
4974          ownerDocument = document;
4975        }
4976        if(supportsUnknownElements){
4977          return ownerDocument.createDocumentFragment();
4978        }
4979        data = data || getExpandoData(ownerDocument);
4980        var clone = data.frag.cloneNode(),
4981          i = 0,
4982          elems = getElements(),
4983          l = elems.length;
4984        for(;i<l;i++){
4985          clone.createElement(elems[i]);
4986        }
4987        return clone;
4988      }
4989
4990      /**
4991       * Shivs the `createElement` and `createDocumentFragment` methods of the document.
4992       * @private
4993       * @param {Document|DocumentFragment} ownerDocument The document.
4994       * @param {Object} data of the document.
4995       */
4996      function shivMethods(ownerDocument, data) {
4997        if (!data.cache) {
4998          data.cache = {};
4999          data.createElem = ownerDocument.createElement;
5000          data.createFrag = ownerDocument.createDocumentFragment;
5001          data.frag = data.createFrag();
5002        }
5003
5004
5005        ownerDocument.createElement = function(nodeName) {
5006          //abort shiv
5007          if (!html5.shivMethods) {
5008            return data.createElem(nodeName);
5009          }
5010          return createElement(nodeName, ownerDocument, data);
5011        };
5012
5013        ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
5014                                                        'var n=f.cloneNode(),c=n.createElement;' +
5015                                                        'h.shivMethods&&(' +
5016                                                        // unroll the `createElement` calls
5017                                                        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
5018          data.createElem(nodeName);
5019          data.frag.createElement(nodeName);
5020          return 'c("' + nodeName + '")';
5021        }) +
5022          ');return n}'
5023                                                       )(html5, data.frag);
5024      }
5025
5026      /*--------------------------------------------------------------------------*/
5027
5028      /**
5029       * Shivs the given document.
5030       * @memberOf html5
5031       * @param {Document} ownerDocument The document to shiv.
5032       * @returns {Document} The shived document.
5033       */
5034      function shivDocument(ownerDocument) {
5035        if (!ownerDocument) {
5036          ownerDocument = document;
5037        }
5038        var data = getExpandoData(ownerDocument);
5039
5040        if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
5041          data.hasCSS = !!addStyleSheet(ownerDocument,
5042                                        // corrects block display not defined in IE6/7/8/9
5043                                        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
5043play:block}' +
5044                                        // adds styling not present in IE6/7/8/9
5045                                        'mark{background:#FF0;color:#000}' +
5046                                        // hides non-rendered elements
5047                                        'template{display:none}'
5048                                       );
5049        }
5050        if (!supportsUnknownElements) {
5051          shivMethods(ownerDocument, data);
5052        }
5053        return ownerDocument;
5054      }
5055
5056      /*--------------------------------------------------------------------------*/
5057
5058      /**
5059       * The `html5` object is exposed so that more elements can be shived and
5060       * existing shiving can be detected on iframes.
5061       * @type Object
5062       * @example
5063       *
5064       * // options can be changed before the script is included
5065       * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
5066       */
5067      var html5 = {
5068
5069        /**
5070         * An array or space separated string of node names of the elements to shiv.
5071         * @memberOf html5
5072         * @type Array|String
5073         */
5074        'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
5075
5076        /**
5077         * current version of html5shiv
5078         */
5079        'version': version,
5080
5081        /**
5082         * A flag to indicate that the HTML5 style sheet should be inserted.
5083         * @memberOf html5
5084         * @type Boolean
5085         */
5086        'shivCSS': (options.shivCSS !== false),
5087
5088        /**
5089         * Is equal to true if a browser supports creating unknown/HTML5 elements
5090         * @memberOf html5
5091         * @type boolean
5092         */
5093        'supportsUnknownElements': supportsUnknownElements,
5094
5095        /**
5096         * A flag to indicate that the document's `createElement` and `createDocumentFragment`
5097         * methods should be overwritten.
5098         * @memberOf html5
5099         * @type Boolean
5100         */
5101        'shivMethods': (options.shivMethods !== false),
5102
5103        /**
5104         * A string to describe the type of `html5` object ("default" or "default print").
5105         * @memberOf html5
5106         * @type String
5107         */
5108        'type': 'default',
5109
5110        // shivs the document according to the specified `html5` object options
5111        'shivDocument': shivDocument,
5112
5113        //creates a shived element
5114        createElement: createElement,
5115
5116        //creates a shived documentFragment
5117        createDocumentFragment: createDocumentFragment,
5118
5119        //extends list of elements
5120        addElements: addElements
5121      };
5122
5123      /*--------------------------------------------------------------------------*/
5124
5125      // expose html5
5126      window.html5 = html5;
5127
5128      // shiv the document
5129      shivDocument(document);
5130
5131      if(typeof module == 'object' && module.exports){
5132        module.exports = html5;
5133      }
5134
5135    }(typeof window !== "undefined" ? window : this, document));
5136  }
5137;
5138
5139  /**
5140   * If the browsers follow the spec, then they would expose vendor-specific style as:
5141   *   elem.style.WebkitBorderRadius
5142   * instead of something like the following, which would be technically incorrect:
5143   *   elem.style.webkitBorderRadius
5144
5145   * Webkit ghosts their properties in lowercase but Opera & Moz do not.
5146   * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
5147   *   erik.eae.net/archives/2008/03/10/21.48.10/
5148
5149   * More here: github.com/Modernizr/Modernizr/issues/issue/21
5150   *
5151   * @access private
5152   * @returns {string} The string representing the vendor-specific style properties
5153   */
5154
5155  var omPrefixes = 'Moz O ms Webkit';
5156  
5157
5158  /**
5159   * List of JavaScript DOM values used for tests
5160   *
5161   * @memberof Modernizr
5162   * @name Modernizr._domPrefixes
5163   * @optionName Modernizr._domPrefixes
5164   * @optionProp domPrefixes
5165   * @access public
5166   * @example
5167   *
5168   * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather
5169   * than kebab-case properties, all properties are their Capitalized variant
5170   *
5171   * ```js
5172   * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ];
5173   * ```
5174   */
5175
5176  var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);
5177  ModernizrProto._domPrefixes = domPrefixes;
5178  
5179
5180  /**
5181   * cssToDOM takes a kebab-case string and converts it to camelCase
5182   * e.g. box-sizing -> boxSizing
5183   *
5184   * @access private
5185   * @function cssToDOM
5186   * @param {string} name - String name of kebab-case prop we want to convert
5187   * @returns {string} The camelCase version of the supplied name
5188   */
5189
5190  function cssToDOM(name) {
5191    return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
5192      return m1 + m2.toUpperCase();
5193    }).replace(/^-/, '');
5194  }
5195  ;
5196
5197  var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
5198  ModernizrProto._cssomPrefixes = cssomPrefixes;
5199  
5200
5201  /**
5202   * atRule returns a given CSS property at-rule (eg @keyframes), possibly in
5203   * some prefixed form, or false, in the case of an unsupported rule
5204   *
5205   * @memberof Modernizr
5206   * @name Modernizr.atRule
5207   * @optionName Modernizr.atRule()
5208   * @optionProp atRule
5209   * @access public
5210   * @function atRule
5211   * @param {string} prop - String name of the @-rule to test for
5212   * @returns {string|boolean} The string representing the (possibly prefixed)
5213   * valid version of the @-rule, or `false` when it is unsupported.
5214   * @example
5215   * ```js
5216   *  var keyframes = Modernizr.atRule('@keyframes');
5217   *
5218   *  if (keyframes) {
5219   *    // keyframes are supported
5220   *    // could be `@-webkit-keyframes` or `@keyframes`
5221   *  } else {
5222   *    // keyframes === `false`
5223   *  }
5224   * ```
5225   *
5226   */
5227
5228  var atRule = function(prop) {
5229    var length = prefixes.length;
5230    var cssrule = window.CSSRule;
5231    var rule;
5232
5233    if (typeof cssrule === 'undefined') {
5234      return undefined;
5235    }
5236
5237    if (!prop) {
5238      return false;
5239    }
5240
5241    // remove literal @ from beginning of provided property
5242    prop = prop.replace(/^@/, '');
5243
5244    // CSSRules use underscores instead of dashes
5245    rule = prop.replace(/-/g, '_').toUpperCase() + '_RULE';
5246
5247    if (rule in cssrule) {
5248      return '@' + prop;
5249    }
5250
5251    for (var i = 0; i < length; i++) {
5252      // prefixes gives us something like -o-, and we want O_
5253      var prefix = prefixes[i];
5254      var thisRule = prefix.toUpperCase() + '_' + rule;
5255
5256      if (thisRule in cssrule) {
5257        return '@-' + prefix.toLowerCase() + '-' + prop;
5258      }
5259    }
5260
5261    return false;
5262  };
5263
5264  ModernizrProto.atRule = atRule;
5265
5266  
5267
5268
5269  /**
5270   * contains checks to see if a string contains another string
5271   *
5272   * @access private
5273   * @function contains
5274   * @param {string} str - The string we want to check for substrings
5275   * @param {string} substr - The substring we want to search the first string for
5276   * @returns {boolean}
5277   */
5278
5279  function contains(str, substr) {
5280    return !!~('' + str).indexOf(substr);
5281  }
5282
5283  ;
5284
5285  /**
5286   * createElement is a convenience wrapper around document.createElement. Since we
5287   * use createElement all over the place, this allows for (slightly) smaller code
5288   * as well as abstracting away issues with creating elements in contexts other than
5289   * HTML documents (e.g. SVG documents).
5290   *
5291   * @access private
5292   * @function createElement
5293   * @returns {HTMLElement|SVGElement} An HTML or SVG element
5294   */
5295
5296  function createElement() {
5297    if (typeof document.createElement !== 'function') {
5298      // This is the case in IE7, where the type of createElement is "object".
5299      // For this reason, we cannot call apply() as Object is not a Function.
5300      return document.createElement(arguments[0]);
5301    } else if (isSVG) {
5302      return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);
5303    } else {
5304      return document.createElement.apply(document, arguments);
5305    }
5306  }
5307
5308  ;
5309
5310  /**
5311   * getBody returns the body of a document, or an element that can stand in for
5312   * the body if a real body does not exist
5313   *
5314   * @access private
5315   * @function getBody
5316   * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an
5317   * artificially created element that stands in for the body
5318   */
5319
5320  function getBody() {
5321    // After page load injecting a fake body doesn't work so check if body exists
5322    var body = document.body;
5323
5324    if (!body) {
5325      // Can't use the real body create a fake one.
5326      body = createElement(isSVG ? 'svg' : 'body');
5327      body.fake = true;
5328    }
5329
5330    return body;
5331  }
5332
5333  ;
5334
5335  /**
5336   * injectElementWithStyles injects an element with style element and some CSS rules
5337   *
5338   * @access private
5339   * @function injectElementWithStyles
5340   * @param {string} rule - String representing a css rule
5341   * @param {function} callback - A function that is used to test the injected element
5342   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
5343   * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
5344   * @returns {boolean}
5345   */
5346
5347  function injectElementWithStyles(rule, callback, nodes, testnames) {
5348    var mod = 'modernizr';
5349    var style;
5350    var ret;
5351    var node;
5352    var docOverflow;
5353    var div = createElement('div');
5354    var body = getBody();
5355
5356    if (parseInt(nodes, 10)) {
5357      // In order not to give false positives we create a node for each test
5358      // This also allows the method to scale for unspecified uses
5359      while (nodes--) {
5360        node = createElement('div');
5361        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
5362        div.appendChild(node);
5363      }
5364    }
5365
5366    style = createElement('style');
5367    style.type = 'text/css';
5368    style.id = 's' + mod;
5369
5370    // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
5371    // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
5372    (!body.fake ? div : body).appendChild(style);
5373    body.appendChild(div);
5374
5375    if (style.styleSheet) {
5376      style.styleSheet.cssText = rule;
5377    } else {
5378      style.appendChild(document.createTextNode(rule));
5379    }
5380    div.id = mod;
5381
5382    if (body.fake) {
5383      //avoid crashing IE8, if background image is used
5384      body.style.background = '';
5385      //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
5386      body.style.overflow = 'hidden';
5387      docOverflow = docElement.style.overflow;
5388      docElement.style.overflow = 'hidden';
5389      docElement.appendChild(body);
5390    }
5391
5392    ret = callback(div, rule);
5393    // If this is done after page load we don't want to remove the body so check if body exists
5394    if (body.fake) {
5395      body.parentNode.removeChild(body);
5396      docElement.style.overflow = docOverflow;
5397      // Trigger layout so kinetic scrolling isn't disabled in iOS6+
5398      docElement.offsetHeight;
5399    } else {
5400      div.parentNode.removeChild(div);
5401    }
5402
5403    return !!ret;
5404
5405  }
5406
5407  ;
5408
5409  /**
5410   * testStyles injects an element with style element and some CSS rules
5411   *
5412   * @memberof Modernizr
5413   * @name Modernizr.testStyles
5414   * @optionName Modernizr.testStyles()
5415   * @optionProp testStyles
5416   * @access public
5417   * @function testStyles
5418   * @param {string} rule - String representing a css rule
5419   * @param {function} callback - A function that is used to test the injected element
5420   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
5421   * @param {string[]}
5421 [testnames] - An array of strings that are used as ids for the additional nodes
5422   * @returns {boolean}
5423   * @example
5424   *
5425   * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page
5426   * along with (possibly multiple) DOM elements. This lets you check for features
5427   * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules).
5428   *
5429   * ```js
5430   * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) {
5431   *   // elem is the first DOM node in the page (by default #modernizr)
5432   *   // rule is the first argument you supplied - the CSS rule in string form
5433   *
5434   *   addTest('widthworks', elem.style.width === '9px')
5435   * });
5436   * ```
5437   *
5438   * If your test requires multiple nodes, you can include a third argument
5439   * indicating how many additional div elements to include on the page. The
5440   * additional nodes are injected as children of the `elem` that is returned as
5441   * the first argument to the callback.
5442   *
5443   * ```js
5444   * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) {
5445   *   document.getElementById('modernizr').style.width === '1px'; // true
5446   *   document.getElementById('modernizr2').style.width === '2px'; // true
5447   *   elem.firstChild === document.getElementById('modernizr2'); // true
5448   * }, 1);
5449   * ```
5450   *
5451   * By default, all of the additional elements have an ID of `modernizr[n]`, where
5452   * `n` is its index (e.g. the first additional, second overall is `#modernizr2`,
5453   * the second additional is `#modernizr3`, etc.).
5454   * If you want to have more meaningful IDs for your function, you can provide
5455   * them as the fourth argument, as an array of strings
5456   *
5457   * ```js
5458   * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) {
5459   *   elem.firstChild === document.getElementById('foo'); // true
5460   *   elem.lastChild === document.getElementById('bar'); // true
5461   * }, 2, ['foo', 'bar']);
5462   * ```
5463   *
5464   */
5465
5466  var testStyles = ModernizrProto.testStyles = injectElementWithStyles;
5467  
5468
5469  /**
5470   * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.
5471   *
5472   * @access private
5473   * @function fnBind
5474   * @param {function} fn - a function you want to change `this` reference to
5475   * @param {object} that - the `this` you want to call the function with
5476   * @returns {function} The wrapped version of the supplied function
5477   */
5478
5479  function fnBind(fn, that) {
5480    return function() {
5481      return fn.apply(that, arguments);
5482    };
5483  }
5484
5485  ;
5486
5487  /**
5488   * testDOMProps is a generic DOM property test; if a browser supports
5489   *   a certain property, it won't return undefined for it.
5490   *
5491   * @access private
5492   * @function testDOMProps
5493   * @param {array.<string>} props - An array of properties to test for
5494   * @param {object} obj - An object or Element you want to use to test the parameters again
5495   * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check
5496   */
5497  function testDOMProps(props, obj, elem) {
5498    var item;
5499
5500    for (var i in props) {
5501      if (props[i] in obj) {
5502
5503        // return the property name as a string
5504        if (elem === false) {
5505          return props[i];
5506        }
5507
5508        item = obj[props[i]];
5509
5510        // let's bind a function
5511        if (is(item, 'function')) {
5512          // bind to obj unless overriden
5513          return fnBind(item, elem || obj);
5514        }
5515
5516        // return the unbound function or obj or value
5517        return item;
5518      }
5519    }
5520    return false;
5521  }
5522
5523  ;
5524
5525  /**
5526   * Create our "modernizr" element that we do most feature tests on.
5527   *
5528   * @access private
5529   */
5530
5531  var modElem = {
5532    elem: createElement('modernizr')
5533  };
5534
5535  // Clean up this element
5536  Modernizr._q.push(function() {
5537    delete modElem.elem;
5538  });
5539
5540  
5541
5542  var mStyle = {
5543    style: modElem.elem.style
5544  };
5545
5546  // kill ref for gc, must happen before mod.elem is removed, so we unshift on to
5547  // the front of the queue.
5548  Modernizr._q.unshift(function() {
5549    delete mStyle.style;
5550  });
5551
5552  
5553
5554  /**
5555   * domToCSS takes a camelCase string and converts it to kebab-case
5556   * e.g. boxSizing -> box-sizing
5557   *
5558   * @access private
5559   * @function domToCSS
5560   * @param {string} name - String name of camelCase prop we want to convert
5561   * @returns {string} The kebab-case version of the supplied name
5562   */
5563
5564  function domToCSS(name) {
5565    return name.replace(/([A-Z])/g, function(str, m1) {
5566      return '-' + m1.toLowerCase();
5567    }).replace(/^ms-/, '-ms-');
5568  }
5569  ;
5570
5571  /**
5572   * nativeTestProps allows for us to use native feature detection functionality if available.
5573   * some prefixed form, or false, in the case of an unsupported rule
5574   *
5575   * @access private
5576   * @function nativeTestProps
5577   * @param {array} props - An array of property names
5578   * @param {string} value - A string representing the value we want to check via @supports
5579   * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise
5580   */
5581
5582  // Accepts a list of property names and a single value
5583  // Returns `undefined` if native detection not available
5584  function nativeTestProps(props, value) {
5585    var i = props.length;
5586    // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
5587    if ('CSS' in window && 'supports' in window.CSS) {
5588      // Try every prefixed variant of the property
5589      while (i--) {
5590        if (window.CSS.supports(domToCSS(props[i]), value)) {
5591          return true;
5592        }
5593      }
5594      return false;
5595    }
5596    // Otherwise fall back to at-rule (for Opera 12.x)
5597    else if ('CSSSupportsRule' in window) {
5598      // Build a condition string for every prefixed variant
5599      var conditionText = [];
5600      while (i--) {
5601        conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
5602      }
5603      conditionText = conditionText.join(' or ');
5604      return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {
5605        return getComputedStyle(node, null).position == 'absolute';
5606      });
5607    }
5608    return undefined;
5609  }
5610  ;
5611
5612  // testProps is a generic CSS / DOM property test.
5613
5614  // In testing support for a given CSS property, it's legit to test:
5615  //    `elem.style[styleName] !== undefined`
5616  // If the property is supported it will return an empty string,
5617  // if unsupported it will return undefined.
5618
5619  // We'll take advantage of this quick test and skip setting a style
5620  // on our modernizr element, but instead just testing undefined vs
5621  // empty string.
5622
5623  // Property names can be provided in either camelCase or kebab-case.
5624
5625  function testProps(props, prefixed, value, skipValueTest) {
5626    skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;
5627
5628    // Try native detect first
5629    if (!is(value, 'undefined')) {
5630      var result = nativeTestProps(props, value);
5631      if (!is(result, 'undefined')) {
5632        return result;
5633      }
5634    }
5635
5636    // Otherwise do it properly
5637    var afterInit, i, propsLength, prop, before;
5638
5639    // If we don't have a style element, that means we're running async or after
5640    // the core tests, so we'll need to create our own elements to use
5641
5642    // inside of an SVG element, in certain browsers, the `style` element is only
5643    // defined for valid tags. Therefore, if `modernizr` does not have one, we
5644    // fall back to a less used element and hope for the best.
5645    // for strict XHTML browsers the hardly used samp element is used
5646    var elems = ['modernizr', 'tspan', 'samp'];
5647    while (!mStyle.style && elems.length) {
5648      afterInit = true;
5649      mStyle.modElem = createElement(elems.shift());
5650      mStyle.style = mStyle.modElem.style;
5651    }
5652
5653    // Delete the objects if we created them.
5654    function cleanElems() {
5655      if (afterInit) {
5656        delete mStyle.style;
5657        delete mStyle.modElem;
5658      }
5659    }
5660
5661    propsLength = props.length;
5662    for (i = 0; i < propsLength; i++) {
5663      prop = props[i];
5664      before = mStyle.style[prop];
5665
5666      if (contains(prop, '-')) {
5667        prop = cssToDOM(prop);
5668      }
5669
5670      if (mStyle.style[prop] !== undefined) {
5671
5672        // If value to test has been passed in, do a set-and-check test.
5673        // 0 (integer) is a valid property value, so check that `value` isn't
5674        // undefined, rather than just checking it's truthy.
5675        if (!skipValueTest && !is(value, 'undefined')) {
5676
5677          // Needs a try catch block because of old IE. This is slow, but will
5678          // be avoided in most cases because `skipValueTest` will be used.
5679          try {
5680            mStyle.style[prop] = value;
5681          } catch (e) {}
5682
5683          // If the property value has changed, we assume the value used is
5684          // supported. If `value` is empty string, it'll fail here (because
5685          // it hasn't changed), which matches how browsers have implemented
5686          // CSS.supports()
5687          if (mStyle.style[prop] != before) {
5688            cleanElems();
5689            return prefixed == 'pfx' ? prop : true;
5690          }
5691        }
5692        // Otherwise just return true, or the property name if this is a
5693        // `prefixed()` call
5694        else {
5695          cleanElems();
5696          return prefixed == 'pfx' ? prop : true;
5697        }
5698      }
5699    }
5700    cleanElems();
5701    return false;
5702  }
5703
5704  ;
5705
5706  /**
5707   * testProp() investigates whether a given style property is recognized
5708   * Property names can be provided in either camelCase or kebab-case.
5709   *
5710   * @memberof Modernizr
5711   * @name Modernizr.testProp
5712   * @access public
5713   * @optionName Modernizr.testProp()
5714   * @optionProp testProp
5715   * @function testProp
5716   * @param {string} prop - Name of the CSS property to check
5717   * @param {string} [value] - Name of the CSS value to check
5718   * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported
5719   * @returns {boolean}
5720   * @example
5721   *
5722   * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed
5723   * version of the string.
5724   *
5725   * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing)
5726   *
5727   * ```js
5728   * Modernizr.testProp('pointerEvents')  // true
5729   * ```
5730   *
5731   * You can also provide a value as an optional second argument to check if a
5732   * specific value is supported
5733   *
5734   * ```js
5735   * Modernizr.testProp('pointerEvents', 'none') // true
5736   * Modernizr.testProp('pointerEvents', 'penguin') // false
5737   * ```
5738   */
5739
5740  var testProp = ModernizrProto.testProp = function(prop, value, useValue) {
5741    return testProps([prop], undefined, value, useValue);
5742  };
5743  
5744
5745  /**
5746   * testPropsAll tests a list of DOM properties we want to check against.
5747   * We specify literally ALL possible (known and/or likely) properties on
5748   * the element including the non-vendor prefixed one, for forward-
5749   * compatibility.
5750   *
5751   * @access private
5752   * @function testPropsAll
5753   * @param {string} prop - A string of the property to test for
5754   * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip
5755   * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against
5756   * @param {string} [value] - A string of a css value
5757   * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set
5758   */
5759  function testPropsAll(prop, prefixed, elem, value, skipValueTest) {
5760
5761    var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
5762    props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
5763
5764    // did they call .prefixed('boxSizing') or are we just testing a prop?
5765    if (is(prefixed, 'string') || is(prefixed, 'undefined')) {
5766      return testProps(props, prefixed, value, skipValueTest);
5767
5768      // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
5769    } else {
5770      props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
5771      return testDOMProps(props, prefixed, elem);
5772    }
5773  }
5774
5775  // Modernizr.testAllProps() investigates whether a given style property,
5776  // or any of its vendor-prefixed variants, is recognized
5777  //
5778  // Note that the property names must be provided in the camelCase variant.
5779  // Modernizr.testAllProps('boxSizing')
5780  ModernizrProto.testAllProps = testPropsAll;
5781
5782  
5783
5784  /**
5785   * prefixed returns the prefixed or nonprefixed property name variant of your input
5786   *
5787   * @memberof Modernizr
5788   * @name Modernizr.prefixed
5789   * @optionName Modernizr.prefixed()
5790   * @optionProp prefixed
5791   * @access public
5792   * @function prefixed
5793   * @param {string} prop - String name of the property to test for
5794   * @param {object} [obj] - An object to test for the prefixed properties on
5795   * @param {HTMLElement} [elem] - An element used to test specific properties against
5796   * @returns {string|false} The string representing the (possibly prefixed) valid
5797   * version of the property, or `false` when it is unsupported.
5798   * @example
5799   *
5800   * Modernizr.prefixed takes a string css value in the DOM style camelCase (as
5801   * opposed to the css style kebab-case) form and returns the (possibly prefixed)
5802   * version of that property that the browser actually supports.
5803   *
5804   * For example, in older Firefox...
5805   * ```js
5806   * prefixed('boxSizing')
5807   * ```
5808   * returns 'MozBoxSizing'
5809   *
5810   * In newer Firefox, as well as any other browser that support the unprefixed
5811   * version would simply return `boxSizing`. Any browser that does not support
5812   * the property at all, it will return `false`.
5813   *
5814   * By default, prefixed is checked against a DOM element. If you want to check
5815   * for a property on another object, just pass it as a second argument
5816   *
5817   * ```js
5818   * var rAF = prefixed('requestAnimationFrame', window);
5819   *
5820   * raf(function() {
5821   *  renderFunction();
5822   * })
5823   * ```
5824   *
5825   * Note that this will return _the actual function_ - not the name of the function.
5826   * If you need the actual name of the property, pass in `false` as a third argument
5827   *
5828   * ```js
5829   * var rAFProp = prefixed('requestAnimationFrame', window, false);
5830   *
5831   * rafProp === 'WebkitRequestAnimationFrame' // in older webkit
5832   * ```
5833   *
5834   * One common use case for prefixed is if you're trying to determine which transition
5835   * end event to bind to, you might do something like...
5836   * ```js
5837   * var transEndEventNames = {
5838   *     'WebkitTransition' : 'webkitTransitionEnd', * Saf 6, Android Browser
5839   *     'MozTransition'    : 'transitionend',       * only for FF < 15
5840   *     'transition'       : 'transitionend'        * IE10, Opera, Chrome, FF 15+, Saf 7+
5841   * };
5842   *
5843   * var transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
5844   * ```
5845   *
5846   * If you want a similar lookup, but in kebab-case, you can use [prefixedCSS](#modernizr-prefixedcss).
5847   */
5848
5849  var prefixed = ModernizrProto.prefixed = function(prop, obj, elem) {
5850    if (prop.indexOf('@') === 0) {
5851      return atRule(prop);
5852    }
5853
5854    if (prop.indexOf('-') != -1) {
5855      // Convert kebab-case to camelCase
5856      prop = cssToDOM(prop);
5857    }
5858    if (!obj) {
5859      return testPropsAll(prop, 'pfx');
5860    } else {
5861      // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
5862      return testPropsAll(prop, obj, elem);
5863    }
5864  };
5865
5866  
5867
5868  /**
5869   * testAllProps determines whether a given CSS property is supported in the browser
5870   *
5871   * @memberof Modernizr
5872   * @name Modernizr.testAllProps
5873   * @optionName Modernizr.testAllProps()
5874   * @optionProp testAllProps
5875   * @access public
5876   * @function testAllProps
5877   * @param {string} prop - String naming the property to test (either camelCase or kebab-case)
5878   * @param {string} [value] - String of the value to test
5879   * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection
5880   * @example
5881   *
5882   * testAllProps determines whether a given CSS property, in some prefixed form,
5883   * is supported by the browser.
5884   *
5885   * ```js
5886   * testAllProps('boxSizing')  // true
5887   * ```
5888   *
5889   * It can optionally be given a CSS value in string form to test if a property
5890   * value is valid
5891   *
5892   * ```js
5893   * testAllProps('display', 'block') // true
5894   * testAllProps('display', 'penguin') // false
5895   * ```
5896   *
5897   * A boolean can be passed as a third parameter to skip the value check when
5898   * native detection (@supports) isn't available.
5899   *
5900   * ```js
5901   * testAllProps('shapeOutside', 'content-box', true);
5902   * ```
5903   */
5904
5905  function testAllProps(prop, value, skipValueTest) {
5906    return testPropsAll(prop, undefined, undefined, value, skipValueTest);
5907  }
5908  ModernizrProto.testAllProps = testAllProps;
5909  
5910/*!
5911{
5912  "name": "CSS Animations",
5913  "property": "cssanimations",
5914  "caniuse": "css-animation",
5915  "polyfills": ["transformie", "csssandpaper"],
5916  "tags": ["css"],
5917  "warnings": ["Android < 4 will pass this test, but can only animate a single property at a time"],
5918  "notes": [{
5919    "name" : "Article: 'Dispelling the Android CSS animation myths'",
5920    "href": "https://goo.gl/OGw5Gm"
5921  }]
5922}
5923!*/
5924/* DOC
5925Detects whether or not elements can be animated using CSS
5926*/
5927
5928  Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true));
5929
5930/*!
5931{
5932  "name": "CSS Transitions",
5933  "property": "csstransitions",
5934  "caniuse": "css-transitions",
5935  "tags": ["css"]
5936}
5937!*/
5938
5939  Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true));
5940
5941/*!
5942{
5943  "name": "Touch Events",
5944  "property": "touchevents",
5945  "caniuse" : "touch",
5946  "tags": ["media", "attribute"],
5947  "notes": [{
5948    "name": "Touch Events spec",
5949    "href": "https://www.w3.org/TR/2013/WD-touch-events-20130124/"
5950  }],
5951  "warnings": [
5952    "Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device"
5953  ],
5954  "knownBugs": [
5955    "False-positive on some configurations of Nokia N900",
5956    "False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695"
5957  ]
5958}
5959!*/
5960/* DOC
5961Indicates if the browser supports the W3C Touch Events API.
5962
5963This *does not* necessarily reflect a touchscreen device:
5964
5965* Older touchscreen devices only emulate mouse events
5966* Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that
5967* Some browsers & OS setups may enable touch APIs when no touchscreen is connected
5968* Future browsers may implement other event models for touch interactions
5969
5970See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/).
5971
5972It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](http://www.html5rocks.com/en/mobile/touchandmouse/).
5973
5974This test will also return `true` for Firefox 4 Multitouch support.
5975*/
5976
5977  // Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415
5978  Modernizr.addTest('touchevents', function() {
5979    var bool;
5980    if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
5981      bool = true;
5982    } else {
5983      // include the 'heartz' as a way to have a non matching MQ to help terminate the join
5984      // https://git.io/vznFH
5985      var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#modernizr{top:9px;position:absolute}}'].join('');
5986      testStyles(query, function(node) {
5987        bool = node.offsetTop === 9;
5988      });
5989    }
5990    return bool;
5991  });
5992
5993
5994  // Run each test
5995  testRunner();
5996
5997  // Remove the "no-js" class if it exists
5998  setClasses(classes);
5999
6000  delete ModernizrProto.addTest;
6001  delete ModernizrProto.addAsyncTest;
6002
6003  // Run the things that are supposed to run after the tests
6004  for (var i = 0; i < Modernizr._q.length; i++) {
6005    Modernizr._q[i]();
6006  }
6007
6008  // Leak Modernizr namespace
6009  window.Modernizr = Modernizr;
6010
6011
6012;
6013
6014})(window, document);
6015$(function() {
6016    ParallaxScroll.init();
6017});
6018
6019// Credit: https://github.com/alumbo/jquery.parallax-scroll
6020var ParallaxScroll = {
6021    /* PUBLIC VARIABLES */
6022    showLogs: false,
6023    round: 1000,
6024
6025    /* PUBLIC FUNCTIONS */
6026    init: function() {
6027        this._log("init");
6028        if (this._inited) {
6029            this._log("Already Inited");
6030            this._inited = true;
6031            return;
6032        }
6033        this._requestAnimationFrame = (function(){
6034          return  window.requestAnimationFrame       || 
6035                  window.webkitRequestAnimationFrame || 
6036                  window.mozRequestAnimationFrame    || 
6037                  window.oRequestAnimationFrame      || 
6038                  window.msRequestAnimationFrame     || 
6039                  function(/* function */ callback, /* DOMElement */ element){
6040                      window.setTimeout(callback, 1000 / 60);
6041                  };
6042        })();
6043        this._onScroll(true);
6044    },
6045
6046    /* PRIVATE VARIABLES */
6047    _inited: false,
6048    _properties: ['x', 'y', 'z', 'rotateX', 'rotateY', 'rotateZ', 'scaleX', 'scaleY', 'scaleZ', 'scale'],
6049    _requestAnimationFrame:null,
6050
6051    /* PRIVATE FUNCTIONS */
6052    _log: function(message) {
6053        if (this.showLogs) console.log("Parallax Scroll / " + message);
6054    },
6055    _onScroll: function(noSmooth) {
6056        var scroll = $(document).scrollTop();
6057        var windowHeight = $(window).height();
6058        this._log("onScroll " + scroll);
6059        $("[data-parallax]").each($.proxy(function(index, el) {
6060            var $el = $(el);
6061            var properties = [];
6062            var applyProperties = false;
6063            var style = $el.data("style");
6064            if (style == undefined) {
6065                style = $el.attr("style") || "";
6066                $el.data("style", style);
6067            }
6068            var datas = [$el.data("parallax")];
6069            var iData;
6070            for(iData = 2; ; iData++) {
6071                if($el.data("parallax"+iData)) {
6072                    datas.push($el.data("parallax-"+iData));
6073                }
6074                else {
6075                    break;
6076                }
6077            }
6078            var datasLength = datas.length;
6079            for(iData = 0; iData < datasLength; iData ++) {
6080                var data = datas[iData];
6081                var scrollFrom = data["from-scroll"];
6082                if (scrollFrom == undefined) scrollFrom = Math.max(0, $(el).offset().top - windowHeight);
6083                scrollFrom = scrollFrom | 0;
6084                var scrollDistance = data["distance"];
6085                var scrollTo = data["to-scroll"];
6086                if (scrollDistance == undefined && scrollTo == undefined) scrollDistance = windowHeight;
6087                scrollDistance = Math.max(scrollDistance | 0, 1);
6088                var easing = data["easing"];
6089                var easingReturn = data["easing-return"];
6090                if (easing == undefined || !$.easing|| !$.easing[easing]) easing = null;
6091                if (easingReturn == undefined || !$.easing|| !$.easing[easingReturn]) easingReturn = easing;
6092                if (easing) {
6093                    var totalTime = data["duration"];
6094                    if (totalTime == undefined) totalTime = scrollDistance;
6095                    totalTime = Math.max(totalTime | 0, 1);
6096                    var totalTimeReturn = data["duration-return"];
6097                    if (totalTimeReturn == undefined) totalTimeReturn = totalTime;
6098                    scrollDistance = 1;
6099                    var currentTime = $el.data("current-time");
6100                    if(currentTime == undefined) currentTime = 0;
6101                }
6102                if (scrollTo == undefined) scrollTo = scrollFrom + scrollDistance;
6103                scrollTo = scrollTo | 0;
6104                var smoothness = data["smoothness"];
6105                if (smoothness == undefined) smoothness = 30;
6106                smoothness = smoothness | 0;
6107                if (noSmooth || smoothness == 0) smoothness = 1;
6108                smoothness = smoothness | 0;
6109                var scrollCurrent = scroll;
6110                scrollCurrent = Math.max(scrollCurrent, scrollFrom);
6111                scrollCurrent = Math.min(scrollCurrent, scrollTo);
6112                if(easing) {
6113                    if($el.data("sens") == undefined) $el.data("sens", "back");
6114                    if(scrollCurrent>scrollFrom) {
6115                        if($el.data("sens") == "back") {
6116                            currentTime = 1;
6117                            $el.data("sens", "go");
6118                        }
6119                        else {
6120                            currentTime++;
6121                        }
6122                    }
6123                    if(scrollCurrent<scrollTo) {
6124                        if($el.data("sens") == "go") {
6125                            currentTime = 1;
6126                            $el.data("sens", "back");
6127                        }
6128                        else {
6129                            currentTime++;
6130                        }
6131                    }
6132                    if(noSmooth) currentTime = totalTime;
6133                    $el.data("current-time", currentTime);
6134                }
6135                this._properties.map($.proxy(function(prop) {
6136                    var defaultProp = 0;
6137                    var to = data[prop];
6138                    if (to == undefined) return;
6139                    if(prop=="scale" || prop=="scaleX" || prop=="scaleY" || prop=="scaleZ" ) {
6140                        defaultProp = 1;
6141                    }
6142                    else {
6143                        to = to | 0;
6144                    }
6145                    var prev = $el.data("_" + prop);
6146                    if (prev == undefined) prev = defaultProp;
6147                    var next = ((to-defaultProp) * ((scrollCurrent - scrollFrom) / (scrollTo - scrollFrom))) + defaultProp;
6148                    var val = prev + (next - prev) / smoothness;
6149                    if(easing && currentTime>0 && currentTime<=totalTime) {
6150                        var from = defaultProp;
6151                        if($el.data("sens") == "back") {
6152                            from = to;
6153                            to = -to;
6154                            easing = easingReturn;
6155                            totalTime = totalTimeReturn;
6156                        }
6157                        val = $.easing[easing](null, currentTime, from, to, totalTime);
6158                    }
6159                    val = Math.ceil(val * this.round) / this.round;
6160                    if(val==prev&&next==to) val = to;
6161                    if(!properties[prop]) properties[prop] = 0;
6162                    properties[prop] += val;
6163                    if (prev != properties[prop]) {
6164                        $el.data("_" + prop, properties[prop]);
6165                        applyProperties = true;
6166                    }
6167                }, this));
6168            }
6169            if (applyProperties) {
6170                if (properties["z"] != undefined) {
6171                    var perspective = data["perspective"];
6172                    if (perspective == undefined) perspective = 800;
6173                    var $parent = $el.parent();
6174                    if(!$parent.data("style")) $parent.data("style", $parent.attr("style") || "");
6175                    $parent.attr("style", "perspective:" + perspective + "px; -webkit-perspective:" + perspective + "px; "+ $parent.data("style"));
6176                }
6177                if(properties["scaleX"] == undefined) properties["scaleX"] = 1;
6178                if(properties["scaleY"] == undefined) properties["scaleY"] = 1;
6179                if(properties["scaleZ"] == undefined) properties["scaleZ"] = 1;
6180                if (properties["scale"] != undefined) {
6181                    properties["scaleX"] *= properties["scale"];
6182                    properties["scaleY"] *= properties["scale"];
6183                    properties["scaleZ"] *= properties["scale"];
6184                }
6185                var translate3d = "translate3d(" + (properties["x"] ? properties["x"] : 0) + "px, " + (properties["y"] ? properties["y"] : 0) + "px, " + (properties["z"] ? properties["z"] : 0) + "px)";
6186                var rotate3d = "rotateX(" + (properties["rotateX"] ? properties["rotateX"] : 0) + "deg) rotateY(" + (properties["rotateY"] ? properties["rotateY"] : 0) + "deg) rotateZ(" + (properties["rotateZ"] ? properties["rotateZ"] : 0) + "deg)";
6187                var scale3d = "scaleX(" + properties["scaleX"] + ") scaleY(" + properties["scaleY"] + ") scaleZ(" + properties["scaleZ"] + ")";
6188                var cssTransform = translate3d + " " + rotate3d + " " + scale3d + ";";
6189                this._log(cssTransform);
6190                $el.attr("style", "transform:" + cssTransform + " -webkit-transform:" + cssTransform + " " + style);
6191            }
6192        }, this));
6193        if(window.requestAnimationFrame) {
6194            window.requestAnimationFrame($.proxy(this._onScroll, this, false));
6195        }
6196        else {
6197            this._requestAnimationFrame($.proxy(this._onScroll, this, false));
6198        }
6199    }
6200};
6201;
6202(function($, window, undefined) {
6203
6204	'use strict';
6205
6206	// global
6207	var Modernizr = window.Modernizr,
6208		$body = $('body');
6209
6210	$.DLMenu = function(options, element) {
6211		this.$el = $(element);
6212		this._init(options);
6213	};
6214
6215	$.DLMenu.defaults = {
6216		animationClasses: {
6217			classin: 'mk-vm-animate-in-' + mk_vertical_header_anim,
6218			classout: 'mk-vm-animate-out-' + mk_vertical_header_anim
6219		},
6220		onLevelClick: function(el, name) {
6221			return false;
6222		},
6223		onLinkClick: function(el, ev) {
6224			return false;
6225		}
6226	};
6227
6228	$.DLMenu.prototype = {
6229		_init: function(options) {
6230
6231			this.options = $.extend(true, {}, $.DLMenu.defaults, options);
6232			this._config();
6233
6234			var animEndEventNames = {
6235					'WebkitAnimation': 'webkitAnimationEnd',
6236					'OAnimation': 'oAnimationEnd',
6237					'msAnimation': 'MSAnimationEnd',
6238					'animation': 'animationend'
6239				},
6240				transEndEventNames = {
6241					'WebkitTransition': 'webkitTransitionEnd',
6242					'MozTransition': 'transitionend',
6243					'OTransition': 'oTransitionEnd',
6244					'msTransition': 'MSTransitionEnd',
6245					'transition': 'transitionend'
6246				};
6247
6248			this.animEndEventName = animEndEventNames[Modernizr.prefixed('animation')] + '.dlmenu';
6249			this.transEndEventName = transEndEventNames[Modernizr.prefixed('transition')] + '.dlmenu';
6250
6251			this.animEndEventNameUnsufixed = animEndEventNames[Modernizr.prefixed('animation')];
6252			this.transEndEventNameUnsufixed = transEndEventNames[Modernizr.prefixed('transition')];
6253
6254			this.supportAnimations = Modernizr.cssanimations;
6255			this.supportTransitions = Modernizr.csstransitions;
6256
6257			this._initEvents();
6258
6259		},
6260		_config: function() {
6261			this.open = false;
6262			this.$trigger = this.$el.children('.mk-vm-trigger');
6263			this.$menu = this.$el.children('ul.mk-vm-menu');
6264			this.$menuitems = this.$menu.find('li:not(.mk-vm-back)');
6265			this.$back = this.$menu.find('li.mk-vm-back');
6266		},
6267		_initEvents: function() {
6268
6269			var self = this;
6270			
6271			$('.mk-vm-menuwrapper a').on('transitionend', function(event) {
6272				event.stopPropagation();
6273			});
6274
6275			this.$menuitems.on('click.dlmenu', 'a', function(event) {
6276
6277				// Breaks smooth scroll in vertical menu
6278				// event.stopPropagation();
6279
6280				var $item = $(event.delegateTarget),
6281					$submenu = $(event.currentTarget).siblings('ul.sub-menu');
6282
6283				if ($submenu.length > 0) {
6284					var $flyin = $submenu.clone().css('opacity', 0).insertAfter(self.$menu);
6285					var onAnimationEndFn = function() {
6286						var $parent = $item.parents('.mk-vm-subviewopen:first');
6287						self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classout).addClass('mk-vm-subview');
6288						$item.addClass('mk-vm-subviewopen')
6289						$parent.removeClass('mk-vm-subviewopen').addClass('mk-vm-subview');
6290						$flyin.remove();
6291
6292						// Redraw for firefox issues
6293						var $txt = $item.find('.meni-item-text');
6294						$txt.css('opacity', 0.99);
6295						setTimeout(function() { $txt.css('opacity', 1) }, 0);
6296					};
6297
6298					setTimeout(function() {
6299						$flyin.addClass(self.options.animationClasses.classin);
6300						self.$menu.addClass(self.options.animationClasses.classout);
6301						if (self.supportAnimations) {
6302							self.$menu.on(self.animEndEventName, onAnimationEndFn);
6303						} else {
6304							onAnimationEndFn.call();
6305						}
6306
6307						self.options.onLevelClick($item, $item.children('a:first').text());
6308					});
6309
6310
6311					// This caused firefox issue. Test properly if need to bring it back
6312					// if (self.open) {
6313					// 	self._closeMenu();
6314					// } else {
6315					// 	self._openMenu();
6316					// }
6317
6318					return false;
6319
6320				} else {
6321					self.options.onLinkClick($item, event);
6322				}
6323
6324			});
6325
6326
6327			// this.$trigger.on('click.dlmenu', function() {
6328
6329			// 	if (self.open) {
6330			// 		self._closeMenu();
6331			// 	} else {
6332			// 		// if( ! $(this).hasClass('menu-item-has-children') ) return false;
6333			// 		self._openMenu();
6334			// 	}
6335			// 	return false;
6336
6337			// });
6338
6339			this.$back.on('click.dlmenu', function(event) {
6340
6341				var $this = $(this),
6342					$submenu = $this.parents('ul.sub-menu:first'),
6343					$item = $submenu.parent(),
6344
6345					$flyin = $submenu.clone().insertAfter(self.$menu);
6346
6347				var onAnimationEndFn = function() {
6348					self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classin);
6349					$flyin.remove();
6350				};
6351
6352				setTimeout(function() {
6353					$flyin.addClass(self.options.animationClasses.classout);
6354					self.$menu.addClass(self.options.animationClasses.classin);
6355					if (self.supportAnimations) {
6356						self.$menu.on(self.animEndEventName, onAnimationEndFn);
6357					} else {
6358						onAnimationEndFn.call();
6359					}
6360
6361					$item.removeClass('mk-vm-subviewopen');
6362
6363					var $subview = $this.parents('.mk-vm-subview:first');
6364					if ($subview.is('li')) {
6365						$subview.addClass('mk-vm-subviewopen');
6366					}
6367					$subview.removeClass('mk-vm-subview');
6368				});
6369
6370				return false;
6371
6372			});
6373
6374		},
6375		closeMenu: function() {
6376			if (this.open) {
6377				this._closeMenu();
6378			}
6379		},
6380		_closeMenu: function() {
6381			var self = this,
6382				onTransitionEndFn = function() {
6383					self.$menu.off(self.transEndEventName);
6384					self._resetMenu();
6385				};
6386
6387			this.$menu.removeClass('mk-vm-menuopen');
6388			this.$menu.addClass('mk-vm-menu-toggle');
6389			this.$trigger.removeClass('mk-vm-active');
6390
6391			if (this.supportTransitions) {
6392				this.$menu.on(this.transEndEventName, onTransitionEndFn);
6393			} else {
6394				onTransitionEndFn.call();
6395			}
6396
6397			this.open = false;
6398		},
6399		openMenu: function() {
6400			if (!this.open) {
6401				this._openMenu();
6402			}
6403		},
6404		_openMenu: function() {
6405			var self = this;
6406			$body.off('click').on('click.dlmenu', function() {
6407				self._closeMenu();
6408			});
6409			this.$menu.addClass('mk-vm-menuopen mk-vm-menu-toggle').on(this.transEndEventName, function() {
6410				$(this).removeClass('mk-vm-menu-toggle');
6411			});
6412			this.$trigger.addClass('mk-vm-active');
6413			this.open = true;
6414		},
6415		_resetMenu: function() {
6416			this.$menu.removeClass('mk-vm-subview');
6417			this.$menuitems.removeClass('mk-vm-subview mk-vm-subviewopen');
6418		}
6419	};
6420
6421	var logError = function(message) {
6422		if (window.console) {
6423			window.console.error(message);
6424		}
6425	};
6426
6427	$.fn.dlmenu = function(options) {
6428		if (typeof options === 'string') {
6429			var args = Array.prototype.slice.call(arguments, 1);
6430			this.each(function() {
6431				var instance = $.data(this, 'dlmenu');
6432				if (!instance) {
6433					logError("cannot call methods on dlmenu prior to initialization; " +
6434						"attempted to call method '" + options + "'");
6435					return;
6436				}
6437				if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
6438					logError("no such method '" + options + "' for dlmenu instance");
6439					return;
6440				}
6441				instance[options].apply(instance, args);
6442			});
6443		} else {
6444			this.each(function() {
6445				var instance = $.data(this, 'dlmenu');
6446				if (instance) {
6447					instance._init();
6448				} else {
6449					instance = $.data(this, 'dlmenu', new $.DLMenu(options, this));
6450				}
6451			});
6452		}
6453		return this;
6454	};
6455
6456})(jQuery, window);
6457( function($) {
6458    'use strict';
6459
6460	/* 
6461	 * Define popup / hover states manually to prevent click for IE on touchdevices
6462	 */
6463
6464	$('.mk-main-navigation .menu-item-has-children').children('a').attr('aria-haspopup', 'true'); 
6465	$('.animated-column-item').attr('aria-haspopup', 'true');
6466
6467})( jQuery );
6468(function($) {
6469    'use strict';
6470
6471    var Accordion = function(el) { 
6472        // Private
6473        var that = this,
6474            $el = $(el),
6475            initial = $el.data('initialindex'),
6476            timeout;
6477
6478        // Public
6479        this.$el = $el;
6480        this.$single = $('.' + this.dom.single, $el);
6481        this.isExpendable = ($el.data('style') === 'toggle-action');
6482
6483        // Init 
6484        this.bindClicks();
6485        // Reveal initial tab on load event (wait for possible images inside)
6486        $(window).on('load', function() {
6487            if( initial !== -1 ) that.show(that.$single.eq(initial))
6488        });
6489        $(window).on('resize', function() {
6490            clearTimeout(timeout);
6491            timeout = setTimeout(that.bindClicks.bind(that), 500);
6492        }); 
6493    }
6494
6495    Accordion.prototype.dom = {
6496        // only class names please!
6497        single        : 'mk-accordion-single',
6498        tab           : 'mk-accordion-tab',
6499        pane          : 'mk-accordion-pane',
6500        current       : 'current',
6501        mobileToggle  : 'mobile-false',
6502        mobileBreakPoint : 767
6503    }
6504
6505    Accordion.prototype.bindClicks = function() {
6506        // Prevent multiple events binding
6507        this.$single.off('click', '.' + this.dom.tab);
6508
6509        if( !(window.matchMedia('(max-width: ' + this.dom.mobileBreakPoint +'px)').matches 
6510          && this.$el.hasClass(this.dom.mobileToggle)) ) {
6511
6512            this.$single.on('click', '.' + this.dom.tab, this.handleEvent.bind(this));
6513            // When website is loaded in mobile view and resized to desktop 'current' will 
6514            // inherit display: none from css. Repair it by calling show() on this element
6515            var $current = $('.' + this.dom.current, this.$el);
6516            if($('.' + this.dom.pane, $current).css('display') === 'none') this.show($current);
6517        }
6518    }
6519
6520    Accordion.prototype.handleEvent = function(e) {
6521        e.preventDefault();
6522        e.stopPropagation();
6523
6524        var $single = $(e.delegateTarget);
6525
6526        if(!$single.hasClass(this.dom.current)) {
6527            this.show($single);
6528        }
6529        else {
6530            if(this.isExpendable) this.hide($single);
6531        }
6532    }
6533
6534    Accordion.prototype.hide = function($single) {
6535        $single.removeClass(this.dom.current);
6536        $('.' + this.dom.pane, $single).slideUp();
6537    }
6538
6539    Accordion.prototype.show = function($single) {
6540        // hide currently opened tab
6541        if(!this.isExpendable) {
6542            var that = this;
6543            this.hide($('.' + this.dom.current, that.$el));
6544        }
6545
6546        $single.addClass(this.dom.current);
6547        $('.' + this.dom.pane, $single).slideDown();
6548    }
6549
6550
6551
6552    // ///////////////////////////////////////
6553    //
6554    // Apply to:
6555    //
6556    // ///////////////////////////////////////
6557
6558	function init() {
6559		$('.mk-accordion').each(function() {
6560			new Accordion(this);
6561		});
6562	}
6563
6564	init();
6565	$(window).on('vc_reload', init);
6566
6567})(jQuery);
6568
6569(function($) {
6570
6571    'use strict';
6572
6573    var SkillDiagram = function( el ) {
6574        this.el = el;
6575    }
6576
6577    SkillDiagram.prototype = {
6578        init : function() {
6579            this.cacheElements();
6580            this.createDiagram();
6581            this.$skills.each( this.createSkill.bind( this ) );
6582        },
6583
6584        cacheElements : function() {
6585            this.$el = $( this.el );
6586            this.$skills = this.$el.find( '.mk-meter-arch');
6587            this.config  = this.$el.data();
6588            this.config.radius = this.config.dimension / 2;
6589        },
6590
6591        random : function( l, u ) {
6592            return Math.floor( ( Math.random() * ( u - l + 1 ) ) + l );
6593        },
6594
6595        createDiagram : function() {
6596            var self = this;
6597            $(this.el).find('svg').remove();
6598            
6599            this.diagram = Raphael( this.el, this.config.dimension, this.config.dimension );
6600
6601            // Make svg scalable in different screen sizes
6602            this.diagram.setViewBox(0,0,this.config.dimension,this.config.dimension,true);
6603            this.diagram.setSize('90%', '90%');
6604
6605            this.diagram.circle( this.config.radius, this.config.radius, 80 ).attr({ 
6606                stroke: 'none', 
6607                fill: this.config.circleColor 
6608            });
6609        
6610            // Export title
6611            this.title = this.diagram.text( this.config.radius, this.config.radius, this.config.defaultText ).attr({
6612                font: "22px helvetica",
6613                fill: this.config.defaultTextColor
6614            }).toFront();
6615            
6616            this.diagram.customAttributes.arc = function(value, color, rad){
6617                var v = 3.6 * value,
6618                    alpha = v == 360 ? 359.99 : v,
6619                    r  = self.random( 91, 240 ),
6620                    a  = (r - alpha) * Math.PI/180,
6621                    b  = r * Math.PI/180,
6622                    sx = self.config.radius + rad * Math.cos(b),
6623                    sy = self.config.radius - rad * Math.sin(b),
6624                    x  = self.config.radius + rad * Math.cos(a),
6625                    y  = self.config.radius - rad * Math.sin(a),
6626                    path = [['M', sx, sy], ['A', rad, rad, 0, +(alpha > 180), 1, x, y]];
6627
6628                return { 
6629                    path: path, 
6630                    stroke: color 
6631                }
6632            }
6633        },
6634
6635        createSkill : function( id, el ) {
6636            var self   = this,
6637                $this  = $( el ),
6638                config = $this.data(),
6639                radMin = 72,
6640                radVal = 27,
6641                newRad = radMin + ( radVal * (id + 1) );
6642
6643            var $path = this.diagram.path().attr({
6644                'stroke-width': 28,
6645                arc: [config.percent, config.color, newRad]
6646            });
6647
6648            $path.mouseover( function() {
6649                self.showSkill( this, config.name, config.percent );
6650            }).mouseout( function() {
6651                self.hideSkill( this ) 
6652            });
6653        },
6654
6655        showSkill : function( self, name, percent ) {
6656            var $this = self,
6657                time = 250;
6658
6659            //solves IE problem
6660            if(Raphael.type != 'VML') $this.toFront();
6661
6662            $this.animate({ 
6663                'stroke-width': 50, 
6664                'opacity': 0.9, 
6665            }, 800, 'elastic' );
6666
6667            this.title.stop()
6668                .animate({ opacity: 0 }, time, '>', function(){
6669                    this.attr({ text: name + '\n' + percent + '%' }).animate({ opacity: 1 }, time, '<');
6670                }).toFront();
6671        },
6672
6673        hideSkill : function( self ) {
6674            var $this = self,
6675                self = this,
6676                time = 250;
6677
6678            $this.stop().animate({ 
6679                'stroke-width': 28, 
6680                opacity: 1 
6681            }, time * 4, 'elastic' );
6682
6683            self.title.stop()
6684                .animate({ opacity: 0 }, time, '>', function(){
6685                    self.title.attr({ text: self.config.defaultText })
6686                    .animate({ opacity: 1 }, time, '<');
6687                }); 
6688        }
6689    }
6690
6691    var init = function init() {
6692        if( typeof Raphael === 'undefined' ) return;
6693        $( '.mk-skill-diagram' ).each( function() {
6694            var diagram = new SkillDiagram( this );
6695                diagram.init();
6696        });
6697    }
6698
6699    init();
6700    $(window).on('vc_reload', init);
6701
6702})(jQuery);
6703/*
6704 * Tab delegation 
6705 * Action for modules when we don't have access to chidren DOM on processing templates
6706 * yet we want ass option of opening link in new tab. 
6707 * Helpful for use with external widgets like flickr
6708 */
6709
6710(function($) {
6711
6712	'use strict';
6713
6714	$( '[data-js="tab-delegation"]' ).each( tabDelegation );
6715
6716	function tabDelegation() {
6717		var $this = $( this ),
6718			data  = $this.data();
6719
6720		// Create delegation on parent element to affect async loaded children
6721		if( data.tab ) $this.on( 'click', 'a', openInTab );
6722	}
6723
6724	function openInTab( e ) {
6725		e.preventDefault(); 
6726
6727		var $this = $( this ),
6728			url = $this.attr( 'href' );
6729
6730		window.open( url, '_blank' );
6731	}
6732
6733})(jQuery);
6734(function($) {
6735    'use strict';
6736
6737    var init = function init() {
6738        var Toggle = function(el) {
6739        var that = this,
6740            $el = $(el);
6741
6742            this.$el = $el;
6743            $el.on('click', function() {
6744                $el.hasClass('active-toggle') ? that.close() : that.open()
6745            });
6746        };
6747
6748        Toggle.prototype.dom = {
6749            pane   : 'mk-toggle-pane',
6750            active : 'active-toggle'
6751        };
6752
6753        Toggle.prototype.open = function() {
6754            var $this = this.$el;
6755            $this.addClass(this.dom.active);
6756            $this.siblings('.' + this.dom.pane).slideDown(200);
6757        };
6758
6759        Toggle.prototype.close = function() {
6760            var $this = this.$el;
6761            $this.removeClass(this.dom.active);
6762            $this.siblings('.' + this.dom.pane).slideUp(200);
6763        };
6764
6765        // Apply to.
6766        var $toggle = $('.mk-toggle-title');
6767
6768        if(!$toggle.length) return;
6769
6770        $toggle.each(function() {
6771            new Toggle(this);
6772        });
6773    }
6774    $(window).on('load vc_reload', init);
6775
6776})(jQuery);
6777
6778//////////////////////////////////////////////////////////////////////////
6779//
6780//   Init all scripts
6781//
6782//////////////////////////////////////////////////////////////////////////
6783
6784// This is bad but we don't have other access to this scope.
6785// Ajax Portfolio  is defined as plugin and on success needs these to be reinited
6786// We'll refactor all of this.
6787window.ajaxInit = function() {
6788    mk_lightbox_init();
6789    mk_click_events();
6790    mk_social_share_global();
6791   // mk_social_share();
6792    mk_gallery();
6793    loop_audio_init();
6794};
6795
6796window.ajaxDelayedInit = function() {
6797    mk_flexslider_init();
6798    // mk_portfolio_ajax();
6799};
6800
6801$(document).ready(function() {
6802    mk_lightbox_init();
6803    mk_login_form();
6804    mk_backgrounds_parallax();
6805    mk_flexslider_init();
6806    mk_event_countdown();
6807    mk_skill_meter();
6808    mk_milestone();
6809    mk_ajax_search();
6810    mk_hover_events();
6811    mk_portfolio_ajax();
6812    product_loop_add_cart();
6813  //  mk_social_share();
6814    mk_portfolio_widget();
6815    mk_contact_form();
6816    mk_blog_carousel();
6817    mk_header_searchform();
6818    mk_click_events();
6819    mk_text_typer();
6820    mk_tab_slider_func();
6821
6822    $(window).on('load', function() {
6823        mk_unfold_footer();
6824        mk_tabs();
6825        mk_accordion_toggles_tooltip();
6826        mk_gallery();
6827        mk_theatre_responsive_calculator();
6828        mk_tabs_responsive();
6829        mk_start_tour_resize();
6830        mk_header_social_resize();
6831        mk_page_section_social_video_bg();
6832        loop_audio_init();
6833        mk_one_page_scroller();
6834        mkPositionSidebar();
6835
6836        setTimeout(function() {
6837            /*
6838                Somehow the values are not correctly updated for the screens
6839                and we need to put setTimeout to fix the issue
6840            */
6841            mk_mobile_tablet_responsive_calculator();
6842        }, 300);
6843
6844        console.log("ready for rock");
6845    });
6846
6847
6848    var onDebouncedResize = function() {
6849        mk_theatre_responsive_calculator();
6850        mk_mobile_tablet_responsive_calculator();
6851        mk_tabs_responsive();
6852        mk_accordion_toggles_tooltip();
6853        mk_start_tour_resize();
6854        mk_header_social_resize();
6855
6856        setTimeout(function() {
6857            mk_unfold_footer();
6858        }, 300);
6859    };
6860
6861    var debounceResize = null;
6862    $(window).on("resize", function() {
6863        if( debounceResize !== null ) { clearTimeout( debounceResize ); }
6864        debounceResize = setTimeout( onDebouncedResize, 300 );
6865    });
6866
6867    var onDebouncedScroll = function() {
6868        mk_skill_meter();
6869        //TODO: Ask to Bart how we can call javascript component
6870        //mk_charts();
6871        mk_milestone();
6872    };
6873
6874    var debounceScroll = null;
6875    $(window).on("scroll", function() {
6876        if( debounceScroll !== null ) { clearTimeout( debounceScroll ); }
6877        debounceScroll = setTimeout( onDebouncedScroll, 100 );
6878    });
6879
6880    if (MK.utils.isMobile()) {
6881        $('body').addClass('no-transform');
6882    }
6883
6884});
6885
6886/* VC frontend editor  */
6887/* -------------------------------------------------------------------- */
6888$(window).on("vc_reload",function () {
6889    mk_flexslider_init();
6890    loop_audio_init();
6891    mk_tab_slider_func();
6892    mk_event_countdown();
6893    videoLoadState();
6894    mk_page_section_social_video_bg();
6895    mk_hover_events();
6896
6897    setTimeout(function() {
6898        mkPositionSidebar();
6899    }, 200);
6900});
6901
6902// Replace this if new event for remove found.
6903$( document ).on( 'click', '.vc_control-btn-delete', function() {
6904    $( window ).trigger( 'vc_reload' );
6905} );
6906
6907$( document ).on( 'sortupdate', '.ui-sortable', function() {
6908    $( window ).trigger( 'vc_reload' );
6909} );
6910
6911/* Typer */
6912/* -------------------------------------------------------------------- */
6913function mk_text_typer() {
6914
6915    "use strict";
6916
6917    $('[data-typer-targets]').each(function() {
6918        var that = this;
6919        MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.typed.js' ], function() {
6920            var $this = $(that),
6921                $first_string = [$this.text()],
6922                $rest_strings = $this.attr('data-typer-targets').split(','),
6923                $strings = $first_string.concat($rest_strings);
6924
6925            $this.text('');
6926
6927            $this.typed({
6928                strings: $strings,
6929                typeSpeed: 30, // typing speed
6930                backDelay: 1200, // pause before backspacing
6931                loop: true, // loop on or off (true or false)
6932                loopCount: false, // number of loops, false = infinite
6933            });
6934        });
6935    });
6936}
6937
6938
6939
6940/* Tab Slider */
6941/* -------------------------------------------------------------------- */
6942
6943function mk_tab_slider_func() {
6944
6945    "use strict";
6946
6947    $('.mk-tab-slider').each(function() {
6948        var that = this;
6949
6950        MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.swiper.js' ], function() {
6951            var $this = $(that),
6952                id = $this.data('id'),
6953                $autoplayTime = $this.data('autoplay'),
6954                $content = $('.mk-slider-content');
6955
6956            var mk_tab_slider = $this.swiper({
6957                wrapperClass: 'mk-tab-slider-wrapper',
6958                slideClass: 'mk-tab-slider-item',
6959                calculateHeight: true,
6960                speed: 500,
6961                autoplay: isTest ? false : $autoplayTime,
6962                onSlideChangeStart: function() {
6963                    $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active')
6964                    $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").eq(mk_tab_slider.activeIndex).addClass('active')
6965                }
6966            });
6967
6968            // Simple repaint for firefox issue (can't handle 100% height after plugin init)
6969            function repaintFirefox() {
6970                $content.css('display','block');
6971                setTimeout(function() {
6972                    mk_tab_slider.reInit();
6973                    $content.css('display','table');
6974                },100);
6975            }
6976
6977            $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").first().addClass('active');
6978
6979            $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").on('touchstart mousedown', function(e) {
6980                e.preventDefault()
6981                $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active')
6982                $(this).addClass('active')
6983                mk_tab_slider.swipeTo($(this).index())
6984            });
6985
6986            $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").click(function(e) {
6987                e.preventDefault();
6988            });
6989
6990            repaintFirefox();
6991            $(window).on('resize', repaintFirefox);
6992        });
6993
6994    });
6995
6996}
6997
6998
6999
7000/* Edge One Pager */
7001/* -------------------------------------------------------------------- */
7002function mk_one_page_scroller() {
7003
7004    "use strict";
7005
7006    $('.mk-edge-one-pager').each(function() {
7007        var self = this;
7008
7009        MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.fullpage.js' ], function() {
7010
7011            var $this = $(self),
7012                anchorArr = [];
7013
7014            $this.find('.section').each(function() {
7015                anchorArr.push($(this).attr('data-title'));
7016            });
7017
7018            var scrollable = true;
7019            $this.find('.section').each(function() {
7020                var $section = $(this),
7021                    $content = $section.find('.edge-slide-content'),
7022                    sectionHeight = $section.height(),
7023                    contentHeight = $content.innerHeight();
7024
7025                if((contentHeight + 30) > $(window).height()) {
7026                    scrollable = false;
7027                }
7028            });
7029
7030            if(!scrollable){
7031                $this.find('.section').each(function() {
7032                    var $section = $(this);
7033                    $section.addClass('active').css({
7034                        'padding-bottom': '50px'
7035                    });
7036                });
7037            }
7038
7039            if(scrollable) {
7040                $this.fullpage({
7041                    verticalCentered: false,
7042                    resize: true,
7043                    slidesColor: ['#ccc', '#fff'],
7044                    anchors: anchorArr,
7045                    scrollingSpeed: 600,
7046                    easing: 'easeInQuart',
7047                    menu: false,
7048                    navigation: true,
7049                    navigationPosition: 'right',
7050                    navigationTooltips: false,
7051                    slidesNavigation: true,
7052                    slidesNavPosition: 'bottom',
7053                    loopBottom: false,
7054                    loopTop: false,
7055                    loopHorizontal: true,
7056                    autoScrolling: true,
7057                    scrollOverflow: false,
7058                    css3: true,
7059                    paddingTop: 0,
7060                    paddingBottom: 0,
7061                    normalScrollElements: '.mk-header, .mk-responsive-wrap',
7062                    normalScrollElementTouchThreshold: 5,
7063                    keyboardScrolling: true,
7064                    touchSensitivity: 15,
7065                    continuousVertical: false,
7066                    animateAnchor: true,
7067
7068                    onLeave: function(index, nextIndex, direction) {
7069                        var currentSkin = $this.find('.one-pager-slide').eq(nextIndex - 1).attr('data-header-skin');
7070                        MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin );
7071                        $('#fullPage-nav').removeClass('light-skin dark-skin').addClass(currentSkin + '-skin');
7072
7073                    },
7074                    afterRender: function() {
7075
7076                        var $nav = $('#fullPage-nav');
7077
7078                        setTimeout(function() {
7079                            var currentSkin = $this.find('.one-pager-slide').eq(0).attr('data-header-skin');
7080                            MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin );
7081                            if($nav.length) $nav.removeClass('light-skin dark-skin').addClass(currentSkin + '-skin');
7082                        }, 300);
7083
7084                        var $slide = $this.find('.section'),
7085                            headerHeight = MK.val.offsetHeaderHeight(0),
7086                            windowHeight = $(window).height();
7087
7088                        $slide.height(windowHeight - headerHeight);
7089
7090                        if($nav.length) {
7091                            $nav.css({
7092                                'top': 'calc(50% + ' + (headerHeight/2) + 'px)',
7093                                'marginTop': 0
7094                            });
7095
7096                            var style = $this.attr('data-pagination');
7097                            $nav.addClass('pagination-' + style);
7098                        }
7099
7100                        setTimeout(mk_one_pager_resposnive, 1000);
7101                    },
7102                    afterResize: function() {
7103                        var $slide = $this.find('.section'),
7104                            headerHeight = MK.val.offsetHeaderHeight(0),
7105                            windowHeight = $(window).height();
7106
7107                        $slide.height(windowHeight - headerHeight);
7108
7109                        $('#fullPage-nav').css({
7110                            'top': 'calc(50% + ' + (headerHeight/2) + 'px)',
7111                            'marginTop': 0
7112                        });
7113
7114                        setTimeout(mk_one_pager_resposnive, 1000);
7115                        console.log('Reposition pager content.');
7116                    },
7117                });
7118            }
7119
7120            // Linking to slides available for desktop and mobile scenarios
7121            function swipeTo(href, e) {
7122                href = '_' + href; // ensure a char before #
7123                if (!~href.indexOf('#')) return;
7124                var section = href.split('#')[1];
7125                if (~anchorArr.indexOf(section)) {
7126                    if (typeof e !== 'undefined') e.preventDefault();
7127                    if (scrollable) $.fn.fullpage.moveTo(section);
7128                    else MK.utils.scrollToAnchor('[data-title="'+section+'"]');
7129                }
7130            }
7131
7132            // onload
7133            var loc = window.location;
7134            if(loc.hash) swipeTo(loc.hash);
7135
7136            $(document).on('click', 'a', function(e) {
7137                var $link = $(e.currentTarget);
7138                swipeTo($link.attr('href'), e);
7139            });
7140        });
7141    });
7142
7143
7144
7145}
7146
7147
7148function mk_one_pager_resposnive() {
7149    "use strict";
7150
7151    $('.mk-edge-one-pager').each(function() {
7152        var $pager = $(this),
7153            headerHeight = MK.val.offsetHeaderHeight(0),
7154            windowHeight = $(window).height() - headerHeight;
7155
7156        $pager.find('.one-pager-slide').each(function() {
7157            var $slide = $(this),
7158                $content = $slide.find('.edge-slide-content');
7159
7160            if ($slide.hasClass('left_center') || $slide.hasClass('center_center') || $slide.hasClass('right_center')) {
7161                var contentHeight  = $content.height(),
7162                    distanceFromTop = (windowHeight - contentHeight) / 2;
7163
7164                distanceFromTop  = (distanceFromTop < 50) ? 50 + headerHeight : distanceFromTop;
7165
7166                $content.css('marginTop', distanceFromTop);
7167            }
7168
7169            if ($slide.hasClass('left_bottom') || $slide.hasClass('center_bottom') || $slide.hasClass('right_bottom')) {
7170                var distanceFromTop = windowHeight - $content.height() - 90;
7171                $content.css('marginTop', (distanceFromTop));
7172            }
7173        });
7174
7175        /**
7176         * Fix AM-2853
7177         *
7178         * @since 6.0.3
7179         *
7180         * At the init of Edge One Pager (EOP), EOP will render all image
7181         * background of each sections from top to bottom. In this case,
7182         * the page height will be more than screen height and the scroll
7183         * bar will appear. At the same time, the full width row will set
7184         * the container width into 100%. But, after all Slides are set up,
7185         * EOP height will be 100% of the screen height, so the scroll bar
7186         * will be disappeared. It's caused spacing issues on the left and
7187         * right side of the EOP container. To fix this, the row width
7188         * should be resized and row position should be readjusted.
7189         */
7190        var $row = $pager.parents( '.vc_row.vc_row-fluid.mk-fullwidth-true' );
7191
7192        // Run only if the Edge One Pager is wrapped inside full width row.
7193        if ( $row.length > 0 ) {
7194            // Set the wrapper and row width.
7195            var $wrapper = $( '.mk-main-wrapper-holder' );
7196            var $grid = $row.children( '.mk-grid' );
7197            var rowWidth = $row.width();         // Original width.
7198            var wrapperWidth = $wrapper.width(); // The new width.
7199
7200            // Run only if original width is smaller than the new width.
7201            if ( rowWidth >= wrapperWidth || $grid.length > 0 ) {
7202                return;
7203            }
7204
7205            // Get the content left offset.
7206            var $content = $wrapper.find( '.theme-content' );
7207            var oriPos = $content.position();
7208            var oriPadLeft = $content.css( 'padding-left' );
7209            var oriLeft = parseInt( oriPos.left ) + parseInt( oriPadLeft );
7210
7211            // Ensure the new width and left position is more than 0.
7212            if ( wrapperWidth <= 0 || oriLeft <= 0 ) {
7213                return;
7214            }
7215
7216            // Resize the width and left position of row full width.
7217            $row.css({
7218                'width': wrapperWidth,
7219                'left': oriLeft * -1,
7220            });
7221        }
7222    });
7223}
7224
7225/* Image Gallery */
7226/* -------------------------------------------------------------------- */
7227
7228function mk_gallery() {
7229
7230    "use strict";
7231
7232    $('.mk-gallery .mk-gallery-item.hover-overlay_layer .item-holder').each(function() {
7233        var itemHolder = $(this),
7234            galleryDesc = itemHolder.find('.gallery-desc');
7235
7236        function updatePosition() {
7237            var parentHeight = itemHolder.outerHeight(),
7238                contentHeight = galleryDesc.innerHeight();
7239
7240            var paddingVal = (parentHeight - contentHeight) / 2;
7241            galleryDesc.css({
7242                'top': paddingVal,
7243                // 'padding-bottom': paddingVal
7244            });
7245
7246            // console.log(parentHeight);
7247            // console.log(contentHeight);
7248
7249
7250        }
7251        updatePosition();
7252
7253        $(window).on('resize', function() {
7254            setTimeout(function() {
7255                updatePosition();
7256            }, 1000);
7257        });
7258    });
7259    // Execute hover state for mk gallery item
7260    if ($(window).width() <= 1024) {
7261        $('.mk-gallery .mk-gallery-item').on('click', function (e) {
7262            var clicks = $(this).data('clicks');
7263            if (clicks) {
7264                // First click
7265                $(this).toggleClass('hover-state');
7266            } else {
7267                // Second click
7268                $(this).toggleClass('hover-state');
7269            }
7270            $(this).data("clicks", !clicks);
7271        });
7272    }
7273}
7274
7275/* Theatre Slider Responsive Calculator */
7276/* -------------------------------------------------------------------- */
7277
7278function mk_theatre_responsive_calculator() {
7279    var $laptopContainer = $(".laptop-theatre-slider");
7280    var $computerContainer = $(".desktop-theatre-slider");
7281    $laptopContainer.each(function() {
7282        var $this = $(this),
7283            $window = $(window),
7284            $windowWidth = $window.outerWidth(),
7285            $windowHeight = $window.outerHeight(),
7286            $width = $this.outerWidth(),
7287            $height = $this.outerHeight(),
7288            $paddingTop = 38,
7289            $paddingRight = 143,
7290            $paddingBottom = 78,
7291            $paddingLeft = 143;
7292
7293        var $player = $this.find('.player-container');
7294
7295        if ($windowWidth > $width) {
7296            $player.css({
7297                'padding-left': parseInt(($width * $paddingLeft) / 1200),
7298                'padding-right': parseInt(($width * $paddingRight) / 1200),
7299                'padding-top': parseInt(($height * $paddingTop) / 690),
7300                'padding-bottom': parseInt(($height * $paddingBottom) / 690),
7301            });
7302        }
7303
7304    });
7305
7306    $computerContainer.each(function() {
7307        var $this = $(this),
7308            $window = $(window),
7309            $windowWidth = $window.outerWidth(),
7310            $windowHeight = $window.outerHeight(),
7311            $width = $this.outerWidth(),
7312            $height = $this.outerHeight(),
7313            $paddingTop = 60,
7314            $paddingRight = 52,
7315            $paddingBottom = 290,
7316            $paddingLeft = 49;
7317
7318        var $player = $this.find('.player-container');
7319
7320        if ($windowWidth > $width) {
7321            $player.css({
7322                'padding-left': parseInt(($width * $paddingLeft) / 1200),
7323                'padding-right': parseInt(($width * $paddingRight) / 1200),
7324                'padding-top': parseInt(($height * $paddingTop) / 969),
7325                'padding-bottom': parseInt(($height * $paddingBottom) / 969),
7326            });
7327        }
7328
7329    });
7330
7331}
7332
7333/* Mobile and Tablet Slideshow Responsive Calculator */
7334/* -------------------------------------------------------------------- */
7335function mk_mobile_tablet_responsive_calculator() {
7336    var $laptopSlideshow = $(".mk-laptop-slideshow-shortcode");
7337    var $lcdSlideshow = $(".mk-lcd-slideshow");
7338
7339    if ($.exists(".mk-laptop-slideshow-shortcode")) {
7340        $laptopSlideshow.each(function() {
7341            var $this = $(this),
7342                $window = $(window),
7343                $windowWidth = $window.outerWidth(),
7344                $windowHeight = $window.outerHeight(),
7345                $width = $this.outerWidth(),
7346                $height = $this.outerHeight(),
7347                $paddingTop = 28,
7348                $paddingRight = 102,
7349                $paddingBottom = 52,
7350                $paddingLeft = 102;
7351
7352            var $player = $this.find(".slideshow-container");
7353
7354            $player.css({
7355                "padding-left": parseInt(($width * $paddingLeft) / 836),
7356                "padding-right": parseInt(($width * $paddingRight) / 836),
7357                "padding-top": parseInt(($height * $paddingTop) / 481),
7358                "padding-bottom": parseInt(($height * $paddingBottom) / 481),
7359            });
7360
7361        });
7362    }
7363
7364    if ($.exists(".mk-lcd-slideshow")) {
7365        $lcdSlideshow.each(function() {
7366            var $this = $(this),
7367                $window = $(window),
7368                $windowWidth = $window.outerWidth(),
7369                $windowHeight = $window.outerHeight(),
7370                $width = $this.outerWidth(),
7371                $height = $this.outerHeight(),
7372                $paddingTop = 35,
7373                $paddingRight = 39,
7374                $paddingBottom = 213,
7375                $paddingLeft = 36;
7376
7377            var $player = $this.find(".slideshow-container");
7378            $player.css({
7379                "padding-left": parseInt(($width * $paddingLeft) / 886),
7380                "padding-right": parseInt(($width * $paddingRight) / 886),
7381                "padding-top": parseInt(($height * $paddingTop) / 713),
7382                "padding-bottom": parseInt(($height * $paddingBottom) / 713),
7383            });
7384        });
7385    }
7386}
7387
7388
7389/* Start a tour resize function */
7390/* -------------------------------------------------------------------- */
7391function mk_start_tour_resize() {
7392
7393    $('.mk-header-start-tour').each(function() {
7394
7395        var $windowWidth = $(document).width(),
7396            $this = $(this),
7397            $linkWidth = $this.width() + 15,
7398            $padding = ($windowWidth - mk_responsive_nav_width) / 2;
7399
7400
7401
7402        function updateStartTour(){
7403            if($windowWidth < mk_responsive_nav_width){
7404                $this.removeClass('hidden');
7405                $this.addClass('show');
7406            }else{
7407                if($padding < $linkWidth){
7408                    $this.removeClass('show');
7409                    $this.addClass('hidden');
7410                }else{
7411                    $this.removeClass('hidden');
7412                    $this.addClass('show');
7413                }
7414            }
7415        }
7416
7417        setTimeout(function() {
7418            updateStartTour();
7419        }, 300);
7420    });
7421}
7422
7423/* Header social resize function */
7424/* -------------------------------------------------------------------- */
7425function mk_header_social_resize() {
7426
7427    $('.mk-header-social.header-section').each(function() {
7428
7429        var $windowWidth = $(document).width(),
7430            $this = $(this),
7431            $linkWidth = $this.width() + 15,
7432            $padding = ($windowWidth - mk_responsive_nav_width) / 2;
7433
7434
7435
7436        function updateStartTour(){
7437            if($windowWidth < mk_responsive_nav_width){
7438                $this.removeClass('hidden');
7439                $this.addClass('show');
7440            }else{
7441                if($padding < $linkWidth){
7442                    $this.removeClass('show');
7443                    $this.addClass('hidden');
7444                }else{
7445                    $this.removeClass('hidden');
7446                    $this.addClass('show');
7447                }
7448            }
7449        }
7450
7451        setTimeout(function() {
7452            updateStartTour();
7453        }, 300);
7454    });
7455}
7456
7457/* Page Section Socail Video Player Controls */
7458/* -------------------------------------------------------------------- */
7459
7460function mk_page_section_social_video_bg() {
7461    $(".mk-page-section.social-hosted").each(function() {
7462        var $container = $(this),
7463            $sound = $container.data('sound'),
7464            $source = $container.data('source'),
7465            player,
7466            timer = 1000;
7467
7468        if ( $( 'body' ).hasClass( '.compose-mode' ) ) {
7469            timer = 2000;
7470        }
7471
7472        if ($source == 'youtube') {
7473            var youtube = $container.find('iframe')[0];
7474            try {
7475                player = new YT.Player(youtube, {
7476                    events: {
7477                        'onReady': function () {
7478                           player.playVideo();
7479                           if($sound == false) {
7480                               player.mute();
7481                           }
7482                       }
7483                    }
7484                });
7485
7486                
7487            } catch (e) {
7488            	console.log( e );
7489            }
7490        }
7491        if ($source == 'vimeo') {
7492            var vimeo = $container.find('iframe')[0];
7493            player = $f(vimeo);
7494            setTimeout(function() {
7495                player.api('play');
7496                if($sound === false) {
7497                    player.api('setVolume', 0);
7498                }
7499            }, timer);
7500        }
7501
7502    });
7503}
7504
7505// Pre RequireJS hot bug fixing
7506
7507function videoLoadState() {
7508    $('.mk-section-video video').each(function() {
7509        var mkVideo = this;
7510
7511        mkVideo.play();
7512        this.onload = fire();
7513
7514        function fire() {
7515            setTimeout(function() {
7516                $(mkVideo).animate({
7517                    'opacity': 1
7518                }, 300);
7519            }, 1000);
7520        }
7521    });
7522}
7523videoLoadState();
7524
7525
7526// Gmap Widget
7527(function($) {
7528
7529    $(window).on('load vc_reload', initialize);
7530
7531    function initialize() {
7532        var $gmap = $('.gmap_widget');
7533        if($gmap.length && typeof google !== 'undefined') $gmap.each(run);
7534    }
7535
7536    function run() {
7537        var $mapHolder = $(this);
7538        var myLatlng = new google.maps.LatLng($mapHolder.data('latitude'), $mapHolder.data('longitude'));
7539        var mapOptions = $mapHolder.data('options');
7540            mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;
7541            mapOptions.center = myLatlng;
7542        var map = new google.maps.Map(this, mapOptions);
7543
7544        new google.maps.Marker({
7545            position: myLatlng,
7546            map: map
7547        });
7548    }
7549
7550}(jQuery));
7551
7552// Instagram Widget
7553(function($) {
7554
7555    $(window).on('load', function() {
7556        var $feeds = $('.mk-instagram-feeds');
7557        if($feeds.length) $feeds.each(run);
7558    });
7559
7560    function run() {
7561        var options = $(this).data('options');
7562            options.template = '<a class="featured-image '+options.tmp_col+'-columns" href="{{link}}" target="_'+options.tmp_target+'"><div class="item-holder"><img src="{{image}}" /><div class="image-hover-overlay"></div></div></a>';
7563        var feed = new Instafeed(options);
7564        feed.run();
7565    }
7566}(jQuery));
7567
7568
7569// Flipbox backface visibility fix for chrome
7570(function($) {
7571     $(window).on('load', function() {
7572         setTimeout( function() {
7573            $('.chrome-flipbox-backface-fix').removeClass('chrome-flipbox-backface-fix');
7574         }, 300);
7575     });
7576}(jQuery));
7577
7578
7579/* Product in VC Tab Bug Fix
7580/* -------------------------------------------------------------------- */
7581(function($) {
7582    $(window).on('load', function() {
7583        $('.vc_tta-tab a').on('click', function() {
7584            setTimeout( function() {
7585                $(window).trigger('resize');
7586            }, 100);
7587        });
7588    });
7589}(jQuery));
7590
7591
7592/* Vertical menu fix when childrens exceed screen height
7593/* -------------------------------------------------------------------- */
7594(function($) {
7595    $(window).on('load', function() {
7596        $('#mk-vm-menu .menu-item-has-children, #mk-vm-menu .mk-vm-back').on('mouseenter', function() {
7597            var $header_inner = $(this).closest('.mk-header-inner'),
7598                $header_inner_height = $header_inner.outerHeight(),
7599                $header_bg = $header_inner.find('.mk-header-bg'),
7600                total_height = 0;
7601            $header_bg.css('height', '100%');
7602            setTimeout( function() {
7603                $header_inner.children(':visible').each(function() {
7604                    total_height += $(this).outerHeight(true);
7605                });
7606                total_height -= $header_bg.height();
7607                if ( total_height < $header_inner_height ) {
7608                    $header_bg.css('height', '100%');
7609                } else {
7610                    $header_bg.css('height', total_height + 'px');
7611                }
7612            }, 600);
7613        });
7614    });
7615}(jQuery));
7616
7617
7618/* Woocommerce varitions lightbox fix
7619/* -------------------------------------------------------------------- */
7620(function($) {
7621    $(window).on('load', function() {
7622
7623        var $variations_form = $('.variations_form');
7624
7625        if ( $variations_form.length ) {
7626
7627            var $varitions_selects = $variations_form.find('.variations').find('.value').find('select');
7628            $varitions_selects.on('change', function() {
7629
7630                // Woocommerce variations lightbox with galleries
7631                var $all_img_container = $('.mk-product-image .mk-woocommerce-main-image');
7632                if ( $all_img_container.length ) {
7633                    $( $all_img_container ).each( set_lightbox_href );
7634                }
7635
7636            });
7637            $varitions_selects.trigger('change');
7638
7639        }
7640
7641    });
7642
7643    function set_lightbox_href() {
7644
7645        var $product_img = $( this ).find( 'img' ),
7646            $lightbox    = $( this ).find( '.mk-lightbox' );
7647
7648        setTimeout( function() {
7649            var image_url    = $product_img.attr( 'src' ),
7650                image_suffix = image_url.substr( image_url.lastIndexOf('.') - image_url.length ), // Get image suffix
7651                image_url    = image_url.slice( 0 , image_url.lastIndexOf('-') ); // Remove image size
7652            $lightbox.attr('href', image_url + image_suffix );
7653        }, 300);
7654    }
7655
7656}(jQuery));
7657
7658
7659/* Remove video section when on mobile */
7660/* -------------------------------------------------------------------- */
7661(function($) {
7662    if ( MK.utils.isMobile() ) {
7663      $('.mk-section-video video').remove();
7664    }
7665}(jQuery));
7666
7667
7668/* Yith AJAX Product Filter & Yith Infinite Scrolling Plugin Fix
7669/* -------------------------------------------------------------------- */
7670(function($) {
7671    $(window).on('load', function() {
7672
7673        $(document).on( 'yith-wcan-ajax-filtered yith_infs_added_elem yith-wcan-ajax-reset-filtered', function(){
7674            setTimeout( function() {
7675                MK.utils.eventManager.publish('ajaxLoaded');
7676                MK.core.initAll( document );
7677            }, 1000 );
7678        });
7679
7680        // Fixed YITH Filter plugin causes issue for dropdown sort
7681        $(document).on( 'yith-wcan-ajax-filtered yith-wcan-ajax-reset-filtered', function(){
7682            setTimeout( function() {
7683                $( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function() {
7684                    $( this ).closest( 'form' ).submit();
7685                });
7686            }, 1000 );
7687        });
7688
7689    });
7690}(jQuery));
7691
7692
7693/* Toggle loading state in URL for anchor links.
7694 * - Add a filter to escape meta-chars from hash string.
7695/* -------------------------------------------------------------------- */
7696!function(e){var a=window.location,n=a.hash;if(n.length&&n.substring(1).length){var hSuf = n.substring(1).replace(/[!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g, "\\$&");var r=e(".vc_row, .mk-main-wrapper-holder, .mk-page-section, #comments"),t=r.filter("#"+hSuf);if(!t.length)return;n=n.replace("!loading","");var i=n+"!loading";a.hash=i}}(jQuery);
7697
7698
7699/* Determine the top spacing of sidebar for full-width page section & row.
7700/* -------------------------------------------------------------------- */
7701function mkPositionSidebar() {
7702	
7703	var themeContent = $( '.theme-content' ),
7704		lastFullWidthChild = themeContent.find( '.vc_row-full-width' ).last(),
7705		top,
7706		sidebar = $( '#theme-page > .mk-main-wrapper-holder > .theme-page-wrapper > #mk-sidebar' );
7707
7708	if ( ! lastFullWidthChild.length ) {
7709		sidebar.removeAttr( 'style' );
7710		return;
7711	}
7712
7713	top = lastFullWidthChild.offset().top - themeContent.offset().top;
7714	sidebar.css( 'padding-top', top );
7715}
7716
7717function mk_accordion_toggles_tooltip() {
7718
7719  "use strict";
7720
7721
7722  /* Message Boxes */
7723  /* -------------------------------------------------------------------- */
7724
7725  $('.box-close-btn').on('click', function() {
7726    $(this).parent().fadeOut(300);
7727    return false;
7728
7729  });
7730
7731}
7732
7733function mk_portfolio_ajax() {
7734  "use strict";
7735
7736  var headerHeight = 0;
7737  if ($.exists("#wpadminbar")) {
7738    headerHeight += $("#wpadminbar").height();
7739  }
7740  if (!$.exists('.mk-vm-menuwrapper')) {
7741    headerHeight += parseInt($('.mk-header').attr('data-sticky-height'));
7742  }
7743
7744  function init() {
7745    var $portfolio = $('.portfolio-grid.portfolio-ajax-enabled');
7746    if (!$portfolio.length) return; // quit if no portfolio wrappers
7747    MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.ajax.portfolio.js' ], function() {
7748      // wait for ajax response propagation and insertion
7749      setTimeout(function() {
7750        $portfolio.each( function() {
7751          $(this).ajaxPortfolio({ extraOffset: headerHeight });
7752        });
7753      }, 100);
7754    });
7755  }
7756
7757  init();
7758
7759  // Reinit when ajax loaded stuff
7760  // We have global reinit on Components. so move the ajaxPortfolio to component namespace as a standalone module to get it right.
7761  MK.utils.eventManager.subscribe('ajaxLoaded', init);
7762}
7763
7764/**
7765 * Ajax Search on header nav.
7766 */
7767function mk_ajax_search() {
7768    "use strict";
7769
7770    // Check if ajax search box enabled.
7771    if (mk_ajax_search_option !== "beside_nav") {
7772        return;
7773    }
7774
7775    // Set minimum length of text to get ajax result.
7776    var minimumLengthToSearch = 3;
7777    var $mkAjaxSearchInput = $('#mk-ajax-search-input');
7778    var security = $mkAjaxSearchInput.siblings('input[name="security"]').val();
7779    var wpHttpReferer = $mkAjaxSearchInput.siblings('input[name="_wp_http_referer"]').val();
7780    var querySpliter = (ajaxurl.indexOf('?') > -1) ? '&' : '?';
7781    var ul = document.getElementById('mk-nav-search-result');
7782    var searchTerm; // Search term
7783    var requestCounter = 0;
7784    var responseCounter = 0;
7785
7786    // Add listener for getting result quickly while user entering text, past text and etc.
7787    $mkAjaxSearchInput.on('paste input propertychange', onSearchBoxInput);
7788
7789    /**
7790     * Callback function for entering search term listener (e.g. keyup).
7791     * It will generate AJAX request to get data.
7792     *
7793     * @param e
7794     */
7795    function onSearchBoxInput(e) {
7796        var target = e.target || e.srcElement;
7797        var newValue = target.value;
7798
7799        // Check if user change the value of text box
7800        if (searchTerm !== newValue) {
7801            searchTerm = newValue;
7802            ul.innerHTML = '';
7803            if (searchTerm.length >= minimumLengthToSearch) {
7804                // Show loading icon
7805                $mkAjaxSearchInput.addClass('ajax-searching');
7806                requestCounter++;
7807                $.getJSON(ajaxurl + querySpliter + 'callback=?&action=mk_ajax_search&security=' + security + '&_wp_http_referer=' + wpHttpReferer + '&term=' + searchTerm)
7808                    .done(showSearchResult)
7809                    .fail(showErrorMessage);
7810            }
7811        }
7812    }
7813
7814    /**
7815     * Callback function for the response of the search request.
7816     *
7817     * @param data
7818     */
7819    function showSearchResult(data) {
7820        responseCounter++;
7821
7822        // Only show response of latest request.
7823        if (isCorrectResponse()) {
7824            if (data.length > 0) {
7825                // Append result to result container
7826                for (var i = 0; i < data.length; i++) {
7827                    var item = data[i];
7828                    $('<li>').append('<a href="' + item.link + '">' + item.image + '<span class="search-title">' + item.label + '</span><span class="search-date">' + item.date + '</span></a>').appendTo(ul);
7829                }
7830            } else {
7831                // Show no result message
7832                ul.innerHTML = '<li class="mk-nav-search-result-zero">No Result.</li>';
7833            }
7834
7835            // Hide loading icon
7836            $mkAjaxSearchInput.parent('form').removeClass('ajax-searching').addClass('ajax-search-complete');
7837        }
7838    }
7839
7840    /**
7841     * If any errors, we need a handler to show error message.
7842     */
7843    function showErrorMessage() {
7844        responseCounter++;
7845
7846        if (isCorrectResponse()) {
7847            ul.innerHTML = '<li class="mk-nav-search-error-message">Can not search! Please try again.</li>';
7848        }
7849    }
7850
7851    /**
7852     * Check if the response is right for the request. we show latest response only.
7853     *
7854     * @returns {boolean}
7855     */
7856    function isCorrectResponse() {
7857        return requestCounter === responseCounter;
7858    }
7859}
7860/* Background Parallax Effects */
7861/* -------------------------------------------------------------------- */
7862
7863function mk_backgrounds_parallax() {
7864
7865  "use strict";
7866
7867  if (mk_header_parallax == true) {
7868    $('.mk-header-bg').addClass('mk-parallax-enabled');
7869  }
7870  if (mk_body_parallax == true) {
7871    $('body').addClass('mk-parallax-enabled');
7872  }
7873  if (mk_banner_parallax == true) {
7874    $('.mk-header').addClass('mk-parallax-enabled');
7875  }
7876  if (mk_footer_parallax == true) {
7877    $('#mk-footer').addClass('mk-parallax-enabled');
7878  }
7879
7880  $('.mk-parallax-enabled').each(function () {
7881    var $this = $( this );
7882    if (!MK.utils.isMobile()) {
7883      MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() {
7884        $this.parallax("49%", 0.3);
7885      });
7886    }
7887  });
7888
7889  $('.mk-fullwidth-slideshow.parallax-slideshow').each(function () {
7890    var $this = $( this );
7891    if (!MK.utils.isMobile()) {
7892      MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() {
7893        var speed_factor = $this.attr('data-speedFactor');
7894        $this.parallax("49%", speed_factor);
7895      });
7896    }
7897  });
7898
7899}
7900/* Blog, Portfolio Audio */
7901/* -------------------------------------------------------------------- */
7902
7903function loop_audio_init() {
7904  if ($.exists('.jp-jplayer')) {
7905    $('.jp-jplayer.mk-blog-audio').each(function () {
7906      var $this = $( this );
7907      MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.jplayer.js' ], function() {
7908        var css_selector_ancestor = "#" + $this.siblings('.jp-audio').attr('id');
7909        var ogg_file, mp3_file, mk_theme_js_path;
7910        ogg_file = $this.attr('data-ogg');
7911        mp3_file = $this.attr('data-mp3');
7912        $this.jPlayer({
7913          ready: function () {
7914            $this.jPlayer("setMedia", {
7915              mp3: mp3_file,
7916              ogg: ogg_file
7917            });
7918          },
7919          play: function () { // To avoid both jPlayers playing together.
7920            $this.jPlayer("pauseOthers");
7921          }, 
7922          swfPath: mk_theme_js_path,
7923          supplied: "mp3, ogg",
7924          cssSelectorAncestor: css_selector_ancestor,
7925          wmode: "window"
7926        });
7927      });
7928    });
7929  }
7930}
7931
7932
7933/* Blog Loop Carousel Shortcode */
7934/* -------------------------------------------------------------------- */
7935
7936
7937function mk_blog_carousel() {
7938
7939  "use strict";
7940
7941  if (!$.exists('.mk-blog-showcase')) {
7942    return;
7943  }
7944  $('.mk-blog-showcase ul li').each(function () {
7945
7946    $(this).on('hover', function () {
7947
7948      $(this).siblings('li').removeClass('mk-blog-first-el').end().addClass('mk-blog-first-el');
7949
7950    });
7951
7952  });
7953
7954
7955}
7956
7957
7958
7959
7960/**
7961 * Contact Form
7962 *
7963 * Mostly implemented in Vanilla JS instead of jQuery.
7964 */
7965function mk_contact_form() {
7966    "use strict";
7967    var mkContactForms = document.getElementsByClassName('mk-contact-form');
7968    if (mkContactForms.length === 0) {
7969        return;
7970    }
7971    var captchaImageHolder = $('.captcha-image-holder');
7972    var activeClassName = 'is-active';
7973    var invalidClassName = 'mk-invalid';
7974    for (var i = 0; i < mkContactForms.length; i++) {
7975        initializeForm(mkContactForms[i], activeClassName, invalidClassName);
7976    }
7977    if (captchaImageHolder.length > 0) {
7978        $(window).on('load', initializeCaptchas);
7979    }
7980    /**
7981     * Initialize mk forms. e.g add activeClassName for inputs.
7982     *
7983     * @param form
7984     * @param activeClassName
7985     * @param invalidClassName
7986     */
7987    function initializeForm(form, activeClassName, invalidClassName) {
7988        var inputs = getFormInputs(form);
7989        for (var i = 0; i < inputs.length; i++) {
7990            markActiveClass(inputs[i]);
7991        }
7992        form.addEventListener('submit', function(e) {
7993            validateForm(e, invalidClassName);
7994        });
7995        /**
7996         * Set activeClassName for the parent node of the inout
7997         */
7998        function setActiveClass() {
7999            addClass(this.parentNode, activeClassName);
8000        }
8001        /**
8002         * Unset activeClassName from the parent node of the input.
8003         * We need to unset activeClassName only if the data was empty.
8004         * e.g. in the line style of the mk-contact-form, we set labels position based on activeClassName.
8005         */
8006        function unsetActiveClass() {
8007            if (this.value === '') {
8008                removeClass(this.parentNode, activeClassName);
8009            }
8010        }
8011        /**
8012         * Add event listeners (focus,blur) for input to set and unset activeClassName.
8013         *
8014         * @param input
8015         */
8016        function markActiveClass(input) {
8017            input.addEventListener('focus', setActiveClass);
8018            input.addEventListener('blur', unsetActiveClass);
8019        }
8020    }
8021    /**
8022     * Validate form when it's submitted. If everything was valid, we with post form in ajax request.
8023     *
8024     * @param e
8025     * @param invalidClassName
8026     */
8027    function validateForm(e, invalidClassName) {
8028        e.preventDefault();
8029        var form = e.target || e.srcElement;
8030        var inputs = getFormInputs(form);
8031        var isValidForm = true;
8032        var hasCaptchaField = false;
8033        for (var i = 0; i < inputs.length; i++) {
8034            var input = inputs[i];
8035            input.value = String(input.value).trim();
8036            switch (input.type) {
8037                case 'hidden':
8038                    break;
8039                case 'checkbox':
8040                    isValidForm = validateCheckBox(input, invalidClassName) && isValidForm;
8041                    break;
8042                case 'email':
8043                    isValidForm = validateEmail(input, invalidClassName) && isValidForm;
8044                    break;
8045                case 'textarea':
8046                    isValidForm = validateText(input, invalidClassName) && isValidForm;
8047                    break;
8048                case 'text':
8049                    /**
8050                     * Some old browsers such as IE 8 and 9 detect email type as text.
8051                     * So, we need to extra check for data-type attribute
8052                     */
8053                    if (input.dataset.type === 'captcha') {
8054                        isValidForm = validateText(input, invalidClassName) && isValidForm;
8055                        hasCaptchaField = true;
8056                    } else if (input.dataset.type === 'email') {
8057                        isValidForm = validateEmail(input, invalidClassName) && isValidForm;
8058                    } else {
8059                        isValidForm = validateText(input, invalidClassName) && isValidForm;
8060                    }
8061                    break;
8062                default:
8063                    /**
8064                     * e.g. validating for radiobox, selectbox and etc.
8065                     */
8066                    console.warn('Implement validation for ' + input.name + ':' + input.type);
8067                    break;
8068            }
8069        }
8070        if (isValidForm) {
8071            if (hasCaptchaField) {
8072                validateCaptcha(form, invalidClassName, sendForm);
8073            } else {
8074                sendForm(form);
8075            }
8076        }
8077    }
8078    /**
8079     * Validate captcha of form. If everything was, we will execute captchaIsValidCallback which as sendForm().
8080     *
8081     * @param form
8082     * @param invalidClassName
8083     * @param captchaIsValidCallback
8084     * @returns boolean
8085     */
8086    function validateCaptcha(form, invalidClassName, captchaIsValidCallback) {
8087        var input = form.querySelectorAll('[data-type="captcha"]')[0];
8088        if (input.value.length === 0) {
8089            addClass(input, invalidClassName);
8090            return false;
8091        } else {
8092            window.get.captcha(input.value).done(function(data) {
8093                loadCaptcha();
8094                input.value = '';
8095                if (data !== 'ok') {
8096                    addClass(input, invalidClassName);
8097                    addClass(input, 'contact-captcha-invalid');
8098                    removeClass(input, 'contact-captcha-valid');
8099                    input.placeholder = mk_captcha_invalid_txt;
8100                } else {
8101                    removeClass(input, invalidClassName);
8102                    removeClass(input, 'contact-captcha-invalid');
8103                    addClass(input, 'contact-captcha-valid');
8104                    input.placeholder = mk_captcha_correct_txt;
8105                    captchaIsValidCallback(form);
8106                }
8107            });
8108        }
8109    }
8110    /**
8111     * Send submitted form.
8112     *
8113     * @param form
8114     */
8115    function sendForm(form) {
8116        var $form = $(form);
8117        var data = getFormData(form);
8118        progressButton.loader($form);
8119        $.post(ajaxurl, data, function(response) {
8120            var res = JSON.parse(response);
8121            if (res.action_Status) {
8122                progressButton.success($form);
8123                $form.find('.text-input').val('');
8124                $form.find('textarea').val('');
8125                $form.find('input[type=checkbox]').attr("checked", false);
8126                $form.find('.contact-form-message').slideDown().addClass('state-success').html(res.message);
8127                setTimeout(function() {
8128                   $form.find('.contact-form-message').slideUp();  
8129                }, 5000);
8130            } else {
8131                progressButton.error($form);
8132                $form.find('.contact-form-message').removeClass('state-success').html(res.message);
8133            }
8134        });
8135    }
8136    /**
8137     * Initialize all captcha images for first time. All captcha images is always same. e.g. if we have multiple form,
8138     * all of them will have the same image.
8139     * It will also add event listener for '.captcha-change-image' objects to reload the captcha.
8140     */
8141    function initializeCaptchas() {
8142        var captchaChangeImageButtons = document.getElementsByClassName('captcha-change-image');
8143        for (var i = 0; i < captchaChangeImageButtons.length; i++) {
8144            captchaChangeImageButtons[i].addEventListener('click', loadCaptcha);
8145        }
8146    }
8147    /**
8148     * Load captcha text and append the image to captcha container.
8149     * If it used as a callback, it will prevent default behave of the event.
8150     * e.g. loading new captcha by click on <a> without changing url.
8151     */
8152    function loadCaptcha(e) {
8153        if (e) {
8154            e.preventDefault();
8155        }
8156        $.post(ajaxurl, {
8157            action: 'mk_create_captcha_image'
8158        }, appendImage);
8159        /**
8160         * The callback function for append or change old image src based on response. T
8161         * The captchaImageURL is the url of the captcha which is provided in ajax response of mk_create_captcha_image.
8162         * @param captchaImageURL
8163         */
8164        function appendImage(captchaImageURL) {
8165            if (captchaImageHolder.find('.captcha-image').length === 0) {
8166                captchaImageHolder.html('<img src="' + captchaImageURL + '" class="captcha-image" alt="captcha txt">');
8167            } else {
8168                captchaImageHolder.find('.captcha-image').attr("src", captchaImageURL + '?' + new Date().getTime());
8169            }
8170        }
8171    }
8172    /**
8173     * Get form inputs using querySelectorAll().
8174     * It returns <input> and <textarea> tags. If you need any other tags such as <select>, please update this function.
8175     *
8176     * @param form
8177     * @returns {NodeList}
8178     */
8179    function getFormInputs(form) {
8180        return form.querySelectorAll('input,textarea');
8181    }
8182    /**
8183     * Get data of the form inputs and textareas as a object.
8184     *
8185     * @param form
8186     * @returns {{action: string}}
8187     */
8188    function getFormData(form) {
8189        var data = {
8190            action: 'mk_contact_form'
8191        };
8192        var inputs = getFormInputs(form);
8193        for (var i = 0; i < inputs.length; i++) {
8194            data[inputs[i].name] = inputs[i].value;
8195        }
8196        return data;
8197    }
8198}
8199/* Ajax Login Form */
8200/* -------------------------------------------------------------------- */
8201function mk_login_form() {
8202    $('form.mk-login-form').each(function() {
8203        var $this = $(this);
8204        $this.on('submit', function(e) {
8205            $('p.mk-login-status', $this).show().text(ajax_login_object.loadingmessage);
8206            $.ajax({
8207                type: 'POST',
8208                dataType: 'json',
8209                url: ajax_login_object.ajaxurl,
8210                data: {
8211                    'action': 'ajaxlogin',
8212                    'username': $('#username', $this).val(),
8213                    'password': $('#password', $this).val(),
8214                    'security': $('#security', $this).val()
8215                },
8216                success: function(data) {
8217                    $('p.mk-login-status', $this).text(data.message);
8218                    if (data.loggedin === true) {
8219                        document.location.href = ajax_login_object.redirecturl;
8220                    }
8221                }
8222            });
8223            e.preventDefault();
8224        });
8225    });
8226}
8227/* Progress Button */
8228/* -------------------------------------------------------------------- */
8229var progressButton = {
8230    loader: function(form) {
8231        MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() {
8232            var $form = form,
8233                progressBar = $form.find(".mk-progress-button .mk-progress-inner"),
8234                buttonText = $form.find(".mk-progress-button .mk-progress-button-content"),
8235                progressButton = new TimelineLite();
8236            progressButton.to(progressBar, 0, {
8237                width: "100%",
8238                scaleX: 0,
8239                scaleY: 1
8240            }).to(buttonText, .3, {
8241                y: -5
8242            }).to(progressBar, 1.5, {
8243                scaleX: 1,
8244                ease: Power2.easeInOut
8245            }, "-=.1").to(buttonText, .3, {
8246                y: 0
8247            }).to(progressBar, .3, {
8248                scaleY: 0
8249            });
8250        });
8251    },
8252    success: function(form) {
8253        MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() {
8254            var $form = form,
8255                buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"),
8256                successIcon = $form.find(".mk-progress-button .state-success"),
8257                progressButtonSuccess = new TimelineLite({
8258                    onComplete: hideSuccessMessage
8259                });
8260            progressButtonSuccess.to(buttonText, .3, {
8261                paddingRight: 20,
8262                ease: Power2.easeInOut
8263            }, "+=1").to(successIcon, .3, {
8264                opacity: 1
8265            }).to(successIcon, 2, {
8266                opacity: 1
8267            });
8268
8269            function hideSuccessMessage() {
8270                progressButtonSuccess.reverse()
8271            }
8272        });
8273    },
8274    error: function(form) {
8275        MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() {
8276            var $form = form,
8277                buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"),
8278                errorIcon = $form.find(".mk-progress-button .state-error"),
8279                progressButtonError = new TimelineLite({
8280                    onComplete: hideErrorMessage
8281                });
8282            progressButtonError.to(buttonText, .3, {
8283                paddingRight: 20
8284            }, "+=1").to(errorIcon, .3, {
8285                opacity: 1
8286            }).to(errorIcon, 2, {
8287                opacity: 1
8288            });
8289
8290            function hideErrorMessage() {
8291                progressButtonError.reverse()
8292            }
8293        });
8294    }
8295};
8296function mk_click_events() {
8297  "use strict";
8298
8299  var eventtype = 'click'; 
8300
8301  $(".mk-header-login, .mk-header-signup, .mk-side-dashboard, .mk-quick-contact-wrapper, .mk-dashboard-trigger, .blog-share-container, .news-share-buttons, .main-nav-side-search, #mk-fullscreen-search-wrapper, #fullscreen-navigation").on(eventtype, function(event) {
8302    if (event.stopPropagation) {
8303      event.stopPropagation();
8304    } else if (window.event) {
8305      window.event.cancelBubble = true;
8306    }
8307  });
8308  $("html").on(eventtype, function() {
8309    $(".mk-login-register, .mk-header-subscribe, #mk-quick-contact, .single-share-buttons, .single-share-box, .blog-social-share, .news-share-buttons, #mk-nav-search-wrapper").fadeOut(300);
8310    $('.mk-quick-contact-link').removeClass('quick-contact-active');
8311    // Removed By Maki for repairing fullnav scroll issue. Hope it odesnt break anything
8312    // $('body').css('overflow', 'visible');
8313  });
8314
8315  $('.mk-fullscreen-search-overlay').on(eventtype,function(){
8316    $(this).removeClass('mk-fullscreen-search-overlay-show');
8317  });
8318
8319  $('.mk-forget-password').on(eventtype, function() {
8320    $('.mk-forget-panel').siblings().hide().end().show();
8321  });
8322
8323  $('.mk-create-account').on(eventtype, function() {
8324    $('#mk-register-panel').siblings().hide().end().show();
8325  });
8326
8327  $('.mk-return-login').on(eventtype, function() {
8328    $('#mk-login-panel').siblings().hide().end().show();
8329  });
8330
8331
8332  $('.mk-quick-contact-link').on(eventtype, function() {
8333    var $this = $(this),
8334        $quickContact = $('#mk-quick-contact');
8335    if (!$this.hasClass('quick-contact-active')) {
8336      $quickContact.addClass('quick-contact-anim').fadeIn(250);
8337      $this.addClass('quick-contact-active');
8338    } else {
8339      $quickContact.removeClass('quick-contact-anim').fadeOut(100);
8340      $this.removeClass('quick-contact-active');
8341    }
8342    return false;
8343  });
8344
8345}
8346
8347function mk_social_share_global() {
8348
8349  "use strict";
8350
8351  var eventtype = 'click';
8352
8353  $('.twitter-share').on(eventtype, function() {
8354    var $this = $(this),
8355        $url = $this.attr('data-url'),
8356        $title = $this.attr('data-title');
8357
8358    window.open('http://twitter.com/intent/tweet?text=' + $title + ' ' + $url, "twitterWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8359    return false;
8360  });
8361
8362  $('.pinterest-share').on(eventtype, function() {
8363    var $this = $(this),
8364        $url = $this.attr('data-url'),
8365        $title = $this.attr('data-title'),
8366        $image = $this.attr('data-image');
8367    window.open('http://pinterest.com/pin/create/button/?url=' + $url + '&media=' + $image + '&description=' + $title, "twitterWindow", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8368    return false;
8369  });
8370
8371  $('.facebook-share').on(eventtype, function() {
8372    var $url = $(this).attr('data-url');
8373    window.open('https://www.facebook.com/sharer/sharer.php?u=' + $url, "facebookWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8374    return false;
8375  });
8376
8377  $('.googleplus-share').on(eventtype, function() {
8378    var $url = $(this).attr('data-url');
8379    window.open('https://plus.google.com/share?url=' + $url, "googlePlusWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8380    return false;
8381  });
8382
8383  $('.linkedin-share').on(eventtype, function() {
8384    var $this = $(this),
8385        $url = $this.attr('data-url'),
8386        $title = $this.attr('data-title'),
8387        $desc = $this.attr('data-desc');
8388    window.open('http://www.linkedin.com/shareArticle?mini=true&url=' + $url + '&title=' + $title + '&summary=' + $desc, "linkedInWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8389    return false;
8390  });
8391}
8392
8393
8394/* Event Count Down */
8395/* -------------------------------------------------------------------- */
8396
8397function mk_event_countdown() {
8398  if ($.exists('.mk-event-countdown')) {
8399
8400    MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.countdown.js' ], function() {
8401
8402      $('.mk-event-countdown').each(function () {
8403        if (isTest) return;
8404        var $this = $(this),
8405          $date = $this.attr('data-date'),
8406          $offset = $this.attr('data-offset');
8407
8408        $this.downCount({
8409          date: $date,
8410          offset: $offset
8411        });
8412      });
8413      
8414    });
8415  }
8416}
8417/* Flexslider init */
8418/* -------------------------------------------------------------------- */
8419
8420function mk_flexslider_init() {
8421
8422  var $lcd = $('.mk-lcd-slideshow'),
8423      $laptop = $('.mk-laptop-slideshow-shortcode');
8424
8425  if($lcd.length) $lcd.find('.mk-lcd-image').fadeIn();
8426  if($laptop.length) $laptop.find(".mk-laptop-image").fadeIn();
8427
8428  $('.js-flexslider').each(function () {
8429
8430    if ($(this).parents('.mk-tabs').length || $(this).parents('.mk-accordion').length) {
8431      $(this).removeData("flexslider");
8432    }
8433
8434    var $this = $(this),
8435      $selector = $this.attr('data-selector'),
8436      $animation = $this.attr('data-animation'),
8437      $easing = $this.attr('data-easing'),
8438      $direction = $this.attr('data-direction'),
8439      $smoothHeight = $this.attr('data-smoothHeight') == "true" ? true : false,
8440      $slideshowSpeed = $this.attr('data-slideshowSpeed'),
8441      $animationSpeed = $this.attr('data-animationSpeed'),
8442      $controlNav = $this.attr('data-controlNav') == "true" ? true : false,
8443      $directionNav = $this.attr('data-directionNav') == "true" ? true : false,
8444      $pauseOnHover = $this.attr('data-pauseOnHover') == "true" ? true : false,
8445      $isCarousel = $this.attr('data-isCarousel') == "true" ? true : false;
8446
8447
8448    if ($selector !== undefined) {
8449      var $selector_class = $selector;
8450    } else {
8451      var $selector_class = ".mk-flex-slides > li";
8452    }
8453
8454    if ($isCarousel === true) {
8455      var $itemWidth = parseInt($this.attr('data-itemWidth')),
8456        $itemMargin = parseInt($this.attr('data-itemMargin')),
8457        $minItems = parseInt($this.attr('data-minItems')),
8458        $maxItems = parseInt($this.attr('data-maxItems')),
8459        $move = parseInt($this.attr('data-move'));
8460    } else {
8461      var $itemWidth = $itemMargin = $minItems = $maxItems = $move = 0;
8462    }
8463
8464    MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.flexslider.js' ], function() {
8465      $this.flexslider({
8466        selector: $selector_class,
8467        animation: $animation,
8468        easing: $easing,
8469        direction: $direction,
8470        smoothHeight: $smoothHeight,
8471        slideshow: !isTest, // autoplay
8472        slideshowSpeed: $slideshowSpeed,
8473        animationSpeed: $animationSpeed,
8474        controlNav: $controlNav,
8475        directionNav: $directionNav,
8476        pauseOnHover: $pauseOnHover,
8477        prevText: "",
8478        nextText: "",
8479        itemWidth: $itemWidth,
8480        itemMargin: $itemMargin,
8481        minItems: $minItems,
8482        maxItems: $maxItems,
8483        move: $move
8484      });
8485    });
8486
8487  });
8488
8489}
8490
8491/* Header Search Form */
8492/* -------------------------------------------------------------------- */
8493
8494function mk_header_searchform() {
8495
8496  $('.mk-search-trigger').click(function(){
8497    setTimeout(function() {
8498        $('#mk-ajax-search-input').focus();
8499    },500);
8500  });
8501
8502  "use strict";
8503
8504  $('.mk-header-toolbar .mk-header-searchform .text-input').on('focus', function () {
8505
8506    if ($('.mk-header-toolbar .mk-header-searchform .text-input').hasClass('on-close-state')) {
8507      $('.mk-header-toolbar .mk-header-searchform .text-input').removeClass('on-close-state').animate({
8508        'width': '200px'
8509      }, 200);
8510      return false;
8511    }
8512  });
8513
8514  $(".mk-header-toolbar .mk-header-searchform").click(function (event) {
8515    if (event.stopPropagation) {
8516      event.stopPropagation();
8517    } else if (window.event) {
8518      window.event.cancelBubble = true;
8519    }
8520  });
8521
8522
8523  $("html").click(function () {
8524    $(this).find(".mk-header-toolbar .mk-header-searchform .text-input").addClass('on-close-state').animate({
8525      'width': 90
8526    }, 300);
8527  });
8528
8529  // Fix search for edge browser
8530  if(MK.utils.browser.name === 'Edge') {
8531    $('#mk-fullscreen-search-input').on('keydown', function(e) {
8532      if (e.which == 13) {
8533        e.preventDefault();
8534        $('#mk-fullscreen-searchform').submit();
8535      }
8536    });
8537  }
8538 
8539}
8540
8541
8542
8543
8544/* Hover Events */
8545/* -------------------------------------------------------------------- */
8546
8547function mk_hover_events() {
8548
8549  "use strict";
8550
8551  $('.shopping-cart-header').hover(
8552    function() {
8553      $(this).find('.mk-shopping-cart-box').stop(true, true).fadeIn(250);
8554    },
8555    function() {
8556      $(this).find('.mk-shopping-cart-box').stop(true, true).delay(500).fadeOut(250);
8557    }
8558  );
8559
8560
8561  $('.widget-sub-navigation > ul > li, .widget_nav_menu ul.menu > li, .widget_product_categories ul > .cat-item').each(function() {
8562
8563    var $this = $(this),
8564        $subLevel = $this.find('ul').first();
8565
8566    if ($this.hasClass('page_item_has_children') || $this.hasClass('menu-item-has-children') || $this.hasClass('cat-parent')) {
8567      $this.on('click', function() {
8568        if($this.hasClass('toggle-active')) {
8569            $subLevel.stop(true, true).slideUp(700);  
8570            $this.removeClass('toggle-active');
8571        } else {
8572            $subLevel.stop(true, true).slideDown(700);
8573            $this.addClass('toggle-active');
8574        }
8575      });
8576
8577      $subLevel.on('click', function(e){
8578        e.stopPropagation();
8579      });
8580    }
8581
8582  });  
8583
8584  // var eventtype = mobilecheck() ? 'touchstart' : 'click';
8585  var eventtype = 'click';
8586  
8587  $('.mk-fullscreen-trigger').on(eventtype, function(e) {
8588    $('.mk-fullscreen-search-overlay').addClass('mk-fullscreen-search-overlay-show');
8589    setTimeout(function(){
8590      $("#mk-fullscreen-search-input").focus();
8591    }, 300);
8592    e.preventDefault();
8593  });
8594
8595  $('.mk-fullscreen-close').on(eventtype, function(e) {
8596    $('.mk-fullscreen-search-overlay').removeClass('mk-fullscreen-search-overlay-show');
8597    e.preventDefault();
8598  });
8599
8600}
8601
8602function mk_unfold_footer() {
8603  var $this = $('#mk-footer'),
8604      $spacer = $('#mk-footer-unfold-spacer'),
8605      $footerHeight = $this.outerHeight();
8606
8607  // Stick with CSS media query breakpoint to target exact screen width
8608  if( !window.matchMedia("(max-width: 767px)").matches ) {
8609      if ($this.hasClass('mk-footer-unfold')) {
8610        $spacer.css('height', $footerHeight);
8611      }
8612  } else {
8613     $spacer.css('height', 0);
8614  }
8615}
8616/* jQuery fancybox lightbox */
8617/* -------------------------------------------------------------------- */
8618function mk_lightbox_init() {
8619
8620var $lightbox = $(".mk-lightbox");
8621
8622  $lightbox.fancybox({
8623            padding: 15,
8624            margin: 15, 
8625
8626            width: 800,
8627            height: 600,
8628            minWidth: 100,
8629            minHeight: 100,
8630            maxWidth: 9999,
8631            maxHeight: 9999,
8632            pixelRatio: 1, // Set to 2 for retina display support
8633
8634            autoSize: true,
8635            autoHeight: false,
8636            autoWidth: false,
8637
8638            autoResize: true,
8639            fitToView: true,
8640            aspectRatio: false,
8641            topRatio: 0.5,
8642            leftRatio: 0.5,
8643
8644            scrolling: 'auto', // 'auto', 'yes' or 'no'
8645            wrapCSS: '',
8646
8647            arrows: true,
8648            closeBtn: true,
8649            closeClick: false,
8650            nextClick: false,
8651            mouseWheel: true,
8652            autoPlay: false,
8653            playSpeed: 3000,
8654            preload: 3,
8655            modal: false,
8656            loop: true,
8657            // Properties for each animation type
8658            // Opening fancyBox
8659            openEffect: 'fade', // 'elastic', 'fade' or 'none'
8660            openSpeed: 200,
8661            openEasing: 'swing',
8662            openOpacity: true,
8663            openMethod: 'zoomIn',
8664
8665            // Closing fancyBox
8666            closeEffect: 'fade', // 'elastic', 'fade' or 'none'
8667            closeSpeed: 200,
8668            closeEasing: 'swing',
8669            closeOpacity: true,
8670            closeMethod: 'zoomOut',
8671
8672            // Changing next gallery item
8673            nextEffect: 'none', // 'elastic', 'fade' or 'none'
8674            nextSpeed: 350,
8675            nextEasing: 'swing',
8676            nextMethod: 'changeIn',
8677
8678            // Changing previous gallery item
8679            prevEffect: 'none', // 'elastic', 'fade' or 'none'
8680            prevSpeed: 350,
8681            prevEasing: 'swing',
8682            prevMethod: 'changeOut',
8683            helpers : {
8684                media : {},
8685                overlay: {
8686                  locked: true 
8687                }
8688            },
8689
8690            tpl: {
8691                wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
8692                image: '<img class="fancybox-image" src="{href}" alt="" />',
8693                error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
8694                closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"><i><svg class="mk-svg-icon" svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M390.628 345.372l-45.256 45.256-89.372-89.373-89.373 89.372-45.255-45.255 89.373-89.372-89.372-89.373 45.254-45.254 89.373 89.372 89.372-89.373 45.256 45.255-89.373 89.373 89.373 89.372z"/></svg></i></a>',
8695                next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span><i><svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M144 505.6c8 0 16-3.2 22.4-8l240-225.6c6.4-6.4 9.6-14.4 9.6-22.4s-3.2-16-9.6-22.4l-240-224c-12.8-12.8-32-12.8-44.8 0s-11.2 32 1.6 44.8l214.4 201.6-216 203.2c-12.8 11.2-12.8 32 0 44.8 6.4 4.8 14.4 8 22.4 8z"/></svg></i></span></a>',
8696                prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span><i><svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M368 505.6c-8 0-16-3.2-22.4-8l-240-225.6c-6.4-6.4-9.6-14.4-9.6-24 0-8 3.2-16 9.6-22.4l240-224c12.8-11.2 33.6-11.2 44.8 1.6 12.8 12.8 11.2 32-1.6 44.8l-214.4 201.6 216 203.2c12.8 11.2 12.8 32 0 44.8-4.8 4.8-14.4 8-22.4 8z"/></svg></i></span></a>',
8697                loading: '<div id="fancybox-loading"><div></div></div>'
8698            },
8699
8700            afterLoad: function() {
8701                $('html').addClass('fancybox-lock');
8702                $('.fancybox-wrap').appendTo('.fancybox-overlay');
8703            },
8704            beforeShow: function(){
8705                this.locked = true;
8706            },
8707            afterClose: function() {
8708                // Only for gallery shortcode.
8709                var galleryParent = this.element.parents( '.mk-gallery-item' );
8710
8711                if ( galleryParent ) {
8712                    galleryParent.removeClass('hover-state');
8713                }
8714            }
8715
8716        });
8717}
8718
8719
8720/* Milestone Number Shortcode */
8721/* -------------------------------------------------------------------- */
8722
8723function mk_milestone() {
8724
8725  "use strict";
8726
8727  if( isTest || !$.exists('.mk-milestone') ) return;
8728
8729  $('.mk-milestone').each(function () {
8730    var $this = $(this),
8731      stop_number = $this.find('.milestone-number').attr('data-stop'),
8732      animation_speed = parseInt($this.find('.milestone-number').attr('data-speed'));
8733
8734    var build = function() {
8735      if (!$this.hasClass('scroll-animated')) {
8736        $this.addClass('scroll-animated');
8737
8738        $({
8739          countNum: $this.find('.milestone-number').text()
8740        }).animate({
8741          countNum: stop_number
8742        }, {
8743          duration: animation_speed,
8744          easing: 'linear',
8745          step: function () {
8746            $this.find('.milestone-number').text(Math.floor(this.countNum));
8747          },
8748          complete: function () {
8749            $this.find('.milestone-number').text(this.countNum);
8750          }
8751        });
8752      }
8753    };
8754
8755    if ( !MK.utils.isMobile() ) {
8756      // refactored only :in-viewport logic. rest is to-do
8757      MK.utils.scrollSpy( this, {
8758          position: 'bottom',
8759          after: build
8760      });
8761    } else {
8762      build();
8763    }
8764
8765  });
8766
8767}
8768
8769
8770
8771
8772/* Recent Works Widget */
8773/* -------------------------------------------------------------------- */
8774
8775function mk_portfolio_widget() {
8776
8777  "use strict";
8778
8779  $('.widget_recent_portfolio li').each(function () {
8780
8781    $(this).find('.portfolio-widget-thumb').hover(function () {
8782
8783      $(this).siblings('.portfolio-widget-info').animate({
8784        'opacity': 1
8785      }, 200);
8786    }, function () {
8787
8788      $(this).siblings('.portfolio-widget-info').animate({
8789        'opacity': 0
8790      }, 200);
8791    });
8792
8793  });
8794}
8795
8796
8797
8798/* Skill Meter and Charts */
8799/* -------------------------------------------------------------------- */
8800function mk_skill_meter() {
8801    "use strict";
8802    if ($.exists('.mk-skill-meter')) {
8803        if (!MK.utils.isMobile()) {
8804            $(".mk-skill-meter .progress-outer").each(function() {
8805                var $this = $(this);
8806
8807                var build = function() {
8808                    if (!$this.hasClass('scroll-animated')) {
8809                        $this.addClass('scroll-animated');
8810                        $this.animate({
8811                            width: $this.attr("data-width") + '%'
8812                        }, 2000);
8813                    }
8814                };
8815
8816                MK.utils.scrollSpy( this, {
8817                    position: 'bottom',
8818                    after: build
8819                });
8820            });
8821        } else {
8822            $(".mk-skill-meter .progress-outer").each(function() {
8823                var $this = $(this);
8824                if (!$this.hasClass('scroll-animated')) {
8825                    $this.addClass('scroll-animated');
8826                    $this.css({
8827                        width: $(this).attr("data-width") + '%'
8828                    });
8829                }
8830            });
8831        }
8832    }
8833}
8834
8835// function mk_charts() {
8836//     "use strict";
8837
8838//     if( !$.exists('.mk-chart') ) return;
8839
8840//     MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.easyPieChart.js' ], function() {
8841
8842//         $('.mk-chart').each(function() {
8843
8844//             var $this = $(this),
8845//                 $parent_width = $(this).parent().width(),
8846//                 $chart_size = parseInt($this.attr('data-barSize'));
8847
8848//             if ($parent_width < $chart_size) {
8849//                 $chart_size = $parent_width;
8850//                 $this.css('line-height', $chart_size);
8851//                 $this.find('i').css({
8852//                     'line-height': $chart_size + 'px'
8853//                 });
8854//                 $this.css({
8855//                     'line-height': $chart_size + 'px'
8856//                 });
8857//             }
8858
8859//             var build = function() {
8860//                 $this.easyPieChart({
8861//                     animate: 1300,
8862//                     lineCap: 'butt',
8863//                     lineWidth: $this.attr('data-lineWidth'),
8864//                     size: $chart_size,
8865//                     barColor: $this.attr('data-barColor'),
8866//                     trackColor: $this.attr('data-trackColor'),
8867//                     scaleColor: 'transparent',
8868//                     onStep: function(value) {
8869//                         this.$el.find('.chart-percent span').text(Math.ceil(value));
8870//                     }
8871//                 });
8872//             };
8873
8874//             // refactored only :in-viewport logic. rest is to-do
8875//             MK.utils.scrollSpy( this, {
8876//                 position: 'bottom',
8877//                 after: build
8878//             });
8879
8880
8881//         });
8882//     });
8883// }
8884/* Toolbar subscribe form */
8885/* -------------------------------------------------------------------- */
8886
8887$( "#mc-embedded-subscribe-form" ).submit(function( e ){
8888    var $this = $(this);
8889  
8890    e.preventDefault();
8891    $.ajax({
8892        url: MK.core.path.ajaxUrl,
8893        type: "POST",
8894        data: {
8895            action: "mk_ajax_subscribe",
8896            email: $this.find( ".mk-subscribe--email" ).val(),
8897            list_id: $this.find( ".mk-subscribe--list-id" ).val(),
8898            optin: $this.find( ".mk-subscribe--optin" ).val()
8899        },
8900        success: function ( res ) {
8901            $this.parent().find( ".mk-subscribe--message" ).html( $.parseJSON( res ).message );
8902        }
8903    });
8904});
8905/**
8906 * Add class to tag. It's vanilla js instead of jQuery.
8907 * @param tag
8908 * @param className
8909 */
8910function addClass(tag, className) {
8911    tag.className += ' ' + className;
8912}
8913
8914/**
8915 * Remove class from tag. It's vanilla js instead of jQuery.
8916 * Replacing should be with g for replacing all occurrence.
8917 *
8918 * @param tag
8919 * @param className
8920 */
8921function removeClass(tag, className) {
8922    tag.className = tag.className.replace(new RegExp(className, 'g'), '');
8923}
8924
8925
8926/**
8927 * If we're running under Node for testing purpose.
8928 */
8929if(typeof exports !== 'undefined') {
8930    exports.addClass = addClass;
8931    exports.removeClass = removeClass;
8932}
8933
8934/*!
8935*  javascript-debounce 1.0.0
8936*
8937*  A lightweight, dependency-free JavaScript module for debouncing functions based on David Walsh's debounce function.
8938*
8939*  Source code available at: https://github.com/jgarber623/javascript-debounce
8940*
8941*  (c) 2015-present Jason Garber (http://sixtwothree.org)
8942*
8943*  javascript-debounce may be freely distributed under the MIT license.
8944*/
8945
8946(function(root, factory) {
8947	if (typeof define === "function" && define.amd) {
8948		define([], factory);
8949	} else if (typeof exports === "object") {
8950		module.exports = factory();
8951	} else {
8952		root.debounce = factory();
8953	}
8954})(this, function() {
8955	"use strict";
8956	return function(callback, delay) {
8957		var timeout;
8958		return function() {
8959			var context = this, args = arguments;
8960			clearTimeout(timeout);
8961			timeout = setTimeout(function() {
8962				callback.apply(context, args);
8963			}, delay);
8964		};
8965	};
8966});
8967
8968/**
8969 * Validate email address.
8970 *
8971 * @param input
8972 * @param invalidClassName
8973 * @returns boolean
8974 */
8975function validateEmail(input, invalidClassName) {
8976    var value = input.value.trim();
8977    if ((input.required || value.length > 0) && !/^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,63})$/i.test(value)) {
8978        if (invalidClassName) {
8979            addClass(input, invalidClassName);
8980        }
8981        return false;
8982    } else {
8983        if (invalidClassName) {
8984            removeClass(input, invalidClassName);
8985        }
8986        return true;
8987    }
8988}
8989/**
8990 * Validate text entry.
8991 *
8992 * @param input
8993 * @param invalidClassName
8994 * @returns boolean
8995 */
8996function validateText(input, invalidClassName) {
8997    var value = input.value.trim();
8998    if (input.required && value.length === 0) {
8999        if (invalidClassName) {
9000            addClass(input, invalidClassName);
9001        }
9002        return false;
9003    } else {
9004        if (invalidClassName) {
9005            removeClass(input, invalidClassName);
9006        }
9007        return true;
9008    }
9009}
9010/**
9011 * Validate Checkbox.
9012 *
9013 * @param input
9014 * @param invalidClassName
9015 * @returns boolean
9016 */
9017function validateCheckBox(input, invalidClassName) {
9018    if (input.required && input.checked == false) {
9019        if (invalidClassName) {
9020            addClass(input, invalidClassName);
9021        }
9022        return false;
9023    } else {
9024        if (invalidClassName) {
9025            removeClass(input, invalidClassName);
9026        }
9027        return true;
9028    }
9029}
9030/**
9031 * If we're running under Node for testing purpose.
9032 */
9033if (typeof exports !== 'undefined') {
9034    exports.validateEmail = validateEmail;
9035    exports.validateText = validateText;
9036}
9037(function( $ ) {
9038	'use strict';
9039
9040    var $wrapper = $('.js-bottom-corner-btns');
9041    var $contactBtn = $wrapper.find('.js-bottom-corner-btn--contact');
9042    var $backBtn = $wrapper.find('.js-bottom-corner-btn--back');
9043    var hasContactBtn = $contactBtn.length;
9044    var hasBackBtn = $backBtn.length;
9045
9046    if(!hasBackBtn) return;
9047
9048    function deactivate() {
9049        $contactBtn.removeClass('is-active');
9050        $backBtn.removeClass('is-active');
9051    }
9052
9053    function activate() { 
9054        $contactBtn.addClass('is-active');
9055        $backBtn.addClass('is-active');
9056    }
9057
9058    MK.utils.scrollSpy( 400, {
9059        before: deactivate,
9060        after: activate
9061    });
9062
9063})( jQuery );
9064(function($) {
9065	'use strict';
9066	
9067	$('.mk-fullscreen-nav-close, .mk-fullscreen-nav-wrapper, #fullscreen-navigation a').on('click', function(e) {
9068		
9069		// Close nav with removing classes
9070		$('.mk-fullscreen-nav').removeClass('opened');
9071		$('.mk-dashboard-trigger').removeClass('fullscreen-active');
9072		$('body').removeClass('fullscreen-nav-opened'); 
9073		
9074		var anchor = MK.utils.detectAnchor( this ),
9075		$this = $( this );
9076		
9077		// Scroll to anchor if exists
9078		if( anchor.length ) {
9079			// Moved 4 these lines after anchor check because console error. If anchor
9080			// return false, split part will throw an error because $this is not a link.
9081			// Fix AM-2027
9082			var href = $this.attr( 'href' ).split( '#' )[0];
9083			var url = window.location.href;
9084			var isSamePage = url.indexOf( href ) !== -1;
9085
9086			if ( isSamePage ) {
9087				e.preventDefault();
9088			}
9089			MK.utils.scrollToAnchor( anchor );
9090			
9091		// Or do nothing if pointless # as href
9092		// BAD  PRACTICE: it is very popular to use "#" for click elements that we listen to with js.
9093		// GOOD PRACTICE: prefer "javascript:;" as easier to handle and more readable version
9094		} else if( $this.attr( 'href' ) === '#' ) {
9095			e.preventDefault();
9096		}
9097	});
9098	
9099	$('.fullscreen-navigation-ul .menu-sub-level-arrow').on('click', function(){
9100		$(this).siblings('.sub-menu').slideToggle();
9101	});
9102	
9103}(jQuery));
9104(function($) {
9105	'use strict';
9106
9107	/**
9108     * Mega menu
9109     */
9110    var $navList = $(".main-navigation-ul");
9111    var megaMenu = function megaMenu() {
9112
9113        $navList.MegaMenu({
9114            type: "vertical",
9115            delay: 200
9116        });
9117    };
9118
9119    $(window).on('load', megaMenu);
9120
9121}(jQuery));
9122(function($) {
9123	'use strict';
9124
9125	/**
9126     * One pager menu hash update. 
9127     * Smooth scroll is appended globally whenever the click element has corresponding #el
9128     */    
9129    var onePageNavItem = function onePageNavItem() {
9130        var $this = $( this ),
9131            link = $this.find( 'a' ),
9132            anchor = MK.utils.detectAnchor( link ); // anchor on current page
9133
9134        if( !anchor.length ) return;
9135
9136        $this.removeClass( 'current-menu-item current-menu-ancestor current-menu-parent' );
9137
9138        var activeNav = function( state ) {
9139            return function() {
9140                $this[ state ? 'addClass' : 'removeClass' ]( 'current-menu-item' );
9141                window.history.replaceState( undefined, undefined, [ state ? anchor : ' ' ] );
9142            };
9143        };
9144
9145        MK.utils.scrollSpy( $( anchor )[0], {
9146            before : activeNav( false ),
9147            active : activeNav( true ),
9148            after  : activeNav( false ),
9149        });
9150    };
9151
9152    var $navItems = $('.js-main-nav').find( 'li' );
9153    
9154    $(window).on('load', function() {
9155        // Wait with spying anchors so we do not assign anchor that is browser scroll to after page load
9156        // Especially when there are anchors on top - refreshing page can cause grabbing one of them into url
9157        // and force unwanted scroll
9158        setTimeout(function() {
9159            $navItems.each( onePageNavItem );
9160        }, 1000);
9161    });
9162	
9163}(jQuery));
9164(function($) {
9165    'use strict';
9166
9167    var $window = $(window);
9168    var $body = $('body');
9169    var $resMenuWrap = $('.mk-responsive-wrap');
9170    var $post_nav = $('.mk-post-nav');
9171    var $toolbar = $('.mk-header-toolbar');
9172    var $resMenuLink = $('.mk-nav-responsive-link');
9173
9174    // Flags
9175    var hasResMenu = ($resMenuWrap.length > 0);
9176
9177    //initial window and screen height
9178    var windowHeight = $window.height();
9179    var screenHeight = screen.height;
9180
9181    // We keep this handler above hasResMenu flag.
9182    // Even if our header doesn't contain droppable responsive menu (in favor of fullscreen or side menu) 
9183    // we still transform tollbar into collapsible menu part in responsive state
9184    $('.mk-toolbar-resposnive-icon').on('click', function(e) {
9185        e.preventDefault();
9186        console.log('clicked');
9187        if ($body.hasClass('toolbar-opened')) {
9188            $body.removeClass('toolbar-opened').addClass('toolbar-closed');
9189            $toolbar.hide();
9190        } else {
9191            $body.removeClass('toolbar-closed').addClass('toolbar-opened');
9192            $toolbar.show();
9193        }
9194    });
9195
9196
9197    if ( ! hasResMenu && ! $('.vc_mk_header') ) return;
9198
9199    function toggleResMenu(e) {
9200        e.preventDefault();
9201        var $this = $(this);
9202        var $headerInner = $this.parents('header');
9203        var $resMenu = $headerInner.find('.mk-responsive-wrap');
9204        var searchBox = $('.responsive-searchform .text-input');
9205        var adminBarHeight = $('#wpadminbar').height(); /* Fix AM-1918 */
9206
9207        if ($body.hasClass('mk-opened-nav')) {
9208            $this.removeClass('is-active');
9209            $body.removeClass('mk-opened-nav').addClass('mk-closed-nav').trigger('mk-closed-nav');
9210            $resMenu.hide();
9211            $post_nav.removeClass('post-nav-backward');
9212        } else {
9213            $this.addClass('is-active');
9214            $body.removeClass('mk-closed-nav').addClass('mk-opened-nav').trigger('mk-opened-nav');
9215            $resMenu.show();
9216            $post_nav.addClass('post-nav-backward');
9217
9218        }
9219
9220        //for iPhone 5 focus bug , remove search box focused class
9221        if(searchBox.hasClass('input-focused')){
9222            searchBox.removeClass('input-focused');
9223        }
9224        
9225    }
9226
9227    $resMenuLink.each(function() {
9228        $(this).on('click', toggleResMenu);
9229    });
9230
9231    $( window ).on( 'vc_reload', function () {
9232        $('.vc_mk_header .mk-nav-responsive-link').each(function() {
9233            $(this).on('click', toggleResMenu);
9234        });
9235    } )
9236
9237    var setResMenuHeight = function() {
9238        var height = $window.height() - MK.val.offsetHeaderHeight(0);
9239        $resMenuWrap.css('max-height', height);
9240    };
9241
9242    // check if device virtual keyboard is active 
9243    var isVirtualKeyboard = function() {
9244        var currentWindowHeight = $window.height();
9245        var currentScreenHeight = screen.height;
9246        var searchBox = $('.responsive-searchform .text-input');
9247        var searchBoxIsFocused = false; 
9248
9249        //for iPhone 5 focus bug , add class for detect focus state
9250        searchBox.on('touchstart touchend', function(e) {
9251            searchBox.addClass('input-focused');
9252        });
9253
9254        searchBoxIsFocused = (searchBox.is(':focus') || searchBox.hasClass("input-focused"));
9255
9256        if ($body.hasClass('mk-opened-nav') && searchBoxIsFocused && currentScreenHeight == screenHeight && currentWindowHeight != windowHeight) {
9257            return true;
9258        } else {
9259            return false;
9260        }
9261    };
9262
9263    var hideResMenu = function hideResMenu() {
9264        if (MK.utils.isResponsiveMenuState()) {
9265
9266            //when search box in responsive menu is focused , window resize fired but at this time responsive menu should be open
9267            if (!isVirtualKeyboard()) {
9268                // hide toggled menu and its states
9269                if ($body.hasClass('mk-opened-nav')) {
9270                    $resMenuLink.filter('.is-active').trigger('click');
9271                }
9272                // hide menu wrapper
9273                $resMenuWrap.hide();
9274
9275            }
9276        }
9277    };
9278
9279    $resMenuWrap.on('click', 'a', hideResMenu);
9280
9281}(jQuery));
9282
9283(function($) {
9284    'use strict';
9285
9286    var $header = $('.mk-header');    
9287    var hasHeader = ($header.length > 0);
9288
9289    if(!hasHeader && ! $('.vc_mk_header') ) return;
9290    
9291    var $sticky_style = $header.attr('data-header-style');
9292
9293    //if ($sticky_style !== 3) return;
9294
9295    $('.sidedash-navigation-ul > li').each(function() {
9296        var $this = $(this);
9297
9298        $this.children('ul').siblings('a').after('<span class="mk-nav-arrow mk-nav-sub-closed"><svg class="mk-svg-icon" data-name="mk-moon-arrow-down" data-cacheid="2" style=" height:14px; width: 14px; " xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M512 192l-96-96-160 160-160-160-96 96 256 255.999z"></path></svg></span>');
9299    });
9300
9301    function toggleSubMenu(e) {
9302        e.preventDefault();
9303        var $this = $(this);
9304        
9305        if ($this.hasClass('mk-nav-sub-closed')) {
9306            $this.siblings('ul').slideDown(450).end().removeClass('mk-nav-sub-closed').addClass('mk-nav-sub-opened');
9307        } else {
9308            $this.siblings('ul').slideUp(450).end().removeClass('mk-nav-sub-opened').addClass('mk-nav-sub-closed');
9309        }
9310    };
9311
9312    function toggleFullMenu(e) {
9313        e.preventDefault();
9314        var $this = $(this),
9315            $body = $('body'),
9316            $fullscreen_box = $('.mk-fullscreen-nav');
9317
9318        if ($this.hasClass('dashboard-style')){
9319          if (!$this.hasClass('dashboard-active')) {
9320            $this.addClass('dashboard-active');
9321            $body.addClass('dashboard-opened');
9322          } else {
9323            $this.removeClass('dashboard-active'); 
9324            $body.removeClass('dashboard-opened');
9325          }
9326        }else if($this.hasClass('fullscreen-style')){
9327          if (!$this.hasClass('fullscreen-active')) {
9328            $this.addClass('fullscreen-active');
9329            $body.addClass('fullscreen-nav-opened');
9330            $fullscreen_box.addClass('opened');
9331            // MK.utils.scroll.disable();
9332          } else {
9333            $this.removeClass('fullscreen-active');
9334            $body.removeClass('fullscreen-nav-opened');
9335            $fullscreen_box.removeClass('opened');
9336          }
9337        }
9338    }
9339
9340    $('.mk-nav-arrow').each(function() {
9341        $(this).stop(true).on('click', toggleSubMenu);
9342    });
9343
9344    $('.mk-dashboard-trigger').each(function() {
9345        $(this).on('click', toggleFullMenu);
9346    });
9347
9348    $( window ).on( 'vc_reload', function () {
9349        $('.vc_mk_header .mk-dashboard-trigger').each(function() {
9350            $(this).on('click', toggleFullMenu);
9351        });
9352
9353        $('.vc_mk_header .mk-nav-arrow').each(function() {
9354            $(this).stop(true).on('click', toggleSubMenu);
9355       });
9356    } );
9357
9358    $('html').on('click', function() {
9359        $('body').removeClass('dashboard-opened');
9360        $('.mk-dashboard-trigger').removeClass('dashboard-active');
9361    });
9362
9363}(jQuery));
9364
9365(function($) {
9366	'use strict';
9367
9368    /**
9369     * Vertical menu
9370     */
9371    var $verticalMenu = $('#mk-vm-menu');
9372    var verticalMenu = function verticalMenu() {
9373        if(!$verticalMenu.data('vertical-menu') && !MK.utils.isResponsiveMenuState()) {
9374            $verticalMenu.dlmenu();
9375            $verticalMenu.data('vertical-menu', true);
9376        }
9377    };
9378
9379    verticalMenu();
9380    $(window).on('resize', verticalMenu);
9381	
9382}(jQuery));
9383(function($) {
9384    'use strict';
9385
9386    // WPML
9387    var $lang_item = $('.mk-main-navigation > .main-navigation-ul > .menu-item-language');
9388    $lang_item.addClass('no-mega-menu').css('visibility', 'visible');
9389    $('.mk-main-navigation .menu-item-language > a').addClass('menu-item-link');
9390
9391})(jQuery);
9392(function($) {
9393	'use strict';
9394
9395    var $header = $( '.mk-header' ).first(); // Theme header is always first, do not apply to shortcode headers.
9396    var hasHeader = ($header.length > 0);
9397
9398    if(!hasHeader) return;
9399
9400    var $window = $( window );
9401    var $document = $( document );
9402    var $headerHolder = $header.find( '.mk-header-holder' );
9403    var $paddingWrapper = $header.find('.mk-header-padding-wrapper');
9404    var config = $header.data();
9405
9406    /**
9407     * Flags
9408     * @type {Boolean}
9409     */
9410    var isStickyLazy = (config.stickyStyle === 'lazy');
9411    var isStickyFixed = (config.stickyStyle === 'fixed');
9412    var isStickySlide = (config.stickyStyle === 'slide');
9413
9414    function isSticky() { // Check for sticky compatibility
9415        //return config.headerStyle !== 4; header style 4 needs sticky state for transparent header.
9416        return true;
9417    }
9418
9419    function isColorable() { // Check for coloring compatibility
9420        // TODO make it explicit in DOM that header is transparent as this is only scenario for colorable header
9421        // Monkey patch - exclude header styles that don't fit colorable
9422        return config.headerStyle !== 4;
9423    }
9424
9425
9426    /**
9427     * Change header skin
9428     */
9429	function changeSkin( e, skin ) {
9430		$header.attr( 'data-transparent-skin', skin );
9431        // Fix for class based skining
9432        var contrast = skin === 'light' ? 'dark' : 'light';
9433        $header.addClass(skin + '-skin');
9434        $header.removeClass(contrast + '-skin');
9435	}
9436
9437    if(isColorable()) MK.utils.eventManager.subscribe( 'firstElSkinChange', changeSkin );
9438
9439
9440    // Assign sticky scenarions
9441    if (isSticky() && isStickyLazy) {
9442      if(config.headerStyle !== 2) {
9443        lazySticky();
9444      }
9445    }
9446    else if (isSticky() && isStickyFixed) fixedSticky();
9447    else if (isSticky() && isStickySlide) slideSticky();
9448
9449    /**
9450     * Sticky header behavior: Lazy
9451     */
9452    function lazySticky() {
9453        var elClassHidden = 'header--hidden';
9454        var elClassSticky = 'a-sticky';
9455        var wScrollCurrent = 0;
9456        var wScrollBefore = 0;
9457        var wScrollDiff = 0;
9458        var wHeight = 0;
9459        var dHeight = 0;
9460
9461        var setSizes = function setSizes() {
9462            dHeight = $document.height();
9463            wHeight = $window.height();
9464        };
9465
9466        var onScroll = function onScroll() {
9467            wScrollCurrent = MK.val.scroll();
9468            wScrollDiff = wScrollBefore - wScrollCurrent;
9469
9470            if( wScrollCurrent <= 0 ) { // scrolled to the very top; element sticks to the top
9471                $headerHolder.removeClass( elClassHidden );
9472                $header.removeClass( elClassSticky );
9473                $('body').trigger('mk:header-unsticky');
9474
9475            } else if( wScrollDiff > 0 && $headerHolder.hasClass( elClassHidden ) ) { // scrolled up; element slides in
9476                $headerHolder.removeClass( elClassHidden );
9477                $header.addClass( elClassSticky );
9478                $('body').trigger('mk:header-sticky');
9479
9480            } else if( wScrollDiff < 0 ) { // scrolled down
9481
9482                if( wScrollCurrent + wHeight >= dHeight && $headerHolder.hasClass( elClassHidden ) ) { // scrolled to the very bottom; element slides in
9483                    $headerHolder.removeClass( elClassHidden );
9484                    $header.addClass( elClassSticky );
9485                    $('body').trigger('mk:header-sticky');
9486                } else { // scrolled down; element slides out
9487                    $headerHolder.addClass( elClassHidden );
9488                    $header.removeClass( elClassSticky );
9489                    $('body').trigger('mk:header-unsticky');
9490                }
9491            }
9492
9493            wScrollBefore = wScrollCurrent;
9494        };
9495
9496        setSizes();
9497        onScroll();
9498        $window.on( 'resize', MK.utils.throttle( 100, setSizes ) );
9499        $window.on( 'scroll', MK.utils.throttle( 500, onScroll ) );
9500    }
9501
9502
9503    /**
9504     * Sticky header behavior: Fixed
9505     */
9506    function fixedSticky() {
9507        var sticked = false;
9508        var scrollPos;
9509
9510        var toggleState = function toggleState() {
9511            scrollPos = MK.val.scroll() + MK.val.adminbarHeight();
9512
9513            if( (scrollPos > MK.val.stickyOffset() ) && ! MK.utils.isResponsiveMenuState() ) {
9514                if(sticked) return; // stop if already sticked
9515                $header.addClass('a-sticky');
9516                sticked = true;
9517                $('body').trigger('mk:header-sticky');
9518            } else {
9519                if(!sticked) return; // stop if already unsticked
9520                $header.removeClass('a-sticky');
9521                sticked = false;
9522                $('body').trigger('mk:header-unsticky');
9523            }
9524        };
9525
9526        toggleState();
9527        $window.on( 'scroll', MK.utils.throttle( 100, toggleState) );
9528        $window.on( 'resize', MK.utils.throttle( 100, toggleState) );
9529    }
9530
9531
9532    /**
9533     * Sticky header behavior: Slide
9534     */
9535    function slideSticky() {
9536        var sticked = false;
9537        var onScroll = function onScroll() {
9538            if (MK.val.scroll() > MK.val.stickyOffset()) {
9539                if(sticked) return; // stop if already sticked
9540                $header.addClass('pre-sticky');
9541                $paddingWrapper.addClass('enable-padding');
9542                setTimeout(function() {
9543                    $header.addClass('a-sticky');
9544                    $('body').trigger('mk:header-sticky');
9545                }, 1);
9546                sticked = true;
9547            } else {
9548                if(!sticked) return; // stop if already unsticked
9549                $header.removeClass('a-sticky');
9550                $header.removeClass('pre-sticky');
9551                $paddingWrapper.removeClass('enable-padding');
9552                sticked = false;
9553                $('body').trigger('mk:header-unsticky');
9554            }
9555        };
9556
9557        onScroll();
9558        $window.on( 'scroll', MK.utils.throttle( 100, onScroll) );
9559    }
9560
9561    // TODO
9562    // var pageIntro = $('body').data('intro'); // block scrolling on page intro
9563
9564
9565})( jQuery );
9566
9567(function($){
9568	'use strict';
9569
9570	// Do not assign at all if no touch events
9571	var hasTouchscreen = ('ontouchstart' in document.documentElement);
9572	if(!hasTouchscreen) return;
9573
9574	$('.mk-main-navigation .menu-item-has-children').each( normalizeClick );
9575
9576	function normalizeClick() {
9577		$(this).on('click', handleClick);
9578	}
9579
9580	// Most reasonable way to normalize click and let hover state on first touch yet don't break experience on multiple input devices is to actually check against desired effect.
9581	// Better way would be to check against expected state but JS doesn't detect :hover so it would be nice to have it normalized globally like expecting .hover class in css
9582	function handleClick(e) {
9583		var $this = $(e.currentTarget);
9584		var $child = $this.find('> ul');
9585		var isVisible = $child.css('display') !== 'none';
9586
9587		if(!isVisible) {
9588			e.preventDefault();
9589			e.stopPropagation();
9590		}
9591	}
9592
9593}(jQuery));
9594(function( $ ) {
9595	'use strict';
9596
9597	MK.ui.preloader = {
9598		dom : {
9599			overlay: '.mk-body-loader-overlay'
9600		},
9601
9602		hide : function hide() {
9603			$( this.dom.overlay ).fadeOut(600, "easeInOutExpo", function() {
9604				$('body').removeClass('loading');
9605            //$( this ).remove();
9606         });
9607		}
9608	};  
9609
9610})( jQuery ); 
9611(function($) {
9612	'use strict';
9613
9614    var _ajaxUrl = MK.core.path.ajaxUrl;
9615    var _instances = {};
9616
9617	MK.utils.ajaxLoader = function ajaxLoader(el) {
9618		// retrun a cached instance to have control over state from within multiple places
9619		// we may need for example to reset pageId when do filtering. It is really one instance that controls both filtering and pagination / load more
9620		var id = '#' + ($(el).attr('id'));
9621		if(typeof _instances[id] !== 'undefined') return _instances[id];
9622
9623		// else lets start new instance
9624		this.id = id;
9625		this.el = el;
9626		this.isLoading = false;
9627		this.xhrCounter = 0;
9628	};
9629
9630	MK.utils.ajaxLoader.prototype = { 
9631		init: function init() {
9632			// prevent double initialization of we return an instance
9633			if ( this.initialized && typeof window.vc_iframe === 'undefined' ) {
9634				return;
9635			}
9636
9637			this.createInstance();
9638			this.cacheElements();
9639
9640			this.initialized = true;
9641		},
9642
9643		cacheElements: function cacheElements() {
9644			this.$container = $(this.el);
9645			this.id = '#' + (this.$container.attr('id'));
9646	        this.categories = this.$container.data('loop-categories');
9647
9648			this.data = {};
9649			this.data.action = 'mk_load_more';
9650	        this.data.query = this.$container.data('query');
9651	        this.data.atts = this.$container.data('loop-atts');
9652	        this.data.loop_iterator = this.$container.data('loop-iterator');
9653	        this.data.author = this.$container.data('loop-author');
9654	        this.data.posts = this.$container.data('loop-posts');
9655	        this.data.safe_load_more = this.$container.siblings('#safe_load_more').val();
9656	        this.data._wp_http_referer = this.$container.siblings('input[name="_wp_http_referer"]').val();
9657	        this.data.paged = 1;
9658	        this.data.maxPages = this.$container.data('max-pages');
9659	        this.data.term = this.categories;
9660		},
9661
9662		createInstance: function() {
9663			_instances[this.id] = this;
9664		},
9665
9666		load: function load(unique) {
9667			var self = this;
9668			var seq = ++this.xhrCounter;
9669            this.isLoading = true;
9670			
9671			// If mk-ajax-loaded-posts span exists, get the post ids
9672			if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) {
9673				var loaded_posts = this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts');
9674				
9675				// Do not send looaded posts for Classic Pagination Navigation
9676				if ( this.$container.attr('data-pagination-style') != 1 ) {
9677					self.data.loaded_posts = loaded_posts.split(',');
9678				}
9679			}
9680
9681            return $.when(
9682	            $.ajax({
9683	                url 	: _ajaxUrl,
9684	                type 	: "POST",
9685	                data 	: self.data
9686	            })
9687	        ).done(function(response) {
9688	        	self.onDone(response, unique, seq);
9689	        });
9690		},
9691
9692		onDone: function(response, unique, seq) {
9693			if(seq === this.xhrCounter) {
9694				var self = this;
9695
9696				response = $.parseJSON(response);
9697				response.unique = unique;
9698				response.id = this.id;
9699				
9700				// If mk-ajax-loaded-posts span exists, update current post ids 
9701				// with new post ids from server's response
9702				if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) {
9703					this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', response.loaded_posts);
9704				}
9705
9706	            this.setData({
9707	                maxPages: response.maxPages,
9708	                found_posts: response.found_posts,
9709	                loop_iterator: response.i
9710	            });
9711
9712				// Preload images first by creating object from returned content.
9713				// mk_imagesLoaded() method will create a promise that gets resolved when all images inside are loaded.
9714				// Our ajaxLoad is somehow more similar to window.onload event now.
9715				$(response.content).mk_imagesLoaded().then(function() {
9716					MK.utils.eventManager.publish('ajaxLoaded', response);
9717		        	self.isLoading = false;
9718		        	self.initNewComponents();
9719				});
9720
9721	        } else console.log('XHR request nr '+ seq +' aborted');
9722
9723        },
9724
9725		setData: function setData(atts) {
9726			for(var att in atts) {
9727				if(att === 'term' && atts[att] === '*') this.data.term = '';
9728				else this.data[att] = atts[att];
9729			}
9730		},
9731
9732		getData: function getData(att) {
9733			return this.data[att];
9734		},
9735
9736		initNewComponents: function initNewComponents() {
9737            // Legacy scripts reinit
9738            window.ajaxInit();
9739            setTimeout(window.ajaxDelayedInit, 1000);
9740            // New way to init apended things
9741            MK.core.initAll(this.el);
9742        }
9743	};
9744
9745}(jQuery));
9746MK.component.BackgroundImageSetter = (function ($) {
9747
9748	'use strict';
9749
9750	var module = {};
9751
9752
9753	/*---------------------------------------------------------------------------------*/
9754	/* Private Variables
9755	/*---------------------------------------------------------------------------------*/
9756
9757	/**
9758	 *	Take all elements with data-mk-img-set attribute and evaluate best image according to given device orientation and resolution,
9759	 *	sets style for backround-image on the same node element.	 *
9760	 */
9761
9762	var $win = $(window),
9763		// $layers = $('[data-mk-img-set]'),
9764		screen = getScreenSize(),
9765		orientation = getOrientation(),
9766		device = getDevice(),
9767		lastOrientation = orientation,
9768		lastDevice = device;
9769
9770
9771	/*---------------------------------------------------------------------------------*/
9772	/* Private Methods
9773	/*---------------------------------------------------------------------------------*/
9774
9775	function run($layers) {
9776		$layers.filter( function() {
9777			return !this.hasAttribute("mk-img-loaded");
9778		}).each(applyBg);
9779	}
9780
9781	// Keep our main side effect out of calculations so they can be run once before loop of applying bg as a result
9782	function applyBg() {
9783		var $this = $(this),
9784			imgs = $this.data('mk-img-set');
9785
9786		$this.css('background-image', 'url('+ module.getImage(imgs) +')');
9787		$this.find('.mk-adaptive-image').attr('src', module.getImage(imgs));
9788	}
9789
9790	// Keep track of current screen size while resizing but update device reference
9791	// and reapply backgrounds only when we discover switch point
9792	function handleResize($layers) {
9793		updateScreenSize();
9794		if(hasSwitched()) {
9795			updateDevice();
9796			run($layers);
9797		}
9798	}
9799
9800	function getScreenSize() {
9801		return {
9802			w: $win.width(),
9803			h: $win.height()
9804		};
9805	}
9806
9807	// Name our device classes and add them id which simply means which one is wider
9808	function getDevice() {
9809		if     (screen.w > 1024) 	return {class: 'desktop', id: 2};
9810		else if(screen.w > 736) 	return {class: 'tablet',  id: 1};
9811		else 					 	return {class: 'mobile',  id: 0};
9812	}
9813
9814	function getOrientation() {
9815		if(screen.w > screen.h) 	return 'landscape';
9816		else 						return 'portrait';
9817	}
9818
9819	function updateScreenSize() {
9820		screen = getScreenSize();
9821	}
9822
9823	function updateDevice() {
9824		if(lastOrientation !== orientation) orientation = lastOrientation;
9825		// Switch device only if going from smaller size to bigger.
9826		// Bigger to smaller is perfectly handled by browsers and doesn't require change and reupload
9827		if(lastDevice.id > device.id) device = lastDevice;
9828	}
9829
9830	function hasSwitched() {
9831		lastOrientation = getOrientation();
9832		lastDevice = getDevice();
9833
9834		if(lastOrientation !== orientation || lastDevice.class !== device.class) return true;
9835		else return false;
9836	}
9837
9838
9839	/*---------------------------------------------------------------------------------*/
9840	/* Public Methods
9841	/*---------------------------------------------------------------------------------*/
9842
9843	// As desired image might be not available we have to evaluate the best match.
9844	module.getImage = function (imgs) {
9845		if (imgs['responsive'] === 'false') {
9846			return (imgs['landscape']['desktop']) ? imgs['landscape']['desktop'] : (imgs['landscape']['external'] ? imgs['landscape']['external'] : '');
9847
9848		}
9849		var hasOrientation = !!imgs[orientation];
9850		// there are only two orientations now and we may get them by string name if both are there
9851		// or by index of 0 if only one is available. Note Objects has no lexical order so we need to grab key name by its index.
9852		// Also we may have external file for each orientation which we don't scale internaly so we grab it as it is. If nothing found return an empty string
9853		var imgOriented = imgs[ (hasOrientation ? orientation : Object.keys(imgs)[0]) ],
9854			imgExact    = (imgOriented[device.class]) ? imgOriented[device.class] : (imgOriented['external'] ? imgOriented['external'] : '');
9855		return imgExact;
9856	}
9857
9858	module.init = function ($layers) {
9859
9860		// Run and bind
9861		run($layers);
9862		$layers.attr('mk-img-loaded', '');
9863	};
9864
9865	module.onResize = function ($layers) {
9866		$win.on('resize', MK.utils.throttle( 500, function() {
9867			handleResize($layers);
9868		}));
9869	};
9870
9871	return module;
9872
9873}(jQuery));
9874
9875
9876jQuery(function($) {
9877
9878	var init = function init() {
9879		// Get All Layers, Excluding Edge Slider and Page Section
9880		$allLayers = $('[data-mk-img-set]').filter(function(index) {
9881			return !$(this).hasClass('mk-section-image') && !$(this).hasClass('background-layer') && !$(this).hasClass('mk-video-section-touch');
9882		});;
9883
9884		// Handle the resize
9885		MK.component.BackgroundImageSetter.onResize($allLayers);
9886
9887		// Set all the BG Layers
9888		MK.component.BackgroundImageSetter.init($allLayers);
9889	}
9890	init();
9891
9892	$(window).on('vc_reload', init);
9893
9894});
9895
9896(function( $ ) {
9897	'use strict';
9898
9899	var val = MK.val;
9900
9901	MK.component.FullHeight = function( el ) {
9902		var $window = $( window ),
9903			$this = $( el ),
9904			config = $this.data( 'fullheight-config' ),
9905			container = document.getElementById( 'mk-theme-container' ),
9906			minH = (config && config.min) ? config.min : 0,
9907			winH = null,
9908			height = null,
9909			update_count = 0,
9910			testing = MK.utils.getUrlParameter('testing'),
9911			offset = null;
9912
9913		// We need to provide height on the same specificity level for workaround to IE bug
9914		// connect.microsoft.com/IE/feedback/details/802625/min-height-and-flexbox-flex-direction-column-dont-work-together-in-ie-10-11-preview
9915		// stackoverflow.com/questions/19371626/flexbox-not-centering-vertically-in-ie
9916		if(MK.utils.browser.name === ('IE' || 'Edge')) $this.css( 'height', '1px' );
9917
9918		var update = function() {
9919
9920			if(update_count === 0) {
9921				winH = $window.height();
9922				// for correct calculate
9923				offset = $this.offset().top - 1;
9924				height = Math.max(minH, winH - val.offsetHeaderHeight( offset ));
9925				$this.css( 'min-height', height );
9926				if(testing !== undefined )
9927				update_count++;
9928			}
9929
9930		};
9931
9932		// TODO remove scroll listener by dynamic offset reader
9933		var init = function() {
9934			update();
9935			$window.on( 'resize', update );
9936			$window.on( 'scroll', update );
9937			window.addResizeListener( container, update );
9938		};
9939
9940		return {
9941			init : init
9942		};
9943	};
9944
9945})( jQuery );
9946
9947
9948(function( $ ) {
9949	'use strict';
9950
9951	var core  = MK.core,
9952		utils = MK.utils,
9953		path  = MK.core.path;
9954
9955
9956	MK.ui.FullScreenGallery = function( element, settings ) {
9957		this.element = element;
9958		this.config = settings;
9959
9960		this.isFullScreen = false;
9961	};
9962
9963
9964	// preload slick PLUGIN TO USE THIS
9965	MK.ui.FullScreenGallery.prototype = {
9966		dom : {
9967			fullScrBtn 		: '.slick-full-screen',
9968			exitFullScrBtn 	: '.slick-minimize',
9969			playBtn 		: '.slick-play',
9970			pauseBtn 		: '.slick-pause',
9971			shareBtn 		: '.slick-share',
9972			socialShare 	: '.slick-social-share',
9973		    wrapper 		: '.slick-slider-wrapper',
9974			slider 			: '.slick-slides',
9975			slides 			: '.slick-slide',
9976			dots 			: '.slick-dot',
9977			active 			: '.slick-active',
9978			hiddenClass 	: 'is-hidden',
9979			dataId 			: 'slick-index'
9980		},
9981
9982		tpl: {
9983			dot  : '<div class="slick-dot"></div>',
9984			next : '<a href="javascript:;" class="slick-next"> <svg width="33px" height="65px"> <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points=" 0.5,0.5 32.5,32.5 0.5,64.5"/> </svg> </a>',
9985			prev : '<a href="javascript:;" class="slick-prev"> <svg  width="33px" height="65px"> <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points=" 32.5,64.5 0.5,32.5 32.5,0.5"/> </svg> </a>'
9986		},
9987
9988		init : function() { 
9989			var self = this;
9990
9991			// core.loadDependencies([ path.plugins + 'slick.js' ], function() {
9992				self.cacheElements();
9993				self.getViewportSizes();
9994				self.updateSizes( 'window' );
9995				self.create();
9996				// update cache with elements propagated by plugin
9997				self.updateCacheElements();
9998				self.createPagination();
9999				self.bindEvents();
10000			// });
10001		},
10002
10003		create : function() {
10004			var self = this;
10005
10006			this.slick = this.$gallery.slick({
10007		        dots: true,
10008		        arrows: true,
10009				infinite: true,
10010				speed: 300,
10011				slidesToShow: 1,
10012				centerMode: true,
10013				centerPadding: '0px',
10014				variableWidth: true,
10015				autoplay: false,
10016				autoplaySpeed: 3000,
10017        		useTransform: true,
10018                prevArrow: self.tpl.prev,
10019                nextArrow: self.tpl.next,
10020                customPaging: function(slider, i) {
10021                    return self.tpl.dot;
10022                },
10023			});
10024		},
10025
10026		cacheElements : function() {
10027			this.$window = $( window );
10028			this.$gallery = $( this.element );
10029
10030			this.$fullScrBtn = $( this.dom.fullScrBtn );
10031			this.$exitFullScrBtn = $( this.dom.exitFullScrBtn );
10032			this.$playBtn = $( this.dom.playBtn );
10033			this.$pauseBtn = $( this.dom.pauseBtn );
10034			this.$shareBtn = $( this.dom.shareBtn );
10035			this.$socialShare = $( this.dom.socialShare );
10036
10037		    this.$wrapper = $( this.dom.wrapper );
10038			this.$slider = $( this.dom.slider );
10039			this.$slides = $( this.dom.slides );
10040			this.$imgs = this.$slides.find( 'img' );
10041			// store reference to initial images without slides appended by pugin
10042			// - needed for creating of pagination
10043			this.$originalImgs = this.$imgs;
10044		},
10045
10046		updateCacheElements : function() {
10047			this.$slides = $( this.dom.slides );
10048			this.$imgs = this.$slides.find( 'img' );
10049			this.$dots = $( this.dom.dots );
10050		},
10051
10052		bindEvents : function() {
10053			var self = this;
10054			this.$fullScrBtn.on( 'click', this.toFullScreen.bind( this ) );
10055			this.$exitFullScrBtn.on( 'click', this.exitFullScreen.bind( this ) );
10056			this.$playBtn.on( 'click', this.play.bind( this ) );
10057			this.$pauseBtn.on( 'click', this.pause.bind( this ) );
10058			this.$shareBtn.on( 'click', this.toggleShare.bind( this ) );
10059			this.$socialShare.on( 'click', 'a', this.socialShare.bind( this ) );
10060			this.$window.on( 'resize', this.onResize.bind( this ) );
10061			this.$window.on( 'keydown', function(e) {
10062				if(e.keyCode === 39) self.$gallery.slick('slickNext');
10063				if(e.keyCode === 37) self.$gallery.slick('slickPrev');
10064			});
10065			$( document ).on( 'fullscreenchange mozfullscreenchange webkitfullscreenchange msfullcreenchange', this.exitFullScreen.bind( this ) );
10066		},
10067
10068		getViewportSizes : function() {
10069			this.screen = {
10070				w: screen.width,
10071				h: screen.height
10072			};
10073			this.window = {
10074				w: this.$window.width(),
10075				h: this.$window.height()
10076			};
10077		},
10078
10079		updateSizes : function( viewport ) {
10080			this.$wrapper.width( this[ viewport ].w );
10081			this.$wrapper.height( '100%' );
10082			this.$imgs.height( '100%');
10083		},
10084
10085		createPagination : function() {
10086			var self = this;
10087			this.$dots.each( function( i ) {
10088				var img = self.$originalImgs.eq( i ).attr( 'src' );
10089
10090				$( this ).css({
10091					'background-image': 'url('+ img +')'
10092				});
10093			});	
10094		},
10095
10096		play : function(e) {
10097			e.preventDefault();
10098			this.$playBtn.addClass( this.dom.hiddenClass );
10099			this.$pauseBtn.removeClass( this.dom.hiddenClass );
10100			$( this.element ).slick( 'slickPlay' );
10101		},
10102
10103		pause : function(e) {
10104			e.preventDefault();
10105			this.$pauseBtn.addClass( this.dom.hiddenClass );
10106			this.$playBtn.removeClass( this.dom.hiddenClass );
10107			$( this.element ).slick( 'slickPause' );
10108		},
10109
10110		toggleShare : function(e) {
10111			e.preventDefault();
10112			this.$socialShare.toggleClass( this.dom.hiddenClass );
10113		},
10114
10115		getCurentId : function() {
10116			return this.$slides.filter( this.dom.active ).data( this.dom.dataId );
10117		},
10118
10119		toFullScreen : function() {
10120			var self = this;
10121
10122			this.$fullScrBtn.addClass( this.dom.hiddenClass );
10123			this.$exitFullScrBtn.removeClass( this.dom.hiddenClass );
10124
10125			this.$slider.hide().fadeIn( 500 );
10126			utils.launchIntoFullscreen( document.documentElement );
10127			this.updateSizes( 'screen' );
10128			$( this.element ).slick( 'slickGoTo', this.getCurentId(), true );
10129
10130			// Update state with delay so we avoid triggering exitFullScreen fn from 
10131			// fullscreenchange event
10132			setTimeout( function() {
10133				self.isFullScreen = true;
10134			}, 1000);					
10135		},
10136
10137		exitFullScreen : function() {
10138			if( this.isFullScreen ) { 
10139				this.$exitFullScrBtn.addClass( this.dom.hiddenClass );
10140				this.$fullScrBtn.removeClass( this.dom.hiddenClass );
10141
10142				utils.exitFullscreen();
10143				this.updateSizes( 'window' );
10144				$( this.element ).slick( 'slickGoTo', this.getCurentId(), true );
10145
10146				this.isFullScreen = false;
10147			}
10148
10149		},
10150
10151		onResize : function() {
10152			this.getViewportSizes();
10153			this.updateSizes( this.isFullScreen ? 'screen' : 'window' );
10154			$( this.element ).slick( 'refresh' );  
10155			$( this.element ).slick( 'slickGoTo', this.getCurentId(), true );
10156			this.updateCacheElements();
10157			this.createPagination();
10158		},
10159
10160		socialShare : function( e ) {
10161			e.preventDefault();
10162			var $this = $( e.currentTarget ),
10163				network = $this.data( 'network' ),
10164				id = this.config.id,
10165				url = this.config.url,
10166				title = this.$wrapper.find( '.slick-title' ).text(),
10167				name;
10168				var picture = this.$slides.filter( this.dom.active ).children().first().attr( 'src' );
10169			switch( network ) {
10170				case 'facebook': 
10171					url = 'https://www.facebook.com/sharer/sharer.php?picture=' + picture+'&u=' + url + '#id=' + id;
10172					name = 'Facebook Share';
10173					break;
10174				case 'twitter':
10175					url = 'http://twitter.com/intent/tweet?text=' + url + '#id=' + id;
10176					name = 'Twitter Share';
10177					break;
10178				case 'pinterest':
10179					url = 'http://pinterest.com/pin/create/bookmarklet/?media=' + picture + '&url=' + url + '&is_video=false&description=' + title;
10180					// other available link paranmeters: media, description
10181					name = 'Pinterest Share';
10182					break;
10183
10184			}
10185
10186       		window.open( url, name, "height=380 ,width=660, resizable=0, toolbar=0, menubar=0, status=0, location=0, scrollbars=0" );
10187		}
10188	};
10189
10190})( jQuery );
10191(function( $ ) {
10192	'use strict';
10193
10194	/**
10195	 * A fork from original VC function.
10196	 * The original one is adding some padding which causes extra padding
10197	 * on our templates so we customized the codes.
10198	 *
10199	 * @since 5.9.8
10200	 * @since 6.0.1 Improve logic to handle LTR responsive state.
10201	 * @since 6.0.1 Fix missing padding-left if row has its own padding-left when
10202	 *              Vertical Header is active.
10203	 */
10204	function MkfullWidthRow() {
10205		var $windowWidth = $(document).width();
10206		var $elements = $('[data-mk-full-width="true"]');
10207		var direction = $('body.rtl').length ? 'right' : 'left';
10208		var verticalHeader = $('body.vertical-header-enabled').length ? true : false;
10209		var verticalHeaderWidth = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : 270;
10210		var verticalHeaderRtl = $('body.rtl').length ? -1 : 1;
10211		var verticalHeaderRtlWidth = $('body.rtl.vertical-header-enabled').length ? verticalHeaderWidth : 0;
10212		var verticalHeaderRight = $('body.vertical-header-right').length ? -1 : 1;
10213		var verticalHeaderWidthBoxed = 0;
10214		var boxed = $('body.mk-boxed-enabled').length;
10215		var boxedOffset = ( boxed ) ? ( $(window).width() - $('#theme-page').outerWidth() ) / 2 : 0;
10216		var boxedMaxWidth = ( boxed ) ? $('#theme-page').outerWidth() : 'auto';
10217
10218		if ( verticalHeader && boxed ) {
10219			verticalHeaderWidthBoxed = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : verticalHeaderRtl * verticalHeaderRight * 135;
10220		}
10221
10222		var transparentHeader = $('.transparent-header').length;
10223		if ( transparentHeader > 0 ) {
10224			verticalHeaderWidthBoxed = 0;
10225		}
10226
10227		$.each($elements, function(key, item) {
10228			var $el = $(this);
10229			var css;
10230			$el.addClass("vc_hidden");
10231			var $el_full = $el.next(".vc_row-full-width");
10232			if ($el_full.length || ($el_full = $el.parent().next(".vc_row-full-width")), $el_full.length) {
10233				var el_margin_left = parseInt($el.css("margin-left"), 10),
10234				el_margin_right = parseInt($el.css("margin-right"), 10),
10235				offset = 0 - $el_full.offset().left - el_margin_left,
10236				width = $(window).width();
10237				if (css = {
10238					position: "relative",
10239					"box-sizing": "border-box",
10240					width: $(window).width(),
10241					maxWidth: boxedMaxWidth
10242				},
10243				css[direction] = offset + boxedOffset + verticalHeaderWidthBoxed + ( verticalHeaderRight * verticalHeaderRtlWidth ),
10244				$el.css(css), !$el.data("mkStretchContent")) {
10245					var padding = -1 * offset;
10246					0 > padding && (padding = 0);
10247					var paddingRight = width - padding - $el_full.width() + el_margin_left + el_margin_right;
10248					padding = padding - paddingRight;
10249					if ( 0 > paddingRight && (paddingRight = 0) ) {
10250						css = {};
10251						if ( 'right' === direction ) {
10252							css["padding-left"] = padding + "px";
10253							css["padding-right"] = 0;
10254						} else {
10255							css["padding-right"] = padding + "px";
10256							css["padding-left"] = 0;
10257						}
10258
10259						$el.css(css)
10260					}
10261				}
10262
10263				/**
10264				 * Fix AM-2974
10265				 *
10266				 * When user set padding-left or padding-right in the row, both of them
10267				 * will be prioritized as important styles. It breaks padding-left set
10268				 * by Vertical Header to make the row content fit with the content
10269				 * container. We need to repopulate the padding-{side - based on Vertical
10270				 * Header position} value.
10271				 *
10272				 * Works when:
10273				 * - Vertical Header is active
10274				 * - Main layout is not boxed
10275				 * - Page Section is full layout
10276				 * - Row is full width layout and content
10277				 * - Row has its own padding-left and padding-right
10278				 * - There is no additional padding added
10279				 *
10280				 * How it works:
10281				 * Get current row padding-left and vertical header width. If both of them
10282				 * are equal, it means row position is correct related to Vertical Header.
10283				 * If not, we should sum both of them, then declare new padding-{side}
10284				 * style attribute.
10285				 *
10286				 * Tested with:
10287				 * - Main Layout: Full & Boxed Layout
10288				 * - Page Section: Full Layout and Non Full Layout
10289				 * - Row: Full Width, Full Width Content, and Non Full Width
10290				 * - Header: Non vertical headers
10291				 * - Transparent Header
10292				 * - RTL and LTR
10293				 */
10294				if ( verticalHeader && ! boxed && ! transparentHeader && ! css.hasOwnProperty( 'padding-left' ) && ! css.hasOwnProperty( 'padding-right' )) {
10295					// Get row padding-{side} and Vertical Header width.
10296					var side = 'left';
10297					if ( verticalHeaderRight === -1 ) {
10298						side = 'right';
10299					}
10300					var el_padding_dir = parseInt( $el.css( 'padding-' + side ), 10 );
10301					var header_padding_dir = $( '.header-style-4 .mk-header-inner' ).outerWidth();
10302					// Compare both of row and vertical header padding-{side}.
10303					if ( el_padding_dir != header_padding_dir) {
10304						if($windowWidth > mk_responsive_nav_width) {
10305							$el[0].style.setProperty( 'padding-' + side, header_padding_dir + 'px', 'important' );	
10306						} else {
10307							$el[0].style.removeProperty( 'padding-' + side);	
10308						}
10309						
10310
10311						// Reset padding-{side} for page section.
10312						var $el_page_section = $el.find( '.mk-page-section.full_layout' );
10313						if ( $el_page_section.length > 0 ) {
10314							$el_page_section[0].style.setProperty( 'padding-' + side, 'unset', 'important' );
10315						}
10316					}
10317				}
10318
10319				$el.attr("data-mk-full-width-init", "true"), $el.removeClass("vc_hidden"), $(document).trigger("vc-full-width-row-single", {
10320					el: $el,
10321					offset: offset,
10322					marginLeft: el_margin_left,
10323					marginRight: el_margin_right,
10324					elFull: $el_full,
10325					width: width
10326				})
10327			}
10328		}
10328), $(document).trigger("mk-full-width-row", $elements);
10329	}
10330
10331	MkfullWidthRow();
10332	var debounceResize = null;
10333	$(window).on("resize", function() {
10334		if( debounceResize !== null ) { clearTimeout( debounceResize ); }
10335		debounceResize = setTimeout( MkfullWidthRow, 100 );
10336	});
10337
10338})( jQuery );
10339
10340(function($) {
10341    'use strict';
10342
10343    MK.component.Grid = function( el ) {
10344    	var $container = $(el);
10345    	var config = $container.data( 'grid-config' );
10346        var isSlideshow = $container.closest('[data-mk-component="SwipeSlideshow"]').length;
10347        var miniGridConfig = {
10348            container: el,
10349            item: config.item + ':not(.is-hidden)',
10350            gutter: 0 
10351        };
10352
10353        var init = function init(){
10354            // Flags for cancelling usage goes first :
10355            // Quit early if we discover that Grid is used inside SwipeSlideshow as it brings bug with crossoverriding positioning 
10356            // + grid is not really needed as we have single row all handled by slider.
10357            // It happens only in woocommerce carousel as of hardcoded Grid in loop-start.php
10358            if(isSlideshow) return; 
10359	        MK.core.loadDependencies([ MK.core.path.plugins + 'minigrid.js' ], create);
10360        };
10361
10362        // Remove el hidden without adding proper class
10363        var prepareForGrid = function prepareForGrid() {
10364            var $item = $(this);
10365            var isHidden = ($item.css('display') === 'none');
10366            if(isHidden) $item.addClass('is-hidden');
10367            else $item.removeClass('is-hidden');
10368        };
10369
10370        var create = function create() {
10371            var timer = null;
10372
10373	        function draw() { 
10374                // Prevent plugin breaking when feeding it with hidden elements
10375                $container.find(config.item).each( prepareForGrid );
10376	            minigrid(miniGridConfig);
10377	        }
10378
10379            function redraw() {
10380                if (timer) clearTimeout(timer);
10381                timer = setTimeout(draw, 100);
10382            }
10383
10384            // init
10385	        draw(); 
10386            // If reinitializing drop existing event handler
10387            $(window).off('resize', redraw);
10388            $(window).on('resize', redraw);
10389            MK.utils.eventManager.subscribe('item-expanded', redraw);
10390            MK.utils.eventManager.subscribe('ajaxLoaded', redraw);
10391            MK.utils.eventManager.subscribe('staticFilter', redraw);
10392        };
10393
10394        return {
10395         	init : init
10396        };
10397    };
10398
10399})(jQuery);
10400
10401
10402
10403
10404
10405
10406
10407
10408/**
10409 * ICON FACTORY @ Maki
10410 * 
10411 * Javascript part that translates css styles into link to server side manufacturer.
10412 * By passing extra args we generate icons as needed on server and send them back with ajax and attch them to DOM here.
10413 *
10414 * This is temporary solution that helps us switching from font icons to singular svgs without too match overhead. The finalized solution shoulnd be 99% server side.
10415 * Our main templating is happening there. We should have an icon_factory(name, properties) function that we can call directly in templates to serve us icons. 
10416 * Post load, js soluition should target only elements that we have no direct access to. We set it as TODO for future as part of progressive development. 
10417 * When correct factory is done we should be able to use it here and there to progressively kill overhead generated by current solution until we could totally switch it.
10418 * 
10419 * Prons:
10420 * - automated process where we can mimic old behaviour
10421 * - possible bugs are easy to patch 
10422 * - far samller download size for assets needed by theme (no font families css and fonts itself to download, which are currently blocking page load time)
10423 * - icon generation moved to server side where our main templating is already happening
10424 * - we can easily switch how our Icon should be outputed - inline, img, object, iframe. Whatever our situation requires (img for responsive icons for example)
10425 *
10426 * Cons:
10427 * - possible bugs based on different nature of svgs / fonts. Need to be manually fixed
10428 * - some manual work to straighten things - litle css refactors here and there
10429 * - as the mapping the icons happens in server side, it may cause CPU bottlenecks and should be cashed in DB for repetitve usage.
10430 *
10431 *
10432 * TODO Refactor to config obj as parameter for easier passing it. Also decouple more - especially loops
10433 */
10434(function ($) {
10435	'use strict';
10436
10437	// As long as we can manage this manually it is better like so. We avoid delay based on waiting for ajax to finish
10438 	// $.get( MK.core.path.theme + '/assets/icons/icon-families.json', createAll);
10439 	var families = [
10440		['awesome-icons' , 'mk-icon-'], // [family, prefix]
10441		['icomoon' 		 , 'mk-moon-'],
10442		['pe-line-icons' , 'mk-li-'],
10443		['theme-icons' 	 , 'mk-jupiter-icon-'] 
10444	];
10445
10446	// Our css contains this extends for particular families of fonts. For now we automate the process and extend it here as well
10447	var extend = {
10448		'awesome-icons' : [], 
10449		'icomoon' : [],
10450		'pe-line-icons' : [],
10451		'theme-icons' : []
10452	};	
10453 	
10454 	// Cache holder for quick access to repeating icons. config / svg
10455	var _cache = {};
10456	var _cacheId = 0;
10457	// Merge configs to call it with single ajax
10458	var _config = [];
10459	// Counter for all families. We merge all our families for single ajax request and countdown when to trigger the download.
10460	var _roundCount = 0;
10461	// Mapper for icons - config / array with nodes
10462	var _iconMap = {};
10463
10464
10465	// Closure to merge $icons together and to run the download when we counted down icon families to 0
10466 	var getIconsSprite = (function() {
10467 		var $icons = null;
10468 		var iterator = 0;
10469
10470 		function run(callback) {
10471	 		var config = encodeURIComponent(JSON.stringify(_config));
10472
10473			$.ajax({
10474				url : MK.core.path.ajaxUrl,
10475				// dataType: 'xml',
10476				method: 'POST',
10477				data: {action : 'mk_get_icon', iterator: iterator++, config: config},
10478				success: function(sprite) { 
10479					callback(sprite, $icons);
10480					_config = [];
10481					_iconMap = {};
10482					$icons = null;
10483				},
10484				error: function(err) { 
10485					console.log('Icon load problem');
10486				}
10487			});
10488		}
10489
10490		return function(callback, $els, count) {
10491			if(!$icons) $icons = $els;
10492			else $icons.add($els);
10493			// console.log(count);
10494			if(!count) run(callback);
10495		};
10496 	}());
10497
10498 	// Wait for DOM manipulations and run where really needed
10499 	$(window).on('load', function() { 
10500 		setTimeout(function() {
10501 			createAll(document);
10502 			if($('.mk-header').length) createAll('.mk-header');
10503 			if($('.js-flexslider, .mk-flexslider').length) createAll('.js-flexslider, .mk-flexslider');
10504 			if($('.mk-accordion').length) createAll('.mk-accordion'); 
10505 		}, 1000); 
10506 	});
10507
10508 	MK.utils.eventManager.subscribe('ajaxLoaded', function() {
10509 		// Wait for actuall DOM insertion
10510 		setTimeout(createAll, 100, '.js-loop');
10511 	});
10512
10513	MK.utils.eventManager.subscribe('ajax-preview', function() {
10514 		setTimeout(createAll, 100, '.ajax-container');
10515	});
10516
10517	MK.utils.eventManager.subscribe('photoAlbum-open', function() {
10518 		setTimeout(createAll, 100, '.gallery-share');
10519	});
10520
10521	MK.utils.eventManager.subscribe('quickViewOpen', function() {
10522 		setTimeout(createAll, 300, '.mk-modal-content');
10523	});
10524
10525 	// Our main runner that creates all icons in given scope
10526 	function createAll(scope) {
10527		// iterate through families
10528 		for(var i = 0, l = families.length; i < l; i++) {
10529 			var family = families[i][0];
10530 			var prefix = families[i][1];
10531 			var $icons = getIcons(family, prefix, scope);
10532 			if($icons.length) {
10533 				_roundCount++;
10534 				// apply arguments from current loop iteration but send createIcons to event loop so it will get trigerred in the same order as this loop finish.
10535 				// We need it to pass all $icons first so we can merge all families before ajax request.
10536 				setTimeout(createIcons, 0, $icons, family, prefix);
10537 			}
10538 		}
10539 	}
10540
10541 	// Grab all els in given scope that contains our prefix, anywhere in class attribute. Extend if needed
10542 	function getIcons(family, prefix, scope) {
10543 		var $scope = $(scope);
10544 		var $icons = $scope.find('[class*='+ prefix +']');
10545 		var extraClassNames = extend[family];
10546 		// if nothing to extend just return what we have till now
10547 		if(!extraClassNames) return $icons; 
10548 		// Extend it with our css garbish
10549 		extraClassNames.forEach(function(className) {
10550 			var $icon = $scope.find(className);
10551 			$icons = $icons.add($icon);
10552 		});
10553 		// serve all
10554 		return $icons;
10555 	}
10556
10557
10558 	function createIcons($icons, family, prefix, i, unicode) {
10559 		var id   = i || 0;
10560		var icon = $icons[id];
10561
10562		// quick check point, if no more icons break recursion
10563		if(!icon) {
10564			_roundCount--;
10565			getIconsSprite(insertIcons, $icons, _roundCount, _config);
10566			return;
10567		}
10568
10569		var css       = getComputedStyle( icon, ':before');
10570		var classAttr = icon.getAttribute('class');
10571		var name      = (classAttr) ? matchClass(classAttr.split(' '), prefix) : false;
10572		var h         = getComputedStyle(icon).fontSize;
10573		var config    = createConfig(css, name, family, unicode, h);
10574		var cache 	  = JSON.stringify(config);
10575
10576		if(!config) {
10577			// Yep, we have a mess so sometimes we try to call for an icon where it should not exist (no class match or unicode found)
10578			// As we expect empty response from server, we just skip to next icon
10579
10580		} else if(_cache[cache]) {
10581			// Use cached icon when possible
10582			// 
10583			if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)];
10584			else _iconMap[cache].push($icons.eq(id));
10585
10586		} else {
10587			if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)];
10588			else _iconMap[cache].push($icons.eq(id));
10589
10590			_cache[cache] = _cacheId.toString(); // number as string so we could do [var] key lookup after reversal
10591			config.id = _cacheId; // extend config for server only
10592			_config.push(config);
10593
10594			_cacheId++; // increment after caching
10595		}
10596
10597		createIcons($icons, family, prefix, ++id);
10598 	}
10599
10600 	function insertIcons(sprite, $icons) {
10601 		var $sprite = $(sprite);
10602 		var $svgs   = $sprite.find('svg');
10603 		var idMap   = invert(_cache);
10604
10605 		$sprite.each(function() {
10606 			var $svg = $(this);
10607 			var id   = $svg.attr('data-cacheid'); // read as string
10608 			var configKey = idMap[id];
10609
10610 			_cache[configKey] = this;
10611 			// console.log(id, this)
10612 		});
10613
10614 		// console.log('sprite',sprite)
10615 		// 
10616
10617 		Object.keys(_iconMap).forEach(function (cacheKey) {
10618		   	_iconMap[cacheKey].forEach(function($icons) {
10619		   		$icons.each(function() {
10620		   			var $svg = $(_cache[cacheKey]).clone();
10621		   			var $icon = $(this);
10622
10623		   			// console.log($icon[0], _cache[cacheKey]);  
10624		   			
10625		   			function remove() {
10626		   				// exclude problematic stuff
10627		   				if($icon.parents('.pricing-features')) return;
10628			   			$icon.not('.mk-jupiter-icon-xing') 
10629			   				 .not('.mk-jupiter-icon-square-xing')
10630			   				 .not('.mk-jupiter-icon-simple-xing')
10631			   				 .find('.mk-svg-icon') 
10632			   				 .not('[data-name="mk-moon-zoom-in"]')
10633			   				 .remove(); // and remove else to reapply styles with new loaded svg
10634		   			}
10635
10636		   			if($svg.length ) remove();
10637
10638		   			if(!$icon.find('svg').length) {
10639		   				if($icon.parents('.widget ul').length) $icon.prepend($svg);
10640		   				else $icon.append($svg);
10641					}
10642		   		});
10643		   	});
10644		});
10645
10646 		// Notify rest of app
10647		MK.utils.eventManager.publish('iconsInsert');
10648 	}
10649
10650 	// Prepare configuration for server side. We need to grab icons and manipulate them a little there
10651 	function createConfig(css, name, family, unicode, height) {
10652 		var hasGradient  = checkGradient(css);
10653 		var hasDirection = extractGradient('direction', css.background);
10654
10655 		var config = {
10656 			family: family, 
10657 			// this is mostly for Extends. Because we've been customizing singular elements and assigning content unicode manually, 
10658 			// now we don't have any proper anchor for usage with our json map
10659 			unicode: (unicode) ? unicode : decodeUnicode(css.content), 
10660 			name: name,
10661 			// fill: css.color,
10662 			gradient_type:  hasGradient ? extractGradient('type' , css.background) : false,
10663 			gradient_start: hasGradient ? extractGradient('start', css.background) : false,
10664 			gradient_stop:  hasGradient ? extractGradient('stop' , css.background) : false,
10665 			gradient_direction: hasDirection ? extractGradient('direction', css.background).replace(' ', '-') : false,
10666 			height: height
10667 		};
10668
10669 		// If there is no name or unicode the whole config is invalid
10670 		if(!config.name && !config.unicode) return false;
10671 		else return config;
10672 	}
10673
10674 	// Extract class name that represents the icon that we try to generate
10675 	function matchClass(classes, prefix) {
10676 		// var missing = '';
10677 		for(var i = 0, l = classes.length; i < l; i++) {
10678 			if(classes[i].indexOf(prefix) !== -1) return classes[i]; // return first matched class name
10679 			// else missing += ' .' + classes[i]; // collect not matching classes
10680 		}
10681 		// if we didn't returned anything within loop we output notification here. Keep it for testing only
10682 		// console.log('Possibility of missing icons for element with classes:' + missing);
10683 	}
10684
10685 	// Check if background conatains gradient declaration and return bg string if so or false 
10686 	function checkGradient(css) {
10687 		var bg = css.background;
10688 		if(bg.indexOf('radial') !== -1 || bg.indexOf('linear') !== -1) return bg;
10689 		else return false;
10690 	}
10691
10692 	// Extract background attribiutes from bg string.
10693 	// Multipurpose function which returns part we ask for
10694 	function extractGradient(attr, grad) {
10695 		// quit if gradient is falsy
10696 		// console.log(grad);
10697 		if(!grad) return false;
10698
10699 		var isRadial = grad.indexOf('radial')  !== -1;
10700 		var isLinear = grad.indexOf('linear')  !== -1;
10701 		var hasDirection = grad.indexOf('(to') !== -1;
10702 		var f, t; // from, to
10703
10704 		if(attr === 'type') {
10705 			if(isRadial) return 'radial';
10706 			if(isLinear) return 'linear';
10707
10708 		} else if(attr === 'start') {
10709 			f = getStrPosition(grad, 'rgb(', 1);
10710 			t = getStrPosition(grad, '0%'  , 1);
10711
10712 		} else if(attr === 'stop') {
10713 			f = getStrPosition(grad, 'rgb(', 2);
10714 			t = getStrPosition(grad, '100%', 1);
10715
10716 		} else if(attr === 'direction') {
10717 			if(!hasDirection) return false;
10718 			f = getStrPosition(grad, '(to', 1) + 4;
10719 			t = getStrPosition(grad, ', rgb(', 1);
10720
10721 		} else {
10722 			return false;
10723 		}
10724 		
10725 		return grad.slice(f, t);
10726 	}
10727
10728 	// Helper for getting indexOf but with lookup for instance of the string
10729 	// str - string to search
10730 	// m - what we're looking for
10731 	// i - instance, starting at 1
10732 	function getStrPosition(str, m, i) {
10733	   return str.split(m, i).join(m).length;
10734	}
10735
10736	// JS outputs unicode results rather than code representation. This helper function does the job
10737	function decodeUnicode(content) {
10738		// escape() kills \ escape signature and outputs it as %u
10739		// str replace to drop special chars
10740		// and we bring it all to lowercase to match filenames we keep on server
10741		if(content && content !== 'none') return escape(content).replace(/%22/g, '').replace('%u', '').toLowerCase();
10742		else return false; // just in case we haven't provided content to work with
10743	}
10744
10745	function invert(obj) {
10746	  	var new_obj = {};
10747	  	for (var prop in obj) {
10748	    	if(obj.hasOwnProperty(prop)) {
10749	      		new_obj[obj[prop]] = prop;
10750	    	}
10751	  	}
10752	  	return new_obj;
10753	}
10754
10755}(jQuery));
10756/*!
10757 * imagesLoaded PACKAGED v4.1.1
10758 * JavaScript is all like "You images are done yet or what?"
10759 * MIT License
10760 */
10761
10762!function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}(window,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}function n(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e}function o(t,e,r){return this instanceof o?("string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=n(t),this.options=i({},this.options),"function"==typeof e?r=e:i(this.options,e),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(function(){this.check()}.bind(this))):new o(t,e,r)}function r(t){this.img=t}function s(t,e){this.url=t,this.element=e,this.img=new Image}var h=t.jQuery,a=t.console;o.prototype=Object.create(e.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEac
10762h(this.addElementImages,this)},o.prototype.addElementImages=function(t){"IMG"==t.nodeName&&this.addImage(t),this.options.background===!0&&this.addElementBackgroundImages(t);var e=t.nodeType;if(e&&d[e]){for(var i=t.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=t.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var d={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(t){var e=getComputedStyle(t);if(e)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(e.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,t),n=i.exec(e.backgroundImage)}},o.prototype.addImage=function(t){var e=new r(t);this.images.push(e)},o.prototype.addBackground=function(t,e){var i=new s(t,e);this.images.push(i)},o.prototype.check=function(){function t(t,i,n){setTimeout(function(){e.progress(t,i,n)})}var e=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(e){e.once("progress",t),e.check()}):void this.complete()},o.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress: "+i,t,e)},o.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){var e=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[e](this)}},r.prototype=Object.create(e.prototype),r.prototype.check=function(){var t=this.getIsImageComplete();return t?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&void 0!==this.img.naturalWidth},r.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.img,e])},r.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},r.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var t=this.getIsImageComplete();t&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},o.makeJQueryPlugin=function(e){e=e||t.jQuery,e&&(h=e,h.fn.imagesLoaded=function(t,e){var i=new o(this,t,e);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o});
10763
10764(function($, window){
10765    'use strict';
10766
10767    var scrollY = MK.val.scroll; 
10768    var dynamicHeight = MK.val.dynamicHeight;
10769
10770    var $window = $(window);
10771    var $containers = $('.js-loop');
10772
10773    $containers.each( pagination );
10774
10775	$window.on( 'vc_reload', function() {
10776		$('.js-loop').each( pagination );
10777	} );
10778
10779    function pagination() {
10780        var unique = Date.now();
10781        var $container = $(this);
10782        var $superContainer = $container.parent(); // should contain clearing so it stretches with floating children
10783        var $loadBtn = $container.siblings('.js-loadmore-holder').find('.js-loadmore-button');
10784        var $loadScroll = $('.js-load-more-scroll');
10785        var style = $container.data('pagination-style');
10786        var maxPages = $container.data('max-pages');
10787        var id = '#' + ($container.attr('id'));
10788        var ajaxLoader = new MK.utils.ajaxLoader(id);
10789        var isLoadBtn = (style === 2);
10790        var isInfiniteScroll = (style === 3); // add flag for last container
10791        var scrollCheckPoint = null;
10792        var isHandlerBinded = false;
10793
10794        ajaxLoader.init();
10795
10796        init();
10797
10798        function init() {
10799            MK.utils.eventManager.subscribe('ajaxLoaded', onLoad);
10800            bindHandlers();
10801            if( isInfiniteScroll ) scrollCheckPoint = spyScrollCheckPoint();
10802
10803			$window.on( 'vc_reload', function() {
10804				$window.off('scroll', handleScroll);
10805			} );
10806        }
10807
10808        function bindHandlers() {
10809            if( isLoadBtn ) $loadBtn.on('click', handleClick);
10810            if( isInfiniteScroll ) $window.on('scroll', handleScroll); 
10811            isHandlerBinded = true;
10812        }
10813
10814        function unbindHandlers() {
10815            if( isLoadBtn ) $loadBtn.off('click', handleClick);
10816            if( isInfiniteScroll ) $window.off('scroll', handleScroll);
10817            isHandlerBinded = false;
10818        }
10819
10820        function handleClick(e) {
10821            e.preventDefault();
10822            if(!ajaxLoader.isLoading) loadMore();
10823        }
10824
10825        function handleScroll() {
10826            if((scrollY() > scrollCheckPoint()) && !ajaxLoader.isLoading) loadMore();
10827        }
10828
10829        function loadMore() {
10830            loadingIndicatorStart();
10831            var page = ajaxLoader.getData('paged');
10832            ajaxLoader.setData({paged: ++page});
10833            ajaxLoader.load(unique);
10834        }
10835
10836        function onLoad(e, response) {
10837            if( typeof response !== 'undefined' && response.id === id) {
10838                // Checking found posts helps to fix all pagination styles 
10839                if( ajaxLoader.getData('found_posts') <= 0 && ajaxLoader.getData('paged') >= ajaxLoader.getData('maxPages')) loadingIndicatorHide();
10840                else loadingIndicatorShow();
10841                if(response.unique === unique) $container.append(response.content);
10842                loadingIndicatorStop();
10843            }
10844        }
10845
10846        function loadingIndicatorStart() {
10847            if(isLoadBtn) $loadBtn.addClass('is-active');
10848            else if(isInfiniteScroll) MK.ui.loader.add('.js-load-more-scroll');
10849
10850        }
10851
10852        function loadingIndicatorStop() {
10853            if(isLoadBtn) $loadBtn.removeClass('is-active');
10854            else if(isInfiniteScroll) MK.ui.loader.remove('.js-load-more-scroll');
10855        }
10856
10857        function loadingIndicatorShow() {
10858            if(isHandlerBinded) return;
10859            if(isLoadBtn) $loadBtn.show();
10860            else if(isInfiniteScroll) $loadScroll.show();
10861            bindHandlers();
10862        }
10863
10864        function loadingIndicatorHide() {
10865            if(!isHandlerBinded) return;
10866            if(isLoadBtn) $loadBtn.hide();
10867            else if(isInfiniteScroll) $loadScroll.hide();
10868            unbindHandlers();
10869        }
10870
10871
10872        function spyScrollCheckPoint() {
10873            var containerO = 0;
10874            var containerH = dynamicHeight( $superContainer );
10875            var winH = dynamicHeight( window );
10876 
10877            var setVals = function() {
10878                containerO = $superContainer.offset().top;
10879            };
10880
10881            setVals();
10882            $window.on('resize', function() { requestAnimationFrame(setVals); });
10883
10884            return function() {
10885                return (containerH() + containerO) - (winH() * 2);
10886            };
10887        }
10888    }
10889
10890})(jQuery, window);
10891(function($) {
10892	'use strict';
10893
10894	// Check if it's inside hidden parent
10895	// Cannot be position: fixed
10896	function isHidden(el) {
10897	    return (el.offsetParent === null);
10898	}
10899
10900	MK.component.Masonry = function(el) {
10901		var $window = $(window);
10902		var $container = $(el);
10903		var config = $container.data( 'masonry-config' );
10904		var $masonryItems = $container.find(config.item);
10905		var cols = config.cols || 8;
10906		var $filterItems = null; // assign only when apply filter
10907		var wall = null;
10908		
10909        var init = function init() {
10910        	MK.core.loadDependencies([ MK.core.path.plugins + 'freewall.js' ], onDepLoad);
10911        };
10912
10913        var onDepLoad = function onDepLoad() {
10914        	masonry();
10915
10916        	// Events
10917	        $window.on('resize', onResize);
10918            MK.utils.eventManager.subscribe('ajaxLoaded', onPostAddition);
10919			MK.utils.eventManager.subscribe('staticFilter', resize);
10920        };
10921
10922	    var masonry = function masonry() {
10923	    	// Quit for hidden elements for now.
10924	    	if(isHidden(el)) return;
10925
10926	    	var newCols;
10927	    	if(window.matchMedia( '(max-width:600px)' ).matches) newCols = 2;
10928	    	else if(window.matchMedia( '(max-width:850px)' ).matches) newCols = 4;
10929	    	else newCols = cols;
10930
10931	    	var colW = $container.width() / newCols;
10932
10933	        wall = new Freewall( config.container );
10934
10935	        // We need to pass settings to a plugin via reset method. Strange but works fine.
10936			wall.reset({
10937				selector: config.item + ':not(.is-hidden)',
10938				gutterX: 0, // set default gutter to 0 and again - apply margins to item holders in css
10939				gutterY: 0,
10940				cellW: colW,
10941				cellH: colW
10942			});
10943
10944	        wall.fillHoles();
10945	        wall.fitWidth();
10946
10947	        $masonryItems.each(function() {
10948	        	$(this).data('loaded', true);
10949	        });
10950        };
10951
10952
10953		// Clear attributes after the plugin. It's API method dosn't handle it properly
10954		var destroyContainer = function destroyContainer() {
10955			$container.removeAttr('style')
10956				 .removeData('wall-height')
10957				 .removeData('wall-width')
10958				 .removeData('min-width')
10959				 .removeData('total-col')
10960				 .removeData('total-row')
10961				 .removeAttr('data-wall-height')
10962				 .removeAttr('data-wall-width')
10963				 .removeAttr('data-min-width')
10964				 .removeAttr('data-total-col')
10965				 .removeAttr('data-total-row');
10966		};
10967
10968		var destroyItem = function destroyItem() {
10969			var $item = $(this);
10970			$item.removeAttr('style')
10971				 .removeData('delay')
10972				 .removeData('height')
10973				 .removeData('width')
10974				 .removeData('state')
10975				 .removeAttr('data-delay')
10976				 .removeAttr('data-height')
10977				 .removeAttr('data-width')
10978				 .removeAttr('data-state'); 
10979		};
10980
10981		var destroyAll = function destroyAll() {
10982	    	if( !wall ) return;
10983    		wall.destroy(); // API destroy
10984    		destroyContainer();
10985    		$masonryItems.each( destroyItem ); // run our deeper destroy
10986		};
10987
10988		var onResize = function onResize() {
10989			requestAnimationFrame(resize);
10990		};
10991
10992        var refresh = function refresh() {
10993	    	if( !wall ) return; 
10994	    	setTimeout(wall.fitWidth.bind(wall), 5);
10995        };
10996
10997        var resize = function resize() {
10998        	destroyAll();
10999	    	masonry();
11000        };
11001
11002        var onPostAddition = function onPostAddition() {
11003        	$masonryItems = $container.find(config.item);
11004
11005        	$masonryItems.each(function() {
11006        		var $item = $(this),
11007        			isLoaded = $item.data('loaded');
11008
11009        		if(!isLoaded) $item.css('visibility', 'hidden');
11010        	});
11011
11012        	
11013        	$container.mk_imagesLoaded().then(function() {
11014        		destroyAll();
11015        		masonry();
11016        	});
11017        };
11018
11019        return {
11020         	init : init
11021        };
11022	};
11023
11024}(jQuery));
11025(function($) {
11026	'use strict';
11027
11028	MK.component.Pagination = function(el) {
11029		this.el = el;
11030	};
11031
11032	MK.component.Pagination.prototype = {
11033		init: function init() {
11034			this.cacheElements(); 
11035			this.bindEvents();
11036			this.onInitLoad();
11037		},
11038
11039		cacheElements: function cacheElements() {
11040			this.lastId = 1;
11041			this.unique = Date.now();
11042			this.$pagination = $(this.el);
11043			this.$container = this.$pagination.prev('.js-loop');
11044			this.$pageLinks = this.$pagination.find('.js-pagination-page');
11045			this.$nextLink = this.$pagination.find('.js-pagination-next');
11046			this.$prevLink = this.$pagination.find('.js-pagination-prev');
11047			this.$current = this.$pagination.find('.js-current-page');
11048			this.$maxPages = this.$pagination.find('.pagination-max-pages'); // TODO change in DOM and here to js class
11049			this.containerId = '#' + this.$container.attr('id');
11050			this.pagePathname = window.location.pathname;
11051			this.pageSearch = window.location.search;
11052			this.popState = false;
11053			this.ajaxLoader = new MK.utils.ajaxLoader('#' + this.$container.attr('id'));
11054			this.ajaxLoader.init();
11055		},
11056
11057		bindEvents: function bindEvents() {
11058			this.$pageLinks.on('click', this.pageClick.bind(this));
11059			this.$nextLink.on('click', this.nextClick.bind(this));
11060			this.$prevLink.on('click', this.prevClick.bind(this)); 
11061			MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this));
11062		},
11063
11064		pageClick: function pageClick(e) {
11065			e.preventDefault(); 
11066			var $this = $(e.currentTarget);
11067			var id = parseFloat($this.attr('data-page-id'));
11068
11069			if(id > this.ajaxLoader.getData('maxPages') || id < 1) return;
11070			this.load(id, $this);
11071			this.updatePagedNumUrl( id );
11072		},
11073
11074		nextClick: function nextClick(e) {
11075			e.preventDefault(); 
11076			if(this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')) return;
11077			this.load(++this.lastId, $(e.currentTarget));
11078			this.updatePagedNumUrl( this.lastId );
11079		},
11080
11081		prevClick: function prevClick(e) {
11082			e.preventDefault(); 
11083			if(this.ajaxLoader.getData('paged') === 1) return;
11084			this.load(--this.lastId, $(e.currentTarget));
11085			this.updatePagedNumUrl( this.lastId );
11086		},
11087
11088		load: function load(id, $el) {
11089			this.lastId = id;
11090			this.ajaxLoader.setData({paged: id});
11091			this.ajaxLoader.load(this.unique);
11092			this.removeIndicator();
11093			MK.ui.loader.add($el);
11094		},
11095
11096		onLoad: function success(e, response) {
11097			if( typeof response !== 'undefined' && response.id === this.containerId) {
11098				this.updatePagination();
11099				this.lastId = this.ajaxLoader.getData('paged');
11100
11101				if(response.unique === this.unique) {
11102					this.removeIndicator();
11103					this.scrollPage();
11104			        this.$container.html(response.content);  
11105				}   
11106			}         
11107        },
11108
11109        updatePagination: function updatePagination() {
11110        	var self = this;
11111
11112        	// Hide / show arrows
11113        	var isFirst = (this.ajaxLoader.getData('paged') === 1);
11114        	var isLast = (this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages'));
11115
11116        	if(isFirst) this.$prevLink.addClass('is-vis-hidden');
11117        	else this.$prevLink.removeClass('is-vis-hidden');
11118
11119        	if(isLast) this.$nextLink.addClass('is-vis-hidden');
11120        	else this.$nextLink.removeClass('is-vis-hidden');
11121
11122			// X of Y
11123			this.$current.html(this.ajaxLoader.getData('paged'));
11124			this.$maxPages.html(this.ajaxLoader.getData('maxPages'));
11125
11126			// Move overfloating items
11127			var displayItems = 10;
11128			var centerAt = displayItems / 2;
11129
11130			if(this.ajaxLoader.getData('maxPages') > displayItems) {
11131				this.$pageLinks.each(function(i) {
11132
11133					var id = self.lastId - centerAt;
11134						id = Math.max(id, 1);
11135						id = Math.min(id, self.ajaxLoader.getData('maxPages') - displayItems + 1);
11136						id = id + i;
11137
11138					$(this).html( id ).attr('data-page-id', id).show();
11139
11140					if(i === 0 && id > 1) $(this).html('...');
11141					if(i === displayItems - 1 && id < self.ajaxLoader.getData('maxPages')) $(this).html('...');
11142				});
11143			} else {
11144				this.$pageLinks.each(function(i) {
11145					var $link = $(this);
11146					var id = i + 1;
11147
11148					$link.html(id).attr('data-page-id', id);
11149
11150					if( self.ajaxLoader.getData('maxPages') === 1) {
11151						self.$pageLinks.hide();
11152					} else {
11153						if(i > self.ajaxLoader.getData('maxPages') - 1) $link.hide();
11154						else $link.show();						
11155					}
11156
11157				});
11158			}
11159
11160        	// Highlight current only
11161			this.$pageLinks.filter('[data-page-id="' + this.ajaxLoader.getData('paged') + '"]' ).addClass('current-page')
11162				 .siblings().removeClass('current-page');
11163
11164        },
11165
11166        scrollPage: function scrollPage() {
11167            var containerOffset = this.$container.offset().top;
11168            var offset = containerOffset - MK.val.offsetHeaderHeight( containerOffset ) - 20; 
11169
11170            this.$container.find('a:first').focus()
11171            MK.utils.scrollTo( offset ); 
11172        },
11173
11174        removeIndicator: function removeIndicator() {
11175        	MK.ui.loader.remove('.js-pagination-page, .js-pagination-next, .js-pagination-prev');
11176        },
11177
11178		/**
11179		 * Set some actions when archive/category page is loaded. Actions list:
11180		 * - Select the correct paged ID on pagination list.
11181		 * - Set current paged ID on the label.
11182		 * - Add event listener onpopstate for handling prev/next button of Browser URL.
11183		 * - Set info for updatePagedNumUrl() about request comes from popstate.
11184		 *
11185		 * @since 5.9.8
11186		 */
11187		onInitLoad: function onInitLoad() {
11188			var initPagedID = this.$pagination.data( 'init-pagination' );
11189			if ( initPagedID && initPagedID > 1 ) {
11190				this.$current.html( initPagedID );
11191				this.$pageLinks.filter( '[data-page-id="' + initPagedID + '"]' ).addClass( 'current-page' ).siblings().removeClass( 'current-page' );
11192			}
11193
11194			// Run popstate only if it's supported by the browser.
11195			if ( 'onpopstate' in window ) {
11196				var thisPop = this;
11197				window.onpopstate = function( event ) {
11198					var id = 1;
11199
11200					// At start, state is always null. So, we should check it before processing.
11201					if ( typeof event.state === 'object' && event.state ) {
11202						var state = event.state;
11203
11204						// Set paged ID for updating page.
11205						if ( state.hasOwnProperty( 'MkPagination' ) ) {
11206							var currentState = state.MkPagination;
11207							if ( currentState.hasOwnProperty( 'paged' ) ) {
11208								id = parseFloat( currentState.paged );
11209							}
11210						}
11211					} else {
11212						id = parseFloat( thisPop.getURLPagedID() );
11213					}
11214
11215					// Tell updatePagedNumUrl() if request come from popstate.
11216					thisPop.popState = true;
11217					thisPop.$pageLinks.filter( '[data-page-id="' + id + '"]' ).trigger( 'click' );
11218				}
11219			}
11220		},
11221
11222		/**
11223		 * Update current pagination browser URL by adding/changing paged number. Only run if
11224		 * the browser support pushState and the request not coming from popstate.
11225		 *
11226		 * WordPress has some ways to set paged number:
11227		 * 1. page/[number], paged=[number] will be directed here.
11228		 * 2. page=[number]
11229		 * So, we should check which one the request is used here.
11230		 *
11231		 * @since 5.9.8
11232		 */
11233		updatePagedNumUrl: function updatePagedNumUrl( id ) {
11234			// Check pushState browser support and ignore if request come from popstate.
11235			if ( 'history' in window && 'pushState' in history && id && ! this.popState ) {
11236				var fullPage = this.pagePathname + this.pageSearch;
11237				var isQueryPage = false;
11238
11239				// Style 1 - /page/[number], as default value.
11240				var newPage = 'page/' + id + '/';
11241				var expPage = /page\/\d+\/?/;
11242				var result = this.pagePathname.match( /\/page\/\d+/ );
11243				var isPagedExist = ( result ) ? true : false;
11244
11245				// Style 2 - ?page=[number], only run if /page/ is not exist and URL query var exist.
11246				if ( ! isPagedExist && this.pageSearch ) {
11247					isQueryPage = this.pageSearch.match( /page\=\d+/ );
11248					if ( isQueryPage ) {
11249						newPage = 'page=' + id;
11250						expPage = /page\=\d+/;
11251					}
11252				}
11253
11254				// If page number is 1, remove paged number from URL.
11255				if ( id === 1 ) {
11256					newPage = '';
11257					if ( isQueryPage ) {
11258						expPage = ( this.pageSearch.match( /\&+/ ) ) ? /page\=\d+\&?/ : /\?page\=\d+\&?/;
11259					}
11260				}
11261
11262				// Set new pathname. Do replacement only if the new pathname contains paged number.
11263				var newURL = this.pagePathname + newPage + this.pageSearch;
11264				if ( fullPage.match( expPage ) ) {
11265					newURL = fullPage.replace( expPage, newPage );
11266				}
11267
11268				// Set history state and return popstate back to fal
11268se.
11269				var historyState = {
11270					MkPagination: {
11271						url: newURL,
11272						paged: id
11273					}
11274				}
11275				this.popState = false;
11276
11277				// Push new pathname to display/hide the paged number.
11278				window.history.pushState( historyState, null, newURL );
11279			}
11280			this.popState = false;
11281		},
11282
11283		/**
11284		 * Get current URL page ID. Notes:
11285		 * 1. page/[number], paged=[number] will be directed here.
11286		 * 2. page=[number]
11287		 *
11288		 * @return {integer} Current paged ID. Default 1.
11289		 */
11290		getURLPagedID: function getURLPagedID() {
11291			var pathname = window.location.pathname;
11292			var search = window.location.search;
11293			var pagedId = 1;
11294			var result = '';
11295			var isPagedExist = false;
11296
11297			// Search based on style 1.
11298			result = pathname.match( /\/page\/(\d+)/ );
11299			if ( result ) {
11300				isPagedExist = true;
11301				pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1;
11302			}
11303
11304			// Search based on style 2.
11305			if ( ! isPagedExist && search ) {
11306				result = search.match( /page\=(\d+)/ );
11307				if ( result ) {
11308					isPagedExist = true;
11309					pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1;
11310				}
11311			}
11312
11313			return pagedId;
11314		}
11315	};
11316
11317}(jQuery));
11318(function( $ ) {
11319	'use strict';
11320
11321	var val = MK.val,
11322		utils = MK.utils;
11323
11324	MK.component.Parallax = function( el ) {
11325		var self = this,
11326			$this = $( el ),
11327        	obj = $this[0],
11328			$window = $( window ),
11329		    container = document.getElementById( 'mk-theme-container' ),
11330			config = $this.data( 'parallax-config' ),
11331			$holder = $( config.holder ),
11332			headerHeight = null,
11333			offset = null,
11334			elHeight = null,
11335			ticking = false,
11336			isMobile = null;
11337
11338
11339		var clientRect = null;
11340
11341		var update = function() {
11342			// Clear styles to check for natural styles
11343			// then apply position and size
11344			obj.style.transform = null;
11345			obj.style.top = null;
11346			obj.style.bottom = null;
11347
11348			isMobile = MK.utils.isMobile();
11349
11350			if( isMobile ) {
11351        		$this.css( 'height', '' );
11352				return;
11353			}
11354
11355			clientRect = $this[ 0 ].getBoundingClientRect();
11356			offset = clientRect.top;
11357			elHeight = clientRect.height;
11358			headerHeight = val.offsetHeaderHeight( offset );
11359			offset = offset - headerHeight + val.scroll(); 
11360
11361			setPosition(); 
11362			setSize( ); 
11363		};
11364
11365
11366        var h = 0,
11367        	winH = 0,
11368        	proportion = 0,
11369        	height = 0;
11370
11371        // Position and background attachement should me moved to CSS but we repair it high specificity here as styles are not reliable currently
11372        var setSize = function() {
11373        	$this.css( 'height', '' );
11374        	winH = $window.height() - headerHeight;
11375        	h = obj.getBoundingClientRect().height; 
11376
11377        	if( config.speed <= 1 && config.speed > 0 ) {
11378        		if( offset === 0 ) {
11379	        		$this.css({
11380	        			backgroundAttachment: 'scroll',
11381	        			'will-change': 'transform'
11382	        		});
11383        		} else {
11384	        		$this.css({
11385						height : h + ( (winH - h) * config.speed ),
11386	        			backgroundAttachment: 'scroll',
11387	        			'will-change': 'transform' 
11388	        		}); 
11389	        	}
11390
11391        	} else if ( config.speed > 1 && h <= winH ) {
11392        		$this.css({
11393        			// good for full heights - 2 because it's viewable by 2 screen heights
11394        			height: ( winH  +  ( ( winH * config.speed ) - winH ) * 2 ),  
11395        			top: -( ( winH * config.speed ) - winH ),
11396        			backgroundAttachment: 'scroll',
11397        			'will-change': 'transform'
11398        		}); 
11399
11400        	} else if ( config.speed > 1 && h > winH ) {
11401        		proportion = h / winH;
11402        		height = ( winH  +  ( ( winH * config.speed ) - winH ) * (1 + proportion) );
11403 
11404        		$this.css({
11405        			height: height,
11406        			top: -( height - (winH * config.speed) ),
11407        			backgroundAttachment: 'scroll',
11408        			'will-change': 'transform'
11409        		}); 
11410
11411        	} else if ( config.speed < 0 && h >= winH ) {
11412        		height = h * (1  - config.speed);
11413        		$this.css({
11414					height: height + (height - h),
11415        			top: h - height,
11416        			backgroundAttachment: 'scroll',
11417        			'will-change': 'transform'
11418        		});   
11419
11420        	} else if ( config.speed < 0 && h < winH ) {
11421        		// candidate to change
11422        		var display = (winH + h) / winH;
11423        		height = h * -config.speed * display;
11424        		$this.css({
11425					height: h + (height * 2),
11426        			top: -height,
11427        			backgroundAttachment: 'scroll',
11428        			'will-change': 'transform'
11429        		});         		
11430        	}
11431        };
11432
11433
11434		var currentPoint = null,
11435			progressVal = null,
11436			startPoint = null,
11437			endPoint = null,
11438			$opacityLayer = config.opacity ? $this.find( config.opacity ) : null,
11439			scrollY = null;
11440
11441		var setPosition = function() {
11442			startPoint = offset - winH;
11443			endPoint = offset + elHeight + winH - headerHeight;
11444			scrollY = val.scroll();
11445
11446			if( scrollY < startPoint || scrollY > endPoint ) { 
11447				ticking = false;
11448				return; 
11449			}
11450
11451			currentPoint = (( -offset + scrollY ) * config.speed);
11452
11453            $this.css({
11454              	'-webkit-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11455              	'-moz-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11456              	'-ms-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11457              	'-o-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11458              	'transform': 'translateY(' + currentPoint + 'px) translateZ(0)'
11459            });  
11460
11461			ticking = false;
11462		};
11463
11464 
11465		var requestTick = function() {
11466			if( !ticking && !isMobile ) {
11467				ticking = true;
11468				window.requestAnimationFrame( setPosition );
11469			}
11470		};
11471
11472
11473		var init = function() { 
11474			// Disable scroll effects when smooth scroll is disabled
11475			if( !MK.utils.isSmoothScroll ) { return; }
11476
11477			update();
11478			setTimeout(update, 100);
11479			$window.on( 'load', update );
11480			$window.on( 'resize', update );
11481	        window.addResizeListener( container, update );
11482	        
11483			$window.on( 'scroll', requestTick );
11484		};
11485		
11486 
11487		return {
11488			init : init
11489		};
11490	};
11491
11492})( jQuery );
11493(function($) {
11494	'use strict';
11495
11496	MK.component.Preloader = function(el) {
11497		this.el = el;
11498	};
11499
11500	MK.component.Preloader.prototype = {
11501		init: function init() {
11502			this.cacheElements();
11503			this.bindEvents();
11504		},
11505
11506		cacheElements: function cacheElements() {
11507			this.$preloader = $(this.el);
11508		},
11509
11510		bindEvents: function bindEvents() {
11511			this.onLoad(); // all components inited on page load
11512		},
11513
11514		onLoad: function onLoad() {
11515			setTimeout(this.hidePreloader.bind(this), 300);
11516		},
11517
11518		hidePreloader: function hidePreloader() {
11519			this.$preloader.hide();
11520		}
11521	};
11522
11523}(jQuery));
11524
11525(function($) {
11526	'use strict';
11527
11528	// Image added for proportional scaling
11529	MK.ui.loader = {
11530		tpl : function() {
11531			return '<div class="mk-loading-indicator">' + 
11532						'<div class="mk-loading-indicator__inner">' +
11533							'<div class="mk-loading-indicator__icon"></div>' +
11534							'<img style="height:100%; width:auto;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">' +
11535						'</div>' +
11536					'</div>';
11537		},
11538
11539		add : function(item) {
11540			$(item).append(this.tpl);
11541		},
11542
11543		remove : function(item) {
11544			if(item) $(item).find('.mk-loading-indicator').remove();
11545			else $('.mk-loading-indicator').remove();
11546		}
11547	};
11548
11549}(jQuery));
11550(function( $ ) {
11551	// IE / Edge fix for fixed positioned elements
11552	// MS clip path doesnt redraw properly so we expirience similar bug like with background attachement fixed on Chrome
11553	if (MK.utils.browser.name === 'Edge' || MK.utils.browser.name === 'IE') {
11554	 	var val = 1;
11555	 	var $edgeClipper = $('.mk-slider-slide'); // edge slider
11556	 	var $sectionClipper = $('.clipper-true'); // edge slider
11557	 	var $bgLayer = $('.background-layer'); // page section
11558
11559    	var onScroll = function onScroll() {
11560	    	val *= -1;
11561	    	if( $edgeClipper.length ) $edgeClipper.each( redraw );
11562	    	if( $sectionClipper.length ) $sectionClipper.each( redraw );
11563	    	if( $bgLayer.length ) $bgLayer.each( redraw );
11564    	};
11565
11566	 	var redraw = function redraw() {
11567	    	$(this).css('margin-top', val / 100);
11568	    };
11569
11570	    $(window).on("scroll", function () {	    	
11571	    	window.requestAnimationFrame(onScroll);
11572	    });
11573	 }
11574}(jQuery));
11575MK.component.ResponsiveImageSetter = (function ($) {
11576
11577	'use strict';
11578
11579	var module = {};
11580
11581
11582	/*---------------------------------------------------------------------------------*/
11583	/* Private Variables
11584	/*---------------------------------------------------------------------------------*/
11585
11586	var viewportClass = getViewportClass();
11587	var isRetina = window.devicePixelRatio >= 2;
11588
11589
11590	/*---------------------------------------------------------------------------------*/
11591	/* Private Methods
11592	/*---------------------------------------------------------------------------------*/
11593
11594	function run($imgs) {
11595		$imgs.filter( function() {
11596			return !this.hasAttribute("mk-img-src-setted");
11597		}).each(setSrcAttr);
11598	}
11599
11600	function setSrcAttr() {
11601		var $img = $(this);
11602		var set = $img.data('mk-image-src-set');
11603		// Set src attribute to img link suitable for our logic. It will load the image.
11604		if(set['responsive'] === 'false' && isRetina && set['2x']) $img.attr('src', set['2x']);
11605		else if(set['responsive'] === 'false') $img.attr('src', set.default);
11606		else if(viewportClass === 1 && isRetina && set['2x']) $img.attr('src', set['2x']); // default x2 for retina
11607		else if(viewportClass === 0 && set.mobile) $img.attr('src', set.mobile);
11608		else $img.attr('src', set.default);
11609
11610		$img.load(function() {
11611			$(window).trigger('mk-image-loaded')
11612		})
11613	}
11614
11615	function getViewportClass() {
11616		if(window.matchMedia('(max-width: 736px)').matches) return 0;
11617		else return 1;
11618	}
11619
11620	function handleResize($imgs) {
11621		if(!$imgs.length) return;
11621 // Do not run if empty collection
11622		var currentViewportClass = getViewportClass();
11623		// We don't need to reload bigger images when screen size is decreasing as browser already performs resize operation.
11624		// Run update on for increasing screen size
11625		if( currentViewportClass > viewportClass) {
11626			viewportClass = currentViewportClass; // update for further reference
11627			run($imgs);
11628		}
11629	}
11630
11631
11632	/*---------------------------------------------------------------------------------*/
11633	/* Public Methods
11634	/*---------------------------------------------------------------------------------*/
11635
11636	module.init = function ($imgs) {
11637
11638		// Do not run if empty collection
11639		if(!$imgs.length) return;
11640
11641		// Run and bind to events
11642		run($imgs);
11643		$imgs.attr('mk-img-src-setted', '');
11644
11645	};
11646
11647	module.onResize = function ($imgs) {
11648
11649		$(window).on( 'resize', MK.utils.throttle( 500, function() {
11650			handleResize($imgs);
11651		}));
11652
11653
11654	};
11655
11656
11657	module.handleAjax = function () {
11658    	setTimeout(function ajaxDelayedCallback() { // give it a chance to insert content first
11659	    	var $newImgs = $('img[data-mk-image-src-set]').filter( function() {
11660				return !this.hasAttribute("mk-lazyload");
11661			});
11662			if(!$newImgs.length) return;
11663	    	run($newImgs);
11664    	}, 100);
11665    }
11666
11667
11668	return module;
11669
11670}(jQuery));
11671
11672
11673jQuery(function($) {
11674
11675	var init = function init() {
11676		// Get All Responsive Images
11677		$allImages = $('img[data-mk-image-src-set]').filter(function(index) {
11678			var isNotPortfolioImage = !$(this).hasClass('portfolio-image'),
11679				isNotBlogImage = $(this).closest('.mk-blog-container').length == 0,
11680				isNotSwiperImage = !$(this).hasClass('swiper-slide-image'),
11681				isNotGalleryImage = !$(this).hasClass('mk-gallery-image');
11682			return isNotPortfolioImage && isNotBlogImage && isNotSwiperImage && isNotGalleryImage;
11683		});;
11684
11685		// Handle the resize
11686		MK.component.ResponsiveImageSetter.onResize($allImages);
11687
11688		MK.component.ResponsiveImageSetter.init($allImages);
11689
11690		MK.utils.eventManager.subscribe('ajaxLoaded', MK.component.ResponsiveImageSetter.handleAjax ); // ajax loops
11691		MK.utils.eventManager.subscribe('ajax-preview', MK.component.ResponsiveImageSetter.handleAjax ); // ajax portfolio
11692		MK.utils.eventManager.subscribe('quickViewOpen', MK.component.ResponsiveImageSetter.handleAjax );
11693	}
11694	init();
11695	$(window).on('vc_reload', init);
11696
11697});
11698
11699
11700
11701(function( $ ) {
11702	'use strict';
11703
11704	var utils = MK.utils;
11705	var val   = MK.val;
11706
11707	/**
11708	 * Keep track of top Level sections so we can easly skip to next one.
11709	 * We must be explicit about DOM level to nested sections.
11710	 * The list of sections is static. If you'd need to refreh it on ajax etc do it with pub/sub (not really needed now).
11711	 * We keep track for the same sections in Footer for mutating window location with '!loading' to prevent native anchor behaviour.
11712	 */
11713	var $topLevelSections = $('#theme-page > .vc_row, #theme-page > .mk-main-wrapper-holder, #theme-page > .mk-page-section');
11714
11715	$( document ).on( 'click', '.mk-skip-to-next', function() {
11716		var $this = $( this ),
11717			/**
11718			 * Static height of button + the space to the bottom of the container.
11719			 *
11720			 * @TODO Possible to calculate dynamically.
11721			 */
11722			btnHeight = $this.hasClass( 'edge-skip-slider' ) ? 150 : 76,
11723			offset = $this.offset().top + btnHeight,
11724			nextOffset = utils.nextHigherVal( utils.offsets( $topLevelSections ), [offset] );
11725
11726		utils.scrollTo( nextOffset - val.offsetHeaderHeight( nextOffset ) );
11727	});
11728
11729})( jQuery );
11730
11731(function($) {
11732	'use strict';
11733
11734	// 
11735	// Constructor
11736	// 
11737	// /////////////////////////////////////////////////////////
11738
11739	MK.ui.Slider = function( container, config ) { 
11740
11741		var defaults = {
11742				slide 				: '.mk-slider-slide',
11743	            nav 	     		: '.mk-slider-nav',
11744                effect              : 'roulete',
11745                ease 				: 'easeOutQuart', // should not be changed, remove
11746                slidesPerView       : 1,
11747                slidesToView        : 1,
11748                transitionTime      : 700,
11749                displayTime         : 3000,
11750                autoplay            : true,
11751                hasNav              : true,
11752                hasPagination       : true,
11753                paginationTpl 		: '<span></span>',
11754                paginationEl 		: '#pagination',
11755                draggable           : true,
11756                fluidHeight 		: false,
11757                pauseOnHover		: false,
11758                lazyload			: false,
11759                activeClass 		: 'is-active',
11760                edgeSlider	 		: false,
11761                spinnerTpl 			: '<div class="mk-slider-spinner-wrap"><div class="mk-slider-spinner-fallback"></div><svg class="mk-slider-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="mk-slider-spinner-path" fill="none" stroke-width="4" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>',
11762                onInitialize 		: function() {},
11763                onAfterSlide 		: function( id ) {},
11764                onBeforeSlide 		: function( id ) {}
11765		};
11766
11767		this.state = {
11768			id 						: 0,
11769			moveForward 			: true,
11770			running   				: false,
11771            zIFlow					: null,
11772            stop 					: false,
11773		};
11774
11775		this.config = $.extend( defaults, config );
11776		this.container = container;
11777
11778		this.initPerView = this.config.slidesPerView;
11779
11780		// Timer holder
11781		this.activeTimer = null;
11782		this.autoplay = null;
11783		this.timer = null;
11784		this.timerRemaining = parseInt(this.config.displayTime);
11785
11786		// Boolean 'Em All, Making sure it's not string
11787		this.config.lazyload = JSON.parse(this.config.lazyload);
11788		this.config.edgeSlider = JSON.parse(this.config.edgeSlider);
11789
11790		// Image Loader Instance
11791		this.imageLoader = null;
11792
11793		// Add abort command to imagesLoaded, Placing it inside script makes it to work with different versions
11794		// of imagesLoaded if loaded by other Plugins
11795		imagesLoaded.prototype.abort = function() {
11796			this.progress = this.complete = function() { };
11797		};
11798	};
11799
11800	
11801
11802	// 
11803	// Shared methods
11804	// 
11805	// /////////////////////////////////////////////////////////
11806
11807	MK.ui.Slider.prototype = {
11808
11809		init : function() {
11810			this.setPerViewItems();
11811			this.cacheElements();
11812			this.getSlideSize();
11813			this.bindEvents();
11814            this.setSize();
11815			this.setPos();
11816
11817			// Hack for preparing 'prev' on first click if needed
11818			this.updateId( -1 );
11819			this.updateId( 1 );
11820
11821			this.val = this.dynamicVal();
11822			this.timeline = this.prepareTimeline( this.config.transitionTime );
11823
11824			this.timeline.build();
11825
11826			if( this.config.hasPagination ) { this.buildPagination(); }
11827			
11828			if( this.config.autoplay && document.hasFocus() ) { this.setTimer(); }
11829
11830			if( typeof this.config.onInitialize === 'function' ) {
11831				this.config.onInitialize( this.slides );
11832			}
11833
11834			if( this.config.fluidHeight === true ) {
11835				$( this.slides ).height( 'auto' );
11836				$( this.container ).css( 'transition', 'height ' + 200 + 'ms ease-out' );
11837				this.setHeight( 0 );
11838			}
11839
11840
11841			if( this.config.fluidHeight === 'toHighest' ) {
11842				this.setHeightToHighest();
11843			}
11844
11845			// Create timer per slide if required
11846			$(this.slides).each(this.createTimer);
11847
11848			// If it's Edge Slider and Lazy Load is enabled 
11849			if ( this.config.lazyload && this.config.edgeSlider ) {
11850
11851				// If It's not a Video Slide
11852				if ( $(this.slides[this.state.id]).find('video').length === 0 ) {
11853					// Set the first slide's BG image
11854					var $slideImg = $(this.slides[this.state.id]).children('[data-mk-img-set]');
11855					MK.component.BackgroundImageSetter.init( $slideImg );
11856				}
11857				$(this.config.spinnerTpl).prependTo( this.$slides );
11858
11859			} else {
11860
11861				// Set all slides's BG images
11862				MK.component.BackgroundImageSetter.init( $(this.slides).children('[data-mk-img-set]') );
11863
11864			}
11865			
11866
11867
11868		},
11869
11870
11871		cacheElements : function () {
11872			this.container = this.isNode( this.container ) ? this.container 
11873				: document.querySelectorAll( this.container )[0];
11874			this.slides = this.container.querySelectorAll( this.config.slide );
11875			this.$slides = $(this.slides);
11876
11877			if( this.config.hasNav ) { this.$nav = $( this.config.nav ); }
11878			if( this.config.hasPagination ) { this.$pagination = $( this.config.paginationEl ); }
11879		},
11880
11881
11882		bindEvents : function() {
11883			var $window = $( window );
11884
11885			if( this.config.slidesPerView > 1 ) { $window.on( 'resize', this.setPerViewItems.bind( this ) ); }
11886			if( this.config.hasNav ) { this.eventsNav(); }
11887			if( this.config.hasPagination ) { this.eventsPag(); }
11888			if( this.config.draggable ) { this.dragHandler(); }
11889			if( this.config.autoplay ) {
11890				$window.on( 'focus', this.windowActive.bind( this ) );
11891				$window.on( 'blur', this.windowInactive.bind( this ) );
11892			}
11893			if( this.config.pauseOnHover ) {
11894				$(this.container).on( 'mouseleave', this.setTimer.bind( this ) );
11895				$(this.container).on( 'mouseenter', this.unsetTimer.bind( this ) );
11896			}
11897			if( this.config.fluidHeight === 'toHighest' ) {
11898				$window.on( 'resize', this.setHeightToHighest.bind( this ) );
11899			}
11900		},
11901
11902
11903		setPerViewItems: function() {
11904			if(window.matchMedia( '(max-width: 500px)' ).matches) { this.config.slidesPerView = 1; }
11905			else if(window.matchMedia( '(max-width: 767px)' ).matches && this.initPerView >= 2 ) { this.config.slidesPerView = 2; }
11906			else if(window.matchMedia( '(max-width: 1024px)' ).matches && this.initPerView >= 3 ) { this.config.slidesPerView = 3; }
11907			else { this.config.slidesPerView = this.initPerView; }
11908			
11909        	if( typeof this.slides === 'undefined' ) return; 
11910			this.getSlideSize();
11911			this.setSize();
11912			this.setPos();
11913			this.timeline = this.prepareTimeline( this.config.transitionTime );
11914			this.timeline.build();
11915		},
11916
11917
11918		eventsNav : function() {
11919			this.$nav.on( 'click', 'a', this.handleNav.bind( this ) );
11920		},
11921
11922
11923		eventsPag : function() {
11924			this.$pagination.on( 'click', 'a', this.handlePagination.bind( this ) );
11925		},
11926
11927
11928		handleNav : function( e ) {
11929			e.preventDefault();
11930
11931			if( this.state.running ) { return; }
11932			this.state.running = true;
11933
11934			var $this = $( e.currentTarget ),
11935				moveForward = $this.data( 'direction' ) === 'next';
11936
11937
11938			if( this.config.autoplay ) { 
11939				this.unsetTimer();
11940				setTimeout( this.setTimer.bind( this ), this.config.transitionTime );
11941			}
11942
11943			this.state.moveForward = moveForward;
11944			this.timeline.build();
11945			this.timeline.play();
11946
11947			this.setActive( this.nextId( moveForward ? 1 : -1 ) );
11948			if( this.config.fluidHeight ) { this.setHeight( this.nextId( moveForward ? 1 : -1 ) ); }
11949		},
11950
11951
11952		handlePagination : function( e ) {
11953			e.preventDefault();
11954
11955			var $this = $( e.currentTarget ),
11956				id = $this.index();
11957
11958			this.goTo( id );
11959		},
11960
11961
11962		reset: function() {
11963			this.state.stop = true;
11964			this.state.id = 0;
11965			this.setPos();
11966			this.unsetTimer();
11967			this.setTimer();
11968		},
11969
11970
11971		goTo : function(id) {
11972			if( this.state.running ) { return; }
11973			this.state.running = true;
11974
11975			var lastId = this.state.id;
11976
11977			if( lastId === id ) {
11978				return;
11979			} else if( lastId < id ) {
11980				this.state.moveForward = true;
11981			} else {
11982				this.state.moveForward = false;
11983			}
11984
11985			if( this.config.autoplay ) { 
11986				this.unsetTimer();
11987				setTimeout( this.setTimer.bind( this ), this.config.transitionTime );
11988			}
11989
11990			this.timeline.build( Math.abs( lastId - id ) );
11991			this.timeline.play();
11992
11993			this.setActive( id );
11994			if( this.config.fluidHeight ) { this.setHeight( id ); } 
11995		},
11996
11997
11998		windowActive : function() {
11999			this.setTimer(false, true);
12000			$(this.container).removeClass('is-paused'); 
12001		},
12002
12003
12004		windowInactive : function() {
12005			this.unsetTimer();
12006			$(this.container).addClass('is-paused');
12007		},
12008
12009
12010		updateId : function( val ) {
12011			this.state.id = this.nextId(val);
12012		},
12013
12014		nextId : function( val ) {
12015			var len = this.slides.length,
12016				insertVal = this.state.id + val;
12017				insertVal = ( insertVal >= 0 ) ? insertVal : len + val;
12018				insertVal = ( insertVal >= len ) ? 0 : insertVal;
12019
12020			return insertVal;
12021		},
12022
12023
12024		setStyle : function( obj, style ) {
12025            var hasT = style.transform,
12026            	t = {
12027	                x       : ( hasT ) ? style.transform.translateX : null,
12028	                y       : ( hasT ) ? style.transform.translateY : null,
12029	                scale   : ( hasT ) ? style.transform.scale 		: null,
12030	                rotate  : ( hasT ) ? style.transform.rotate 	: null,
12031	                rotateX : ( hasT ) ? style.transform.rotateX 	: null,
12032	                rotateY : ( hasT ) ? style.transform.rotateY 	: null
12033           		},
12034				z  = 'translateZ(0)',
12035            	x  = (t.x) ?  'translateX(' + t.x + '%)' 		: 'translateX(0)',
12036                y  = (t.y) ?  'translateY(' + t.y + '%)' 		: 'translateY(0)',
12037                s  = (t.scale)  ?  'scale(' + t.scale + ')' 	: 'scale(1)',
12038                r  = (t.rotate) ? 'rotate(' + t.rotate + 'deg)' : 'rotate(0)',
12039                rX = (t.rotateX) ? 'rotateX(' + t.rotateX + 'deg)' : '',
12040                rY = (t.rotateY) ? 'rotateY(' + t.rotateY + 'deg)' : '',
12041
12042           		o = style.opacity,
12043           		h = style.height,
12044           		w = style.width;
12045
12046            var c = z + x + y  + s + r + rX + rY;
12047
12048            if( c.length ) {
12049	            obj.style.webkitTransform 	= c;
12050	            obj.style.msTransform 		= c;
12051	            obj.style.transform 		= c;
12052	        }
12053
12054            if( typeof o === 'number' ) { obj.style.opacity = o; }
12055            if( h ) { obj.style.height  = h + '%'; }
12056            if( w ) { obj.style.width   = w + '%'; }
12057		},
12058
12059
12060		setPos : function() {
12061        	if( typeof this.slides === 'undefined' ) return; 
12062		    var id 			= this.state.id,
12063		    	i 			= 0,
12064		    	len 		= this.slides.length,
12065		    	animation 	= this.animation[ this.config.effect ],
12066		    	axis 		= animation.axis,
12067				animNext	= animation.next,
12068				animActi 	= animation.active,
12069				animPrev 	= animation.prev,
12070                perView 	= this.config.slidesPerView,
12071                slideId 	= null,
12072                zIFlow 		= null,
12073                style 		= {};
12074
12075            style.transform = {};
12076
12077
12078            for( ; i < len; i += 1 ) {
12079                if(i < perView) {
12080                	// Position for visible slides. Apply active styles
12081                	style = animActi;
12082                    style.transform[ 'translate' + axis ] = i * 100;
12083                } else {
12084                	// Rest slides move after edge based on axis and moveForward. Apply Next / Prev styles
12085                	style = this.state.moveForward ? animNext : animPrev;
12086                    style.transform[ 'translate' + axis ] =  this.state.moveForward ? perView * 100 : -100;
12087                }
12088
12089                this.slides[ i ].style.zIndex = 0;
12090
12091                slideId = ( i + id ) % len;
12092                this.setStyle( this.slides[ slideId ], style );
12093            }
12094		},
12095
12096
12097        // When we're setting animation along Y axis we're going to set up height
12098        // otherwise width. It is shared amongst all slides
12099        setSize : function() {
12100        	if( typeof this.slides === 'undefined' ) return; 
12101        	var i = 0,
12102		    	len = this.slides.length,
12103		    	axis = this.animation[ this.config.effect ].axis,
12104                slideSize = this.slideSize,
12105        		style = {};
12106
12107            if( axis === 'Y' ) {
12108                style.height = slideSize[ axis ];
12109            } else {
12110                style.width = slideSize[ axis ];
12111            }
12112
12113            for( ; i < len; i += 1 ) {
12114                this.setStyle( this.slides[ i ], style );
12115            }
12116        },
12117
12118
12119        setHeight : function( id ) {
12120			var $slides = $( this.slides ),
12121				$activeSlide = $slides.eq( id );
12122
12123        	var currentHeight = $activeSlide.height();
12124        	$( this.container ).height( currentHeight ); 
12125        },
12126
12127
12128        setHeightToHighest : function() {
12129        	// this is becouse of alliginig woocommrece carousel. Too much DOM
12130        	// Refactor someday
12131			var $slides = $( this.slides ),
12132				height = 0;
12133
12134        	$slides.each(function() {
12135        		height = Math.max(height, $(this).find('> div').outerHeight());
12136        	});
12137
12138        	$( this.container ).height( height ); 
12139        },
12140
12141
12142        // Little utility inspired by GreenSock.
12143        // We export this to this.timeline on init. 
12144        prepareTimeline : function( time ) {
12145			var self 		= this,
12146				iteration 	= 0,
12147            	totalIter 	= time / (1000 / 60),
12148            	animLoop 	= [],
12149            	aL 			= 0, // animation length
12150            	loops 		= 1,
12151				ease 		= this.config.ease, 
12152				currentStyle, timeProg, 
12153				build, move, add, play, reverse, progress, kill;
12154
12155
12156			// Build constants, run them only once
12157			// take out possibly
12158			var len 		= this.slides.length,
12159				perView   	= this.config.slidesPerView,
12160				animation 	= this.animation[ this.config.effect ],
12161				animAxis 	= animation.axis,
12162				animNext	= animation.next,
12163				animActi 	= animation.active,
12164				animPrev 	= animation.prev,
12165				style 		= {},
12166				slideId 	= null,
12167				zIFlow 		= null;
12168
12169				style.transform = {};
12170
12171
12172			build = function( repeats ) {
12173				var currentEase = ease;
12174				loops = repeats || loops;
12175
12176				// console.log('build', loops);
12177
12178				if( !loops ) { return; }
12179				if( loops > 1 ) {
12180					currentEase = 'linearEase';
12181				}
12182
12183				// clean before running new build
12184				kill();
12185				// set new positions
12186				self.setPos();
12187
12188				var id = self.state.id,
12189					moveForward = self.state.moveForward,
12190					i = 0,
12191					axisMove = (moveForward) ? -100 : 100;
12192
12193				for( ; i <= perView; i += 1 ) {
12194					slideId = ( (moveForward) ? i + id : i + id - 1 ) % len;
12195					slideId = ( slideId < 0 ) ? len + slideId : slideId;
12196
12197					if( i === 0 ) {
12198						style = moveForward ? animPrev : animActi;
12199					} else if( i === perView ) {
12200						style = moveForward ? animActi : animNext;
12201					} else {
12202						style = animActi;
12203	            	}
12204
12205               	 	zIFlow = (self.state.moveForward) ? animNext.zIndex : animPrev.zIndex; 
12206	                if( zIFlow ) { 
12207	                	// console.log( zIFlow );
12208	                	self.slides[ slideId ].style.zIndex = (zIFlow === '+') ? i + 1 : len - i;
12209	                }
12210
12211					style.transform[ 'translate' + animAxis ] = axisMove;
12212	            	add( self.slides[ slideId ], style, currentEase );
12213				}
12214			};
12215
12216			add = function( slide, toStyles, ease ) {
12217				if( typeof slide === 'undefined' ) {
12218					throw 'Add at least one slide';
12219				}
12220
12221	            var fromStyles = slide.style,
12222					style = self.refStyle( toStyles, fromStyles );
12223
12224				animLoop.push( [slide, style, ease] );
12225				aL += 1;
12226			};
12227
12228			move = function( startProg, mode ) {
12229				if (isTest) return;
12230				var currentTotalIter = totalIter;
12231
12232				if( loops > 1 ) {
12233				 	currentTotalIter = totalIter / 5;
12234				}
12235
12236				if( !self.state.running ) { self.state.running = true; }
12237
12238				if( startProg ) {
12239					// update iteration val to cached outside var
12240					// ceil to handle properly play after mouse up / touch end
12241					iteration = Math.ceil(startProg * currentTotalIter);
12242				}
12243				
12244				timeProg = iteration / currentTotalIter;
12245				progress( timeProg );
12246
12247				// Break loop
12248				if( iteration >= currentTotalIter && mode === 'play' || 
12249					iteration <= 0 && mode === 'reverse' ) { 
12250
12251					self.state.running = false;
12252					iteration = 0;
12253					kill();
12254	            	self.updateId( self.state.moveForward ? 1 : -1 );
12255					// If we're creating multiple animation loop we trigger outside only first pass to start all game.
12256					// the rest are triggered as callback
12257					loops -= 1;
12258					if( loops > 0 ) {
12259						build();
12260						play();
12261					}
12262
12263					// if we run all loops reset back the default value
12264					if( !loops ) {
12265						loops = 1;
12266						self.timerRemaining = parseInt(self.config.displayTime);
12267						self.config.onAfterSlide( self.state.id );
12268					}
12269
12270					return; 
12271				}
12272
12273				// Run in given mode
12274				if( mode === 'play') {
12275					iteration += 1;
12276				} else {
12277					iteration -= 1;
12278				}
12279
12280				requestAnimationFrame( function() {
12281					if(self.state.stop) return;
12282					move( 0, mode );
12283				});
12284			};
12285
12286			play = function( startProg ) {
12287
12288				var $nextSlide = $(self.slides[ self.nextId(self.state.moveForward ? 1 : -1) ] );
12289
12290				// If it's Edge Slider and Lazy Load is enabled and It's not a Video Slide
12291				if ( self.config.lazyload && self.config.edgeSlider ) {
12292
12293					// Set the next slide's BG Image
12294					var $slideImg = $nextSlide.find('[data-mk-img-set]');
12295					if ( $slideImg.length ) {
12296						MK.component.BackgroundImageSetter.init( $slideImg );
12297					}
12298
12299				}
12300
12301				self.config.onBeforeSlide( self.nextId(self.state.moveForward ? 1 : -1) );
12302				var start = startProg || 0;
12303				iteration = 0;
12304				self.state.stop = false;
12305				move( start, 'play' );
12306
12307			};
12308
12309			reverse = function( startProg ) {
12310				var start = startProg || 1;
12311				move( start, 'reverse' );
12312			};
12313
12314			progress = function( progVal ) {
12315            	var aI = 0, 
12316            		currentStyle;
12317
12318				for( aI; aI < aL; aI++ ) {
12319					if( progVal !== 1 && progVal !== 0 ) {
12320						currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], animLoop[ aI ][ 2 ] );
12321					} else if( progVal === 1) {
12322						currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' );
12323					} else if ( progVal === 0 ) {
12324						currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' );
12325					} 
12326					self.setStyle( animLoop[ aI ][ 0 ], currentStyle );
12327				}
12328			};
12329
12330			// Clear previous loop
12331			kill = function() {
12332				animLoop = [];
12333            	aL = 0;
12334			};
12335
12336
12337			return {
12338				build 		: build,
12339				add 		: add,
12340				play 		: play,
12341				reverse 	: reverse,
12342				progress 	: progress
12343			};
12344		},
12345
12346
12347		// Build reference styles.
12348		// Return object with array containig initial style and change of its value
12349		// as required for easing functions
12350		refStyle : function( toStyles, fromStyles ) {
12351			var axis = this.animation[ this.config.effect ].axis,
12352            	style = {},
12353				initVal, changeVal, endVal, dynamicEnd, styleProp, transProp, transform;
12354
12355			for( styleProp in toStyles ) {
12356
12357				if( styleProp === 'transform' ) {
12358					transform = this.getTransforms( fromStyles );
12359					style.transform = {};
12360
12361					for( transProp in toStyles.transform ) {
12362						// don't care about z
12363						if( transProp === 'translateZ' ) { continue; }
12364
12365						initVal = transform[ transProp ] || 0; // if it is undefined it means it's 0
12366						dynamicEnd = ( transProp === 'translate' + axis ) ? initVal : 0;
12367						endVal  = toStyles.transform[ transProp ] + dynamicEnd; // it is dynamic, based on slide position in current set
12368						changeVal = endVal - initVal;
12369						style.transform[ transProp ] = [ initVal, changeVal ];
12370					}
12371				} else if( styleProp === 'zIndex' ) {
12372					// console.log( 'z' );
12373					continue;
12374				} else {
12375					initVal = parseFloat( fromStyles[ styleProp ] ) || 0; // if it is undefined it means it's 0
12376					endVal  = toStyles[ styleProp ];
12377					changeVal = endVal - initVal;
12378					style[ styleProp ] =  [ initVal, changeVal ];
12379				}
12380			}
12381
12382			return style;
12383		},
12384
12385
12386		currentStyle : function( progress, style, ease ) {
12387			var self = this,
12388				currentStyle = {},
12389            	currentVals, styleProp, transProp, prog;
12390
12391			// Redo same loop but construct currentStyle object out of cached values
12392			for( styleProp in style ) {
12393
12394				if( styleProp === 'transform' ) {
12395					currentStyle.transform = {};
12396
12397					for( transProp in style.transform ) {
12398						// remove this line. double check first if needed by logging
12399						if( transProp === 'translateZ' ) { continue; }
12400
12401						currentVals = style.transform[ transProp ];
12402						currentStyle.transform[ transProp ] = 
12403							// (currentIteration, startValue, changeInValue, totalIterations)
12404								self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 );
12405					}
12406				} else {
12407					currentVals = style[ styleProp ];
12408					currentStyle[ styleProp ] = 
12409						self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 );
12410				}
12411			}
12412
12413			return currentStyle;
12414		},
12415
12416
12417		setActive : function( id ) {
12418			var $slides = $( this.slides ),
12419				className = this.config.activeClass;
12420
12421			$slides.removeClass( className );
12422
12423			if( this.config.hasPagination ) {
12424				var $pagination = this.$pagination.find( 'a' );
12425				$pagination.removeClass( className );
12426				$pagination.eq( id ).addClass( className );
12427			}
12428
12429			if( this.activeTimer ) {
12430				clearTimeout( this.activeTimer );
12431				if ( this.imageLoader ) {
12432					this.imageLoader.abort();
12433				}
12434			} 
12435			
12436
12437			var self = this;
12438
12439			this.activeTimer = setTimeout( function() {
12440
12441				var $currentSlide = $slides.eq( id );
12442
12443				if ( self.config.lazyload && self.config.edgeSlider ) {  // If it's Edge Slider and Lazy Load is enabled
12444
12445					if ( $currentSlide.find('.mk-section-video').length && $currentSlide.children('.mk-video-section-touch').length ) {  // If it's a Video Slide and has a Preview image
12446						
12447						var imgSet = $currentSlide.children('.mk-video-section-touch').data('mk-img-set');
12448						var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet );
12449						var $bgImage = $('<img>').attr('src', exactImg );
12450
12451						self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) {
12452							$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12453							setTimeout( function() {
12454						 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12455						 	}, 200);
12456							$currentSlide.addClass( className );
12457					 	});
12458
12459					} else if ( $currentSlide.find('.mk-section-video').length && $currentSlide.children('.mk-video-section-touch').length === 0 ) { // If it's a Video Slide and has NOT a Preview image
12460
12461						$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12462						setTimeout( function() {
12463					 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12464					 	}, 200);
12465						$currentSlide.addClass( className );
12466						
12467					} else {  // If it's a Image Slide
12468
12469						if ( $currentSlide.children('[data-mk-img-set]').length ) {
12470							// Get the matching Image URL to start lazy loading
12471							var imgSet = $currentSlide.children('[data-mk-img-set]').data('mk-img-set');
12472							var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet );
12473							var $bgImage = $('<img>').attr('src', exactImg );
12474
12475							// Prevent counting time on slide until the image loads
12476							self.unsetTimer();
12477							self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) {
12478								// Hide spinner, Continue counting time on slide and show the content
12479							 	$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12480							 	setTimeout( function() {
12481							 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12482							 	}, 200);
12483								self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) );
12484								$currentSlide.addClass( className );
12485							});
12486						} else {
12487							$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12488						 	setTimeout( function() {
12489						 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12490						 	}, 200);
12491							self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) );
12492							$currentSlide.addClass( className );
12493						}
12494
12495					}
12496
12497				} else {
12498
12499					$currentSlide.addClass( className );
12500
12501				}
12502				
12503				
12504			}, this.config.transitionTime );
12505		},
12506
12507		createTimer : function() {
12508
12509			var $slide = $(this),
12510				video = $slide.find('video').get(0);
12511
12512			if(video) {
12513				// A hacky but reliable way to ge the video duration
12514				var interval = setInterval( function() {
12515					// If the metadata is ready
12516					if ( video.readyState > 0 ) {
12517						$slide.data('timer', (video.duration * 1000));
12518						$slide.attr('data-timer', (video.duration * 1000));
12519						clearInterval(interval);
12520					}
12521				}, 100);
12522			}
12523
12524		},
12525		
12526		setTimer : function( isFirst, isPaused, fixed_time ) {
12527			// check for custom timer
12528			var customTimer = this.$slides.eq(this.nextId(this.state.moveForward ? 1 : -1)).data('timer'),
12529				trans = parseInt( this.config.transitionTime ),
12530				interval = customTimer ? customTimer : parseInt( this.config.displayTime ),
12531				timer = interval + trans;
12532
12533			var self  = this,
12534				first = isFirst || true,
12535				fixed_time = fixed_time || 0,
12536				create, run;
12537
12538			this.timer = true;
12539			this.lastSetTimer = Date.now();
12540
12541			create = function() {	
12542
12543				if( self.autoplay ) { clearTimeout( self.autoplay ); }
12544				if( !self.timer ) {
12545					return;
12546				}
12547				self.state.moveForward = true;
12548				self.timeline.build();
12549				self.timeline.play();
12550				self.setActive( self.nextId( 1 ) );
12551				if( self.config.fluidHeight ) { self.setHeight( self.nextId( 1 ) ); }
12552				first = false;
12553				self.lastSetTimer = Date.now();
12554
12555				run();
12556			};
12557
12558			run = function(newInterval) {
12559				// check for custom timer
12560				customTimer = self.$slides.eq(self.nextId(self.state.moveForward ? 1 : -1)).data('timer');
12561				interval = customTimer ? customTimer : parseInt( self.config.displayTime );
12562				timer = interval + trans; // update timer with current val
12563
12564				var time = newInterval || timer;
12565				self.autoplay = setTimeout( create, time );
12566			};
12567
12568			if ( fixed_time ) {
12569				run( fixed_time );
12570			} else if (isPaused) {
12571				run( this.timerRemaining );
12572			} else {
12573				run();
12574			}
12575		},
12576
12577
12578		unsetTimer : function() {
12579			this.timer = false;
12580			this.lastUnsetTimer = Date.now();
12581			this.timerRemaining -= this.lastUnsetTimer - this.lastSetTimer;
12582			if( this.autoplay ) { clearTimeout( this.autoplay ); }
12583		},
12584
12585
12586		buildPagination : function() {
12587			var i   = 0,
12588				len = this.slides.length,
12589				tpl = '';
12590
12591			for( ; i < len; i += 1 ) {
12592				tpl += '<a href="javascript:;">' + this.config.paginationTpl + '</a>';
12593			}
12594
12595			this.$pagination.html( tpl );
12596			this.setActive( 0 );
12597		},
12598
12599
12600		getSlideSize : function() {
12601			this.slideSize = {
12602                X: 100 / this.config.slidesPerView,
12603                Y: 100 / this.config.slidesPerView
12604            };
12605		},
12606
12607
12608		getTransforms : function( style ) {
12609			// console.log( style );
12610		    var transform = style.transform || style.webkitTransform || style.mozTransform,
12611		    	regex = /(\w+)\(([^)]*)\)/g,
12612				match,
12613				T = {};
12614
12615			if( typeof transform !== 'string' ) {
12616				throw 'Transform prop is not a string.';
12617			}
12618
12619		    if( !transform ) { return; }
12620	
12621			// Run regex assignment
12622			while( match = regex.exec( transform ) ) {
12623				T[ match[ 1 ] ] = parseFloat( match[ 2 ] );
12624			}
12625
12626		    return T;
12627		},
12628
12629		isNode : function( o ) {
12630			return (
12631		    	typeof Node === "object" ? o instanceof Node : 
12632		   			o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
12633		  	);
12634		},
12635
12636
12637		dragHandler : function() {
12638			var self = this,
12639				$container = $( this.container ),
12640				prevBuild = false, 
12641				nextBuild = false,
12642				dragging = false,
12643				buffor = 5, // helpful for decoupling with click events
12644				dragStart, dragMove, dragEnd, progress;
12645
12646			progress = function( moveX ) {
12647				return moveX / self.val.viewportW();
12648			};
12649
12650			dragStart = function( moveX, startX ) {
12651				// console.log( 'start', moveX, startX );
12652			};
12653
12654			dragMove = function( moveX ) {
12655				// console.log('move');
12656				if( self.state.running ) return;
12657
12658				// Don't need to check for existance here
12659
12660				if( moveX < -buffor ) {
12661
12662					if( !nextBuild ) {
12663						self.state.moveForward = true;
12664						self.timeline.build();
12665						nextBuild = true;
12666						prevBuild = false;
12667						self.unsetTimer();
12668					} else {
12669						// turn progress into positive val
12670						self.timeline.progress( -progress( moveX ) );
12671					}
12672					dragging = true;
12673				} else if( moveX > buffor ) {
12674
12675					if( !prevBuild ) {
12676						self.state.moveForward = false;
12677						self.timeline.build();
12678						prevBuild = true;
12679						nextBuild = false;
12680						self.unsetTimer();
12681					} else {
12682						self.timeline.progress( progress( moveX ) );
12683					}
12684					dragging = true;
12685				}
12686			};
12687
12688			dragEnd = function( moveX ) {
12689				if( dragging ) {
12690					var prog = progress( moveX ),
12691						absProg = prog < 0 ? -prog : prog;
12692
12693					if( absProg > 0.1 ) {
12694						self.timeline.play( absProg );
12695						self.setActive( self.nextId( prog < 0 ? 1 : -1 ) );
12696						if( self.config.fluidHeight ) { self.setHeight( self.nextId( prog < 0 ? 1 : -1 ) ); }
12697					} else {
12698						self.timeline.reverse( absProg );
12699						// eventually move this to reverse callbacks	
12700						if(prog < 0) {
12701							self.updateId( -1 );
12702						} else {
12703							self.updateId( 1 );
12704						}
12705					}
12706
12707					prevBuild = false;
12708					nextBuild = false;
12709					dragging = false;
12710					if( self.config.autoplay ) { self.setTimer( false ); }
12711				}
12712			};
12713
12714			this.drag( $container, dragStart, dragMove, dragEnd );
12715		},
12716
12717
12718		drag : function( $el, startFn, moveFn, stopFn ) {
12719
12720		    var touchX, touchY, movX, movY, go, evt,
12721		   		prevent, start, move, stop;
12722
12723		    prevent = function( e ) {
12724		        e.preventDefault();
12725		    };
12726
12727		    start = function( e ) {
12728		        // $el.on("touchmove", prevent);
12729		        $el.on("mousemove", prevent);
12730		        $el.on("touchmove", move);
12731		        $el.on("mousemove", move);
12732
12733		        evt = (e.type === 'touchstart') ? e.originalEvent.touches[0] : e;
12734		        touchX = evt.pageX;
12735
12736		        if(typeof startFn === 'function') {
12737		        	startFn(movX, touchX);
12738		        }
12739		    };
12740
12741		    move = function( e ) {
12742		        evt = (e.type === 'touchmove') ? e.originalEvent.touches[0] : e;
12743		        movX = evt.pageX - touchX;
12744
12745	        	if(typeof moveFn === 'function') {
12746		        	moveFn(movX);
12747		        }
12748		    };
12749
12750		    stop = function( e ) {
12751		        // $el.off("touchmove", prevent);
12752		        $el.off("mousemove", prevent);
12753		        $el.off("touchmove", move);
12754		        $el.off("mousemove", move);
12755
12756		    	if(typeof stopFn === 'function') {
12757		        	stopFn(movX);
12758		        }
12759		    };
12760
12761		    $el.on("touchstart", start);
12762		    $el.on("mousedown", start);
12763		    $el.on("touchend", stop);
12764		    $el.on("touchleave", stop);
12765		    $el.on("touchcancel", stop);
12766		    $el.on("mouseup", stop);
12767		    $el.on("mouseleave", stop);
12768		},
12769
12770
12771		dynamicVal : function() {
12772			var $window = $( window ),
12773				update, 
12774				getViewportW, viewportW;
12775
12776			update = function() {
12777 				viewportW = $window.width();
12778			};
12779
12780			getViewportW = function() {
12781				return viewportW;
12782			};
12783
12784			update();
12785			$window.on( 'load', update );
12786			$window.on( 'resize', update );
12787
12788			return {
12789				viewportW : getViewportW
12790			};
12791		}
12792	};
12793
12794
12795
12796	// 
12797	// Set of default animations
12798	// 
12799	// /////////////////////////////////////////////////////////
12800
12801	MK.ui.Slider.prototype.animation = {
12802
12803        slide : {
12804        	axis : 'X', 
12805            next : { transform: {} },
12806            active : { transform: {} },
12807            prev : { transform: {} }
12808        },
12809
12810        vertical_slide : {
12811        	axis : 'Y',
12812            next : { transform: {} },
12813            active : { transform: {} },
12814            prev : { transform: {} }
12815        },
12816
12817        perspective_flip : {
12818        	axis : 'Y',
12819            next : { 
12820            	transform: {
12821            		rotateX : 80
12822            	} 
12823            },
12824            active : { 
12825            	transform: {
12826            		rotateX : 0
12827            	} 
12828            },
12829            prev : { 
12830            	transform: {
12831            		rotateX : 0
12832            	} 
12833            }
12834        },
12835
12836        zoom : {
12837			axis : 'Z',
12838            next: {
12839                opacity	: 0,
12840                transform : {
12841	                scale : 0.9
12842	            }
12843            },
12844            active: {
12845                opacity	: 1,
12846                transform : {
12847	                scale : 1
12848	            }
12849            },
12850            prev: {
12851                opacity	: 0,
12852                transform : {
12853	                scale : 1.1
12854	            }
12855            }
12856        },
12857
12858        fade : {
12859			axis : 'Z',
12860            next: {
12861                opacity	: 0,
12862                transform : {}
12863            },
12864            active: {
12865                opacity	: 1,
12866                transform : {}
12867            },
12868            prev: {
12869                opacity	: 0,
12870                transform : {}
12871            }
12872        },
12873
12874        kenburned : {
12875			axis : 'Z',
12876            next: {
12877                opacity	: 0,
12878                transform : {}
12879            },
12880            active: {
12881                opacity	: 1,
12882                transform : {}
12883            },
12884            prev: {
12885                opacity	: 0,
12886                transform : {}
12887            }
12888        },
12889
12890        zoom_out : {
12891			axis : 'Z',
12892            next: {
12893				zIndex : '+',
12894                opacity	: 1,
12895                transform : {
12896	                translateY : 100,
12897	                scale : 1
12898	            }
12899            },
12900            active: {
12901                opacity	: 1,
12902                transform : {
12903	                translateY : 0,
12904	                scale : 1
12905	            }
12906            },
12907            prev: {
12908				zIndex : '+',
12909                opacity	: 0,
12910                transform : {
12911	                translateY : 0,
12912	                scale : 0.5
12913	            }
12914            }
12915        },
12916
12917        // Problem with Z-Flow
12918        horizontal_curtain : {
12919			axis : 'Z',
12920            next: {
12921				zIndex : '+',
12922                transform : {
12923	                translateX : 100,
12924	            }
12925            },
12926            active: {
12927                transform : {
12928	                translateX : 0,
12929	            }
12930            },
12931            prev: {
12932				zIndex : '+',
12933                transform : {
12934	                translateX : -70,
12935	            }
12936            }
12937        },
12938
12939		roulete : {
12940			axis : 'X',
12941            next: {
12942                opacity	: 0.5,
12943                transform : {
12944	                scale : 0.5,
12945	                rotate : 10,
12946	                translateY : 20
12947	            }
12948            },
12949            active: {
12950                opacity	: 1,
12951                transform : {
12952	                scale : 1,
12953	                rotate : 0,
12954	                translateY : 0
12955	            }
12956            },
12957            prev: {
12958                opacity	: 0.3,
12959                transform : {
12960	                scale : 0.5,
12961	                rotate : -10,
12962	                translateY : 20
12963	            }
12964            }
12965		}
12966	};
12967
12968
12969
12970	// 
12971	// Penner's easing library
12972	// 
12973	// /////////////////////////////////////////////////////////
12974
12975	MK.ui.Slider.prototype.ease = {
12976		/*
12977		 *
12978		 * TERMS OF USE - EASING EQUATIONS
12979		 * 
12980		 * Open source under the BSD License. 
12981		 * 
12982		 * Copyright © 2001 Robert Penner
12983		 * All rights reserved.
12984		 * 
12985		 * Redistribution and use in source and binary forms, with or without modification, 
12986		 * are permitted provided that the following conditions are met:
12987		 * 
12988		 * Redistributions of source code must retain the above copyright notice, this list of 
12989		 * conditions and the following disclaimer.
12990		 * Redistributions in binary form must reproduce the above copyright notice, this list 
12991		 * of conditions and the following disclaimer in the documentation and/or other materials 
12992		 * provided with the distribution.
12993		 * 
12994		 * Neither the name of the author nor the names of contributors may be used to endorse 
12995		 * or promote products derived from this software without specific prior written permission.
12996		 * 
12997		 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
12998		 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12999		 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13000		 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
13001		 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
13002		 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
13003		 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
13004		 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
13005		 * OF THE POSSIBILITY OF SUCH DAMAGE. 
13006		 *
13007		 */
13008		linearEase : function(currentIteration, startValue, changeInValue, totalIterations) {
13009			return changeInValue * currentIteration / totalIterations + startValue;
13010		},
13011
13012		easeInQuad : function(currentIteration, startValue, changeInValue, totalIterations) {
13013			return changeInValue * (currentIteration /= totalIterations) * currentIteration + startValue;
13014		},
13015
13016		easeOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) {
13017			return -changeInValue * (currentIteration /= totalIterations) * (currentIteration - 2) + startValue;
13018		},
13019
13020		easeInOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) {
13021			if ((currentIteration /= totalIterations / 2) < 1) {
13022				return changeInValue / 2 * currentIteration * currentIteration + startValue;
13023			}
13024			return -changeInValue / 2 * ((--currentIteration) * (currentIteration - 2) - 1) + startValue;
13025		},
13026
13027		easeInCubic : function(currentIteration, startValue, changeInValue, totalIterations) {
13028			return changeInValue * Math.pow(currentIteration / totalIterations, 3) + startValue;
13029		},
13030
13031		easeOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) {
13032			return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 3) + 1) + startValue;
13033		},
13034
13035		easeInOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) {
13036			if ((currentIteration /= totalIterations / 2) < 1) {
13037				return changeInValue / 2 * Math.pow(currentIteration, 3) + startValue;
13038			}
13039			return changeInValue / 2 * (Math.pow(currentIteration - 2, 3) + 2) + startValue;
13040		},
13041
13042		easeInQuart : function(currentIteration, startValue, changeInValue, totalIterations) {
13043			return changeInValue * Math.pow (currentIteration / totalIterations, 4) + startValue;
13044		},
13045
13046		easeOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) {
13047			return -changeInValue * (Math.pow(currentIteration / totalIterations - 1, 4) - 1) + startValue;
13048		},
13049
13050		easeInOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) {
13051			if ((currentIteration /= totalIterations / 2) < 1) {
13052				return changeInValue / 2 * Math.pow(currentIteration, 4) + startValue;
13053			}
13054			return -changeInValue/2 * (Math.pow(currentIteration - 2, 4) - 2) + startValue;
13055		},
13056
13057		easeInQuint : function(currentIteration, startValue, changeInValue, totalIterations) {
13058			return changeInValue * Math.pow (currentIteration / totalIterations, 5) + startValue;
13059		},
13060
13061		easeOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) {
13062			return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 5) + 1) + startValue;
13063		},
13064
13065		easeInOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) {
13066			if ((currentIteration /= totalIterations / 2) < 1) {
13067				return changeInValue / 2 * Math.pow(currentIteration, 5) + startValue;
13068			}
13069			return changeInValue / 2 * (Math.pow(currentIteration - 2, 5) + 2) + startValue;
13070		},
13071
13072		easeInSine : function(currentIteration, startValue, changeInValue, totalIterations) {
13073			return changeInValue * (1 - Math.cos(currentIteration / totalIterations * (Math.PI / 2))) + startValue;
13074		},
13075
13076		easeOutSine : function(currentIteration, startValue, changeInValue, totalIterations) {
13077			return changeInValue * Math.sin(currentIteration / totalIterations * (Math.PI / 2)) + startValue;
13078		},
13079
13080		easeInOutSine : function(currentIteration, startValue, changeInValue, totalIterations) {
13081			return changeInValue / 2 * (1 - Math.cos(Math.PI * currentIteration / totalIterations)) + startValue;
13082		},
13083
13084		easeInExpo : function(currentIteration, startValue, changeInValue, totalIterations) {
13085			return changeInValue * Math.pow(2, 10 * (currentIteration / totalIterations - 1)) + startValue;
13086		},
13087
13088		easeOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) {
13089			return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue;
13090		},
13091
13092		easeInOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) {
13093			if ((currentIteration /= totalIterations / 2) < 1) {
13094				return changeInValue / 2 * Math.pow(2, 10 * (currentIteration - 1)) + startValue;
13095			}
13096			return changeInValue / 2 * (-Math.pow(2, -10 * --currentIteration) + 2) + startValue;
13097		},
13098
13099		easeInCirc : function(currentIteration, startValue, changeInValue, totalIterations) {
13100			return changeInValue * (1 - Math.sqrt(1 - (currentIteration /= totalIterations) * currentIteration)) + startValue;
13101		},
13102
13103		easeOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) {
13104			return changeInValue * Math.sqrt(1 - (currentIteration = currentIteration / totalIterations - 1) * currentIteration) + startValue;
13105		},
13106
13107		easeInOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) {
13108			if ((currentIteration /= totalIterations / 2) < 1) {
13109				return changeInValue / 2 * (1 - Math.sqrt(1 - currentIteration * currentIteration)) + startValue;
13110			}
13111			return changeInValue / 2 * (Math.sqrt(1 - (currentIteration -= 2) * currentIteration) + 1) + startValue;
13112		}
13113	};
13114
13115})(jQuery);
13116/* Social Share */
13117/* -------------------------------------------------------------------- */
13118(function($) {
13119    'use strict';
13120
13121    MK.component.SocialShare = function( el ) {
13122        var networks = {
13123			twitter : 'http://twitter.com/intent/tweet?text={title}&url={url}',
13124			pinterest : 'http://pinterest.com/pin/create/button/?url={url}&media={image}&description={title}',
13125			facebook : 'https://www.facebook.com/sharer/sharer.php?u={url}',
13126			googleplus : 'https://plus.google.com/share?url={url}',
13127			linkedin : 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&summary={desc}',
13128			digg : 'http://digg.com/submit?url={url}&title={title}',
13129			reddit : 'http://reddit.com/submit?url={url}&title={title}',
13130        };
13131
13132        this.networks = networks;
13133        this.el = el;
13134    };
13135
13136
13137	MK.component.SocialShare.prototype = {
13138
13139        init : function() {
13140            this.cacheElements();
13141            this.bindEvents();
13142        },
13143
13144        cacheElements : function() {
13145            this.$this  = $( this.el );
13146
13147
13148        },
13149
13150        bindEvents : function() {
13151			var thisObject = this;
13152			var tempClass = "";
13153			$.each(this.networks, function( key, value ) {
13154				  thisObject.$tempClass = $('.' + key + '-share');
13155				  thisObject.$tempClass.click(thisObject.openSharingDialog.bind(self, this, key));
13156
13157			});
13158        },
13159
13160        openSharingDialog : function(url, site, args) {
13161			var urlWrapper = url;
13162			var rx = new RegExp('\{[a-z]*\}','g'), res;
13163			var match = rx.exec(url);
13164			while (match != null) {
13165				var pureAttr = match[0].replace("{", "").replace("}" , "");
13166				var attValue = $(args.currentTarget).attr('data-' + pureAttr);
13167				if (attValue === undefined || attValue === null) {
13168					attValue = "";
13169				}
13170				attValue = attValue.replace('#', '%23'); // fix for twitter description
13171				urlWrapper = urlWrapper.replace(match, attValue);
13172				match = rx.exec(url);
13173			}
13174
13175			window.open(urlWrapper, site + "Window", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13176
13177        },
13178
13179
13180    };
13181
13182
13183	//////////////////////////////////////////
13184    //
13185    // Apply to:
13186    //
13187    // ///////////////////////////////////////
13188
13189    var $body = $('body');
13190
13191    if(!$body.length) return;
13192
13193    $body.each(function() {
13194        var socialShare = new MK.component.SocialShare(this);
13195			socialShare.init();
13196    });
13197
13198})(jQuery);
13199
13200
13201
13202//function mk_social_share() {
13203//
13204//  "use strict";
13205//
13206//  $('.twitter-share').on('click', function () {
13207//    var $url = $(this).attr('data-url'),
13208//      $title = $(this).attr('data-title');
13209//
13210//    window.open('http://twitter.com/intent/tweet?text=' + $title + ' ' + $url, "twitterWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13211//    return false;
13212//  });
13213//
13214//  $('.pinterest-share').on('click', function () {
13215//    var $url = $(this).attr('data-url'),
13216//      $title = $(this).attr('data-title'),
13217//      $image = $(this).attr('data-image');
13218//    window.open('http://pinterest.com/pin/create/button/?url=' + $url + '&media=' + $image + '&description=' + $title, "twitterWindow", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13219//    return false;
13220//  });
13221//
13222//  $('.facebook-share').on('click', function () {
13223//    var $url = $(this).attr('data-url');
13224//    window.open('https://www.facebook.com/sharer/sharer.php?u=' + $url, "facebookWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13225//    return false;
13226//  });
13227//
13228//  $('.googleplus-share').on('click', function () {
13229//    var $url = $(this).attr('data-url');
13230//    window.open('https://plus.google.com/share?url=' + $url, "googlePlusWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13231//    return false;
13232//  });
13233//
13234//  $('.linkedin-share').on('click', function () {
13235//    var $url = $(this).attr('data-url'),
13236//      $title = $(this).attr('data-title'),
13237//      $desc = $(this).attr('data-desc');
13238//    window.open('http://www.linkedin.com/shareArticle?mini=true&url=' + $url + '&title=' + $title + '&summary=' + $desc, "linkedInWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13239//    return false;
13240//  });
13241//}
13242
13243
13244
13245
13246(function($) {
13247	'use strict';
13248
13249	MK.component.Sortable = function(el) {
13250		this.el = el; 
13251	};
13252
13253	MK.component.Sortable.prototype = {
13254		init: function init() {
13255			this.cacheElements();
13256			this.bindEvents();
13257		},
13258
13259		cacheElements: function cacheElements() {
13260			this.unique = Date.now();
13261			this.$filter = $(this.el);
13262			this.config = this.$filter.data('sortable-config');
13263
13264			this.ajaxLoader = new MK.utils.ajaxLoader(this.config.container);
13265			this.ajaxLoader.init();
13266
13267			this.$container = $( this.config.container );
13268			this.$navItems = this.$filter.find('a');
13269			this.$filterItems = this.$container.find(this.config.item);
13270		},
13271
13272		bindEvents: function bindEvents() {
13273			this.$navItems.on('click', this.handleClick.bind(this));
13274			MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this));
13275		},
13276
13277		handleClick: function handleClick(e) {
13278			e.preventDefault();
13279
13280			var $item = $(e.currentTarget);
13281			var term = $item.data('filter');
13282
13283			this.$navItems.removeClass('current');
13284			$item.addClass('current');
13285
13286			if(this.config.mode === 'ajax') this.inDB(term, $item);
13287	        else this.inPage(term);
13288		},
13289
13290		inDB: function inDB(term, $item) { 
13291			// Add load indicator only for long requests
13292			MK.ui.loader.remove(this.$filter);
13293			MK.ui.loader.add($item);
13294			
13295			// If mk-ajax-loaded-posts span exists and one of the filter is clicked,
13296			// clear post ids
13297			if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) {		
13298				this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', '');
13299			}
13300
13301			this.ajaxLoader.setData({
13302				paged: 1,
13303				term: term
13304			});
13305            this.ajaxLoader.load(this.unique);
13306		},
13307
13308		inPage: function inPage(term) {
13309			var $filterItems = this.$container.find(this.config.item);
13310			$filterItems.removeClass('is-hidden'); // show all first
13311			// Replace all ', ' with ', .'. It's used to add '.' as class selector of each category.
13312			var className = term.replace( /, /g, ", ." );
13313			if(term !== '*') $filterItems.not( '.' + className ).addClass('is-hidden'); // hide filtered
13314			MK.utils.eventManager.publish('staticFilter');
13315		},
13316
13317		onLoad: function onLoad(e, response) {
13318			if(this.config.mode === 'static') {
13319				this.$navItems.removeClass('current').first().addClass('current');
13320			}
13321			if( typeof response !== 'undefined' &&  response.id === this.config.container) {
13322				MK.ui.loader.remove(this.$filter);
13323				if(response.unique === this.unique) {
13324		            this.$container.html(response.content);
13325					this.ajaxLoader.setData({paged: 1});
13326				}
13327			}
13328		}
13329	};
13330
13331})(jQuery);
13332(function($) {
13333    'use strict';
13334
13335    MK.component.Tabs = function( el ) {
13336        var defaults = {
13337            activeClass : 'is-active'
13338        };
13339
13340        this.config = defaults;
13341        this.el = el;
13342    };
13343
13344    MK.component.Tabs.prototype = {
13345
13346        init : function() {
13347            this.cacheElements();
13348            this.bindEvents();
13349        },
13350
13351        cacheElements : function() {
13352            this.$this  = $( this.el );
13353            this.$tabs  = this.$this.find( '.mk-tabs-tab' );
13354            this.$panes = this.$this.find( '.mk-tabs-pane' );
13355            this.currentId = 0;
13356        },
13357
13358        bindEvents : function() {
13359            var self = this;
13360
13361            this.$tabs.on( 'click', this.switchPane.bind( this ) );
13362        },
13363
13364        switchPane : function( evt ) {
13365            evt.preventDefault();
13366
13367            var clickedId = $( evt.currentTarget ).index();
13368
13369            this.hide( this.currentId );
13370            this.show( clickedId );
13371
13372            // Update current id
13373            this.currentId = clickedId;
13374
13375            // Notify rest of the app
13376            MK.utils.eventManager.publish('item-expanded');            
13377        },
13378
13379        show : function( id ) {
13380            this.$tabs.eq( id ).addClass( this.config.activeClass );
13381            this.$panes.eq( id ).addClass( this.config.activeClass );
13382        },
13383
13384        hide : function( id ) {
13385            this.$tabs.eq( id ).removeClass( this.config.activeClass );
13386            this.$panes.eq( id ).removeClass( this.config.activeClass );
13387        }
13388    };
13389
13390})(jQuery);
13391
13392
13393/* Tabs */
13394/* -------------------------------------------------------------------- */
13395
13396function mk_tabs() {
13397
13398  // "use strict";
13399
13400  // if ($.exists('.mk-tabs, .mk-news-tab, .mk-woo-tabs')) {
13401  //   $(".mk-tabs, .mk-news-tab, .mk-woo-tabs").tabs();
13402
13403  //    $('.mk-tabs').on('click', function () {
13404  //      $('.mk-theme-loop').isotope('layout');
13405  //    });
13406
13407  //   $('.mk-tabs.vertical-style').each(function () {
13408  //     $(this).find('.mk-tabs-pane').css('minHeight', $(this).find('.mk-tabs-tabs').height() - 1);
13409  //   });
13410
13411  // }
13412}
13413
13414function mk_tabs_responsive(){
13415  // $('.mk-tabs, .mk-news-tab').each(function () {
13416  //   $this = $(this);
13417  //   if ($this.hasClass('mobile-true')) {
13418  //     if (window.matchMedia('(max-width: 767px)').matches)
13419  //     {
13420  //         $this.tabs("destroy");
13421  //     } else {
13422  //       $this.tabs();
13423  //     }
13424  //   }
13425  // });
13426  
13427}
13428
13429
13430(function($) {
13431  'use strict';
13432
13433  $(document).on('click', function(e) {
13434    $('.mk-toggle-trigger').removeClass('mk-toggle-active');
13435  });
13436
13437  function toggle(e) {
13438      e.preventDefault();
13439      e.stopPropagation();
13440      var $this = $(e.currentTarget);
13441
13442      if (!$this.hasClass('mk-toggle-active')) {
13443
13444        $('.mk-box-to-trigger').fadeOut(200);
13445        $this.parent().find('.mk-box-to-trigger').fadeIn(250);
13446        $('.mk-toggle-trigger').removeClass('mk-toggle-active');
13447        $this.addClass('mk-toggle-active');
13448
13449      } else {
13450
13451        $('.mk-box-to-trigger').fadeOut(200);
13452        $this.removeClass('mk-toggle-active');
13453
13454      }
13455  }
13456
13457  function assignToggle() {
13458    // wait for ajax response propagation and insertion
13459    setTimeout(function() {
13460      $('.mk-toggle-trigger').off('click', toggle);
13461      $('.mk-toggle-trigger').on('click', toggle);
13462    }, 100);
13463  }
13464
13465  assignToggle();
13466  MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle);
13467  MK.utils.eventManager.subscribe('ajax-preview', assignToggle);
13468
13469  $(window).on('vc_reload', function(){
13470    assignToggle();
13471    MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle);
13472    MK.utils.eventManager.subscribe('ajax-preview', assignToggle);
13473  });
13474
13475}(jQuery));
13476(function($) {
13477	'use strict';
13478
13479	var $iframes = $('iframe');
13480
13481	$iframes.each(function() {
13482		var $iframe = $(this);
13483		var parent = $iframe.parent().get(0);
13484		var tagName = parent.tagName;
13485
13486		if(tagName === 'P') $iframe.wrap('<div class="mk-video-container"></div>');
13487	});
13488
13489}(jQuery));
13490(function( $ ) {
13491    'use strict';
13492    if( MK.utils.isMobile() ) {
13493        $('.mk-animate-element').removeClass('mk-animate-element');
13494        return;
13495    }
13496    var init = function init() {
13497        var $rootLevelEls = $('.js-master-row, .widget');
13498        $rootLevelEls.each( spyViewport );
13499        $rootLevelEls.each( function rootLevelEl() {
13500            var $animateEl = $(this).find( '.mk-animate-element' );
13501            $animateEl.each( spyViewport );
13502            /**
13503             * Firefox has known issue where horizontal scrollbar will appear if an
13504             * element uses animation CSS. The solution should be set the element
13505             * position as fixed or overflow-x as hidden. Position fixed is not possible
13506             * to use because it's only cause other big problems. The best way is
13507             * set overflow-x as hidden in the page content container #theme-page.
13508             *
13509             * NOTE: The problem is spotted on Right To Left viewport only. So, it's
13510             *       limited to '.right-to-left' selector only for now to avoid other
13511             *       problems. Please extend the functionallity if it's happen in
13512             *       other viewport animation effect.
13513             */
13514            var browserName  = MK.utils.browser.name;
13515            if ( browserName === 'Firefox' ) {
13516                var $rightToLeft = $( this ).find( '.right-to-left' );
13517                if ( $rightToLeft.length > 0 ) {
13518                    $( '#theme-page' ).css( 'overflow-x', 'hidden' );
13519                }
13520            }
13521        });
13522    };
13523    var spyViewport = function spyViewport(i) {
13524        var self = this;
13525        MK.utils.scrollSpy( this, {
13526            position  : 'bottom',
13527            threshold : 200,
13528            after     : function() {
13529                animate.call(self, i);
13530            }
13531        });
13532    };
13533    var animate = function animate(i) {
13534        var $this = $(this);
13535        setTimeout(function() {
13536            $this.addClass( 'mk-in-viewport' );
13537        }, 100 * i);
13538    };
13539    $(window).on('load vc_reload', init);
13540}(jQuery));
13541
13542function product_loop_add_cart() {
13543    var $body = $('body');
13544    $body.on('click', '.add_to_cart_button', function() {
13545        var icon = '<svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M437.011 74.99c-46.326-46.328-110.318-74.99-181.011-74.99-109.744 0-203.345 69.064-239.749 166.094l59.938 22.477c27.302-72.773 97.503-124.571 179.811-124.571 53.02 0 101.01 21.5 135.753 56.247l-71.753 71.753h192v-192l-74.989 74.99zm-181.011 373.01c-53.02 0-101.013-21.496-135.756-56.244l71.756-71.756h-192v192l74.997-74.997c46.323 46.331 110.309 74.997 181.003 74.997 109.745 0 203.346-69.064 239.75-166.094l-59.938-22.477c-27.302 72.773-97.503 124.571-179.812 124.571z"/></svg>';
13546        var $holder = $(this).parents('.product:eq(0)');
13547        var $i = $holder.find('.product-loading-icon');
13548        $holder.addClass('adding-to-cart').removeClass('added-to-cart');
13549        $i.html(icon);
13550    });
13551    $body.bind('added_to_cart', function() {
13552        var icon = '<svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M432 64l-240 240-112-112-80 80 192 192 320-320z"/></svg>';
13553        var $holder = $('.adding-to-cart');
13554        var $i = $holder.find('.product-loading-icon');
13555        $holder.removeClass('adding-to-cart').addClass('added-to-cart');
13556        $i.html(icon);
13557    });
13558}
13559(function($) {
13560    'use strict';
13561
13562    /**
13563     * Entry point of application. Runs all components
13564     */
13565    $( window ).on( 'load', function() {
13566        MK.core.initAll( document );
13567        MK.utils.scrollToURLHash();
13568        // TODO move preloader to components and manage it state from within
13569        setTimeout( function() { 
13570            MK.ui.preloader.hide(); // site wide 
13571            $('.mk-preloader').hide(); // components
13572            $('body').removeClass('loading');
13573        }, 150 ); 
13574    });
13575
13576    /**
13577     * VC frontend editor. Init all components.
13578     */
13579    $( window ).on( 'vc_reload', function() {
13580        setTimeout(function(){ 
13581            MK.core.initAll( document ); 
13582        }, 100);
13583    });
13584
13585    /**
13586     * Assign global click handlers
13587     */
13588    $( document ).on( 'click', '.js-smooth-scroll, .js-main-nav a', smoothScrollToAnchor);
13589    $( '.side_dashboard_menu a' ).on( 'click', smoothScrollToAnchor);
13590
13591    function smoothScrollToAnchor( evt ) {
13592        var anchor = MK.utils.detectAnchor( this );
13593        var $this = $(evt.currentTarget);
13594        var loc = window.location;
13595        var currentPage = loc.origin + loc.pathname;
13596        var href = $this.attr( 'href' );
13597        var linkSplit = (href) ? href.split( '#' ) : '';
13598        var hrefPage  = linkSplit[0] ? linkSplit[0] : ''; 
13599        var hrefHash  = linkSplit[1] ? linkSplit[1] : '';
13600
13601        if( anchor.length ) {
13602            if(hrefPage === currentPage || hrefPage === '') evt.preventDefault();
13603            MK.utils.scrollToAnchor( anchor );
13604
13605        } else if( $this.attr( 'href' ) === '#' ) {
13606            evt.preventDefault();
13607        }
13608    }
13609    
13610}(jQuery));})(jQuery);

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.