PageSourceSearch

https://www.kabgallery.com/system/wp-content/plugins/pixelyoursite/dist/scripts/public.js?ver=8.2.5

js kabgallery.com collected 2026-10-06 04:17:16 UTC 77,529 bytes, 2,062 lines download raw bytes

1/* global pysOptions */
2
3// https://bitbucket.org/pixelyoursite/pys_pro_7/issues/7/possible-ie-11-error
4// https://tc39.github.io/ecma262/#sec-array.prototype.includes
5if (!Array.prototype.includes) {
6    Object.defineProperty(Array.prototype, 'includes', {
7        value: function (searchElement, fromIndex) {
8
9            if (this == null) {
10                throw new TypeError('"this" is null or not defined');
11            }
12
13            // 1. Let O be ? ToObject(this value).
14            var o = Object(this);
15
16            // 2. Let len be ? ToLength(? Get(O, "length")).
17            var len = o.length >>> 0;
18
19            // 3. If len is 0, return false.
20            if (len === 0) {
21                return false;
22            }
23
24            // 4. Let n be ? ToInteger(fromIndex).
25            //    (If fromIndex is undefined, this step produces the value 0.)
26            var n = fromIndex | 0;
27
28            // 5. If n ≥ 0, then
29            //  a. Let k be n.
30            // 6. Else n < 0,
31            //  a. Let k be len + n.
32            //  b. If k < 0, let k be 0.
33            var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
34
35            function sameValueZero(x, y) {
36                return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
37            }
38
39            // 7. Repeat, while k < len
40            while (k < len) {
41                // a. Let elementK be the result of ? Get(O, ! ToString(k)).
42                // b. If SameValueZero(searchElement, elementK) is true, return true.
43                if (sameValueZero(o[k], searchElement)) {
44                    return true;
45                }
46                // c. Increase k by 1.
47                k++;
48            }
49
50            // 8. Return false
51            return false;
52        }
53    });
54}
55
56!function ($, options) {
57
58    if (options.debug) {
59        console.log('PYS:', options);
60    }
61
62    var dummyPinterest = function () {
63
64        /**
65         * Public API
66         */
67        return {
68
69            isEnabled: function () {
70            },
71
72            disable: function () {
73            },
74
75            loadPixel: function () {
76            },
77
78            fireEvent: function (name, data) {
79                return false;
80            },
81
82            onCommentEvent: function () {
83            },
84
85            onDownloadEvent: function (params) {
86            },
87
88            onFormEvent: function (params) {
89            },
90
91            onWooAddToCartOnButtonEvent: function (product_id) {
92            },
93
94            onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {
95            },
96
97            onWooRemoveFromCartEvent: function (cart_item_hash) {
98            },
99
100            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
101            },
102
103            onEddRemoveFromCartEvent: function (item) {
104            },
105            onPageScroll: function (event) {},
106            onTime: function (event) {
107
108            },
109
110        }
111
112    }();
113
114    var dummyBing = function () {
115
116        /**
117         * Public API
118         */
119        return {
120
121            isEnabled: function () {
122            },
123
124            disable: function () {
125            },
126
127            loadPixel: function () {
128            },
129
130            fireEvent: function (name, data) {
131                return false;
132            },
133
134            onAdSenseEvent: function () {
135            },
136
137            onClickEvent: function (params) {
138            },
139
140            onWatchVideo: function (params) {
141            },
142
143            onCommentEvent: function () {
144            },
145
146            onFormEvent: function (params) {
147            },
148
149            onDownloadEvent: function (params) {
150            },
151
152            onWooAddToCartOnButtonEvent: function (product_id) {
153            },
154
155            onWooAddToCartOnSingleEvent: function (product_id, qty, is_variable, is_external, $form) {
156            },
157
158            onWooRemoveFromCartEvent: function (cart_item_hash) {
159            },
160
161            onWooAffiliateEvent: function (product_id) {
162            },
163
164            onWooPayPalEvent: function () {
165            },
166
167            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
168            },
169
170            onEddRemoveFromCartEvent: function (item) {
171            },
172
173            onPageScroll: function (event) {
174            },
175
176            onTime: function (event) {
177            },
178
179        }
180
181    }();
182
183    var Utils = function (options) {
184
185        var Pinterest = dummyPinterest;
186
187        var Bing = dummyBing;
188
189        var gtag_loaded = false;
190
191        function loadPixels() {
192
193            if (!options.gdpr.all_disabled_by_api) {
194
195                if (!options.gdpr.facebook_disabled_by_api) {
196                    Facebook.loadPixel();
197                }
198
199                if (!options.gdpr.analytics_disabled_by_api) {
200                    Analytics.loadPixel();
201                }
202
203                if (!options.gdpr.pinterest_disabled_by_api) {
204                    Pinterest.loadPixel();
205                }
206
207                if (!options.gdpr.bing_disabled_by_api) {
208                    Bing.loadPixel();
209                }
210            }
211
212        }
213
214        /**
215         * PUBLIC API
216         */
217        return {
218            PRODUCT_SIMPLE : 0,
219            PRODUCT_VARIABLE : 1,
220            PRODUCT_BUNDLE : 2,
221            PRODUCT_GROUPED : 3,
222            fireEventForAllPixel:function(functionName,events){
223                if (events.hasOwnProperty(Facebook.tag()))
224                    Facebook[functionName](events[Facebook.tag()]);
225                if (events.hasOwnProperty(Analytics.tag()))
226                    Analytics[functionName](events[Analytics.tag()]);
227                if (events.hasOwnProperty(Pinterest.tag()))
228                    Pinterest[functionName](events[Pinterest.tag()]);
229                if (events.hasOwnProperty(Bing.tag()))
230                    Bing[functionName](events[Bing.tag()]);
231            },
232
233            setupPinterestObject: function () {
234                Pinterest = window.pys.Pinterest || Pinterest;
235                return Pinterest;
236            },
237
238            setupBingObject: function () {
239                Bing = window.pys.Bing || Bing;
240                return Bing;
241            },
242
243            // Clone all object members to another and return it
244            copyProperties: function (from, to) {
245                for (var key in from) {
246                    if("function" == typeof from[key]) {
247                        continue;
248                    }
249                    to[key] = from[key];
250                }
251                return to;
252            },
253            // clone object
254            clone: function(obj) {
255                var copy;
256
257                // Handle the 3 simple types, and null or undefined
258                if (null == obj || "object" != typeof obj) return obj;
259
260                // Handle Date
261                if (obj instanceof Date) {
262                    copy = new Date();
263                    copy.setTime(obj.getTime());
264                    return copy;
265                }
266
267                // Handle Array
268                if (obj instanceof Array) {
269                    copy = [];
270                    for (var i = 0, len = obj.length; i < len; i++) {
271                        if("function" == typeof obj[i]) {
272                            continue;
273                        }
274                        copy[i] = Utils.clone(obj[i]);
275                    }
276                    return copy;
277                }
278
279                // Handle Object
280                if (obj instanceof Object) {
281                    copy = {};
282                    for (var attr in obj) {
283                        if (obj.hasOwnProperty(attr)) {
284                            if("function" == typeof obj[attr]) {
285                                continue;
286                            }
287                            copy[attr] = Utils.clone(obj[attr]);
288                        }
289                    }
290                    return copy;
291                }
292
293                return obj;
294            },
295
296            // Returns array of elements with given tag name
297            getTagsAsArray: function (tag) {
298                return [].slice.call(document.getElementsByTagName(tag));
299            },
300
301            getRequestParams: function () {
302                return [];
303            },
304
305            /**
306             * CUSTOM EVENTS
307             */
308
309            setupMouseOverClickEvents: function (eventId, triggers) {
310
311                // Non-default binding used to avoid situations when some code in external js
312                // stopping events propagation, eg. returns false, and our handler will never called
313                $(document).onFirst('mouseover', triggers.join(','), function () {
314
315                    // do not fire event multiple times
316                    if ($(this).hasClass('pys-mouse-over-' + eventId)) {
317                        return true;
318                    } else {
319                        $(this).addClass('pys-mouse-over-' + eventId);
320                    }
321
322                    Utils.fireDynamicEvent(eventId);
323
324                });
325
326            },
327
328            setupCSSClickEvents: function (eventId, triggers) {
329
330                // Non-default binding used to avoid situations when some code in external js
331                // stopping events propagation, eg. returns false, and our handler will never called
332                $(document).onFirst('click', triggers.join(','), function () {
333                    Utils.fireTriggerEvent(eventId);
334                });
335            },
336
337            setupURLClickEvents: function () {
338
339                // Non-default binding used to avoid situations when some code in external js
340                // stopping events propagation, eg. returns false, and our handler will never called
341                $('a[data-pys-event-id]').onFirst('click', function (evt) {
342
343                    $(this).attr('data-pys-event-id').split(',').forEach(function (eventId) {
344
345                        eventId = parseInt(eventId);
346
347                        if (isNaN(eventId) === false) {
348                            Utils.fireTriggerEvent(eventId);
349                        }
350
351                    });
352
353                });
354
355
356            },
357
358            setupScrollPosEvents: function (eventId, triggers) {
359
360                var scrollPosThresholds = {},
361                    docHeight = $(document).height() - $(window).height();
362
363                // convert % to absolute positions
364                $.each(triggers, function (index, scrollPos) {
365
366                    // convert % to pixels
367                    scrollPos = docHeight * scrollPos / 100;
368                    scrollPos = Math.round(scrollPos);
369
370                    scrollPosThresholds[scrollPos] = eventId;
371
372                });
373
374                $(document).on("scroll",function () {
375
376                    var scrollPos = $(window).scrollTop();
377
378                    $.each(scrollPosThresholds, function (threshold, eventId) {
379
380                        // position has not reached yes
381                        if (scrollPos <= threshold) {
382                            return true;
383                        }
384
385                        // fire event only once
386                        if (eventId === null) {
387                            return true;
388                        } else {
389                            scrollPosThresholds[threshold] = null;
390                        }
391
392                        Utils.fireTriggerEvent(eventId);
393
394                    });
395
396                });
397
398
399            },
400            setupCommentEvents : function (eventId,triggers) {
401                $('form.comment-form').on("submit",function () {
402                    Utils.fireTriggerEvent(eventId);
403                });
404            },
405
406            /**
407             * Events
408             */
409            fireTriggerEvent: function (eventId) {
410
411                if (!options.triggerEvents.hasOwnProperty(eventId)) {
412                    return;
413                }
414
415                var event = {};
416                var events = options.triggerEvents[eventId];
417
418                if (events.hasOwnProperty('facebook')) {
419                    event = events.facebook;
420                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_facebook_"+eventId)) {
421                        Facebook.fireEvent(event.name, event);
422                    }
423                }
424
425                if (events.hasOwnProperty('ga')) {
426                    event = events.ga;
427                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_ga_"+eventId)) {
428                        Analytics.fireEvent(event.name, event);
429                    }
430                }
431
432                if (events.hasOwnProperty('pinterest')) {
433                    event = events.pinterest;
434                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_pinterest_"+eventId)) {
435                        Pinterest.fireEvent(event.name, event);
436                    }
437                }
438
439                if (events.hasOwnProperty('bing')) {
440                    event = events.bing;
441                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) {
442                        Bing.fireEvent(event.name, event);
443                    }
444                }
445            },
446
447            fireStaticEvents: function (pixel) {
448
449                if (options.staticEvents.hasOwnProperty(pixel)) {
450
451                    $.each(options.staticEvents[pixel], function (eventName, events) {
452                        $.each(events, function (index, eventData) {
453
454                            eventData.fired = eventData.fired || false;
455
456                            if (!eventData.fired) {
457
458                                var fired = false;
459
460                                // fire event
461                                if ('facebook' === pixel) {
462                                    fired = Facebook.fireEvent(eventName, eventData);
463                                } else if ('ga' === pixel) {
464                                    fired = Analytics.fireEvent(eventName, eventData);
465                                } else if ('pinterest' === pixel) {
466                                    fired = Pinterest.fireEvent(eventName, eventData);
467                                } else if ('bing' === pixel) {
468                                    fired = Bing.fireEvent(eventName, eventData);
469                                }
470
471                                // prevent event double event firing
472                                eventData.fired = fired;
473
474                            }
475
476                        });
477                    });
478
479                }
480
481            },
482
483            /**
484             * Load tag's JS
485             *
486             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/
487             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
488             */
489            loadGoogleTag: function (id) {
490
491                if (!gtag_loaded) {
492
493                    (function (window, document, src) {
494                        var a = document.createElement('script'),
495                            m = document.getElementsByTagName('script')[0];
496                        a.async = 1;
497                        a.src = src;
498                        m.parentNode.insertBefore(a, m);
499                    })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id);
500
501                    window.dataLayer = window.dataLayer || [];
502                    window.gtag = window.gtag || function gtag() {
503                        dataLayer.push(arguments);
504                    };
505
506                    gtag('js', new Date());
507
508                    gtag_loaded = true;
509
510                }
511
512            },
513
514            /**
515             * GDPR
516             */
517
518            loadPixels: function () {
519
520                if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) {
521
522                    // retrieves actual PYS GDPR filters values which allow to avoid cache issues
523                    $.get({
524                        url: options.ajaxUrl,
525                        dataType: 'json',
526                        data: {
527                            action: 'pys_get_gdpr_filters_values'
528                        },
529                        success: function (res) {
530
531                            if (res.success) {
532
533                                options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api;
534                                options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api;
535                                options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api;
536                                options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api;
537                                options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api;
538                                options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api;
539
540                            }
541
542                            loadPixels();
543
544                        }
545                    });
546
547                } else {
548                    loadPixels();
549                }
550
551            },
552
553            consentGiven: function (pixel) {
554
555                /**
556                 * ConsentMagic
557                 */
558                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
559
560                    var cs_cookie = Cookies.get('cs_viewed_cookie_policy'+test_prefix);
561
562                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
563                        if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') {
564                            return true;
565                        }
566                    } else {
567                        if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') {
568                            return true;
569                        }
570                    }
571
572                    return false;
573
574                }
575
576                /**
577                 * Real Cookie Banner
578                 */
579                if(options.gdpr.real_cookie_banner_integration_enabled) {
580                    var consentApi = window.consentApi;
581                    if (consentApi) {
582                        switch (pixel) {
583                            case "analytics":
584                                return consentApi.consentSync("http", "_ga", "*").cookieOptIn;
585                            case "facebook":
586                                return consentApi.consentSync("http", "_fbp", "*").cookieOptIn;
587                            case "pinterest":
588                                return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn;
589                            default:
590                                return true;
591                        }
592                    }
593                }
594
595                /**
596                 * Cookiebot
597                 */
598                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
599
600                    var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category'];
601
602                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
603                        if (Cookiebot.consented === false || Cookiebot.consent[cookiebot_consent_category]) {
604                            return true;
605                        }
606                    } else {
607                        if (Cookiebot.consent[cookiebot_consent_category]) {
608                            return true;
609                        }
610                    }
611
612                    return false;
613
614                }
615
616                /**
617                 * Cookie Notice
618                 */
619                if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') {
620
621                    var cn_cookie = Cookies.get(cnArgs.cookieName);
622
623                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
624                        if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') {
625                            return true;
626                        }
627                    } else {
628                        if (cn_cookie === 'true') {
629                            return true;
630                        }
631                    }
632
633                    return false;
634
635                }
636
637                /**
638                 * Cookie Law Info
639                 */
640                if (options.gdpr.cookie_law_info_integration_enabled) {
641
642                    var cli_cookie = Cookies.get('viewed_cookie_policy');
643
644                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
645                        if (typeof cli_cookie === 'undefined' || cli_cookie === 'yes') {
646                            return true;
647                        }
648                    } else {
649                        if (cli_cookie === 'yes') {
650                            return true;
651                        }
652                    }
653
654                    return false;
655
656                }
657
658                return true;
659
660            },
661
662            setupGdprCallbacks: function () {
663                /**
664                 * ConsentMagic
665                 */
666                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
667                    var test_prefix = CS_Data.test_prefix,
668                        cs_refresh_after_consent = false,
669                        substring = "cs_enabled_cookie_term";
670
671                    if (CS_Data.cs_refresh_after_consent == 1) {
672                        cs_refresh_after_consent = CS_Data.cs_refresh_after_consent;
673                    }
674
675                    if (!cs_refresh_after_consent) {
676                        var theCookies = document.cookie.split(';');
677                        for (var i = 1 ; i <= theCookies.length; i++) {
678                            if (theCookies[i-1].indexOf(substring) !== -1) {
679                                var categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_','');
680                                categoryCookie = Number(categoryCookie.replace(/\D+/g,""));
681                                var cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie);
682                                if(cs_cookie_val == 'yes') {
683                                    if (categoryCookie === CS_Data.cs_script_cat.facebook) {
684                                        Facebook.loadPixel();
685                                    } else if (categoryCookie === CS_Data.cs_script_cat.bing) {
686                                        Bing.loadPixel();
687                                    } else if (categoryCookie === CS_Data.cs_script_cat.analytics) {
688                                        Analytics.loadPixel();
689                                    } else if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
690                                        Pinterest.loadPixel();
691                                    }
692                                } else {
693                                    if (categoryCookie === CS_Data.cs_script_cat.facebook) {
694                                        Facebook.disable();
695                                    } else if (categoryCookie === CS_Data.cs_script_cat.bing) {
696                                        Bing.disable();
697                                    } else if (categoryCookie === CS_Data.cs_script_cat.analytics) {
698                                        Analytics.disable();
699                                    } else if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
700                                        Pinterest.disable();
701                                    }
702                                }
703                                if (Cookies.get('cs_enabled_advanced_matching') == 'yes') {
704                                    Facebook.loadPixel();
705                                }
706                            }
707                        }
708
709                        $(document).on('click','.cs_action_btn',function(e) {
710                            e.preventDefault();
711                            var elm = $(this),
712                                button_action = elm.attr('data-cs_action');
713
714                            if(button_action === 'allow_all') {
715                                Facebook.loadPixel();
716                                Bing.loadPixel();
717                                Analytics.loadPixel();
718                                Pinterest.loadPixel();
719                            } else if(button_action === 'disable_all') {
720                                Facebook.disable();
721                                Bing.disable();
722                                Analytics.disable();
723                                Pinterest.disable();
724                            }
725                        });
726                    }
727                }
728                /**
729                 * Real Cookie Banner
730                 */
731                if(options.gdpr.real_cookie_banner_integration_enabled) {
732                    var consentApi = window.consentApi;
733                    if (consentApi) {
734                        consentApi.consent("http", "_ga", "*")
735                            .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics));
736                        consentApi.consent("http", "_fbp", "*")
737                            .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook));
738                        consentApi.consent("http", "_pinterest_sess", ".pinterest.com")
739                            .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest));
740                    }
741                }
742                /**
743                 * Cookiebot
744                 */
745                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
746
747                    Cookiebot.onaccept = function () {
748
749                        if (Cookiebot.consent[options.gdpr.cookiebot_facebook_consent_category]) {
750                            Facebook.loadPixel();
751                        }
752
753                        if (Cookiebot.consent[options.gdpr.cookiebot_analytics_consent_category]) {
754                            Analytics.loadPixel();
755                        }
756
757                        if (Cookiebot.consent[options.gdpr.cookiebot_pinterest_consent_category]) {
758                            Pinterest.loadPixel();
759                        }
760
761                        if (Cookiebot.consent[options.gdpr.cookiebot_bing_consent_category]) {
762                            bing.loadPixel();
763                        }
764
765                    };
766
767                    Cookiebot.ondecline = function () {
768                        Facebook.disable();
769                        Analytics.disable();
770                        Pinterest.disable();
771                        Bing.disable();
772                    };
773
774                }
775
776                /**
777                 * Cookie Notice
778                 */
779                if (options.gdpr.cookie_notice_integration_enabled) {
780
781                    $(document).onFirst('click', '.cn-set-cookie', function () {
782
783                        if ($(this).data('cookie-set') === 'accept') {
784                            Facebook.loadPixel();
785                            Analytics.loadPixel();
786                            Pinterest.loadPixel();
787                            Bing.loadPixel();
788                        } else {
789                            Facebook.disable();
790                            Analytics.disable();
791                            Pinterest.disable();
792                            Bing.disable();
793                        }
794
795                    });
796
797                    $(document).onFirst('click', '.cn-revoke-cookie', function () {
798                        Facebook.disable();
799                        Analytics.disable();
800                        Pinterest.disable();
801                        Bing.disable();
802                    });
803
804                }
805
806                /**
807                 * Cookie Law Info
808                 */
809                if (options.gdpr.cookie_law_info_integration_enabled) {
810
811                    $(document).onFirst('click', '#cookie_action_close_header', function () {
812                        Facebook.loadPixel();
813                        Analytics.loadPixel();
814                        Pinterest.loadPixel();
815                        Bing.loadPixel();
816                    });
817
818                    $(document).onFirst('click', '#cookie_action_close_header_reject', function () {
819                        Facebook.disable();
820                        Analytics.disable();
821                        Pinterest.disable();
822                        Bing.disable();
823                    });
824
825                }
826
827            },
828
829            /**
830             * DOWNLOAD DOCS
831             */
832
833            getLinkExtension: function (link) {
834
835                // Remove anchor, query string and everything before last slash
836                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
837                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
838                link = link.substring(link.lastIndexOf("/") + 1, link.length);
839
840                // If there's a period left in the URL, then there's a extension
841                if (link.length > 0 && link.indexOf('.') !== -1) {
842                    link = link.substring(link.indexOf(".") + 1); // Remove everything but what's after the first period
843                    return link;
844                } else {
845                    return "";
846                }
847            },
848
849            getLinkFilename: function (link) {
850
851                // Remove anchor, query string and everything before last slash
852                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
853                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
854                link = link.substring(link.lastIndexOf("/") + 1, link.length);
855
856                // If there's a period left in the URL, then there's a extension
857                if (link.length > 0 && link.indexOf('.') !== -1) {
858                    return link;
859                } else {
860                    return "";
861                }
862            }
863
864        };
865
866    }(options);
867
868    var Facebook = function (options) {
869
870
871        var defaultEventTypes = [
872            'PageView',
873            'ViewContent',
874            'Search',
875            'AddToCart',
876            'AddToWishlist',
877            'InitiateCheckout',
878            'AddPaymentInfo',
879            'Purchase',
880            'Lead',
881
882            'Subscribe',
883            'CustomizeProduct',
884            'FindLocation',
885            'StartTrial',
886            'SubmitApplication',
887            'Schedule',
888            'Contact',
889            'Donate'
890        ];
891
892        var initialized = false;
893
894
895        function fireEvent(name, allData) {
896
897            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) {
898                return;
899            }
900
901            var actionType = defaultEventTypes.includes(name) ? 'track' : 'trackCustom';
902            var data = allData.params;
903            var params = {};
904            var arg = {};
905            Utils.copyProperties(data, params);
906
907            if(options.facebook.serverApiEnabled) {
908                // fire server side event gdpr plugin installed
909                var isApiDisabled = options.gdpr.all_disabled_by_api ||
910                    options.gdpr.facebook_disabled_by_api ||
911                    options.gdpr.cookiebot_integration_enabled ||
912                    options.gdpr.consent_magic_integration_enabled ||
913                    options.gdpr.cookie_notice_integration_enabled ||
914                    options.gdpr.cookie_law_info_integration_enabled;
915
916                // Update eventID
917                if( options.facebook.ajaxForServerEvent || allData.type !== "static" ) {
918                    allData.eventID = pys_generate_token(36);
919                }
920                arg.eventID = allData.eventID;
921                // send event from server if they was bloc by gdpr or need send with delay
922                if(  options.facebook.ajaxForServerEvent || isApiDisabled || allData.delay > 0 || allData.type !== "static")
923                {
924                    var json = {
925                        action: 'pys_api_event',
926                        pixel: 'facebook',
927                        event: name,
928                        data:data,
929                        ids:options.facebook.pixelIds,
930                        eventID:allData.eventID,
931                        woo_order:allData.woo_order,
932                        edd_order:allData.edd_order,
933                        url:window.location.href,
934                    };
935                    if(allData.delay > 0) {
936                        jQuery.ajax( {
937                            type: 'POST',
938                            url: options.ajaxUrl,
939                            data: json,
940                            headers: {
941                                'Cache-Control': 'no-cache'
942                            },
943                            success: function(){},
944                        });
945                    } else {
946                       // if(name != "AddToCart") { // AddToCart call from hook
947                            setTimeout(function (json) {
948                                jQuery.ajax({
949                                    type: 'POST',
950                                    url: options.ajaxUrl,
951                                    data: json,
952                                    headers: {
953                                        'Cache-Control': 'no-cache'
954                                    },
955                                    success: function () {
956                                    },
957                                });
958                            }, 500, json);
959                        //}
960                    }
961                }
962            }
963
964
965            if("hCR" === name) {
966                return;
967            }
968
969            if (options.debug) {
970                console.log('[Facebook] ' + name, params,"eventID",allData.eventID);
971            }
972
973            fbq(actionType, name, params,arg);
974        }
975
976        /**
977         * Public API
978         */
979        return {
980            tag: function() {
981                return "facebook";
982            },
983            isEnabled: function () {
984                return options.hasOwnProperty('facebook');
985            },
986
987            disable: function () {
988                initialized = false;
989            },
990
991            /**
992             * Load pixel's JS
993             */
994            loadPixel: function () {
995
996                if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) {
997                    return;
998                }
999
1000                !function (f, b, e, v, n, t, s) {
1001                    if (f.fbq) return;
1002                    n = f.fbq = function () {
1003                        n.callMethod ?
1004                            n.callMethod.apply(n, arguments) : n.queue.push(arguments)
1005                    };
1006                    if (!f._fbq) f._fbq = n;
1007                    n.push = n;
1008                    n.loaded = !0;
1009                    n.version = '2.0';
1010                    n.agent = 'dvpixelyoursite';
1011                    n.queue = [];
1012                    t = b.createElement(e);
1013                    t.async = !0;
1014                    t.src = v;
1015                    s = b.getElementsByTagName(e)[0];
1016                    s.parentNode.insertBefore(t, s)
1017                }(window,
1018                    document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
1019
1020                // initialize pixel
1021                options.facebook.pixelIds.forEach(function (pixelId) {
1022
1023                    if (options.facebook.removeMetadata) {
1024                        fbq('set', 'autoConfig', false, pixelId);
1025                    }
1026                    if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
1027                        if(options.facebook.advancedMatching.length === 0) {
1028                            fbq('init', pixelId);
1029                        } else {
1030                            var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix);
1031                            if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) {
1032                                if (cs_advanced_matching == 'yes') {
1033                                    fbq('init', pixelId, options.facebook.advancedMatching);
1034                                } else {
1035                                    fbq('init', pixelId);
1036                                }
1037                            } else {
1038                                fbq('init', pixelId, options.facebook.advancedMatching);
1039                            }
1040                        }
1041                    } else {
1042                        if (options.facebook.advancedMatching.length === 0) {
1043                            fbq('init', pixelId);
1044                        } else {
1045                            fbq('init', pixelId, options.facebook.advancedMatching);
1046                        }
1047                    }
1048                });
1049
1050                initialized = true;
1051
1052                Utils.fireStaticEvents('facebook');
1053
1054            },
1055
1056            fireEvent: function (name, data) {
1057
1058                if (!initialized || !this.isEnabled()) {
1059                    return false;
1060                }
1061
1062                data.delay = data.delay || 0;
1063                data.params = data.params || {};
1064
1065                if (data.delay === 0) {
1066
1067                    fireEvent(name, data);
1068
1069                } else {
1070
1071                    setTimeout(function (name, params) {
1072                        fireEvent(name, params);
1073                    }, data.delay * 1000, name, data);
1074
1075                }
1076
1077                return true;
1078
1079            },
1080
1081            onCommentEvent: function (event) {
1082                this.fireEvent(event.name, event);
1083            },
1084
1085            onDownloadEvent: function (event) {
1086                this.fireEvent(event.name, event);
1087            },
1088
1089            onFormEvent: function (event) {
1090
1091                this.fireEvent(event.name, event);
1092
1093            },
1094
1095            onWooAddToCartOnButtonEvent: function (product_id) {
1096
1097                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1098                    return;
1099                var event = options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()];
1100
1101                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1102                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
1103                        event = Utils.copyProperties(event, {})
1104                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params)
1105                        this.fireEvent(event.name, event);
1106                    }
1107                }
1108            },
1109
1110            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
1111
1112                window.pysWooProductData = window.pysWooProductData || [];
1113                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1114                    return;
1115                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
1116
1117                if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) {
1118                    product_id = parseInt($form.find('input[name="variation_id"]').val());
1119                }
1120
1121                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1122                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
1123
1124
1125                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook'].params, event.params);
1126
1127                        var groupValue = 0;
1128                        if(product_type === Utils.PRODUCT_GROUPED ) {
1129                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
1130                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
1131                                var quantity = parseInt($(this).val());
1132                                if(isNaN(quantity)) {
1133                                    quantity = 0;
1134                                }
1135                                var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId];
1136
1137                                if(quantity == 0) {
1138                                    event.params.content_ids.forEach(function(el,index,array) {
1139                                        if(el == childItem.content_id) {
1140                                            array.splice(index, 1);
1141                                        }
1142                                    });
1143                                }
1144
1145                                if(event.params.hasOwnProperty('contents')) {
1146                                    event.params.contents.forEach(function(el,index,array) {
1147                                        if(el.id == childItem.content_id) {
1148                                            if(quantity > 0){
1149                                                el.quantity = quantity;
1150                                            } else {
1151                                                array.splice(index, 1);
1152                                            }
1153                                        }
1154                                    });
1155                                }
1156
1157
1158                                groupValue += childItem.price * quantity;
1159                            });
1160                            if(groupValue == 0) return;
1160 // skip if no items selected
1161                        }
1162
1163                        // maybe customize value option
1164                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
1165
1166                            if(product_type === Utils.PRODUCT_GROUPED) {
1167                                event.params.value = groupValue;
1168                            } else if(product_type === Utils.PRODUCT_BUNDLE) {
1169                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
1170                                var items_sum = getBundlePriceOnSingleProduct(data);
1171                                event.params.value = (data.base_price+items_sum )* qty;
1172                            } else {
1173                                event.params.value = event.params.value * qty;
1174                            }
1175                        }
1176
1177                        // only when non Facebook for WooCommerce logic used
1178                        if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) {
1179                            event.params.contents[0].quantity = qty;
1180                        }
1181
1182                        this.fireEvent(event.name, event);
1183
1184                    }
1185                }
1186            },
1187
1188            onWooRemoveFromCartEvent: function (event) {
1189                this.fireEvent(event.name, event);
1190            },
1191
1192            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
1193
1194                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1195                    return;
1196                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
1197
1198                if (window.pysEddProductData.hasOwnProperty(download_id)) {
1199
1200                    var index;
1201
1202                    if (price_index) {
1203                        index = download_id + '_' + price_index;
1204                    } else {
1205                        index = download_id;
1206                    }
1207
1208                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
1209                        if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) {
1210
1211
1212                            Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params)
1213
1214                            // maybe customize value option
1215                            if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') {
1216                                event.params.value = event.params.value * qty;
1217                            }
1218
1219                            // update contents qty param
1220                            var contents = event.params.contents;
1221                            contents[0].quantity = qty;
1222                            event.params.contents = contents;
1223
1224                            this.fireEvent(event.name,event);
1225
1226                        }
1227                    }
1228
1229                }
1230
1231            },
1232
1233            onEddRemoveFromCartEvent: function (event) {
1234                this.fireEvent(event.name, event);
1235            },
1236            onPageScroll: function (event) {
1237                this.fireEvent(event.name, event);
1238            },
1239            onTime: function (event) {
1240                this.fireEvent(event.name, event);
1241            },
1242
1243
1244        };
1245
1246    }(options);
1247
1248    var Analytics = function (options) {
1249
1250        var initialized = false;
1251
1252        /**
1253         * Fires event
1254         *
1255         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
1256         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
1257         * @link: https://developers.google.com/gtagjs/reference/event
1258         * @link: https://developers.google.com/gtagjs/reference/parameter
1259         *
1260         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
1261         *
1262         * @param name
1263         * @param data
1264         */
1265        function fireEvent(name, data) {
1266
1267            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) {
1268                return;
1269            }
1270
1271            var eventParams = Utils.copyProperties(data, {});
1272
1273            var _fireEvent = function (tracking_id) {
1274
1275                var params = Utils.copyProperties(eventParams, {send_to: tracking_id});
1276
1277                if (options.debug) {
1278                    console.log('[Google Analytics #' + tracking_id + '] ' + name, params);
1279                }
1280
1281                gtag('event', name, params);
1282
1283            };
1284
1285            options.ga.trackingIds.forEach(function (tracking_id) {
1286                _fireEvent(tracking_id);
1287            });
1288
1289        }
1290
1291        /**
1292         * Public API
1293         */
1294        return {
1295            tag: function() {
1296                return "ga";
1297            },
1298            isEnabled: function () {
1299                return options.hasOwnProperty('ga');
1300            },
1301
1302            disable: function () {
1303                initialized = false;
1304            },
1305
1306            loadPixel: function () {
1307
1308                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
1309                    return;
1310                }
1311
1312                Utils.loadGoogleTag(options.ga.trackingIds[0]);
1313
1314                var config = {
1315                    'link_attribution': options.ga.enhanceLinkAttr,
1316                    'anonymize_ip': options.ga.anonimizeIP
1317                };
1318
1319                // Cross-Domain tracking
1320                if (options.ga.crossDomainEnabled) {
1321                    config.linker = {
1322                        accept_incoming: options.ga.crossDomainAcceptIncoming,
1323                        domains: options.ga.crossDomainDomains
1324                    };
1325                }
1326
1327                if(options.ga.isUse4Version) {
1328                    if(options.ga.disableAdvertisingFeatures) {
1329                        config.allow_google_signals = false
1330                    }
1331                    if(options.ga.disableAdvertisingPersonalization) {
1332                        config.allow_ad_personalization_signals = false
1333                    }
1334                }
1335
1336                // configure tracking ids
1337                options.ga.trackingIds.forEach(function (trackingId,index) {
1338                    if(options.ga.isDebugEnabled.includes("index_"+index)) {
1339                        config.debug_mode = true;
1340                    } else {
1341                        config.debug_mode = false;
1342                    }
1343                    gtag('config', trackingId, config);
1344                });
1345
1346                initialized = true;
1347
1348                Utils.fireStaticEvents('ga');
1349
1350            },
1351
1352            fireEvent: function (name, data) {
1353
1354                if (!initialized || !this.isEnabled()) {
1355                    return false;
1356                }
1357
1358                data.delay = data.delay || 0;
1359                data.params = data.params || {};
1360
1361                if (data.delay === 0) {
1362
1363                    fireEvent(name, data.params);
1364
1365                } else {
1366
1367                    setTimeout(function (name, params) {
1368                        fireEvent(name, params);
1369                    }, data.delay * 1000, name, data.params);
1370
1371                }
1372
1373                return true;
1374
1375            },
1376
1377            onCommentEvent: function (event) {
1378
1379                if (initialized && this.isEnabled() ) {
1380                    if(options.ga.isUse4Version) {
1381                        this.fireEvent(event.name, event);
1382                    } else {
1383                        this.fireEvent(event.name, {
1384                            params: {
1385                                event_category: event.name,
1386                                event_action: event.params.event_action,
1387                                event_label: document.location.href,
1388                                non_interaction: event.params.non_interaction,
1389                                event_day:event.params.event_day,
1390                                event_hour:event.params.event_hour,
1391                                event_month:event.params.event_month,
1392                                traffic_source:event.params.traffic_source,
1393                            }
1394                        });
1395                    }
1396                }
1397
1398
1399            },
1400
1401            onDownloadEvent: function (event) {
1402
1403                if (initialized && this.isEnabled() ) {
1404                    if(options.ga.isUse4Version) {
1405                        this.fireEvent(event.name, event);
1406                    } else {
1407                        var params = {
1408                            event_category: event.name,
1409                            event_action: event.params.event_action,
1410                            event_label:event.params.download_name,
1411                            non_interaction: event.params.non_interaction,
1412                        };
1413                        this.fireEvent(event.name, {
1414                            params: params
1415                        });
1416                    }
1417                }
1418            },
1419
1420            onFormEvent: function (event) {
1421
1422                if (initialized && this.isEnabled() ) {
1423
1424                    if(options.ga.isUse4Version) {
1425                        this.fireEvent(event.name, event);
1426                    } else {
1427                        var params = {
1428                            event_category: event.name,
1429                            event_action: event.params.event_action,
1430                            non_interaction: event.params.non_interaction,
1431                            event_day:event.params.event_day,
1432                            event_hour:event.params.event_hour,
1433                            event_month:event.params.event_month,
1434                            traffic_source:event.params.traffic_source,
1435                        };
1436                        var formClass = (typeof event.params.form_class != 'undefined') ? 'class: ' + event.params.form_class : '';
1437                        if(formClass != "") {
1438                            params["event_label"] = formClass;
1439                        }
1440                        this.fireEvent(event.name, {
1441                            params: params
1442                        });
1443                    }
1444                }
1445
1446
1447            },
1448
1449            onWooAddToCartOnButtonEvent: function (product_id) {
1450
1451                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1452                    return;
1453                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
1454
1455                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1456                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
1457                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params)
1458                        this.fireEvent(event.name, event);
1459                    }
1460                }
1461
1462
1463            },
1464
1465            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, $form) {
1466
1467                window.pysWooProductData = window.pysWooProductData || [];
1468
1469                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1470                    return;
1471                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
1472
1473                if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) {
1474                    product_id = parseInt($form.find('input[name="variation_id"]').val());
1475                }
1476
1477                if (window.pysWooProductData.hasOwnProperty(product_id)) {
1478                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
1479
1480                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params);
1481                        if(product_type === Utils.PRODUCT_GROUPED ) {
1482                            var groupValue = 0;
1483                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
1484                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
1485                                var quantity = parseInt($(this).val());
1486                                if(isNaN(quantity)) {
1487                                    quantity = 0;
1488                                }
1489                                var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
1490
1491                                if(options.woo.addToCartOnButtonValueEnabled &&
1492                                    options.woo.addToCartOnButtonValueOption !== 'global') {
1493
1494                                    event.params.items.forEach(function(el,index,array) {
1495                                        if(el.id == childItem.content_id) {
1496                                            if(quantity > 0){
1497                                                el.quantity = quantity;
1498                                                el.price = childItem.price * quantity;
1499                                            } else {
1500                                                array.splice(index, 1);
1501                                            }
1502                                        }
1503                                    });
1504
1505                                }
1506                                groupValue += childItem.price * quantity;
1507                            });
1508
1509                            if(groupValue == 0) return; // skip if no items selected
1510                        } else {
1511                            // update items qty param
1512                            event.params.items[0].quantity = qty;
1513                        }
1514
1515                        // maybe customize value option
1516                        if (options.woo.addToCartOnButtonValueEnabled &&
1517                            options.woo.addToCartOnButtonValueOption !== 'global' &&
1518                            product_type !== Utils.PRODUCT_GROUPED)
1519                        {
1520                            if(product_type === Utils.PRODUCT_BUNDLE) {
1521                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
1522                                var items_sum = getBundlePriceOnSingleProduct(data);
1523                                event.params.items[0].price = (data.base_price+items_sum )* qty;
1524                            } else {
1525                                event.params.items[0].price = event.params.items[0].price * qty;
1526                            }
1527
1528                        }
1529
1530
1531                        this.fireEvent(event.name, event);
1532                    }
1533                }
1534
1535            },
1536
1537            onWooRemoveFromCartEvent: function (event) {
1538
1539                this.fireEvent(event.name, event);
1540
1541            },
1542
1543            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
1544
1545                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
1546                    return;
1547                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
1548
1549
1550                if (window.pysEddProductData.hasOwnProperty(download_id)) {
1551
1552                    var index;
1553
1554                    if (price_index) {
1555                        index = download_id + '_' + price_index;
1556                    } else {
1557                        index = download_id;
1558                    }
1559
1560                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
1561                        if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) {
1562
1563                            Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params);
1564
1565                            // update items qty param
1566                            event.params.items[0].quantity = qty;
1567
1568                            this.fireEvent(event.name,event);
1569
1570                        }
1571                    }
1572
1573                }
1574
1575            },
1576
1577            onEddRemoveFromCartEvent: function (event) {
1578                this.fireEvent(event.name, event);
1579            },
1580            onPageScroll: function (event) {
1581                this.fireEvent(event.name, event);
1582            },
1583            onTime: function (event) {
1584                this.fireEvent(event.name, event);
1585            },
1586
1587        };
1588
1589    }(options);
1590
1591    window.pys = window.pys || {};
1592    window.pys.Facebook = Facebook;
1593    window.pys.Analytics = Analytics;
1594    window.pys.Utils = Utils;
1595
1596    function getPixelBySlag(slug) {
1597        switch (slug) {
1598            case "facebook": return window.pys.Facebook;
1599            case "ga": return window.pys.Analytics;
1600            case "bing": return window.pys.Bing;
1601            case "pinterest": return window.pys.Pinterest;
1602        }
1603    }
1604
1605
1606    $(document).ready(function () {
1607
1608        var Pinterest = Utils.setupPinterestObject();
1609        var Bing = Utils.setupBingObject();
1610
1611        Utils.setupGdprCallbacks();
1612        // page scroll event
1613        if (options.dynamicEvents.hasOwnProperty("signal_page_scroll")) {
1614
1615            var singlePageScroll = function () {
1616
1617
1618                var docHeight = $(document).height() - $(window).height();
1619                var isFired = false;
1620                var pixels = Object.keys(options.dynamicEvents.signal_page_scroll);
1621
1622                for(var i = 0;i<pixels.length;i++) {
1623                    var event = Utils.clone(options.dynamicEvents.signal_page_scroll[pixels[i]]);
1624                    var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions
1625
1626                    if(scroll < $(window).scrollTop()) {
1627                        Utils.copyProperties(Utils.getRequestParams(), event.params);
1628                        getPixelBySlag(pixels[i]).onPageScroll(event);
1629                        isFired = true
1630                    }
1631                }
1632                if(isFired) {
1633                    $(document).off("scroll",singlePageScroll);
1634                }
1635            }
1636            $(document).on("scroll",singlePageScroll);
1637        }
1638        // page on time
1639        if (options.dynamicEvents.hasOwnProperty("signal_time_on_page")) {
1640            var pixels = Object.keys(options.dynamicEvents.signal_time_on_page);
1641            var time = options.dynamicEvents.signal_time_on_page[pixels[0]].time_on_page; // the same for all pixel
1642            setTimeout(function(){
1643                for(var i = 0;i<pixels.length;i++) {
1644                    var event = Utils.clone(options.dynamicEvents.signal_time_on_page[pixels[i]]);
1645                    Utils.copyProperties(Utils.getRequestParams(), event.params);
1646                    getPixelBySlag(pixels[i]).onTime(event);
1647                }
1648            },time*1000);
1649        }
1650
1651        // setup Click Event
1652        if (options.dynamicEvents.hasOwnProperty("signal_download")) {
1653
1654            $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) {
1655
1656                var $elem = $(this);
1657
1658                // Download
1659                if (options.dynamicEvents.hasOwnProperty("signal_download")) {
1660                    var isFired = false;
1661                    if ($elem.is('a')) {
1662                        var href = $elem.attr('href');
1663                        if (typeof href !== "string") {
1664                            return;
1665                        }
1666                        href = href.trim();
1667                        var extension = Utils.getLinkExtension(href);
1668                        var track_download = false;
1669
1670                        if (extension.length > 0) {
1671                            var pixels = Object.keys(options.dynamicEvents.signal_download);
1672                            for (var i = 0; i < pixels.length; i++) {
1673                                var event = Utils.clone(options.dynamicEvents.signal_download[pixels[i]]);
1674                                var extensions = event.extensions;
1675                                if (extensions.includes(extension)) {
1676                                    if(options.enable_remove_download_url_param) {
1677                                        href = href.split('?')[0];
1678                                    }
1679                                    event.params.download_url = href;
1680                                    event.params.download_type = extension;
1681                                    event.params.download_name = Utils.getLinkFilename(href);
1682
1683                                    getPixelBySlag(pixels[i]).onDownloadEvent(event);
1684                                    isFired = true;
1685                                }
1686                            }
1687                        }
1688                    }
1689                    if (isFired) { // prevent duplicate events on the same element
1690                        return;
1691                    }
1692                }
1693            });
1694        }
1695
1696
1697        // setup Dynamic events
1698        $.each(options.triggerEventTypes, function (triggerType, events) {
1699
1700            $.each(events, function (eventId, triggers) {
1701
1702                switch (triggerType) {
1703                    case 'url_click':
1704                        //@see: Utils.setupURLClickEvents()
1705                        break;
1706
1707                    case 'css_click':
1708                        Utils.setupCSSClickEvents(eventId, triggers);
1709                        break;
1710
1711                    case 'css_mouseover':
1712                        Utils.setupMouseOverClickEvents(eventId, triggers);
1713                        break;
1714
1715                    case 'scroll_pos':
1716                        Utils.setupScrollPosEvents(eventId, triggers);
1717                        break;
1718                    case 'comment':
1719                        Utils.setupCommentEvents(eventId, triggers);
1720                        break;
1721                }
1722
1723            });
1724
1725        });
1726        // setup WooCommerce events
1727        if (options.woo.enabled) {
1728
1729            // WooCommerce AddToCart
1730            if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")) {
1731
1732                // Loop, any kind of "simple" product, except external
1733                $('.add_to_cart_button:not(.product_type_variable,.single_add_to_cart_button)').on("click",function (e) {
1734
1735                    var product_id = $(this).data('product_id');
1736
1737                    if (typeof product_id !== 'undefined') {
1738                        Facebook.onWooAddToCartOnButtonEvent(product_id);
1739                        Analytics.onWooAddToCartOnButtonEvent(product_id);
1740                        Pinterest.onWooAddToCartOnButtonEvent(product_id);
1741                        Bing.onWooAddToCartOnButtonEvent(product_id);
1742                    }
1743
1744                });
1745
1746                // Single Product
1747                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
1748                $(document).onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
1749
1750                    var $button = $(this);
1751
1752                    if ($button.hasClass('disabled')) {
1753                        return;
1754                    }
1755
1756                    var $form = $button.closest('form');
1757
1758                    var product_type = Utils.PRODUCT_SIMPLE;
1759
1760                    if ($form.length === 0) {
1761                        return ;
1762                    } else if ($form.hasClass('variations_form')) {
1763                        product_type = Utils.PRODUCT_VARIABLE;
1764                    } else if($form.hasClass('bundle_form')) {
1765                        product_type = Utils.PRODUCT_BUNDLE;
1766                    } else if($form.hasClass('grouped_form')) {
1767                        product_type = Utils.PRODUCT_GROUPED;
1768                    }
1769
1770
1771
1772
1773                    var product_id;
1774                    var qty;
1775
1776                    if (product_type === Utils.PRODUCT_GROUPED) {
1777                        qty = 1;
1778                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
1779                    } else if (product_type === Utils.PRODUCT_VARIABLE) {
1780                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
1781                        var qtyTag = $form.find('input[name="quantity"]');
1782                        if(qtyTag.length <= 0) {
1783                            qtyTag = $form.find('select[name="quantity"]');
1784                        }
1785                        qty = parseInt(qtyTag.val());
1786                    } else {
1787                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
1788                        var qtyTag = $form.find('input[name="quantity"]');
1789                        if(qtyTag.length <= 0) {
1790                            qtyTag = $form.find('select[name="quantity"]');
1791                        }
1792                        qty = parseInt(qtyTag.val());
1793                    }
1794
1795                    Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
1796                    Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, $form);
1797
1798                    Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
1799                    Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, false, $form);
1800
1801                });
1802
1803            }
1804
1805            // WooCommerce RemoveFromCart
1806            if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) {
1807
1808                $('body').on('click', options.woo.removeFromCartSelector, function (e) {
1809
1810                    var $a = $(e.currentTarget),
1811                        href = $a.attr('href');
1812
1813                    // extract cart item hash from remove button URL
1814                    var regex = new RegExp("[\\?&]remove_item=([^&#]*)"),
1815                        results = regex.exec(href);
1816
1817                    if (results !== null) {
1818
1819                        var item_hash = results[1];
1820
1821                        if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) {
1822                            var events = options.dynamicEvents["woo_remove_from_cart"][item_hash];
1823                            Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events)
1824                        }
1825
1826                    }
1827
1828                });
1829            }
1830        }
1831
1832        // setup EDD events
1833        if (options.edd.enabled) {
1834
1835            // EDD AddToCart
1836            if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) {
1837
1838                $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) {
1839
1840                    var $button = $(this);
1841                    var $form = $button.closest('form');
1842                    var variable_price = $button.data('variablePrice'); // yes/no
1843                    var price_mode = $button.data('priceMode'); // single/multi
1844                    var ids = [];
1845                    var quantities = [];
1846                    var qty;
1847                    var id;
1848
1849                    if (variable_price === 'yes' && price_mode === 'multi') {
1850
1851                        id = $form.find('input[name="download_id"]').val();
1852
1853                        // get selected variants
1854                        $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) {
1855                            ids.push(id + '_' + $(el).val());
1856                        });
1857
1858                        // get qty for selected variants
1859                        $.each(ids, function (i, variant_id) {
1860
1861                            var variant_index = variant_id.split('_', 2);
1862                            qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val();
1863
1864                            if (typeof qty !== 'undefined') {
1865                                quantities.push(qty);
1866                            } else {
1867                                quantities.push(1);
1868                            }
1869
1870                        });
1871
1872                    } else if (variable_price === 'yes' && price_mode === 'single') {
1873
1874                        id = $form.find('input[name="download_id"]').val();
1875                        ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val());
1876
1877                        qty = $form.find('input[name="edd_download_quantity"]').val();
1878
1879                        if (typeof qty !== 'undefined') {
1880                            quantities.push(qty);
1881                        } else {
1882                            quantities.push(1);
1883                        }
1884
1885                    } else {
1886
1887                        ids.push($button.data('downloadId'));
1888
1889                        qty = $form.find('input[name="edd_download_quantity"]').val();
1890
1891                        if (typeof qty !== 'undefined') {
1892                            quantities.push(qty);
1893                        } else {
1894                            quantities.push(1);
1895                        }
1896                    }
1897
1898                    // fire event for each download/variant
1899                    $.each(ids, function (i, download_id) {
1900
1901                        var q = parseInt(quantities[i]);
1902                        var variant_index = download_id.toString().split('_', 2);
1903                        var price_index;
1904
1905                        if (variant_index.length === 2) {
1906                            download_id = variant_index[0];
1907                            price_index = variant_index[1];
1908                        }
1909
1910                        Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q);
1911                        Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q);
1912                        Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q);
1913                        Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q);
1914
1915                    });
1916
1917                });
1918
1919            }
1920
1921
1922            // EDD RemoveFromCart
1923            if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) {
1924
1925                $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) {
1926
1927                    var href = $(this).attr('href');
1928                    var key = href.substring(href.indexOf('=') + 1).charAt(0);
1929
1930                    if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) {
1931                        var events = options.dynamicEvents.edd_remove_from_cart[key];
1932                        Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events)
1933                    }
1934
1935                });
1936
1937            }
1938
1939        }
1940
1941        // setup Comment Event
1942        if (options.dynamicEvents.hasOwnProperty("signal_comment")) {
1943
1944            $('form.comment-form').on("submit",function () {
1945
1946                var pixels = Object.keys(options.dynamicEvents.signal_comment);
1947                for(var i = 0;i<pixels.length;i++) {
1948                    var event = Utils.clone(options.dynamicEvents.signal_comment[pixels[i]]);
1949                    Utils.copyProperties(Utils.getRequestParams(), event.params);
1950                    getPixelBySlag(pixels[i]).onCommentEvent(event);
1951                }
1952            });
1953
1954        }
1955
1956
1957        // setup Form Event
1958        if ( options.dynamicEvents.hasOwnProperty("signal_form")) {
1959
1960            $(document).onFirst('submit', 'form', function (e) {
1961
1962                var $form = $(this);
1963
1964                // exclude WP forms
1965                if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') {
1966                    return;
1967                }
1968
1969                // exclude Woo forms
1970                if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') ||
1971                    $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) {
1972                    return;
1973                }
1974
1975                // exclude EDD forms
1976                if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) {
1977                    return;
1978                }
1979
1980                var params = {
1981                    form_id: $form.attr('id'),
1982                    form_class: $form.attr('class'),
1983                    text: $form.find('[type="submit"]').is('input') ?
1984                        $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text()
1985                };
1986                var pixels = Object.keys(options.dynamicEvents.signal_form);
1987                for(var i = 0;i<pixels.length;i++) {
1988                    var event = Utils.clone(options.dynamicEvents.signal_form[pixels[i]]);
1989                    Utils.copyProperties(params,event.params,)
1990                    Utils.copyProperties(Utils.getRequestParams(), event.params);
1991                    getPixelBySlag(pixels[i]).onFormEvent(event);
1992                }
1993            });
1994
1995            //Forminator
1996            $(document).on( 'forminator:form:submit:success', function( formData ){
1997                var params = {
1998                    form_id: $(formData.target).find('input[name="form_id"]').val(),
1999                    text: $(formData.target).find('.forminator-button-submit').text()
2000                };
2001
2002                var pixels = Object.keys(options.dynamicEvents.signal_form);
2003                for(var i = 0;i<pixels.length;i++) {
2004                    var event = Utils.clone(options.dynamicEvents.signal_form[pixels[i]]);
2005                    Utils.copyProperties(params,event.params)
2006                    Utils.copyProperties(Utils.getRequestParams(), event.params);
2007                    getPixelBySlag(pixels[i]).onFormEvent(event);
2008                }
2009            });
2010
2011            // Ninja Forms
2012            $(document).onFirst('nfFormSubmitResponse', function (e, data) {
2013
2014                var params = {
2015                    form_id: data.response.data.form_id,
2016                    text: data.response.data.settings.title
2017                };
2018
2019                var pixels = Object.keys(options.dynamicEvents.signal_form);
2020                for(var i = 0;i<pixels.length;i++) {
2021                    var event = Utils.clone(options.dynamicEvents.signal_form[pixels[i]]);
2022                    Utils.copyProperties(params,event.params)
2023                    Utils.copyProperties(Utils.getRequestParams(), event.params);
2024                    getPixelBySlag(pixels[i]).onFormEvent(event);
2025                }
2026
2027            });
2028
2029        }
2030
2031
2032        // load pixel APIs
2033        Utils.loadPixels();
2034
2035    });
2036
2037}(jQuery, pysOptions);
2038
2039function pys_generate_token(length){
2040    //edit the token allowed characters
2041    var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
2042    var b = [];
2043    for (var i=0; i<length; i++) {
2044        var j = (Math.random() * (a.length-1)).toFixed(0);
2045        b[i] = a[j];
2046    }
2047    return b.join("");
2048}
2049
2050function getBundlePriceOnSingleProduct(data) {
2051    var items_sum = 0;
2052    jQuery(".bundle_form .bundled_product").each(function(index){
2053        var id = jQuery(this).find(".cart").data("bundled_item_id");
2054        var item_price = data.prices[id];
2055        var item_quantity = jQuery(this).find(".bundled_qty").val();
2056        if(!jQuery(this).hasClass("bundled_item_optional") ||
2057            jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) {
2058            items_sum += item_price*item_quantity;
2059        }
2060    });
2061    return items_sum;
2062}

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.