PageSourceSearch

https://www.covethouse.eu/blog/wp-content/plugins/wp-popups-lite/src/assets/js/wppopups.js?ver=2.1.5.6

js covethouse.eu collected 2026-10-03 22:26:48 UTC 48,930 bytes, 1,476 lines download raw bytes

1"use strict";
2
3;
4/* global wppopups_settings,*/
5
6(function ($) {
7  'use strict';
8
9  var WPPopups = {
10    popups: {},
11    byBind: {
12      'class': [],
13      'href': []
14    },
15
16    /**
17     * Start the engine.
18     *
19     * @since 2.0.0
20     */
21    init: function init() {
22      // Document ready
23      $(document).ready(WPPopups.ready); // Page load
24
25      $(window).on('load', WPPopups.load); // Document ready
26
27      $(document).on('wppopupsAjaxReady', WPPopups.ajaxStart);
28      WPPopups.bindUIActions();
29    },
30
31    /**
32    * Document ready.
33    *
34    * @since 2.0.0
35    */
36    ready: function ready() {
37      $(document).trigger('wppopupsBeforeReady');
38      if ($(".spu-box").length == 0) return false;
39      var data = {
40        action: 'wppopups_rules',
41        pid: wppopups_vars.pid,
42        referrer: document.referrer,
43        url: document.documentURI,
44        query_string: document.location.search,
45        is_category: wppopups_vars.is_category,
46        is_archive: wppopups_vars.is_archive,
47        is_singular: wppopups_vars.is_singular,
48        is_preview: wppopups_vars.is_preview,
49        is_search: wppopups_vars.is_search,
50        is_front_page: wppopups_vars.is_front_page,
51        is_blog_page: wppopups_vars.is_blog_page,
52        woo_is_shop: wppopups_vars.woo_is_shop,
53        woo_is_order_received: wppopups_vars.woo_is_order_received,
54        woo_is_product_category: wppopups_vars.woo_is_product_category,
55        woo_is_product_tag: wppopups_vars.woo_is_product_tag,
56        woo_is_product: wppopups_vars.woo_is_product,
57        woo_is_cart: wppopups_vars.woo_is_cart,
58        woo_is_checkout: wppopups_vars.woo_is_checkout,
59        woo_is_account_page: wppopups_vars.woo_is_account_page,
60        popups: []
61      }; // save all popups rules into data
62
63      $(".spu-box").each(function () {
64        var $popup = $(this),
65            $id = $popup.data('id'),
66            $need_ajax = $popup.data('need_ajax'),
67            $rules = WPPopups.settings($popup, 'rules'),
68            $global_rules = WPPopups.settings($popup, 'global_rules'); // if old popup it's enabled id will be empty and break things
69
70        if ($id && $need_ajax) {
71          data.popups.push({
72            id: $id,
73            rules: JSON.stringify($rules),
74            global_rules: JSON.stringify($global_rules),
75            parent: $popup.data('parent')
76          });
77        }
78      });
79      var ajax = {
80        url: wppopups_vars.ajax_url,
81        data: window.wp.hooks.applyFilters('wppopups_pre_ready_data', data),
82        cache: false,
83        type: 'POST',
84        dataType: 'json',
85        timeout: 30000,
86        success: function success(r) {
87          if (r.success) {
88            r.success.forEach(function (id) {
89              WPPopups.removePopup(id);
90            });
91          }
92
93          $(document).trigger('wppopupsAjaxReady');
94        },
95        error: function error(r) {
96          console.log(r);
97        }
98      };
99
100      if (data.popups.length) {
101        $.ajax(ajax);
102      }
103
104      WPPopups.initVideoSources();
105      WPPopups.resetPopupsContent();
106      WPPopups.hashTriggerPopups(); // init popups that doesn't need ajax
107
108      $(".spu-box").each(function () {
109        var $popup = $(this),
110            $need_ajax = $popup.data('need_ajax');
111
112        if ($need_ajax) {
113          $popup.hide();
114          return;
115        }
116
117        WPPopups.initPopup($popup);
118      });
119      WPPopups.loadValidation();
120      WPPopups.initSocialShortcodes();
121      $(document).trigger('wppopupsReady');
122    },
123
124    /**
125     * Page load.
126     *
127     * @since 2.0.0
128     */
129    load: function load() {
130      // center again once it's loaded
131      $(".spu-box").each(function () {
132        var $popup = $(this);
133        WPPopups.centerPopup($popup);
134      });
135    },
136    ajaxStart: function ajaxStart() {
137      $(".spu-box").each(function () {
138        var $popup = $(this),
139            $need_ajax = $popup.data('need_ajax');
140
141        if (!$need_ajax) {
142          return;
143        }
144
145        WPPopups.initPopup($popup);
146      });
147      $(document).trigger('wppopupsAjaxStarted');
148    },
149
150    /**
151     * Configure each popup
152     */
153    initPopup: function initPopup($popup) {
154      var $id = $popup.data('id'); // Save popup for later
155
156      WPPopups.popups[$id] = $popup; // all triggers added by users
157
158      WPPopups.bindPopupTriggers($popup); // click triggers
159
160      WPPopups.bindClickTriggers($popup); // Forms inside popups
161
162      WPPopups.formSubmissions($popup); // Forms Email Marketing
163      //WPPopups.formOptinSubmissions($popup);
164      // Events bindings
165
166      $(window).resize(function () {
167        WPPopups.checkPopupSize($popup);
168        WPPopups.centerPopup($popup, true);
169      });
170      $popup.find('input').on('change', function () {
171        WPPopups.checkPopupSize($popup);
172      }); // This hook will be used by third parties
173
174      window.wp.hooks.doAction('wppopups_loop', $popup);
175      window.wp.hooks.addAction('wppopups_show_popup', 'wppopups', WPPopups.centerPopup, 99); // hide it
176
177      $popup.hide();
178    },
179    // --------------------------------------------------------------------//
180    // Triggers
181    // --------------------------------------------------------------------//
182
183    /**
184    * Trigger popup after N seconds
185     * @param value
186     * @param $popup
187     */
188    triggerBySeconds: function triggerBySeconds(value, $popup) {
189      // if not value provided abort
190      if (value === '') {
191        return;
192      }
193
194      if ($popup.timer) {
195        clearTimeout($popup.timer);
196      }
197
198      $popup.timer = window.setTimeout(function () {
199        if (WPPopups.checkConvertion($popup)) {
200          WPPopups.showPopup($popup);
201        }
202      }, parseInt(value, 10) * 1000);
203    },
204
205    /**
206    * Trigger if scroll % amount of screen
207     * @param value
208     * @param $popup
209     */
210    triggerByPercentage: function triggerByPercentage(value, $popup) {
211      // if not value provided abort
212      if (value === '') {
213        return;
214      }
215
216      var $settings = WPPopups.settings($popup, 'settings'); // use custom namespace bind for off later
217
218      $(window).on('scroll.per' + $popup.data('id'), function () {
219        if ($popup.timer) {
220          clearTimeout($popup.timer);
221        }
222
223        $popup.timer = window.setTimeout(function () {
224          var triggerHeight = parseInt(value, 10) / 100 * $(document).height();
225          var scrollY = $(window).scrollTop(),
226              trigger = scrollY + $(window).height() >= triggerHeight; // show box when criteria for this box is matched
227
228          if (trigger && WPPopups.checkConvertion($popup)) {
229            // remove listen event if box shouldn't be hidden again. TODO: add auto hide in trigger settings
230            if (!$settings.auto_hide) {
231              $(window).off('scroll.per' + $popup.data('id'));
232            }
233
234            WPPopups.showPopup($popup);
235          } else if ($settings.auto_hide) {
236            WPPopups.hidePopup($popup, false, 10, false);
237          }
238        }, 100);
239      });
240    },
241
242    /**
243    * Bind TRigger after user scrolled X pixels
244     * @param value
245     * @param $popup
246     */
247    triggerByPixels: function triggerByPixels(value, $popup) {
248      // if not pixels provided abort
249      if (value === '') {
250        return;
251      }
252
253      var $settings = WPPopups.settings($popup, 'settings');
254      $(window).on('scroll.pix' + $popup.data('id'), function () {
255        if ($popup.timer) {
256          clearTimeout($popup.timer);
257        }
258
259        $popup.timer = window.setTimeout(function () {
260          var scrollY = $(window).scrollTop(),
261              trigger = scrollY >= parseInt(value, 10); //triggerSeconds equals to the number field really
262          // show box when criteria for this box is matched
263
264          if (trigger && WPPopups.checkConvertion($popup)) {
265            // remove listen event if box shouldn't be hidden again
266            if (!$settings.auto_hide) {
267              $(window).off('scroll.pix' + $popup.data('id'));
268            }
269
270            WPPopups.showPopup($popup);
271          } else if ($settings.auto_hide) {
272            WPPopups.hidePopup($popup, false, 10, false);
273          }
274        }, 100);
275      });
276    },
277    triggerByClass: function triggerByClass(value, $popup) {
278      // if not class provided abort
279      if (value === '') {
280        return;
281      } // add . to class attribute if missing
282
283
284      value = value.charAt(0) != '.' ? '.' + value : value;
285      WPPopups.setBindActions(value, 'class'); // Only add the trigger if not cookies are set for popup
286
287      if (WPPopups.hasCookies($popup)) {
288        return;
289      }
290
291      $(document.body).on('click', value, function (e) {
292        e.preventDefault();
293        WPPopups.showPopup($popup);
294      });
295    },
296    // --------------------------------------------------------------------//
297    // Binds
298    // --------------------------------------------------------------------//
299
300    /**
301    * Bind document triggers for popups
302     * @param $popup
303     */
304    bindClickTriggers: function bindClickTriggers($popup) {
305      var id = $popup.data('id');
306      WPPopups.setBindActions('.spu-open-' + id, 'class');
307      WPPopups.setBindActions('#spu-' + id, 'href'); // Only add the trigger if not cookies are set for popup
308
309      if (WPPopups.hasCookies($popup)) {
310        return;
311      } // add link listener for this box
312
313
314      $(document.body).on('click', 'a[href="#spu-' + id + '"], .spu-open-' + id, function (e) {
315        e.preventDefault();
316        WPPopups.showPopup($popup, true);
317      });
318      $('a[href="#spu-' + id + '"], .spu-open-' + id).css('cursor', 'pointer').addClass('spu-clickable');
319    },
320
321    /**
322    * Bind triggers set in popup settings
323     * @param $popup
324     */
325    bindPopupTriggers: function bindPopupTriggers($popup) {
326      if (window.wp.hooks.applyFilters('wppopups_disable_triggers', false, $popup)) return;
327      var $triggers = WPPopups.settings($popup, 'triggers');
328
329      if (Object.keys($triggers).length) {
330        for (var i in $triggers) {
331          var func = 'triggerBy' + $triggers[i].trigger.charAt(0).toUpperCase() + $triggers[i].trigger.substr(1),
332              settings = WPPopups.settings($popup, 'settings');
333
334          if (!WPPopups.hasCookies($popup) || wppopups_vars.is_preview || func == 'triggerByClass' || wppopups_vars.is_admin && settings.test_mode == '1') {
335            // only try if func really exist , may be premium one
336            if (typeof WPPopups[func] == 'function') {
337              WPPopups[func]($triggers[i].value, $popup);
338            } // hook for premium
339
340
341            window.wp.hooks.doAction('wppopups_trigger_popup', func, $triggers[i].value, $popup);
342          }
343        }
344      }
345    },
346
347    /**
348    * Element bindings.
349    *
350    * @since 2.0.0
351    */
352    bindUIActions: function bindUIActions() {
353      // Custom links inside popups conversion
354      $(document).on('click', '.spu-box a:not(".spu-close-popup, .spu-box .flp_wrapper a, .spu-box .spu-not-close, .spu-box .spu-not-close a, .spu-box .spu-gdpr a")', function () {
355        // hide the popup and track conversion
356        WPPopups.hidePopup($(this), true);
357      }); // Close and convert button, similar to above
358
359      $(document).on('click', '.spu-box .spu-close-convert,.spu-box .spu-close-convert a', function (e) {
360        e.preventDefault(); // hide the popup and track conversion
361
362        WPPopups.hidePopup($(this), true);
363      }); //close popup
364
365      $(document).on('click', '.spu-box .spu-close-popup', function (e) {
366        e.preventDefault(); // hide box, no conversion
367
368        WPPopups.hidePopup($(this), false);
369      }); //close with esc
370
371      $(document).on('keyup', function (e) {
372        if (e.keyCode == 27) {
373          WPPopups.togglePopups(false, false);
374        }
375      }); // close by clicking outside of popup
376      // get event by device or browser
377
378      var ua = navigator.userAgent,
379          event = ua.match(/iPad/i) || ua.match(/iPhone/i) ? "touchstart" : "click";
380      $('body').on(event, function (ev) {
381        var $target = $(ev.target); // TODO:
382        // for some reason ninja form not working, added this dirty workaround
383        // $target.is('.spu-box *, .spu-box') return false, same for .has .parents, etc
384        // so no popup closing when form is clicked
385
386        if ($target.is('input.nf-element')) return; // Forminator datepicker and also others it may be needed
387
388        if ($target.is(window.wp.hooks.applyFilters('wppopups_disable_click_out_classes', '.flatpickr-calendar,.flatpickr-calendar *, .ui-datepicker-header *,.ui-widget,.ui-widget *'))) return; // verify if some bindAction is present
389
390        if (WPPopups.checkBindActions($target)) return;
391        if (window.wp.hooks.applyFilters('wppopups_disable_click_out', false, $target)) return; // test that event is user triggered and not programatically,
392        // and that it is not fired  within the box
393
394        if (ev.originalEvent !== undefined && !$target.is('.spu-box *, .spu-box')) {
395          WPPopups.togglePopups(false, false);
396        }
397      });
398    },
399
400    /**
401    * Return setting from popup
402     * @param popup
403     * @param key
404     * @returns {*}
405     */
406    settings: function settings(popup, key) {
407      var settings = {};
408
409      if (popup.data('settings')) {
410        settings = popup.data('settings');
411      }
412
413      if (key) {
414        if (typeof settings[key] == 'undefined') return {};
415        return settings[key];
416      }
417
418      return settings;
419    },
420
421    /**
422    * Wrapper to execute toggle box on all popups
423     * @param elements
424     * @param show
425     * @param conversion
426     */
427    togglePopups: function togglePopups(show, conversion) {
428      $('.spu-box').each(function () {
429        if (show) {
430          WPPopups.showPopup($(this));
431        } else {
432          // premium version may disable advanced closing methods which use tooglePopups
433          if (window.wp.hooks.applyFilters('wppopups_allow_togglePopups', true, $(this))) {
434            WPPopups.hidePopup($(this), conversion);
435          }
436        }
437      });
438    },
439
440    /**
441    * Show given popup
442     * @param popup
443     * @param forse true/false
444     * @returns {boolean}
445     */
446    showPopup: function showPopup(popup) {
447      var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
448      var $popup = WPPopups.getPopup(popup),
449          $id = $popup.data('id'),
450          $bg = $('#spu-bg-' + $id); // don't do anything if box is undergoing an animation or already visible
451
452      if ($popup.is(":animated") || $popup.is(":visible")) {
453        return false;
454      } // don't do anything if popup has any cookie created
455
456
457      if (!force && WPPopups.hasCookies($popup)) {
458        return false;
459      } // Hook before the popup it's shown
460
461
462      window.wp.hooks.doAction('wppopups_before_show_popup', $popup); // show container and the popup
463
464      $popup.parent('.wppopups-whole').show(); // Overlay Blur
465
466      WPPopups.toggleBlur($popup, true);
467      WPPopups.centerPopup($popup); // I want to stop  supporting social shortcodes, let's see how many complain
468
469      /* setTimeout(function(){
470           WPPopups.centerShortcodes($popup);
471       },1500);*/
472      // Add scroll if needed
473
474      WPPopups.checkPopupSize($popup); // show box
475
476      var animation = WPPopups.settings($popup, 'animation');
477
478      switch (animation.animation) {
479        case 'fade':
480          $popup.hide().fadeIn('slow');
481          break;
482
483        case 'slide':
484          $popup.hide().slideDown('slow');
485          break;
486
487        default:
488          $popup.show();
489          break;
490      } //background only if not bottom/top bars
491
492
493      if (!$popup.hasClass('spu-position-top-bar') && !$popup.hasClass('spu-position-bottom-bar')) {
494        if (animation.animation === 'disable') {
495          $bg.show();
496        } else {
497          $bg.fadeIn();
498        }
499      } // Hook for show popup, used for example for premium animations
500
501
502      window.wp.hooks.doAction('wppopups_show_popup', $popup); // show videos if any
503
504      WPPopups.toggleVideoSources($popup, true); // trigger opening
505
506      $popup.trigger('wppopups.popup_opened', [$id]);
507    },
508
509    /**
510    * Hide given popup
511     * @param popup
512     * @param conversion
513     * @param time
514     * @returns {boolean}
515     */
516    hidePopup: function hidePopup(popup, conversion) {
517      var time = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
518      var cookie = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
519      var $popup = WPPopups.getPopup(popup),
520          $id = $popup.data('id'),
521          $bg = $('#spu-bg-' + $id); // don't do anything if box is undergoing an animation or already visible
522
523      if ($popup.is(":animated") || $popup.is(":hidden") || window.wp.hooks.applyFilters('wppopups_cancel_hide', false, $popup, conversion)) {
524        return false;
525      } // save cookie
526
527
528      if (conversion === true) {
529        WPPopups.popupConverted($popup, cookie);
530      }
531
532      var settings = WPPopups.settings($popup, 'settings');
533
534      if (settings.close_on_conversion == '1' && conversion || !conversion) {
535        setTimeout(function () {
536          var animation = WPPopups.settings($popup, 'animation'); // Hide with animation
537
538          switch (animation.animation) {
539            case 'slide':
540              $popup.slideUp('slow');
541              $bg.fadeOut();
542              break;
543
544            case 'disable':
545              $popup.hide();
546              $bg.hide();
547              break;
548
549            default:
550              $popup.removeClass('spu-animation-animated');
551              $popup.fadeOut('slow');
552              $bg.fadeOut();
553              break;
554          } // Hook for show popup, used for example for premium animations
555
556
557          window.wp.hooks.doAction('wppopups_hide_popup', $popup); // hide videos if any
558
559          WPPopups.toggleVideoSources($popup, false);
560        }, parseInt(time, 10));
561      } // Overlay Blur
562
563
564      WPPopups.toggleBlur($popup, false); // save cookie
565
566      WPPopups.popupClosed($popup, cookie);
567    },
568    centerPopup: function centerPopup(popup, animate) {
569      if (!popup.hasClass('spu-position-centered') && !popup.hasClass('spu-position-float-right') && !popup.hasClass('spu-position-float-left')) {
570        return;
571      }
572
573      if (popup.is(':animated')) {
574        return;
575      }
576
577      var ww = $(window).width(),
578          wh = $(window).height(),
579          pw = popup.outerWidth(),
580          ph = popup.outerHeight(); // To center the box
581
582      var boxLeft = ww / 2 - pw / 2,
583          boxTop = wh / 2 - ph / 2;
584      var css = {
585        top: boxTop
586      };
587
588      if (popup.hasClass('spu-position-centered')) {
589        css.left = boxLeft;
590      }
591
592      if (animate) {
593        popup.animate(css, {
594          queue: !1,
595          duration: 200
596        });
597      } else {
598        popup.css(css);
599      }
600    },
601
602    /**
603     * Removes the popup from DOM
604     * @param $popup
605     */
606    removePopup: function removePopup(popup) {
607      var $popup = WPPopups.getPopup(popup),
608          $id = $popup.data('id'),
609          $bg = $('#spu-bg-' + $id),
610          $css = $('#spu-css-' + $id);
611      $popup.remove();
612      $bg.remove();
613      $css.remove();
614    },
615
616    /**
617     * Track popup conversion (save cookie)
618     * @param $popup
619     */
620    popupConverted: function popupConverted($popup) {
621      var cookie = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
622
623      if (cookie) {
624        // set cookie
625        var settings = WPPopups.settings($popup, 'settings'),
626            duration = parseFloat(settings.conversion_cookie_duration),
627            _cookie = settings.conversion_cookie_name,
628            type = settings.conversion_cookie_type;
629
630        if (duration > 0) {
631          WPPopups.createCookie(_cookie, true, duration, type);
632        }
633      }
634
635      $popup.trigger('wppopups.popup_converted', [$popup.data('id')]);
636    },
637
638    /**
639     * Track popup closing (save cookie)
640     * @param $popup
641     */
642    popupClosed: function popupClosed($popup) {
643      var cookie = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
644
645      if (cookie) {
646        // set cookie
647        var settings = WPPopups.settings($popup, 'settings'),
648            duration = parseFloat(settings.closing_cookie_duration),
649            _cookie2 = settings.closing_cookie_name,
650            type = settings.closing_cookie_type;
651
652        if (duration > 0) {
653          WPPopups.createCookie(_cookie2, true, duration, type);
654        }
655      }
656
657      $popup.trigger('wppopups.popup_closed', [$popup.data('id')]);
658    },
659
660    /**
661     * Check if the popup has any cookies created.
662     * @param $popup
663     */
664    hasCookies: function hasCookies($popup) {
665      var $settings = WPPopups.settings($popup, 'settings'),
666          conversion_name = $settings.conversion_cookie_name,
667          closing_name = $settings.closing_cookie_name;
668      var hasCookies = false;
669
670      if (!(wppopups_vars.is_admin && $settings.test_mode == '1') && (WPPopups.getCookie(conversion_name) || WPPopups.getCookie(closing_name))) {
671        hasCookies = true;
672      }
673
674      return hasCookies;
675    },
676
677    /**
678     * Apply Overlay Blur
679     * @param  $popup
680     * @param  show   true/false
681     * @return        
682     */
683    toggleBlur: function toggleBlur($popup, show) {
684      // Overlay Blur
685      var colors = WPPopups.settings($popup, 'colors'),
686          $id = $popup.data('id'),
687          $box_css = $('#spu-css-' + $id);
688
689      if (colors.show_overlay == 'yes-blur') {
690        if (show) {
691          var blur_px = colors.overlay_blur ? colors.overlay_blur : 2,
692              blur_css = '/* ini:blur */body > *:not(.wppopups-whole) { -webkit-filter: blur(' + blur_px + 'px); -moz-filter: blur(' + blur_px + 'px); -o-filter: blur(' + blur_px + 'px); -ms-filter: blur(' + blur_px + 'px); filter: blur(' + blur_px + 'px); }/* fin:blur */';
693          $box_css.append(blur_css);
694        } else {
695          var css = $box_css.text(),
696              ini = css.indexOf('/* ini:blur */'),
697              pro = css.substring(ini);
698          $box_css.text(css.replace(pro, ''));
699        }
700      }
701    },
702
703    /**
704    * Check all iframes and set source to empty on page load
705     */
706    initVideoSources: function initVideoSources() {
707      var iframe = $('.spu-box iframe');
708
709      if (iframe && iframe.length) {
710        iframe.each(function () {
711          var iframeSrc = $(this).attr('src');
712
713          if (iframeSrc && iframeSrc.indexOf('recaptcha') !== -1) {// do nothing
714          } else {
715            $(this).attr('spusrc', iframeSrc);
716            $(this).attr('src', 'https://#');
717          }
718        });
719      }
720    },
721
722    /**
723    * Toggle a popup iframe source
724     * @param popup
725     * @param show
726     */
727    toggleVideoSources: function toggleVideoSources(popup, show) {
728      var iframe = popup.find('iframe');
729
730      if (iframe && iframe.length) {
731        iframe.each(function () {
732          if (show) {
733            if ($(this).attr('spusrc')) {
734              $(this).attr('src', $(this).attr('spusrc'));
735              $(this).css("width", "");
736              $(this).css("height", "");
737            }
738          } else {
739            var iframeSrc = $(this).attr('src');
740
741            if (iframeSrc && iframeSrc.indexOf('recaptcha') !== -1) {// do nothing
742            } else {
743              // destroy videos so they stop playing
744              $(this).attr('src', 'https://#');
745            }
746          }
747        });
748      }
749    },
750
751    /**
752    * remove paddings and margins from first and last items inside popups
753    * so it looks even with the given padding
754     */
755    resetPopupsContent: function resetPopupsContent() {
756      $(".spu-content").children().first().not('.spu-fields-container').css({
757        "margin-top": 0,
758        "padding-top": 0
759      }).end().last().not('.spu-fields-container').css({
760        'margin-bottom': 0,
761        'padding-bottom': 0
762      });
763    },
764
765    /**
766     * Trigger popup opening if anyone use #spu-open-123 in url
767     */
768    hashTriggerPopups: function hashTriggerPopups() {
769      // shows the box when hash refers to a box
770      if (window.location.hash && window.location.hash.length > 0) {
771        var hash = window.location.hash,
772            form_key = hash.substring(1).indexOf('spu-form'),
773            link_key = hash.substring(1).indexOf('spu-open'),
774            form_popup = form_key !== -1,
775            link_popup = link_key !== -1;
776        if (form_popup) var i = form_key + 10;else if (link_popup) var i = link_key + 10;
777
778        if ((link_popup || form_popup) && $('#spu-' + hash.substring(i)).is('.spu-box')) {
779          var popup = $('#spu-' + hash.substring(i)); // if triggered by a form add a close button if don't exist already one
780
781          if (form_popup && popup.find('.spu-close-popup').length < 2) {
782            popup.find('.spu-content').append('<p style="text-align: center"><button class="btn btn-primary spu-close-popup">Close</button></p>');
783          } // unbind regular triggers and set conversion
784
785
786          if (form_popup) {
787            $(window).off('scroll.per' + popup.data('id'));
788            $(window).off('scroll.pix' + popup.data('id'));
789            WPPopups.popupConverted(popup);
790          }
791
792          setTimeout(function () {
793            WPPopups.showPopup(popup, true);
794          }, 200);
795        }
796      }
797    },
798
799    /**
800    * Handle form submissions in two ways. Adding ajax most known forms callbacks
801     * and adding #spu-form to action for regular forms that will open on page load
802     * @param $popup
803     */
804    formSubmissions: function formSubmissions($popup) {
805      var popup_id = $popup.data('id');
806      $popup.find('form').each(function () {
807        var box_form = $(this),
808            action = box_form.attr('action') || '';
809
810        if (!wppopups_vars.disable_form_reopen) {
811          box_form.attr('action', action + '#spu-form-' + popup_id);
812        } // only run if not our form
813
814
815        if (box_form.hasClass('spu-optin-form')) {
816          return;
817        } // If url is external, we need to track popup before submission
818
819
820        if (WPPopups.isExternal(action)) {
821          box_form.on('submit', function () {
822            WPPopups.hidePopup($popup, true);
823          });
824        }
825      }); // Ninja forms don't use form elements O_o
826
827      $(document).on('nfFormSubmitResponse', function () {
828        $popup.trigger('wppopups.form_submitted', [popup_id]);
829        WPPopups.hidePopup($popup, true, 2000);
830      }); // Forminator
831
832      $(document).on('forminator:form:submit:success', function () {
833        $popup.trigger('wppopups.form_submitted', [popup_id]);
834        WPPopups.hidePopup($popup, true, 2000);
835      }); // Contact form 7
836
837      $popup.on('wpcf7mailsent', function () {
838        $popup.trigger('wppopups.form_submitted', [popup_id]);
839        WPPopups.hidePopup($popup, true, 2000);
840      }); // Gravity forms (ajax mode)
841
842      $(document).on('gform_post_render', function (jqXHR, form_id) {
843        var $form = $('#gform_ajax_frame_' + form_id);
844
845        if (!$form.is('.spu-box *')) {
846          return;
847        }
848
849        var contents = $form.contents().find('*').html(),
850            form_content = $form.contents().find('#gform_wrapper_' + form_id),
851            is_confirmation = $form.contents().find('#gform_confirmation_wrapper_' + form_id).length > 0,
852            is_redirect = contents.indexOf('gformRedirect(){') >= 0;
853
854        if (is_confirmation || is_redirect) {
855          $popup.trigger('wppopups.form_submitted', [popup_id]);
856          WPPopups.hidePopup($popup, true, 2000);
857        }
858      }); // Caldera Forms (ajax mode)
859
860      $(document).on('cf.submission', function () {
861        $popup.trigger('wppopups.form_submitted', [popup_id]);
862        WPPopups.hidePopup($popup, true, 2000);
863      }); // WPForms (ajax mode)
864
865      $(document).on('wpformsAjaxSubmitSuccess', function () {
866        $popup.trigger('wppopups.form_submitted', [popup_id]);
867        WPPopups.hidePopup($popup, true, 2000);
868      }); // Yikes form
869
870      $(document).on('yikes_mailchimp_ajax_submission', function (e, response) {
871        if (response.success) {
872          $popup.trigger('wppopups.form_submitted', [popup_id]);
873          WPPopups.hidePopup($popup, true, 2000);
874        }
875      });
876    },
877
878    /**
879     * Check if url is external
880     * @param url
881     * @returns {boolean}
882     */
883    isExternal: function isExternal(url) {
884      if (url.length === 0) {
885        return false;
886      }
887
888      var domain = function domain(url) {
889        return url.replace('http://', '').replace('https://', '').split('/')[0];
890      };
891
892      if (domain(url) == '') {
893        return false;
894      }
895
896      return domain(location.href) !== domain(url);
897    },
898
899    /**
900     * Forms to Email Marketing
901     * @param $popup
902     */
903    formOptinSubmissions: function formOptinSubmissions($popup) {
904      var popup_id = $popup.data('id'),
905          $form = $popup.find('.wppopups-form'),
906          $submit_btn = $form.find('.wppopups-submit-button');
907      WPPopups.toggleButton($submit_btn, true);
908      var data = $form.serializeArray();
909      data.push({
910        name: 'action',
911        value: 'wppopups_optin_submit'
912      });
913      data.push({
914        name: 'id',
915        value: popup_id
916      });
917      var ajax = {
918        url: wppopups_vars.ajax_url,
919        data: data,
920        cache: false,
921        type: 'POST',
922        dataType: 'json',
923        timeout: 30000,
924        success: function success(r) {
925          console.log(r);
926
927          if (r.success) {
928            // redirect if set in settings
929            if (r.data[1] && r.data[1].optin_redirect) {
930              $popup.trigger('wppopups.optin_on_redirect', [popup_id]);
931              var redirect = r.data[1].optin_redirect;
932
933              if (r.data[1].pass_lead_data && r.data[1].pass_lead_data == 1) {
934                var qstring = [];
935                var sep = redirect.match(/[\?]/g) ? '&' : '?';
936
937                for (var key in data) {
938                  if (data[key]['value'] == '') continue;
939                  qstring.push(encodeURIComponent(data[key]['name']) + '=' + encodeURIComponent(data[key]['value']));
940                }
941
942                redirect = redirect + sep + qstring.join('&');
943              }
944
945              WPPopups.hidePopup($popup, true);
946              window.location.href = redirect;
947              return;
948            } // clear errors
949
950
951            $popup.find('.optin-errors').html('').hide(); // success message
952
953            if (r.data[0] && r.data[0].optin_success) {
954              WPPopups.popupConverted($popup);
955              $popup.find('.spu-content').html(r.data[0].optin_success);
956              WPPopups.centerPopup($popup, true);
957
958              if (r.data[0].optin_success_seconds && parseInt(r.data[0].optin_success_seconds) > 0) {
959                var seconds = parseInt(r.data[0].optin_success_seconds, 10) * 1000;
960                WPPopups.hidePopup($popup, false, seconds);
961              }
962            } else {
963              WPPopups.hidePopup($popup, true);
964            }
965          } else {
966            $popup.find('.optin-errors').html(r.data).fadeIn();
967          }
968
969          $popup.trigger('wppopups.optin_form_submitted', [popup_id, r]);
970          WPPopups.toggleButton($submit_btn, false);
971        },
972        error: function error(r) {
973          console.log(r);
974          WPPopups.toggleButton($submit_btn, false);
975        }
976      };
977      $.ajax(ajax);
978    },
979    loadValidation: function loadValidation() {
980      // Only load if jQuery validation library exists.
981      if (typeof $.fn.validate !== 'undefined') {
982        // Prepend URL field contents with http:// if user input doesn't contain a schema.
983        $('.wppopups-validate input[type=url]').change(function () {
984          var url = $(this).val();
985
986          if (!url) {
987            return false;
988          }
989
990          if (url.substr(0, 7) !== 'http://' && url.substr(0, 8) !== 'https://') {
991            $(this).val('http://' + url);
992          }
993        });
994        $.validator.messages.required = wppopups_vars.val_required;
995        $.validator.messages.url = wppopups_vars.val_url;
996        $.validator.messages.email = wppopups_vars.val_email;
997        $.validator.messages.number = wppopups_vars.val_number; // Validate email addresses.
998
999        $.validator.methods.email = function (value, element) {
1000          return this.optional(element) || /^[a-z0-9.!#$%&'*+\/=?^_`{|}~-]+@((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/i.test(value);
1001        }; // Validate checkbox choice limit.
1002
1003
1004        $.validator.addMethod('check-limit', function (value, element) {
1005          var $ul = $(element).closest('ul'),
1006              $checked = $ul.find('input[type="checkbox"]:checked'),
1007              choiceLimit = parseInt($ul.attr('data-choice-limit') || 0, 10);
1008
1009          if (0 === choiceLimit) {
1010            return true;
1011          }
1012
1013          return $checked.length <= choiceLimit;
1014        }, function (params, element) {
1015          var choiceLimit = parseInt($(element).closest('ul').attr('data-choice-limit') || 0, 10);
1016          return wppopups_vars.val_checklimit.replace('{#}', choiceLimit);
1017        }); // Finally load jQuery Validation library for our forms.
1018
1019        $('.wppopups-validate').each(function () {
1020          var form = $(this),
1021              popupID = form.data('popupid'),
1022              properties; // TODO: cleanup this BC with wppopups_validate.
1023
1024          if (typeof window['wppopups_' + popupID] !== 'undefined' && window['wppopups_' + popupID].hasOwnProperty('val
1024idate')) {
1025            properties = window['wppopups_' + popupID].validate;
1026          } else if (typeof wppopups_validate !== 'undefined') {
1027            properties = wppopups_validate;
1028          } else {
1029            properties = {
1030              errorClass: 'wppopups-error',
1031              validClass: 'wppopups-valid',
1032              errorPlacement: function errorPlacement(error, element) {
1033                if ('radio' === element.attr('type') || 'checkbox' === element.attr('type')) {
1034                  if (element.hasClass('wppopups-likert-scale-option')) {
1035                    if (element.closest('table').hasClass('single-row')) {
1036                      element.closest('table').after(error);
1037                    } else {
1038                      element.closest('tr').find('th').append(error);
1039                    }
1040                  } else if (element.hasClass('wppopups-net-promoter-score-option')) {
1041                    element.closest('table').after(error);
1042                  } else {
1043                    element.closest('.wppopups-field-checkbox').find('label.wppopups-error').remove();
1044                    element.parent().parent().parent().append(error);
1045                  }
1046                } else if (element.is('select') && element.attr('class').match(/date-month|date-day|date-year/)) {
1047                  if (0 === element.parent().find('label.wppopups-error:visible').length) {
1048                    element.parent().find('select:last').after(error);
1049                  }
1050                } else if (element.hasClass('wppopups-smart-phone-field')) {
1051                  element.parent().after(error);
1052                } else if (element.hasClass('wppopups-validation-group-member')) {
1053                  element.closest('.wppopups-field').append(error);
1054                } else {
1055                  error.insertAfter(element);
1056                }
1057              },
1058              highlight: function highlight(element, errorClass, validClass) {
1059                var $element = $(element),
1060                    $field = $element.closest('.wppopups-field'),
1061                    inputName = $element.attr('name');
1062
1063                if ('radio' === $element.attr('type') || 'checkbox' === $element.attr('type')) {
1064                  $field.find('input[name="' + inputName + '"]').addClass(errorClass).removeClass(validClass);
1065                } else {
1066                  $element.addClass(errorClass).removeClass(validClass);
1067                }
1068
1069                $field.addClass('wppopups-has-error');
1070              },
1071              unhighlight: function unhighlight(element, errorClass, validClass) {
1072                var $element = $(element),
1073                    $field = $element.closest('.wppopups-field'),
1074                    inputName = $element.attr('name');
1075
1076                if ('radio' === $element.attr('type') || 'checkbox' === $element.attr('type')) {
1077                  $field.find('input[name="' + inputName + '"]').addClass(validClass).removeClass(errorClass);
1078                } else {
1079                  $element.addClass(validClass).removeClass(errorClass);
1080                }
1081
1082                $field.removeClass('wppopups-has-error');
1083              },
1084              submitHandler: function submitHandler(form) {
1085                var $popup = $('#spu-' + popupID);
1086                WPPopups.formOptinSubmissions($popup);
1087              },
1088              invalidHandler: function invalidHandler(event, validator) {//if ( typeof validator.errorList[0] !== 'undefined' ) {
1089                //    app.scrollToError( $( validator.errorList[0].element ) );
1090                //}
1091              },
1092              onkeyup: function onkeyup(element, event) {
1093                // This code is copied from JQuery Validate 'onkeyup' method with only one change: 'wppopups-novalidate-onkeyup' class check.
1094                var excludedKeys = [16, 17, 18, 20, 35, 36, 37, 38, 39, 40, 45, 144, 225];
1095
1096                if ($(element).hasClass('wppopups-novalidate-onkeyup')) {
1097                  return; // Disable onkeyup validation for some elements (e.g. remote calls).
1098                }
1099
1100                if (9 === event.which && '' === this.elementValue(element) || $.inArray(event.keyCode, excludedKeys) !== -1) {
1101                  return;
1102                } else if (element.name in this.submitted || element.name in this.invalid) {
1103                  this.element(element);
1104                }
1105              },
1106              onfocusout: function onfocusout(element) {
1107                // This code is copied from JQuery Validate 'onfocusout' method with only one change: 'wppopups-novalidate-onkeyup' class check.
1108                var validate = false;
1109
1110                if ($(element).hasClass('wppopups-novalidate-onkeyup') && !element.value) {
1111                  validate = true; // Empty value error handling for elements with onkeyup validation disabled.
1112                }
1113
1114                if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
1115                  validate = true;
1116                }
1117
1118                if (validate) {
1119                  this.element(element);
1120                }
1121              },
1122              onclick: function onclick(element) {
1123                var validate = false,
1124                    type = (element || {}).type,
1125                    $el = $(element);
1126
1127                if (['checkbox', 'radio'].indexOf(type) > -1) {
1128                  if ($el.hasClass('wppopups-likert-scale-option')) {
1129                    $el = $el.closest('tr');
1130                  } else {
1131                    $el = $el.closest('.wppopups-field');
1132                  }
1133
1134                  $el.find('label.wppopups-error').remove();
1135                  validate = true;
1136                }
1137
1138                if (validate) {
1139                  this.element(element);
1140                }
1141              }
1142            };
1143          }
1144
1145          form.validate(properties);
1146        });
1147      }
1148    },
1149
1150    /**
1151     * Helper func to toggle optin button
1152     * @param $submit_btn
1153     * @param disable
1154     */
1155    toggleButton: function toggleButton($submit_btn, disable) {
1156      var oldText = $submit_btn.data('submit-text'),
1157          altText = $submit_btn.data('alt-text');
1158
1159      if (disable) {
1160        // Display processing text.
1161        if (altText) {
1162          $submit_btn.text(altText);
1163        }
1164
1165        $submit_btn.addClass('spu-sending');
1166        $submit_btn.attr('disabled', 'disabled');
1167      } else {
1168        if (oldText) {
1169          $submit_btn.text(oldText);
1170        }
1171
1172        $submit_btn.removeClass('spu-sending');
1173        $submit_btn.removeAttr('disabled');
1174      }
1175    },
1176
1177    /**
1178     * Check if popup it's bigger than windows to add scroll bars
1179     * @param $popup
1180     */
1181    checkPopupSize: function checkPopupSize($popup) {
1182      // add 150 to give some margins on top/bottom
1183      if ($popup.outerHeight() + 150 >= $(window).height()) {
1184        $popup.css('overflow', 'auto').addClass('spu-scrollable');
1185        $popup.css('max-height', $(window).height());
1186      } else {
1187        $popup.css('overflow', 'initial').removeClass('spu-scrollable');
1188        $popup.css('max-height', '');
1189      }
1190    },
1191    initSocialShortcodes: function initSocialShortcodes() {
1192      // if facebook being used on any popup
1193      if (wppopups_vars.facebook) {
1194        var SPUfb = false,
1195            FbTimer = setInterval(function () {
1196          if (typeof FB !== 'undefined' && !SPUfb) {
1197            try {
1198              FB.Event.subscribe('edge.create', function (href, html_element) {
1199                var $popup = $(html_element).parents('.spu-box');
1200
1201                if ($popup.length) {
1202                  WPPopups.hidePopup($popup, true);
1203                }
1204              });
1205            } catch (ex) {
1206              console.log(ex);
1207            }
1208
1209            SPUfb = true;
1210            clearInterval(FbTimer);
1211          }
1212        }, 1000);
1213      }
1214
1215      if (wppopups_vars.twitter) {
1216        if (typeof twttr !== 'undefined') {
1217          try {
1218            twttr.ready(function (twttr) {
1219              twttr.events.bind('tweet', WPPopups.twitterCB);
1220              twttr.events.bind('follow', WPPopups.twitterCB);
1221            });
1222          } catch (ex) {}
1223        }
1224      }
1225
1226      if (wppopups_vars.google) {
1227        if (typeof twttr !== 'undefined') {
1228          try {
1229            twttr.ready(function (twttr) {
1230              twttr.events.bind('tweet', WPPopups.twitterCB);
1231              twttr.events.bind('follow', WPPopups.twitterCB);
1232            });
1233          } catch (ex) {}
1234        }
1235      }
1236    },
1237    googleCB: function googleCB(a) {
1238      if ("on" == a.state) {
1239        var box_id = $('.spu-gogl').data('box-id');
1240
1241        if (box_id) {
1242          WPPopups.hidePopup(box_id, true);
1243        }
1244      }
1245    },
1246    closeGoogle: function closeGoogle(a) {
1247      if ("confirm" == a.type) {
1248        var box_id = $('.spu-gogl').data('box-id');
1249
1250        if (box_id) {
1251          WPPopups.hidePopup(box_id, true);
1252        }
1253      }
1254    },
1255
1256    /**
1257     * Twitter callback function
1258     * @param intent_event
1259     */
1260    twitterCB: function twitterCB(intent_event) {
1261      var $popup = $(intent_event.target).parents('.spu-box');
1262
1263      if ($popup) {
1264        WPPopups.hidePopup($popup, true);
1265      }
1266    },
1267
1268    /**
1269     * Set cookie container user UUID.
1270     *
1271     */
1272    setUserIndentifier: function setUserIndentifier() {
1273      if (wppopups_settings.uuid_cookie && !WPPopups.getCookie('_wpfuuid')) {
1274        // Generate UUID - http://stackoverflow.com/a/873856/1489528
1275        var s = new Array(36),
1276            hexDigits = '0123456789abcdef',
1277            uuid;
1278
1279        for (var i = 0; i < 36; i++) {
1280          s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
1281        }
1282
1283        s[14] = "4";
1284        s[19] = hexDigits.substr(s[19] & 0x3 | 0x8, 1);
1285        s[8] = s[13] = s[18] = s[23] = '-';
1286        uuid = s.join("");
1287        WPPopups.createCookie('_wpfuuid', uuid, 3999);
1288      }
1289    },
1290
1291    /**
1292     * Set classes or href link in a global array
1293     * @param bind_name
1294     * @param bind_type
1295     */
1296    setBindActions: function setBindActions() {
1297      var bind_name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
1298      var bind_type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'class';
1299
1300      if (bind_name != '') {
1301        switch (bind_type) {
1302          case 'class':
1303            bind_name = bind_name.charAt(0) == '.' ? bind_name.substring(1) : bind_name;
1304            if ($.inArray(bind_name, WPPopups.byBind['class']) === -1) WPPopups.byBind['class'].push(bind_name);
1305            break;
1306
1307          case 'href':
1308            if ($.inArray(bind_name, WPPopups.byBind['href']) === -1) WPPopups.byBind['href'].push(bind_name);
1309            break;
1310        }
1311
1312        window.wp.hooks.doAction('wppopups_set_bindactions', bind_name, bind_type);
1313      }
1314    },
1315
1316    /**
1317     * Check if exists any BindActions when happen a event
1318     * @param target
1319     */
1320    checkBindActions: function checkBindActions(target) {
1321      var $classes = WPPopups.byBind['class'];
1322
1323      for (var i = 0; i < $classes.length; i++) {
1324        if ($classes[i]) {
1325          if (target.hasClass($classes[i]) || target.closest('.' + $classes[i]).length) {
1326            return true;
1327          }
1328        }
1329      }
1330
1331      var $href = WPPopups.byBind['href'];
1332
1333      for (var _i = 0; _i < $href.length; _i++) {
1334        if ($href[_i] && target.attr('href') == $href[_i]) {
1335          return true;
1336        }
1337      }
1338
1339      return false;
1340    },
1341
1342    /**
1343     * Create cookie.
1344     *
1345     * @since 2.0.0
1346     */
1347    createCookie: function createCookie(name, value) {
1348      var duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 999;
1349      var type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'd';
1350      var expires = ''; // If we have a duration value, set it in the expiry of the cookie.
1351
1352      if (duration && type) {
1353        // If -1 is our value, set a session based cookie instead of a persistent cookie.
1354        if ('-1' === duration) {
1355          expires = '';
1356        } else {
1357          var cookie_time;
1358
1359          switch (type) {
1360            case 'm':
1361              cookie_time = 60 * 1000;
1362              break;
1363
1364            case 'h':
1365              cookie_time = 60 * 60 * 1000;
1366              break;
1367
1368            default:
1369              cookie_time = 24 * 60 * 60 * 1000;
1370          }
1371
1372          var date = new Date();
1373          date.setTime(date.getTime() + parseInt(duration) * cookie_time);
1374          expires = '; expires=' + date.toGMTString();
1375        }
1376      } else {
1377        expires = '; expires=Thu, 01 Jan 1970 00:00:01 GMT';
1378      } // Write the cookie.
1379
1380
1381      document.cookie = name + '=' + value + expires + '; path=/';
1382    },
1383
1384    /**
1385     * Retrieve cookie.
1386     *
1387     * @since 2.0.0
1388     */
1389    getCookie: function getCookie(name) {
1390      var nameEQ = name + '=',
1391          ca = document.cookie.split(';');
1392
1393      for (var i = 0; i < ca.length; i++) {
1394        var c = ca[i];
1395
1396        while (c.charAt(0) === ' ') {
1397          c = c.substring(1, c.length);
1398        }
1399
1400        if (c.indexOf(nameEQ) == 0) {
1401          return c.substring(nameEQ.length, c.length);
1402        }
1403      }
1404
1405      return null;
1406    },
1407
1408    /**
1409     * Delete cookie.
1410     */
1411    removeCookie: function removeCookie(name) {
1412      WPPopups.createCookie(name, '', -1);
1413    },
1414
1415    /**
1416     * Check if it's a number. So (12) and ('12') will be good
1417     * @param n
1418     * @returns {boolean}
1419     */
1420    isNumber: function isNumber(n) {
1421      return !isNaN(parseFloat(n)) && !isNaN(n - 0);
1422    },
1423
1424    /**
1425     * Get a popup from a string, or selector or inner selector such as coming from event
1426     * @param popup
1427     */
1428    getPopup: function getPopup(popup) {
1429      if (WPPopups.isNumber(popup)) {
1430        return $('#spu-' + parseInt(popup));
1431      }
1432
1433      if (popup.is('.spu-box')) {
1434        return popup;
1435      }
1436
1437      return popup.closest('.spu-box');
1438    },
1439
1440    /**
1441     * Check if the popup has convertion rules and fire if needed
1442     * We need to runt his check on js because some popups fire when other convert in the same page load
1443     * Eg: Show exit popup A if popup B fails
1444     * @param $popup
1445     * @returns {boolean}
1446     */
1447    checkConvertion: function checkConvertion($popup) {
1448      // if no class trigger as normal
1449      if (!$popup.hasClass('yes-convert') && !$popup.hasClass('no-convert')) return true;
1450      var $settings = WPPopups.settings($('#spu-' + $popup.data('convert-id')), 'settings');
1451      var popup_converted = false;
1452
1453      if (WPPopups.getCookie($settings.conversion_cookie_name)) {
1454        popup_converted = true;
1455      }
1456
1457      if ($popup.hasClass('yes-convert')) {
1458        return popup_converted;
1459      } else {
1460        return !popup_converted;
1461      }
1462    },
1463    isMobile: function isMobile() {
1464      var Android = navigator.userAgent.match(/Android/i),
1465          BlackBerry = navigator.userAgent.match(/BlackBerry/i),
1466          iOS = navigator.userAgent.match(/iPhone|iPad|iPod/i),
1467          Opera = navigator.userAgent.match(/Opera Mini/i),
1468          Windows = navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
1469      return Android || BlackBerry || iOS || Opera || Windows;
1470    }
1471  }; // Initialize.
1472
1473  WPPopups.init(); // Add to global scope.
1474
1475  window.wppopups = WPPopups;
1476})(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.