PageSourceSearch

https://www.grafuk.co.uk/wp-content/plugins/pixelyoursite-pro/dist/scripts/public.js?ver=9.6.1

js grafuk.co.uk collected 2026-10-09 21:55:34 UTC 195,405 bytes, 4,807 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
56if (!String.prototype.startsWith) {
57    Object.defineProperty(String.prototype, 'startsWith', {
58        enumerable: false,
59        configurable: false,
60        writable: false,
61        value: function (searchString, position) {
62            position = position || 0;
63            return this.indexOf(searchString, position) === position;
64        }
65    });
66}
67
68if (!String.prototype.trim) {
69    (function () {
70        String.prototype.trim = function () {
71            return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
72        };
73    })();
74}
75
76! function ($, options) {
77
78    if (options.debug) {
79        console.log('PYS:', options);
80    }
81
82
83
84    var dummyPinterest = function () {
85
86        /**
87         * Public API
88         */
89        return {
90            tag: function() {
91                return "pinterest";
92            },
93            isEnabled: function () {},
94
95            disable: function () {},
96
97            loadPixel: function () {},
98
99            fireEvent: function (name, data) {
100                return false;
101            },
102
103            onAdSenseEvent: function (event) {},
104
105            onClickEvent: function (params) {},
106
107            onWatchVideo: function (params) {},
108
109            onCommentEvent: function (event) {},
110
111            onFormEvent: function (params) {},
112
113            onDownloadEvent: function (params) {},
114
115
116
117            onWooAddToCartOnButtonEvent: function (product_id) {},
118
119            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {},
120
121            onWooRemoveFromCartEvent: function (cart_item_hash) {},
122
123            onWooAffiliateEvent: function (product_id) {},
124
125            onWooPayPalEvent: function (event) {},
126
127            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
128
129            onEddRemoveFromCartEvent: function (item) {},
130
131            onPageScroll: function (event) {},
132            onTime: function (event) {
133
134            },
135
136        }
137
138    }();
139
140    var dummyBing = function () {
141
142        /**
143         * Public API
144         */
145        return {
146            tag: function() {
147                return "bing";
148            },
149            isEnabled: function () {},
150
151            disable: function () {},
152
153            loadPixel: function () {},
154
155            fireEvent: function (name, data) {
156                return false;
157            },
158
159            onAdSenseEvent: function (event) {},
160
161            onClickEvent: function (params) {},
162
163            onWatchVideo: function (params) {},
164
165            onCommentEvent: function (event) {},
166
167            onFormEvent: function (params) {},
168
169            onDownloadEvent: function (params) {},
170
171
172            onWooAddToCartOnButtonEvent: function (product_id) {},
173
174            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {},
175
176            onWooRemoveFromCartEvent: function (cart_item_hash) {},
177
178            onWooAffiliateEvent: function (product_id) {},
179
180            onWooPayPalEvent: function (event) {},
181
182            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
183
184            onEddRemoveFromCartEvent: function (item) {},
185            onPageScroll: function (event) {},
186            onTime: function (event) {
187
188            },
189        }
190
191    }();
192
193    var Utils = function (options) {
194
195
196        var Pinterest = dummyPinterest;
197
198        var Bing = dummyBing;
199
200        var gtag_loaded = false;
201        let isNewSession = checkSession();
202
203
204        function loadPixels() {
205
206            if (!options.gdpr.all_disabled_by_api) {
207                if (!options.gdpr.tiktok_disabled_by_api) {
208                    TikTok.loadPixel();
209                }
210
211                if (!options.gdpr.facebook_disabled_by_api) {
212                    Facebook.loadPixel();
213                }
214
215                if (!options.gdpr.analytics_disabled_by_api) {
216                    Analytics.loadPixel();
217                }
218
219                if (!options.gdpr.google_ads_disabled_by_api) {
220                    GAds.loadPixel();
221                }
222
223                if (!options.gdpr.pinterest_disabled_by_api) {
224                    Pinterest.loadPixel();
225                }
226
227                if (!options.gdpr.bing_disabled_by_api) {
228                    Bing.loadPixel();
229                }
230
231            }
232            if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
233                if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) {
234                    Analytics.loadPixel();
235                }
236
237                if (typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1 ) {
238                    GAds.loadPixel();
239                }
240            }
241
242
243        }
244
245        /**
246         * WATCHVIDEO UTILS
247         */
248
249        function isJSApiAttrEnabled(url) {
250            return url.indexOf('enablejsapi') > -1;
251        }
252
253        function isOriginAttrEnabled(url) {
254            return url.indexOf('origin') > -1;
255        }
256
257        // Returns key/value pairs of percentages: number of seconds to achieve
258        function getVideoCompletionMarks(duration) {
259
260            var marks = {};
261            var points = [0, 10, 50, 90, 100];
262
263            for (var i = 0; i < points.length; i++) {
264
265                var _point = points[i];
266                var _mark = _point + '%';
267                var _time = duration * _point / 100;
268
269                if (_point === 100) {
270                    _time = _time - 1;
271                }
272
273                // 10% => 123
274                marks[_mark] = Math.floor(_time);
275
276            }
277
278            return marks;
279
280        }
281
282        // Determine if the element is a YouTube video or not
283        function tagIsYouTubeVideo(tag) {
284            var src = tag.src || '';
285            return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1;
286        }
287
288        function tagIsYouTubeAsyncVideo(tag) {
289            if(tag.src && tag.src.indexOf("data:image") !== -1) return false; // video is loaded
290            var keys = Object.keys(tag.dataset);
291            for(var i = 0;i<keys.length;i++) {
292                if(keys[i].toLowerCase().indexOf("src") > -1) {
293                    var src = tag.dataset[keys[i]];
294                    return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1;
295                }
296            }
297            return false; //not find src
298        }
299
300        // Turn embed objects into iframe objects and ensure they have the right parameters
301        function normalizeYouTubeIframe(tag) {
302
303            var loc = window.location;
304            var a = document.createElement('a');
305            a.href = tag.src;
306            a.hostname = 'www.youtube.com';
307            a.protocol = loc.protocol;
308            var tmpPathname = a.pathname.charAt(0) === '/' ? a.pathname : '/' + a.pathname; // IE10 shim
309
310            if (!isJSApiAttrEnabled(a.search)) {
311                a.search = (a.search.length > 0 ? a.search + '&' : '') + 'enablejsapi=1';
312            }
313
314            // for security reasons, YouTube wants an origin parameter set that matches our hostname
315            if (!isOriginAttrEnabled(a.search) && loc.hostname.indexOf('localhost') === -1) {
316
317                var port = loc.port ? ':' + loc.port : '';
318                var origin = loc.protocol + '%2F%2F' + loc.hostname + port;
319
320                a.search = a.search + '&origin=' + origin;
321
322            }
323
324            if (tag.type === 'application/x-shockwave-flash') {
325
326                var newIframe = document.createElement('iframe');
327                newIframe.height = tag.height;
328                newIframe.width = tag.width;
329                tmpPathname = tmpPathname.replace('/v/', '/embed/');
330
331                tag.parentNode.parentNode.replaceChild(newIframe, tag.parentNode);
332
333                tag = newIframe;
334
335            }
336
337            a.pathname = tmpPathname;
338
339            if (tag.src !== a.href + a.hash) {
340                tag.src = a.href + a.hash;
341            }
342
343            return tag;
344
345        }
346
347        // Add event handlers for events emitted by the YouTube API
348        function addYouTubeEvents(iframe) {
349
350            var player = YT.get(iframe.id);
351
352            if (!player) {
353                player = new YT.Player(iframe, {});
354            }
355
356            if (typeof iframe.pauseFlag === 'undefined') {
357
358                iframe.pauseFlag = false;
359                player.addEventListener('onStateChange', function (evt) {
360                    onYouTubePlayerStateChange(evt, iframe);
361                });
362
363            }
364
365        }
366
367        function addDynYouTubeVideos(el) {
368            // We only bind to iFrames with a YouTube URL with the enablejsapi=1 and
369            // origin=<<hostname>> parameters
370            if (el.tagName === 'IFRAME'
371                && tagIsYouTubeVideo(el)
372                && isJSApiAttrEnabled(el.src)
373                && isOriginAttrEnabled(el.src))
374            {
375                addYouTubeEvents(el);
376            }
377        }
378
379        // Event handler for events emitted from the YouTube API
380        function onYouTubePlayerStateChange(evt, iframe) {
381
382            var stateIndex = evt.data;
383            var player = evt.target;
384            var targetVideoUrl = player.getVideoUrl();
385            var targetVideoId = targetVideoUrl.match(/[?&]v=([^&#]*)/)[1]; // Extract the ID
386            var playerState = player.getPlayerState();
387            var marks = getVideoCompletionMarks(player.getDuration());
388
389            iframe.playTracker = iframe.playTracker || {};
390
391            if (playerState === YT.PlayerState.PLAYING && !iframe.timer) {
392
393                clearInterval(iframe.timer);
394
395                // check every second to see if we've hit any of our percentage viewed marks
396                iframe.timer = setInterval(function () {
397                    checkYouTubeCompletion(player, marks, iframe.videoId);
398                }, 1000);
399
400            } else {
401
402                clearInterval(iframe.timer);
403                iframe.timer = false;
404
405            }
406
407            // playlist edge-case handler
408            if (stateIndex === YT.PlayerState.PLAYING) {
409                iframe.playTracker[targetVideoId] = true;
410                iframe.videoId = targetVideoId;
411                iframe.pauseFlag = false;
412            }
413
414            if (!iframe.playTracker[iframe.videoId]) {
415                return false; // this video hasn't started yet, so this is spam
416            }
417
418            if (stateIndex === YT.PlayerState.PAUSED) {
419
420                if (!iframe.pauseFlag) {
421                    iframe.pauseFlag = true;
422                } else {
423                    return false; // we don't want to fire consecutive pause events
424                }
425
426            }
427
428        }
429
430        // Trigger event if YouTube video mark was reached
431        function checkYouTubeCompletion(player, marks, videoId) {
432
433            var currentTime = player.getCurrentTime();
434
435            player[videoId] = player[videoId] || {};
436
437            for (var key in marks) {
438
439                if (marks[key] <= currentTime && !player[videoId][key]) {
440                    player[videoId][key] = true;
441
442                    var data = player.getVideoData();
443
444                    if (key === '0%') {
445                        key = 'play';
446                    }
447
448                    var params = {
449                        video_type: 'youtube',
450                        video_id: videoId,
451                        video_title: data.title,
452                    };
453
454                    // Auto
455                    if(options.automatic.enable_video
456                        && options.automatic.enable_youtube
457                        && options.dynamicEvents.hasOwnProperty("automatic_event_video")
458                    ) {
459                        var pixels = Object.keys(options.dynamicEvents.automatic_event_video);
460
461                        for (var i = 0; i < pixels.length; i++) {
462                            var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]);
463                            event.params["progress"] = key
464                            Utils.copyProperties(params, event.params)
465                            Utils.copyProperties(Utils.getRequestParam
465s(), event.params);
466                            getPixelBySlag(pixels[i]).onWatchVideo(event);
467                        }
468                    }
469
470                    if(key == "play") {
471
472                        $.each(options.triggerEventTypes, function (triggerType, events) {
473                            $.each(events, function (eventId, triggers) {
474                                switch (triggerType) {
475                                    case 'video_play':
476                                        Utils.fireTriggerEvent(eventId);
477                                        break;
478                                }
479
480                            });
481                        });
482                    }
483
484                }
485
486            }
487
488        }
489
490        // Determine if the element is a Vimeo video or not
491        function tagIsVimeoVideo(tag) {
492            var src = tag.src || '';
493            return src.indexOf('player.vimeo.com/video/') > -1;
494        }
495
496        function tagIsAsincVimeoVideo(tag) {
497            if(tag.src) return false; // video is loaded
498            var keys = Object.keys(tag.dataset);
499            for(var i = 0;i<keys.length;i++) {
500                if(keys[i].toLowerCase().indexOf("src") > -1) {
501                    var src = tag.dataset[keys[i]];
502                    return src.indexOf('player.vimeo.com/video/') > -1;
503                }
504            }
505            return false; //not find src
506        }
507
508        function attachVimeoPlayerToTag(tag) {
509            var player = new Vimeo.Player(tag);
510
511            player.getDuration().then(function (pl,seconds) {
512                pl.pysMarks = getVideoCompletionMarks(seconds);
513            }.bind(null,player));
514
515            player.getVideoTitle().then(function (pl,title) {
516                pl.pysVideoTitle = title;
517            }.bind(null,player));
518
519            player.getVideoId().then(function (pl,id) {
520                pl.pysVideoId = id;
521            }.bind(null,player));
522
523            player.pysCompletedMarks = {};
524
525            player.on('play', function () {
526
527                if (this.pysTimer) {
528                    return;
529                }
530
531                clearInterval(this.pysTimer);
532
533                var player = this;
534
535                this.pysTimer = setInterval(function () {
536                    checkVimeoCompletion(player);
537                }, 1000);
538
539            });
540
541            player.on('pause', function () {
542                clearInterval(this.pysTimer);
543                this.pysTimer = false;
544            });
545
546            player.on('ended', function () {
547                clearInterval(this.pysTimer);
548                this.pysTimer = false;
549            });
550        }
551
552        // Trigger event if Vimeo video mark was reached
553        function checkVimeoCompletion(player) {
554
555            player.getCurrentTime().then(function (seconds) {
556
557                for (var key in player.pysMarks) {
558
559                    if (player.pysMarks[key] <= seconds && !player.pysCompletedMarks[key]) {
560
561                        player.pysCompletedMarks[key] = true;
562
563                        if (key === '0%') {
564                            key = 'play';
565                        }
566
567                        var params = {
568                            video_type: 'vimeo',
569                            video_id: player.pysVideoId,
570                            video_title: player.pysVideoTitle,
571                        };
572
573                        // Auto
574                        if(options.automatic.enable_video
575                            && options.automatic.enable_vimeo
576                            && options.dynamicEvents.hasOwnProperty("automatic_event_video")
577                        ) {
578                            var pixels = Object.keys(options.dynamicEvents.automatic_event_video);
579
580                            for (var i = 0; i < pixels.length; i++) {
581                                var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]);
582                                event.params["progress"] = key
583                                Utils.copyProperties(params, event.params,);
584                                Utils.copyProperties(Utils.getRequestParam
584s(), event.params);
585                                getPixelBySlag(pixels[i]).onWatchVideo(event);
586                            }
587                        }
588
589                        if(key == "play") {
590                            $.each(options.triggerEventTypes, function (triggerType, events) {
591                                $.each(events, function (eventId, triggers) {
592                                    switch (triggerType) {
593                                        case 'video_play':
594                                            Utils.fireTriggerEvent(eventId);
595                                            break;
596                                    }
597
598                                });
599                            });
600                        }
601                    }
602
603                }
604
605            });
606
607        }
608
609        /**
610         * COOKIES UTILS
611         */
612
613        var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content' ,'utm_term'];
614        var utmId = ['fbadid', 'gadid', 'padid', 'bingid'];
615        var requestParams = [];
616
617
618        function getDomain(url) {
619
620            url = url.replace(/(https?:\/\/)?(www.)?/i, '');
621
622            if (url.indexOf('/') !== -1) {
623                return url.split('/')[0];
624            }
625
626            return url;
627        }
628
629        function checkSession() {
630            let duration = options.last_visit_duration * 60000
631            if( Cookies.get('pys_start_session') === undefined ||
632                Cookies.get('pys_session_limit') === undefined) {
633                var now = new Date();
634                now.setTime(now.getTime() + duration);
635                Cookies.set('pys_session_limit', true,{ expires: now })
636                Cookies.set('pys_start_session', true)
637                return true
638            }
639            return false
640
641        }
642
643        function getTrafficSource() {
644
645            try {
646
647                let referrer = document.referrer.toString(),
648                    source;
649
650                let direct = referrer.length === 0;
651                let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0;
652                let external = !direct && !internal;
653
654                if (external === false) {
655                    source = 'direct';
656                } else {
657                    source = referrer;
658                }
659
660                if (source !== 'direct') {
661                    // leave only domain (Issue #70)
662                    return getDomain(source);
663                } else {
664                    return source;
665                }
666
667            } catch (e) {
668                console.error(e);
669                return 'direct';
670            }
671
672        }
673
674        /**
675         * Return query variables object with where property name is query variable
676         * and property value is query variable value.
677         */
678        function getQueryVars() {
679
680            try {
681
682                var result = {},
683                    tmp = [];
684
685                window.location.search
686                    .substr(1)
687                    .split("&")
688                    .forEach(function (item) {
689
690                        tmp = item.split('=');
691
692                        if (tmp.length > 1) {
693                            result[tmp[0]] = tmp[1];
694                        }
695
696                    });
697
698                return result;
699
700            } catch (e) {
701                console.error(e);
702                return {};
703            }
704
705        }
706
707        function getLandingPageValue() {
708            let name = "pys_landing_page"
709            if(options.visit_data_model === "last_visit") {
710                name = "last_pys_landing_page"
711            }
712            if(Cookies.get(name) === 'undefined') {
713                return "";
714            } else {
715                return Cookies.get(name);
716            }
717        }
718        function getTrafficSourceValue() {
719            let name = "pysTrafficSource"
720            if(options.visit_data_model === "last_visit") {
721                name = "last_pysTrafficSource"
722            }
723            if(Cookies.get(name) === 'undefined') {
724                return "";
725            } else {
726                return Cookies.get(name);
727            }
728        }
729
730        function getUTMId(useLast = false) {
731            try {
732                let cookiePrefix = 'pys_'
733                let terms = [];
734                if (useLast) {
735                    cookiePrefix = 'last_pys_'
736                }
737                $.each(utmId, function (index, name) {
738                    if (Cookies.get(cookiePrefix + name)) {
739                        terms[name] = Cookies.get(cookiePrefix + name)
740                    }
741                });
742                return terms;
743            } catch (e) {
744                console.error(e);
745                return [];
746            }
747        }
748        /**
749         * Return UTM terms from request query variables or from cookies.
750         */
751        function getUTMs(useLast = false) {
752
753            try {
754                let cookiePrefix = 'pys_'
755                if(useLast) {
756                    cookiePrefix = 'last_pys_'
757                }
758                let terms = [];
759                $.each(utmTerms, function (index, name) {
760                    if (Cookies.get(cookiePrefix + name)) {
761                        let value = Cookies.get(cookiePrefix + name);
762                        terms[name] = filterEmails(value); // do not allow email in request params (Issue #70)
763                    }
764                });
765
766                return terms;
767
768            } catch (e) {
769                console.error(e);
770                return [];
771            }
772
773        }
774
775        function getDateTime() {
776            var dateTime = new Array();
777            var date = new Date(),
778                days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
779                months = ['January', 'February', 'March', 'April', 'May', 'June',
780                    'July', 'August', 'September', 'October', 'November', 'December'
781                ],
782                hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08',
783                    '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17',
784                    '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24'
785                ];
786            dateTime.push(hours[date.getHours()]);
787            dateTime.push(days[date.getDay()]);
788            dateTime.push(months[date.getMonth()]);
789            return dateTime;
790        }
791
792        function filterEmails(value) {
793            return Utils.validateEmail(value) ? undefined : value;
794        }
795
796        /**
797         * PUBLIC API
798         */
799        return {
800
801            PRODUCT_SIMPLE : 0,
802            PRODUCT_VARIABLE : 1,
803            PRODUCT_BUNDLE : 2,
804            PRODUCT_GROUPED : 3,
805
806            validateEmail: function (email) {
807                var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
808                return re.test(email);
809            },
810             fireEventForAllPixel:function(functionName,events){
811                if (events.hasOwnProperty(Facebook.tag()))
812                    Facebook[functionName](events[Facebook.tag()]);
813                if (events.hasOwnProperty(Analytics.tag()))
814                    Analytics[functionName](events[Analytics.tag()]);
815                if (events.hasOwnProperty(GAds.tag()))
816                    GAds[functionName](events[GAds.tag()]);
817                if (events.hasOwnProperty(Pinterest.tag()))
818                    Pinterest[functionName](events[Pinterest.tag()]);
819                if (events.hasOwnProperty(Bing.tag()))
820                    Bing[functionName](events[Bing.tag()]);
821                 if (events.hasOwnProperty(TikTok.tag()))
822                     TikTok[functionName](events[TikTok.tag()]);
823            },
824
825            getQueryValue:function (name){
826                return getQueryVars()[name];
827            },
828
829            filterEmails: function (value) {
830                return filterEmails(value);
831            },
832
833            setupPinterestObject: function () {
834                Pinterest = window.pys.Pinterest || Pinterest;
835                return Pinterest;
836            },
837
838            setupBingObject: function () {
839                Bing = window.pys.Bing || Bing;
840                return Bing;
841            },
842
843            // Clone all object members to another and return it
844            copyProperties: function (from, to) {
845                for (var key in from) {
846                    if("function" == typeof from[key]) {
847                        continue;
848                    }
849                    to[key] = from[key];
850                }
851                return to;
852            },
853
854            clone: function(obj) {
855                var copy;
856
857                // Handle the 3 simple types, and null or undefined
858                if (null == obj || "object" != typeof obj) return obj;
859
860                // Handle Date
861                if (obj instanceof Date) {
862                    copy = new Date();
863                    copy.setTime(obj.getTime());
864                    return copy;
865                }
866
867                // Handle Array
868                if (obj instanceof Array) {
869                    copy = [];
870                    for (var i = 0, len = obj.length; i < len; i++) {
871                        if("function" == typeof obj[i]) {
872                            continue;
873                        }
874                        copy[i] = Utils.clone(obj[i]);
875                    }
876                    return copy;
877                }
878
879                // Handle Object
880                if (obj instanceof Object) {
881                    copy = {};
882                    for (var attr in obj) {
883                        if (obj.hasOwnProperty(attr)) {
884                            if("function" == typeof obj[attr]) {
885                                continue;
886                            }
887                            copy[attr] = Utils.clone(obj[attr]);
888                        }
889                    }
890                    return copy;
891                }
892
893                return obj;
894            },
895
896            // Returns array of elements with given tag name
897            getTagsAsArray: function (tag) {
898                return [].slice.call(document.getElementsByTagName(tag));
899            },
900
901            /**
902             * Load and initialize YouTube API
903             *
904             * @link: https://developers.google.com/youtube/iframe_api_reference
905             */
906            initYouTubeAPI: function () {
907
908                // maybe load YouTube JS API
909                if (typeof window.YT === 'undefined') {
910                    var tag = document.createElement('script');
911                    tag.src = '//www.youtube.com/iframe_api';
912                    var firstScriptTag = document.getElementsByTagName('script')[0];
913                    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
914                }
915
916                // initialize when API is ready
917                window.onYouTubeIframeAPIReady = function () {
918
919                    // collect all possible YouTube tags
920                    var potentialVideos = Utils.getTagsAsArray('iframe').concat(Utils.getTagsAsArray('embed'));
921
922                    // turn videos into trackable videos with events
923                    for (var i = 0; i < potentialVideos.length; i++) {
924                        var video = potentialVideos[i];
925                        if (tagIsYouTubeVideo(video)) {
926                            var iframe = normalizeYouTubeIframe(video);
927                            addYouTubeEvents(iframe);
928                        } else {
929                            if(tagIsYouTubeAsyncVideo(video)) {
930                                video.addEventListener("load", function(evt) {
931                                    var iframe = normalizeYouTubeIframe(evt.currentTarget);
932                                    addYouTubeEvents(iframe);
933                                });
934                            }
935                        }
936                    }
937
938
939
940                    var targets = document.querySelectorAll('.elementor-widget-video .elementor-wrapper');
941
942                    const config = {
943                        attributes: false,
944                        childList: true,
945                        subtree: true
946                    };
947
948                    const callback = function(mutationsList, observer) {
949                        for (let mutation of mutationsList) {
950                            if (mutation.type === 'childList') {
951                                for(var m = 0;m<mutation.addedNodes.length;m++) {
952                                    addDynYouTubeVideos(mutation.addedNodes[m]);
953                                }
954                            }
955                        }
956                    };
957                    // observe elementator widget-video and add event when it add iframe
958                    for(var i=0;i<targets.length;i++) {
959                        const observer = new MutationObserver(callback);
960                        observer.observe(targets[i], config);//maybe remove before add
961                    }
962
963
964                };
965
966            },
967
968            /**
969             * Load and initialize Vimeo API
970             *
971             * @link: https://github.com/vimeo/player.js
972             */
973            initVimeoAPI: function () {
974
975              
976                $(document).ready(function () {
977
978                    var potentialVideos = Utils.getTagsAsArray('iframe').concat(Utils.getTagsAsArray('embed'));
979
980                    for (var i = 0; i < potentialVideos.length; i++) {
981                        var tag = potentialVideos[i];
982                        if (tagIsVimeoVideo(tag)) {
983                            attachVimeoPlayerToTag(tag);
984                        } else {
985                            if (tagIsAsincVimeoVideo(tag)) {
986                                tag.addEventListener("load", function(evt) {
987                                    attachVimeoPlayerToTag(evt.currentTarget);
988                                });
989                            }
990                        }
991                    }
992
993                });
994
995            },
996
997            manageCookies: function () {
998                let expires = parseInt(options.cookie_duration); //  days
999                let queryVars = getQueryVars();
1000                let landing = window.location.href.split('?')[0];
1001                try {
1002                    // save data for first visit
1003                    if(Cookies.get('pys_first_visit') === undefined ) {
1004                        Cookies.set('pys_first_visit', true, { expires: expires });
1005                        Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires });
1006                        Cookies.set('pys_landing_page',landing,{ expires: expires });
1007                        $.each(utmTerms, function (index, name) {
1008                            if (queryVars.hasOwnProperty(name)) {
1009                                Cookies.set('pys_' + name, queryVars[name], { expires: expires });
1010                            } else {
1011                                Cookies.remove('pys_' + name)
1012                            }
1013                        });
1014                        $.each(utmId,function(index,name) {
1015                            if (queryVars.hasOwnProperty(name)) {
1016                                Cookies.set('pys_' + name, queryVars[name], { expires: expires });
1017                            } else {
1018                                Cookies.remove('pys_' + name)
1019                            }
1020                        })
1021                    }
1022
1023                    // save data for last visit if it new session
1024                    if(isNewSession) {
1025                        Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires });
1026                        $.each(utmTerms, function (index, name) {
1027                            if (queryVars.hasOwnProperty(name)) {
1028                                Cookies.set('last_pys_' + name, queryVars[name], { expires: expires });
1029                            } else {
1030                                Cookies.remove('last_pys_' + name)
1031                            }
1032                        });
1033                        $.each(utmId,function(index,name) {
1034                            if (queryVars.hasOwnProperty(name)) {
1035                                Cookies.set('last_pys_' + name, queryVars[name], { expires: expires });
1036                            } else {
1037                                Cookies.remove('last_pys_' + name)
1038                            }
1039                        })
1040                        Cookies.set('last_pys_landing_page',landing,{ expires: expires });
1041                    }
1042                } catch (e) {
1043                    console.error(e);
1044                }
1045            },
1046
1047            initializeRequestParams: function () {
1048
1049                if (options.trackTrafficSource) {
1050                    requestParams.traffic_source = getTrafficSourceValue();
1051                }
1052
1053                if (options.trackUTMs) {
1054
1055                    var utms = getUTMs(options.visit_data_model === "last_visit");
1056
1057                    $.each(utmTerms, function (index, term) {
1058                        if (term in utms) {
1059                            requestParams[term] = utms[term];
1060                        }
1061                    });
1062
1063                }
1064
1065
1066                var dateTime = getDateTime();
1067                if(options.enable_event_time_param) {
1068                    requestParams.event_time = dateTime[0];
1069                }
1070
1071                if(options.enable_event_day_param) {
1072                    requestParams.event_day = dateTime[1];
1073                }
1074                if(options.enable_event_month_param) {
1075                    requestParams.event_month = dateTime[2];
1076                }
1077
1078                if(options.enable_lading_page_param){
1079                    requestParams.landing_page = getLandingPageValue();
1080                }
1081            },
1082
1083            getRequestParams: function () {
1084                return requestParams;
1085            },
1086
1087            /**
1088             * DOWNLOAD DOCS
1089             */
1090
1091            getLinkExtension: function (link) {
1092
1093                // Remove anchor, query string and everything before last slash
1094                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1095                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1096                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1097
1098                // If there's a period left in the URL, then there's a extension
1099                if (link.length > 0 && link.indexOf('.') !== -1) {
1100                    link = link.substring(link.lastIndexOf(".") + 1); // Remove everything but what's after the first period
1101                    return link;
1102                } else {
1103                    return "";
1104                }
1105            },
1106
1107            getLinkFilename: function (link) {
1108
1109                // Remove anchor, query string and everything before last slash
1110                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1111                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1112                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1113
1114                // If there's a period left in the URL, then there's a extension
1115                if (link.length > 0 && link.indexOf('.') !== -1) {
1116                    return link;
1117                } else {
1118                    return "";
1119                }
1120            },
1121
1122            /**
1123             * CUSTOM EVENTS
1124             */
1125
1126            setupMouseOverClickEvents: function (eventId, triggers) {
1127
1128                // Non-default binding used to avoid situations when some code in external js
1129                // stopping events propagation, eg. returns false, and our handler will never called
1130                $(document).onFirst('mouseover', triggers.join(','), function () {
1131
1132                    // do not fire event multiple times
1133                    if ($(this).hasClass('pys-mouse-over-' + eventId)) {
1134                        return true;
1135                    } else {
1136                        $(this).addClass('pys-mouse-over-' + eventId);
1137                    }
1138
1139                    Utils.fireTriggerEvent(eventId);
1140
1141                });
1142
1143            },
1144
1145            setupCSSClickEvents: function (eventId, triggers) {
1146
1147                // Non-default binding used to avoid situations when some code in external js
1148                // stopping events propagation, eg. returns false, and our handler will never called
1149                // add event to document to support dyn class
1150                $(document).onFirst('click', triggers.join(','), function () {
1151                    Utils.fireTriggerEvent(eventId);
1152                });
1153
1154            },
1155
1156            setupURLClickEvents: function () {
1157
1158                if( !options.triggerEventTypes.hasOwnProperty('url_click') ) {
1159                    return;
1160                }
1161                // Non-default binding used to avoid situations when some code in external js
1162                // stopping events propagation, eg. returns false, and our handler will never called
1163                $('a').onFirst('click', function (evt) {
1164
1165                    var url  = $(this).attr('href');
1166                    if(url) {
1167                        $.each(options.triggerEventTypes.url_click, function (eventId, triggers) {
1168                            triggers.forEach(function (trigger) {
1169                                if(Utils.compareUrl(url,trigger.value,trigger.rule)) {
1170                                    Utils.fireTriggerEvent(eventId);
1171                                }
1172                            })
1173                        });
1174                    }
1175
1176                });
1177
1178            },
1179
1180            removeUrlDomain(url) {
1181                if(url.indexOf("/#") > -1) {
1182                    url = url.substring(0, url.indexOf("/#"));
1183                }
1184                return url.replace('http://','')
1185                    .replace('https://','')
1186                    .replace('www.','')
1187                    .trim()
1188                    .replace(/^\/+/g, '')
1189
1190            },
1191
1192            compareUrl: function(base,url,rule){
1193
1194                if(url == "*" || url == '') return true;
1195
1196                base = Utils.removeUrlDomain(base)
1197                url = Utils.removeUrlDomain(url)
1198
1199                if(rule == 'match') {
1200                    return url == base;
1201                } else {
1202                    return base.indexOf(url) > -1
1203                }
1204
1205            },
1206
1207            setupScrollPosEvents: function (eventId, triggers) {
1208
1209                var scrollPosThresholds = {},
1210                    docHeight = $(document).height() - $(window).height();
1211
1212                // convert % to absolute positions
1213                $.each(triggers, function (index, scrollPos) {
1214
1215                    // convert % to pixels
1216                    scrollPos = docHeight * scrollPos / 100;
1217                    scrollPos = Math.round(scrollPos);
1218
1219                    scrollPosThresholds[scrollPos] = eventId;
1220
1221                });
1222
1223                $(document).on("scroll",function () {
1224
1225                    var scrollPos = $(window).scrollTop();
1226
1227                    $.each(scrollPosThresholds, function (threshold, eventId) {
1228
1229                        // position has not reached yes
1230                        if (scrollPos <= threshold) {
1231                            return true;
1232                        }
1233
1234                        // fire event only once
1235                        if (eventId === null) {
1236                            return true;
1237                        } else {
1238                            scrollPosThresholds[threshold] = null;
1239                        }
1240
1241                        Utils.fireTriggerEvent(eventId);
1242
1243                    });
1244
1245                });
1246
1247            },
1248            setupCommentEvents : function (eventId,triggers) {
1249                $('form.comment-form').on("submit",function () {
1250                    Utils.fireTriggerEvent(eventId);
1251                });
1252            },
1253            /**
1254             * Events
1255             */
1256
1257            isEventInTimeWindow: function (eventName, event, prefix) {
1258
1259                if(event.hasOwnProperty("hasTimeWindow") && event.hasTimeWindow) {
1260                    var cookieName = prefix+"_"+eventName;
1261                    var now = new Date().getTime();
1262
1263                    if(Cookies.get(cookieName) !== undefined) {
1264
1265                        var lastTimeFire = Cookies.get(cookieName);
1266                        var fireTime = event.timeWindow * 60*60*1000;
1267
1268                        if( now - lastTimeFire > fireTime) {
1269                            Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0} );
1270                        } else {
1271                            return false;
1272                        }
1273                    } else {
1274                        Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0} );
1275                    }
1276                }
1277                return true
1278            },
1279
1280            fireTriggerEvent: function (eventId) {
1281
1282                if (!options.triggerEvents.hasOwnProperty(eventId)) {
1283                    return;
1284                }
1285
1286                var event = {};
1287                var events = options.triggerEvents[eventId];
1288
1289                if (events.hasOwnProperty('facebook')) {
1290                    event = events.facebook;
1291                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_facebook_"+eventId)) {
1292                        Facebook.fireEvent(event.name, event);
1293                    }
1294                }
1295
1296                if (events.hasOwnProperty('ga')) {
1297                    event = events.ga;
1298                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_ga_"+eventId)) {
1299                        Analytics.fireEvent(event.name, event);
1300                    }
1301                }
1302
1303                if (events.hasOwnProperty('google_ads')) {
1304                    event = events.google_ads;
1305                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_google_ads_"+eventId)) {
1306                        GAds.fireEvent(event.name, event);
1307                    }
1308                }
1309
1310                if (events.hasOwnProperty('pinterest')) {
1311                    event = events.pinterest;
1312                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_pinterest_"+eventId)) {
1313                        Pinterest.fireEvent(event.name, event);;
1314                    }
1315                }
1316
1317                if (events.hasOwnProperty('bing')) {
1318                    event = events.bing;
1319                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) {
1320                        Bing.fireEvent(event.name, event);;
1321                    }
1322                }
1323                if (events.hasOwnProperty('tiktok')) {
1324                    event = events.tiktok;
1325                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) {
1326                        TikTok.fireEvent(event.name, event);
1327                    }
1328                }
1329
1330
1331            },
1332
1333            isFirstPurchaseFire: function ($eventName,orderId,pixel) {
1334
1335                if(Cookies.get("pys_"+$eventName+"_order_id_"+pixel) == orderId) {
1336                    return false;
1337                } else {
1338                    Cookies.set("pys_"+$eventName+"_order_id_"+pixel, orderId, { expires: 1 });
1339                }
1340                return true;
1341            },
1342
1343            fireStaticEvents: function (pixel) {
1344
1345                if (options.staticEvents.hasOwnProperty(pixel)) {
1346
1347                    $.each(options.staticEvents[pixel], function (eventId, events) {
1348
1349                        //skip purchase event if this order was fired
1350                        if( options.woo.hasOwnProperty('woo_purchase_on_transaction') &&
1351                            options.woo.woo_purchase_on_transaction &&
1352                            (eventId === "woo_purchase" || eventId === "woo_purchase_category") ) {
1353                            if(!Utils.isFirstPurchaseFire(eventId,events[0].woo_order,pixel)) {
1354                                return;
1355                            }
1356                        }
1357
1358                        if( options.edd.hasOwnProperty('edd_purchase_on_transaction') &&
1359                            options.edd.edd_purchase_on_transaction &&
1360                            (eventId === "edd_purchase" || eventId === "edd_purchase_category") ) {
1361                            if(!Utils.isFirstPurchaseFire(eventId,events[0].edd_order,pixel)) {
1362                                return;
1363                            }
1364                        }
1365
1366
1367                        $.each(events, function (index, event) {
1368
1369                            event.fired = event.fired || false;
1370
1371                            if (!event.fired && Utils.isEventInTimeWindow(event.name,event,'static_' + pixel+"_")) {
1372
1373
1374                                var fired = false;
1375
1376                                // fire event
1377                                getPixelBySlag(pixel).fireEvent(event.name, event);
1378
1379                                // prevent event double event firing
1380                                event.fired = fired;
1381                            }
1382
1383                        });
1384                    });
1385
1386                }
1387
1388            },
1389
1390            /**
1391             * Load tag's JS
1392             *
1393             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/
1394             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets
1395             */
1396            loadGoogleTag: function (id) {
1397
1398                if (!gtag_loaded) {
1399
1400                    (function (window, document, src) {
1401                        var a = document.createElement('script'),
1402                            m = document.getElementsByTagName('script')[0];
1403                        a.async = 1;
1404                        a.src = src;
1405                        m.parentNode.insertBefore(a, m);
1406                    }
1406)(window, document, '//www.googletagmanager.com/gtag/js?id=' + id);
1407
1408                    window.dataLayer = window.dataLayer || [];
1409                    window.gtag = window.gtag || function gtag() {
1410                        dataLayer.push(arguments);
1411                    };
1412
1413                    gtag('js', new Date());
1414
1415                    gtag_loaded = true;
1416
1417                }
1418
1419            },
1420
1421            /**
1422             * GDPR
1423             */
1424
1425            loadPixels: function () {
1426
1427                if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) {
1428
1429                    // retrieves actual PYS GDPR filters values which allow to avoid cache issues
1430                    $.get({
1431                        url: options.ajaxUrl,
1432                        dataType: 'json',
1433                        data: {
1434                            action: 'pys_get_gdpr_filters_values'
1435                        },
1436                        success: function (res) {
1437
1438                            if (res.success) {
1439
1440                                options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api;
1441                                options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api;
1442                                options.gdpr.tiktok_disabled_by_api = res.data.tiktok_disabled_by_api;
1443                                options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api;
1444                                options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api;
1445                                options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api;
1446                                options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api;
1447
1448                            }
1449
1450                            loadPixels();
1451
1452                        }
1453                    });
1454
1455                } else {
1456                    loadPixels();
1457                }
1458
1459            },
1460
1461            consentGiven: function (pixel) {
1462
1463                /**
1464                 * Cookiebot
1465                 */
1466                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1467
1468                    var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category'];
1469
1470                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
1471                        if (Cookiebot.consented === false || Cookiebot.consent[cookiebot_consent_category]) {
1472                            return true;
1473                        }
1474                    } else {
1475                        if (Cookiebot.consent[cookiebot_consent_category]) {
1476                            return true;
1477                        }
1478                    }
1479
1480                    return false;
1481
1482                }
1483
1484                /**
1485                 * Cookie Notice
1486                 */
1487                if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') {
1488
1489                    var cn_cookie = Cookies.get(cnArgs.cookieName);
1490
1491                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
1492                        if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') {
1493                            return true;
1494                        }
1495                    } else {
1496                        if (cn_cookie === 'true') {
1497                            return true;
1498                        }
1499                    }
1500
1501                    return false;
1502
1503                }
1504
1505                /**
1506                 * Cookie Law Info
1507                 */
1508                if (options.gdpr.cookie_law_info_integration_enabled) {
1509
1510                    var cli_cookie = Cookies.get('viewed_cookie_policy');
1511
1512                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
1513                        if (typeof cli_cookie === 'undefined' || cli_cookie === 'yes') {
1514                            return true;
1515                        }
1516                    } else {
1517                        if (cli_cookie === 'yes') {
1518                            return true;
1519                        }
1520                    }
1521
1522                    return false;
1523
1524                }
1525
1526                /**
1527                 * ConsentMagic
1528                 */
1529                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
1530
1531                    var test_prefix = CS_Data.test_prefix;
1532                    if ((typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) && pixel == 'analytics') {
1533                        return true;
1534                    }
1535                    if ((typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1) && pixel == 'google_ads') {
1536                        return true;
1537                    }
1538
1539                    if ( CS_Data.cs_cache_enabled == 1 ) {
1540                        var substring = "cs_enabled_cookie_term";
1541                        var theCookies = document.cookie.split(';');
1542
1543                        for (var i = 1 ; i <= theCookies.length; i++) {
1544                            if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
1545                                var categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
1546                                categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
1547                                var cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
1548
1549                                if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) {
1550                                    if ( cs_cookie_val == 'yes' ) {
1551                                        return true;
1552                                    } else {
1553                                        return false;
1554                                    }
1555                                } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) {
1556                                    if ( cs_cookie_val == 'yes' ) {
1557                                        return true;
1558                                    } else {
1559                                        return false;
1560                                    }
1561                                } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) {
1562                                    if ( cs_cookie_val == 'yes' ) {
1563                                        return true;
1564                                    } else {
1565                                        return false;
1566                                    }
1567                                } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) {
1568                                    if ( cs_cookie_val == 'yes' ) {
1569                                        return true;
1570                                    } else {
1571                                        return false;
1572                                    }
1573                                } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) {
1574                                    if ( cs_cookie_val == 'yes' ) {
1575                                        return true;
1576                                    } else {
1577                                        return false;
1578                                    }
1579                                } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) {
1580                                    if ( cs_cookie_val == 'yes' ) {
1581                                        return true;
1582                                    } else {
1583                                        return false;
1584                                    }
1585                                }
1586                            }
1587                        }
1588                    } else {
1589                        var cs_cookie = Cookies.get('cs_viewed_cookie_policy'+test_prefix);
1590                        if (typeof cs_cookie === 'undefined' || cs_cookie === 'yes') {
1591                            return true;
1592                        }
1593                    }
1594
1595                    return false;
1596
1597                }
1598
1599
1600                /**
1601                 * Real Cookie Banner
1602                 */
1603                if (options.gdpr.real_cookie_banner_integration_enabled) {
1604                    var consentApi = window.consentApi;
1605                    if (consentApi) {
1606                        switch (pixel) {
1607                            case "analytics":
1608                                return consentApi.consentSync("http", "_ga", "*").cookieOptIn;
1609                            case "facebook":
1610                                return consentApi.consentSync("http", "_fbp", "*").cookieOptIn;
1611                            case "pinterest":
1612                                return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn;
1613                            case "bing":
1614                                return consentApi.consentSync("http", "_uetsid", "*").cookieOptIn;
1615                            case "google_ads":
1616                                return consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn;
1617                            case 'tiktok':
1618                                return consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn;
1619                            default:
1620                                return true;
1621                        }
1622                    }
1623                }
1624
1625                return true;
1626
1627            },
1628
1629            setupGdprCallbacks: function () {
1630
1631                /**
1632                 * Cookiebot
1633                 */
1634                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1635
1636                    window.addEventListener("CookiebotOnConsentReady", function() {
1637                        if (Cookiebot.consent.marketing) {
1638                            Facebook.loadPixel();
1639                            Bing.loadPixel();
1640                            Pinterest.loadPixel();
1641                            GAds.loadPixel();
1642                            TikTok.loadPixel();
1643                        }
1644                        if (Cookiebot.consent.statistics) {
1645                            Analytics.loadPixel();
1646                        }
1647                        if (!Cookiebot.consent.marketing) {
1648                            Facebook.disable();
1649                            Pinterest.disable();
1650                            Bing.disable()
1651                            GAds.disable();
1652                            TikTok.disable();
1653                        }
1654                        if (!Cookiebot.consent.statistics) {
1655                            Analytics.disable();
1656                        }
1657                    });
1658                }
1659
1660                /**
1661                 * Cookie Notice
1662                 */
1663                if (options.gdpr.cookie_notice_integration_enabled) {
1664
1665                    $(document).onFirst('click', '.cn-set-cookie', function () {
1666
1667                        if ($(this).data('cookie-set') === 'accept') {
1668                            Facebook.loadPixel();
1669                            Analytics.loadPixel();
1670                            GAds.loadPixel();
1671                            Pinterest.loadPixel();
1672                            Bing.loadPixel();
1673                            TikTok.loadPixel();
1674                        } else {
1675                            Facebook.disable();
1676                            Analytics.disable();
1677                            GAds.disable();
1678                            Pinterest.disable();
1679                            Bing.disable();
1680                            TikTok.disable();
1681                        }
1682
1683                    });
1684
1685                    $(document).onFirst('click', '.cn-revoke-cookie', function () {
1686                        Facebook.disable();
1687                        Analytics.disable();
1688                        GAds.disable();
1689                        Pinterest.disable();
1690                        Bing.disable();
1691                        TikTok.disable();
1692                    });
1693
1694                }
1695
1696                /**
1697                 * Cookie Law Info
1698                 */
1699                if (options.gdpr.cookie_law_info_integration_enabled) {
1700
1701                    $(document).onFirst('click', '#cookie_action_close_header', function () {
1702                        Facebook.loadPixel();
1703                        Analytics.loadPixel();
1704                        GAds.loadPixel();
1705                        Pinterest.loadPixel();
1706                        Bing.loadPixel();
1707                        TikTok.loadPixel();
1708                    });
1709
1710                    $(document).onFirst('click', '#cookie_action_close_header_reject', function () {
1711                        Facebook.disable();
1712                        Analytics.disable();
1713                        GAds.disable();
1714                        Pinterest.disable();
1715                        Bing.disable();
1716                        TikTok.disable();
1717                    });
1718
1719                }
1720
1721                /**
1722                 * ConsentMagic
1723                 */
1724                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
1725                    var test_prefix = CS_Data.test_prefix,
1726                        cs_refresh_after_consent = false,
1727                        substring = "cs_enabled_cookie_term";
1728
1729                    if (CS_Data.cs_refresh_after_consent == 1) {
1730                        cs_refresh_after_consent = CS_Data.cs_refresh_after_consent;
1731                    }
1732
1733                    if (!cs_refresh_after_consent) {
1734                        var theCookies = document.cookie.split(';');
1735                        for (var i = 1 ; i <= theCookies.length; i++) {
1736                            if (theCookies[i-1].indexOf(substring) !== -1) {
1737                                var categoryCookie = theCookies[i-1].replace('cs_enabled_cookie_term'+test_prefix+'_','');
1738                                categoryCookie = Number(categoryCookie.replace(/\D+/g,""));
1739                                var cs_cookie_val = Cookies.get('cs_enabled_cookie_term'+test_prefix+'_'+categoryCookie);
1740                                if(cs_cookie_val == 'yes') {
1741                                    if (categoryCookie === CS_Data.cs_script_cat.facebook) {
1742                                        Facebook.loadPixel();
1743                                    }
1744
1745                                    if (categoryCookie === CS_Data.cs_script_cat.bing) {
1746                                        Bing.loadPixel();
1747                                    }
1748                                    if (categoryCookie === CS_Data.cs_script_cat.analytics || (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1)
1748) {
1749
1750                                        Analytics.loadPixel();
1751                                    }
1752
1753                                    if (categoryCookie === CS_Data.cs_script_cat.gads || (typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1)) {
1754                                        GAds.loadPixel();
1755                                    }
1756
1757                                    if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
1758                                        Pinterest.loadPixel();
1759                                    }
1760
1761                                    if (categoryCookie === CS_Data.cs_script_cat.tiktok) {
1762                                        TikTok.loadPixel();
1763                                    }
1764                                } else {
1765                                    if (categoryCookie === CS_Data.cs_script_cat.facebook) {
1766                                        Facebook.disable();
1767                                    }
1768
1769                                    if (categoryCookie === CS_Data.cs_script_cat.bing) {
1770                                        Bing.disable();
1771                                    }
1772
1773                                    if (categoryCookie === CS_Data.cs_script_cat.analytics && (typeof CS_Data.cs_google_analytics_consent_mode == "undefined" || CS_Data.cs_google_analytics_consent_mode == 0)) {
1774                                        Analytics.disable();
1775                                    }
1776
1777                                    if (categoryCookie === CS_Data.cs_script_cat.gads && (typeof CS_Data.cs_google_ads_consent_mode == "undefined" || CS_Data.cs_google_ads_consent_mode == 0)) {
1778                                        GAds.disable();
1779                                    }
1780
1781                                    if (categoryCookie === CS_Data.cs_script_cat.pinterest) {
1782                                        Pinterest.disable();
1783                                    }
1784
1785                                    if (categoryCookie === CS_Data.cs_script_cat.tiktok) {
1786                                        TikTok.disable();
1787                                    }
1788                                }
1789                                if (Cookies.get('cs_enabled_advanced_matching') == 'yes') {
1790                                    Facebook.loadPixel();
1791                                }
1792                            }
1793                        }
1794
1795                        $(document).on('click','.cs_action_btn',function(e) {
1796                            e.preventDefault();
1797                            var elm = $(this),
1798                                button_action = elm.attr('data-cs_action');
1799
1800                            if(button_action === 'allow_all') {
1801                                Facebook.loadPixel();
1802                                Bing.loadPixel();
1803                                Analytics.loadPixel();
1804                                GAds.loadPixel();
1805                                Pinterest.loadPixel();
1806                                TikTok.loadPixel();
1807                            } else if(button_action === 'disable_all') {
1808
1809                                Facebook.disable();
1810                                Bing.disable();
1811                                if(CS_Data.cs_google_analytics_consent_mode == 0 || typeof CS_Data.cs_google_analytics_consent_mode == "undefined")
1812                                {
1813                                    Analytics.disable();
1814                                }
1815                                if(CS_Data.cs_google_ads_consent_mode == 0 || typeof CS_Data.cs_google_ads_consent_mode == "undefined")
1816                                {
1817                                    GAds.disable();
1818                                }
1819                                Pinterest.disable();
1820                                TikTok.disable();
1821                            }
1822                        });
1823                    }
1824                }
1825
1826                /**
1827                 * Real Cookie Banner
1828                 */
1829                if (options.gdpr.real_cookie_banner_integration_enabled) {
1830                    var consentApi = window.consentApi;
1831                    if (consentApi) {
1832                        consentApi.consent("http", "_ga", "*")
1833                            .then(Analytics.loadPixel.bind(Analytics), Analytics.disable.bind(Analytics));
1834
1835                        consentApi.consent("http", "_fbp", "*")
1836                            .then(Facebook.loadPixel.bind(Facebook), Facebook.disable.bind(Facebook));
1837
1838                        consentApi.consent("http", "_pinterest_sess", ".pinterest.com")
1839                            .then(Pinterest.loadPixel.bind(Pinterest), Pinterest.disable.bind(Pinterest));
1840
1841                        consentApi.consent("http", "_uetsid", "*")
1842                            .then(Bing.loadPixel.bind(Bing), Bing.disable.bind(Bing));
1843
1844                        consentApi.consent("http", "1P_JAR", ".google.com")
1845                            .then(GAds.loadPixel.bind(GAds), GAds.disable.bind(GAds));
1846                        consentApi.consent("http", "tt_webid_v2", ".tiktok.com")
1847                            .then(TikTok.loadPixel.bind(GAds), TikTok.disable.bind(GAds));
1848                    }
1849                }
1850
1851            },
1852
1853            /**
1854             * Enrich
1855             */
1856            isCheckoutPage: function () {
1857                return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') ||
1858                    $('body').hasClass('edd-checkout');
1859            },
1860            addCheckoutFields : function() {
1861                var utm = "";
1862                var utms = getUTMs()
1863                $.each(utmTerms, function (index, name) {
1864                    if(index > 0) {
1865                        utm+="|";
1866                    }
1867                    utm+=name+":"+utms[name];
1868                });
1869                var utmIdList = "";
1870                var utmsIds = getUTMId()
1871                $.each(utmId, function (index, name) {
1872                    if(index > 0) {
1873                        utmIdList+="|";
1874                    }
1875                    utmIdList+=name+":"+utmsIds[name];
1876                });
1877                var utmIdListLast = "";
1878                var utmsIdsLast = getUTMId(true)
1879                $.each(utmId, function (index, name) {
1880                    if(index > 0) {
1881                        utmIdListLast+="|";
1882                    }
1883                    utmIdListLast+=name+":"+utmsIdsLast[name];
1884                });
1885
1886
1887                var utmLast = "";
1888                var utmsLast = getUTMs(true)
1889                $.each(utmTerms, function (index, name) {
1890                    if(index > 0) {
1891                        utmLast+="|";
1892                    }
1893                    utmLast+=name+":"+utmsLast[name];
1894                });
1895
1896                var dateTime = getDateTime();
1897                var landing = Cookies.get('pys_landing_page');
1898                var lastLanding = Cookies.get('last_pys_landing_page');
1899                var trafic = Cookies.get('pysTrafficSource');
1900                var lastTrafic = Cookies.get('last_pysTrafficSource');
1901
1902                var $form = null;
1903                if($('body').hasClass('woocommerce-checkout')) {
1904                    $form = $("form.woocommerce-checkout");
1905                } else {
1906                    $form = $("#edd_purchase_form");
1907                }
1908                var inputs = {'pys_utm':utm,
1909                    'pys_utm_id':utmIdList,
1910                    'pys_browser_time':dateTime.join("|"),
1911                    'pys_landing':landing,
1912                    'pys_source':trafic,
1913                    'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal",
1914
1915                    'last_pys_landing':lastLanding,
1916                    'last_pys_source':lastTrafic,
1917                    'last_pys_utm':utmLast,
1918                    'last_pys_utm_id':utmIdListLast,
1919                }
1920
1921                Object.keys(inputs).forEach(function(key,index) {
1922                    $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> ");
1923                });
1924
1925
1926            },
1927
1928            /**
1929             * Advanced From Data
1930             */
1931            saveAdvancedFormData: function (email,phone,firstName,lastName) {
1932                let data = Utils.getAdvancedFormData();
1933
1934                if(email != null) {
1935                    data["email"] = email;
1936                }
1937                if(phone != null) {
1938                    data["phone"] = phone;
1939                }
1940                if(firstName != null) {
1941                    data["first_name"] = firstName;
1942                }
1943                if(lastName != null) {
1944                    data["last_name"] = lastName;
1945                }
1946                Cookies.set('pys_advanced_form_data', JSON.stringify(data),{ expires: 300 } );
1947
1948                GAds.updateEnhancedConversionData()
1949            },
1950
1951            getAdvancedFormData: function () {
1952                let dataStr = Cookies.get("pys_advanced_form_data");
1953                if(dataStr === undefined) {
1954                    return {'first_name':"",'last_name':"",'email':"",'phone':""};
1955                } else {
1956                    return JSON.parse(dataStr);
1957                }
1958            }
1959
1960        };
1961
1962    }(options);
1963
1964    var TikTok = function (options) {
1965
1966        var initialized = false;
1967
1968        function fireEvent(name, event) {
1969
1970            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'tiktok')) {
1971                return;
1972            }
1973            var params = Utils.copyProperties(event.params, {});
1974
1975                event.pixelIds.forEach(function(pixelId){
1976                    if (options.debug) {
1977                        console.log('[TikTok] ' + name, params,"pixel_id",pixelId);
1978                    }
1979
1980                    if(options.tiktok.hasOwnProperty('advanced_matching')
1981                        && Object.keys(options.tiktok.advanced_matching).length > 0) {
1982                        ttq.instance(pixelId).identify(options.tiktok.advanced_matching)
1983                    }
1984
1985                    ttq.instance(pixelId).track(name,params)
1986                });
1987        }
1988
1989        return {
1990            tag: function() {
1991                return "tiktok";
1992            },
1993            isEnabled: function () {
1994                return options.hasOwnProperty('tiktok');
1995            },
1996            disable: function () {
1997                initialized = false;
1998            },
1999
2000            loadPixel:function () {
2001                if (initialized || !this.isEnabled() || !Utils.consentGiven('tiktok')) {
2002                    return;
2003                }
2004
2005                !function (w, d, t) {
2006                    w.TiktokAnalyticsObject=t;
2007                    var ttq=w[t]=w[t]||[];
2008                    ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"];
2009                    ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};
2010                    for(var i=0;i<ttq.methods.length;i++)
2011                        ttq.setAndDefer(ttq,ttq.methods[i]);
2012                    ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e};
2013                    ttq.load=function(e,n){var i="https://analytics.tiktok.com/i18n/pixel/events.js";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=i+"?sdkid="+e+"&lib="+t;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)};
2014
2015                    //ttq.load('C60QSCQRVDG9JAKNPK2G');
2016                    //ttq.page();
2017                }(window, document, 'ttq');
2018
2019                options.tiktok.pixelIds.forEach(function (pixelId) {
2020                    ttq.load(pixelId);
2021                    ttq.page();
2022                });
2023                initialized = true;
2024
2025                if (options.staticEvents.hasOwnProperty('tiktok')) {
2026                    setTimeout(function () {
2027                        Utils.fireStaticEvents('tiktok');
2028                    }, 1500)
2029                }
2030            },
2031
2032            fireEvent: function (name, data) {
2033                if (!initialized || !this.isEnabled()) {
2034                    return false;
2035                }
2036                data.delay = data.delay || 0;
2037
2038                if (data.delay === 0) {
2039                    fireEvent(name, data);
2040                } else {
2041                    setTimeout(function (name, params) {
2042                        fireEvent(name, params);
2043                    }, data.delay * 1000, name, data);
2044                }
2045                return true;
2046            },
2047
2048            onClickEvent: function (event) {
2049                this.fireEvent(event.name, event);
2050            },
2051
2052            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
2053
2054                window.pysWooProductData = window.pysWooProductData || [];
2055                if (!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2056                    return;
2057
2058                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2059                    if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) {
2060
2061                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
2062
2063                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()]['params'], event.params);
2064
2065                        // maybe customize value option
2066                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
2067
2068                            if (product_type === Utils.PRODUCT_BUNDLE) {
2069                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
2070                                var items_sum = getBundlePriceOnSingleProduct(data);
2071                                event.params.value = (parseFloat(data.base_price) + items_sum) * qty;
2072                            } else {
2073                                event.params.value = event.params.value * qty;
2074                            }
2075                        }
2076
2077                        event.params.quantity = qty;
2078
2079                        this.fireEvent(event.name, event);
2080
2081                    }
2082                }
2083            },
2084
2085            onWooAddToCartOnButtonEvent: function (product_id) {
2086                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2087                    return;
2088
2089                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2090                    if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) {
2091                        var productData = window.pysWooProductData[product_id][this.tag()]
2092                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
2093
2094                        Utils.copyProperties(productData['params'], event.params)
2095                        event.pixelIds = productData['pixelIds'];
2096                        this.fireEvent(event.name, event);
2097                    }
2098                }
2099            },
2100
2101            onEddAddToCartOnButtonEvent : function (download_id, price_index, qty) {
2102                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2103                    return;
2104                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
2105
2106
2107                if (window.pysEddProductData.hasOwnProperty(download_id)) {
2108
2109                    var index;
2110
2111                    if (price_index) {
2112                        index = download_id + '_' + price_index;
2113                    } else {
2114                        index = download_id;
2115                    }
2116
2117                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
2118                        if (window.pysEddProductData[download_id][index].hasOwnProperty(this.tag())) {
2119
2120                            Utils.copyProperties(window.pysEddProductData[download_id][index][this.tag()].params, event.params);
2121                            this.fireEvent(event.name,event);
2122
2123                        }
2124                    }
2125
2126                }
2127            }
2128        }
2129    }(options);
2130
2131    var Facebook = function (options) {
2132
2133        var defaultEventTypes = [
2134            'PageView',
2135            'ViewContent',
2136            'Search',
2137            'AddToCart',
2138            'AddToWishlist',
2139            'InitiateCheckout',
2140            'AddPaymentInfo',
2141            'Purchase',
2142            'Lead',
2143
2144            'Subscribe',
2145            'CustomizeProduct',
2146            'FindLocation',
2147            'StartTrial',
2148            'SubmitApplication',
2149            'Schedule',
2150            'Contact',
2151            'Donate'
2152        ];
2153
2154        var notCachedEventsIds = new Array();
2155        var isAddToCartFromJs =  options.woo.hasOwnProperty("addToCartCatchMethod")
2156                                && options.woo.addToCartCatchMethod === "add_cart_js";
2157        if(!isAddToCartFromJs) {
2158            notCachedEventsIds.push('woo_add_to_cart_on_button_click')
2159        }
2160        var initialized = false;
2161        var configuredPixels = new Array();
2162        function fireEvent(name, event) {
2163
2164            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) {
2165                return;
2166            }
2167
2168            var data = event.params;
2169            var ids = event.pixelIds;
2170            var actionType = defaultEventTypes.includes(name) ? 'trackSingle' : 'trackSingleCustom';
2171
2172            var params = {};
2173
2174            Utils.copyProperties(data, params);
2175            Utils.copyProperties(Utils.getRequestParams(), params);
2176
2177
2178            if(options.facebook.serverApiEnabled) {
2179                if(event.e_id === "woo_remove_from_cart" ) {
2180                    Facebook.updateEventId(event.name);
2181                    event.eventID = Facebook.getEventId(event.name);
2182                } else if(isAddToCartFromJs && event.e_id === "woo_add_to_cart_on_button_click" ) {
2183                    Facebook.updateEventId(event.name);
2184                    event.eventID = Facebook.getEventId(event.name);
2185                } else if(!notCachedEventsIds.includes(event.e_id)) {
2186                    var isApiDisabled = options.gdpr.all_disabled_by_api ||
2187                        options.gdpr.facebook_disabled_by_api ||
2188                        options.gdpr.tiktok_disabled_by_api ||
2189                        options.gdpr.cookiebot_integration_enabled ||
2190                        options.gdpr.cookie_notice_integration_enabled ||
2191                        options.gdpr.consent_magic_integration_enabled ||
2192                        options.gdpr.cookie_law_info_integration_enabled;
2193                    // Update eventID
2194                    if( options.facebook.ajaxForServerEvent || event.type !== "static") {
2195                        event.eventID = pys_generate_token(36);
2196                    }
2197
2198                    // send event from server if they was bloc by gdpr or need send with delay
2199                    if( options.facebook.ajaxForServerEvent || isApiDisabled || event.delay > 0 || event.type !== "static" ){
2200
2201                        var json = {
2202                            action: 'pys_api_event',
2203                            pixel: 'facebook',
2204                            event: name,
2205                            ids: ids,
2206                            data:params,
2207                            url:window.location.href,
2208                            eventID:event.eventID,
2209                            ajax_event:options.ajax_event
2210                        };
2211
2212                        if(event.hasOwnProperty('woo_order')) {
2213                            json['woo_order'] = event.woo_order;
2214                        }
2215
2216                        if(event.hasOwnProperty('edd_order')) {
2217                            json['edd_order'] = event.edd_order;
2218                        }
2219                        if(event.e_id === "automatic_event_internal_link"
2220                            || event.e_id === "automatic_event_outbound_link"
2221                        ) {
2222                            setTimeout(function(){
2223                                jQuery.ajax( {
2224                                    type: 'POST',
2225                                    url: options.ajaxUrl,
2226                                    data: json,
2227                                    headers: {
2228                                        'Cache-Control': 'no-cache'
2229                                    },
2230                                    success: function(){},
2231                                });
2232                            },500)
2233                        } else if(name == 'PageView') {
2234                            let expires = parseInt(options.cookie_duration);
2235                            var currentTimeInSeconds=Date.now();
2236                            var randomNum = Math.floor(1000000000 + Math.random() * 9000000000);
2237                            timeoutDelay = 0;
2238
2239                            if(!Cookies.get('_fbp'))
2240                            {
2241                                timeoutDelay = 100;
2242                            }
2243                            if(getUrlParameter('fbclid') && !Cookies.get('_fbc'))
2244                            {
2245                                timeoutDelay = 100;
2246                            }
2247                            setTimeout(function(){
2248                                if(!Cookies.get('_fbp'))
2249                                {
2250                                    Cookies.set('_fbp','fb.1.'+currentTimeInSeconds+'.'+randomNum,  { expires: expires })
2251                                }
2252                                if(getUrlParameter('fbclid') && !Cookies.get('_fbc'))
2253                                {
2254                                    Cookies.set('_fbc', 'fb.1.'+currentTimeInSeconds+'.'+getUrlParameter('fbclid'),  { expires: expires })
2255                                }
2256                                jQuery.ajax( {
2257                                    type: 'POST',
2258                                    url: options.ajaxUrl,
2259                                    data: json,
2260                                    headers: {
2261                                        'Cache-Control': 'no-cache'
2262                                    },
2263                                    success: function(){},
2264                                });
2265                            },timeoutDelay)
2266                        }
2267                        else
2268                        {
2269                            jQuery.ajax( {
2270                                type: 'POST',
2271                                url: options.ajaxUrl,
2272                                data: json,
2273                                headers: {
2274                                    'Cache-Control': 'no-cache'
2275                                },
2276                                success: function(){},
2277                            });
2278                        }
2279
2280
2281                    }
2282
2283                    if( event.e_id !== "automatic_event_signup" && name == "CompleteRegistration" && options.facebook.wooCRSendFromServer ) {
2284                        return;
2285                    }
2286                }
2287
2288            }
2289
2290
2291
2292            if (options.debug) {
2293                console.log('[Facebook] ' + name, params,"pixel_ids",ids,"eventID",event.eventID);
2294            }
2295            // fire event for each pixel id
2296            ids.forEach(function (pixelId) {
2297                // add eventID for deduplicate events @see https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events/
2298                var args = {};
2299                if(options.facebook.serverApiEnabled && event.hasOwnProperty('eventID')) {
2300                    args.eventID = pixelId+event.eventID;
2301                }
2302                
2303                Facebook.maybeInitPixel(pixelId);
2304                fbq(actionType,pixelId, name, params,args);
2305            });
2306
2307        }
2308
2309        /**
2310         * Public API
2311         */
2312        return {
2313            tag: function() {
2314              return "facebook";
2315            },
2316            isEnabled: function () {
2317                return options.hasOwnProperty('facebook');
2318            },
2319
2320            initEventIdCookies: function (key) {
2321                var ids = {};
2322                ids[key] = pys_generate_token(36)
2323                Cookies.set('pys_fb_event_id', JSON.stringify(ids));
2324            },
2325
2326            updateEventId:function(key) {
2327                var cooData = Cookies.get("pys_fb_event_id")
2328                if(cooData === undefined) {
2329                    this.initEventIdCookies(key);
2330                } else {
2331                    var data = JSON.parse(cooData);
2332                    data[key] = pys_generate_token(36);
2333                    Cookies.set('pys_fb_event_id', JSON.stringify(data) );
2334                }
2335            },
2336
2337            getEventId:function (key) {
2338                var data = Cookies.get("pys_fb_event_id");
2339                if(data === undefined) {
2340                    this.initEventIdCookies(key);
2341                    data = Cookies.get("pys_fb_event_id");
2342                }
2343                return JSON.parse(data)[key];
2344            },
2345
2346            disable: function () {
2347                initialized = false;
2348            },
2349
2350            /**
2351             * Load pixel's JS
2352             */
2353            loadPixel: function () {
2354
2355                if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) {
2356                    return;
2357                }
2358
2359                ! function (f, b, e, v, n, t, s) {
2360                    if (f.fbq) return;
2361                    n = f.fbq = function () {
2362                        n.callMethod ?
2363                            n.callMethod.apply(n, arguments) : n.queue.push(arguments)
2364                    };
2365                    if (!f._fbq) f._fbq = n;
2366                    n.push = n;
2367                    n.loaded = !0;
2368                    n.version = '2.0';
2369                    n.agent = 'dvpixelyoursite';
2370                    n.queue = [];
2371                    t = b.createElement(e);
2372                    t.async = !0;
2373                    t.src = v;
2374                    s = b.getElementsByTagName(e)[0];
2375                    s.parentNode.insertBefore(t, s)
2376                }(window,
2377                    document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
2378
2379                // initialize default pixel
2380                options.facebook.pixelIds.forEach(function (pixelId) {
2381                    Facebook.maybeInitPixel(pixelId);
2382                });
2383                initialized = true;
2384
2385                Utils.fireStaticEvents('facebook');
2386
2387            },
2388            advancedMatching: function () {
2389                if(options.facebook.advancedMatchingEnabled) {
2390                    let advancedMatchingForm = Utils.getAdvancedFormData();
2391                    let advancedMatching = {};
2392                    if(Object.keys(options.facebook.advancedMatching).length > 0) {
2393                        advancedMatching = options.facebook.advancedMatching;
2394                    }
2395
2396                    if(!advancedMatching.hasOwnProperty("em")
2397                        && advancedMatchingForm.hasOwnProperty("email") && advancedMatchingForm["email"].length > 0) {
2398                        advancedMatching["em"] = advancedMatchingForm["email"];
2399                    }
2400                    if(!advancedMatching.hasOwnProperty("ph")
2401                        && advancedMatchingForm.hasOwnProperty("phone") && advancedMatchingForm["phone"].length > 0) {
2402                        advancedMatching["ph"] = advancedMatchingForm["phone"];
2403                    }
2404                    if(!advancedMatching.hasOwnProperty("fn")
2405                        && advancedMatchingForm.hasOwnProperty("first_name") && advancedMatchingForm["first_name"].length > 0) {
2406                        advancedMatching["fn"] = advancedMatchingForm["first_name"];
2407                    }
2408                    if(!advancedMatching.hasOwnProperty("ln")
2409                        && advancedMatchingForm.hasOwnProperty("last_name") && advancedMatchingForm["last_name"].length > 0) {
2410                        advancedMatching["ln"] = advancedMatchingForm["last_name"];
2411                    }
2412
2413                    if(Object.keys(advancedMatching).length > 0) {
2414                        return advancedMatching;
2415                    }
2416                }
2417                return false
2418            },
2419            maybeInitPixel: function(pixelId) {
2420
2421                if(configuredPixels.includes(pixelId)) return;
2422
2423                if (options.facebook.removeMetadata) {
2424                    fbq('set', 'autoConfig', false, pixelId);
2425                }
2426                let advancedMatching = Facebook.advancedMatching();
2427
2428                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
2429                    if(!advancedMatching) {
2430                        fbq('init', pixelId);
2431                    } else {
2432                        var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix);
2433                        if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) {
2434                            if (cs_advanced_matching == 'yes') {
2435                                fbq('init', pixelId, advancedMatching);
2436                            } else {
2437                                fbq('init', pixelId);
2438                            }
2439                        } else {
2440                            fbq('init', pixelId, advancedMatching);
2441                        }
2442                    }
2443                } else {
2444                    if(!advancedMatching) {
2445                        fbq('init', pixelId);
2446                    }  else {
2447                        fbq('init', pixelId, advancedMatching);
2448                    }
2449                }
2450                configuredPixels.push(pixelId);
2451            },
2452
2453            fireEvent: function (name, data) {
2454
2455                if (!initialized || !this.isEnabled()) {
2456                    return false;
2457                }
2458
2459                data.delay = data.delay || 0;
2460                data.params = data.params || {};
2461
2462                if (data.delay === 0) {
2463
2464                    fireEvent(name, data);
2465
2466                } else {
2467
2468                    setTimeout(function (name, params) {
2469                        fireEvent(name, params);
2470                    }, data.delay * 1000, name, data);
2471
2472                }
2473
2474                return true;
2475
2476            },
2477
2478            onAdSenseEvent: function (event) {
2479                this.fireEvent(event.name, event);
2480            },
2481
2482            onClickEvent: function (event) {
2483                this.fireEvent(event.name, event);
2484            },
2485
2486            onWatchVideo: function (event) {
2487                this.fireEvent(event.name, event);
2488            },
2489
2490            onCommentEvent: function (event) {
2491                this.fireEvent(event.name, event);
2492            },
2493
2494            onFormEvent: function (event) {
2495                this.fireEvent(event.name, event);
2496            },
2497
2498            onDownloadEvent: function (event) {
2499                this.fireEvent(event.name, event);
2500
2501            },
2502
2503
2504            onWooAddToCartOnButtonEvent: function (product_id) {
2505                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2506                    return;
2507
2508                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2509                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
2510
2511                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
2512
2513                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params)
2514                        event.pixelIds = window.pysWooProductData[product_id]['facebook']['pixelIds'];
2515                        this.fireEvent(event.name, event);
2516                    }
2517                }
2518            },
2519
2520            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
2521
2522                window.pysWooProductData = window.pysWooProductData || [];
2523                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2524                    return;
2525
2526                if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) {
2527                    product_id = parseInt($form.find('input[name="variation_id"]').val());
2528                }
2529
2530                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2531                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
2532
2533                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click.facebook);
2534
2535
2536                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params);
2537
2538                        var groupValue = 0;
2539                        if(product_type === Utils.PRODUCT_GROUPED ) {
2540                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
2541                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
2542                                var quantity = parseInt($(this).val());
2543                                if(isNaN(quantity)) {
2544                                    quantity = 0;
2545                                }
2546                                var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId];
2547
2548                                if(quantity == 0) {
2549                                    event.params.content_ids.forEach(function(el,index,array) {
2550                                        if(el == childItem.content_id) {
2551                                            array.splice(index, 1);
2552                                        }
2553                                    });
2554                                }
2555
2556                                if(event.params.hasOwnProperty('contents')) {
2557                                    event.params.contents.forEac
2557h(function(el,index,array) {
2558                                        if(el.id == childItem.content_id) {
2559                                            if(quantity > 0){
2560                                                el.quantity = quantity;
2561                                            } else {
2562                                                array.splice(index, 1);
2563                                            }
2564                                        }
2565                                    });
2566                                }
2567
2568
2569                                groupValue += childItem.price * quantity;
2570                            });
2571                            if(groupValue == 0) return; // skip if no items selected
2572                        }
2573
2574
2575
2576                        // maybe customize value option
2577                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
2578
2579                            if(product_type === Utils.PRODUCT_GROUPED) {
2580                                    event.params.value = groupValue;
2581                            } else if(product_type === Utils.PRODUCT_BUNDLE) {
2582                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
2583                                var items_sum = getBundlePriceOnSingleProduct(data);
2584                                event.params.value = (parseFloat(data.base_price) + items_sum )* qty;
2585                            } else {
2586                                event.params.value = event.params.value * qty;
2587                            }
2588                        }
2589
2590                        // only when non Facebook for WooCommerce logic used
2591                        if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) {
2592                            event.params.contents[0].quantity = qty;
2593
2594                        }
2595
2596                        var event_name = is_external ? options.woo.affiliateEventName : event.name;
2597
2598                        this.fireEvent(event_name, event);
2599
2600                    }
2601                }
2602
2603            },
2604
2605            onWooRemoveFromCartEvent: function (event) {
2606                this.fireEvent(event.name, event);
2607            },
2608
2609            onWooAffiliateEvent: function (product_id) {
2610                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
2611                    return;
2612                var event = Utils.clone(options.dynamicEvents.woo_affiliate[this.tag()]);
2613
2614
2615                if (window.pysWooProductData.hasOwnProperty(product_id)) {
2616                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
2617
2618                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()].params, event.params)
2619                        this.fireEvent(options.woo.affiliateEventName, event);
2620
2621                    }
2622                }
2623
2624            },
2625
2626            onWooPayPalEvent: function (event) {
2627                this.fireEvent(event.name, event);
2628            },
2629
2630            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
2631                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
2632                    return;
2633                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
2634
2635                if (window.pysEddProductData.hasOwnProperty(download_id)) {
2636
2637                    var index;
2638
2639                    if (price_index) {
2640                        index = download_id + '_' + price_index;
2641                    } else {
2642                        index = download_id;
2643                    }
2644
2645                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
2646                        if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) {
2647
2648
2649                            Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params)
2650
2651                            // maybe customize value option
2652                            if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') {
2653                                event.params.value = event.params.value * qty;
2654                            }
2655
2656                            // update contents qty param
2657                            var contents = event.params.contents;
2658                            contents[0].quantity = qty;
2659                            event.params.contents = JSON.stringify(contents);
2660
2661                            this.fireEvent(event.name,event);
2662
2663                        }
2664                    }
2665
2666                }
2667
2668            },
2669
2670            onEddRemoveFromCartEvent: function (event) {
2671                this.fireEvent(event.name, event);
2672            },
2673            onPageScroll: function (event) {
2674                this.fireEvent(event.name, event);
2675            },
2676            onTime: function (event) {
2677                this.fireEvent(event.name, event);
2678            },
2679        };
2680
2681    }(options);
2682
2683    var Analytics = function (options) {
2684
2685        var initialized = false;
2686
2687        /**
2688         * Fires event
2689         *
2690         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
2691         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
2692         * @link: https://developers.google.com/gtagjs/reference/event
2693         * @link: https://developers.google.com/gtagjs/reference/parameter
2694         *
2695         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dim
2695s-mets
2696         *
2697         * @param name
2698         * @param data
2699         */
2700        function fireEvent(name, data) {
2701            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) {
2702                return;
2703            }
2704
2705            var eventParams = Utils.copyProperties(data.params, {});
2706            Utils.copyProperties(Utils.getRequestParams(), eventParams);
2707
2708            var _fireEvent = function (tracking_id,name,params) {
2709
2710                params['send_to'] = tracking_id;
2711                if (options.debug) {
2712                    console.log('[Google Analytics #' + tracking_id + '] ' + name, params);
2713                }
2714
2715                gtag('event', name, params);
2716
2717            };
2718
2719            data.trackingIds.forEach(function (tracking_id) {
2720                var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify it
2721                var params = mapParamsTov4(tracking_id,name,copyParams)
2722                _fireEvent(tracking_id, name, params);
2723            });
2724
2725        }
2726
2727        function normalizeEventName(eventName) {
2728
2729            var matches = {
2730                ViewContent: 'view_item',
2731                AddToCart: 'add_to_cart',
2732                AddToWishList: 'add_to_wishlist',
2733                InitiateCheckout: 'begin_checkout',
2734                Purchase: 'purchase',
2735                Lead: 'generate_lead',
2736                CompleteRegistration: 'sign_up',
2737                AddPaymentInfo: 'set_checkout_option'
2738            };
2739
2740            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
2741
2742        }
2743
2744        function mapParamsTov4(tag,name,param) {
2745            //GA4 automatically collects a number of parameters for all events
2746            delete param.page_title;
2747            delete param.event_url;
2748            delete param.landing_page;
2749            // end
2750            if(isv4(tag)) {
2751                delete param.traffic_source;
2752                delete param.event_category;
2753                delete param.event_label;
2754                delete param.ecomm_prodid;
2755                delete param.ecomm_pagetype;
2756                delete param.ecomm_totalvalue;
2757                if(name === 'search') {
2758                    param['search'] = param.search_term;
2759                    delete param.search_term;
2760                    delete param.non_interaction;
2761                    delete param.dynx_itemid;
2762                    delete param.dynx_pagetype;
2763                    delete param.dynx_totalvalue;
2764                }
2765            } else {
2766
2767                switch (name) {
2768                    case 'OutboundClick':
2769                    case 'InternalClick': {
2770                        let params = {
2771                            event_category: "Key Actions",
2772                            event_action: name,
2773                            non_interaction: param.non_interaction,
2774                        }
2775                        if(param.hasOwnProperty("target_url")) {
2776                            params['event_label'] = param.target_url
2777                        }
2778                        if(options.trackTrafficSource) {
2779                            params['traffic_source'] = param.traffic_source
2780                        }
2781                        return params;
2782                    }
2783
2784                    case 'AdSense' :
2785                    case 'Comment' :
2786                    case 'login' :
2787                    case 'sign_up' :
2788                    case 'EmailClick' :
2789                    case 'TelClick' : {
2790                        let params = {
2791                            event_category: "Key Actions",
2792                            event_action: name,
2793                              non_interaction: param.non_interaction,
2794                        }
2795                        return params;
2796                    }
2797                    case 'Form' : {
2798                        let params = {
2799                            event_category: "Key Actions",
2800                            event_action: name,
2801                              non_interaction: param.non_interaction,
2802                        }
2803                        var formClass = (typeof param.form_class != 'undefined') ? 'class: ' + param.form_class : '';
2804                        if(formClass != "") {
2805                            params["event_label"] = formClass;
2806                        }
2807                        return params;
2808                    }
2809                    case 'Download' : {
2810                        let params = {
2811                            event_category: "Key Actions",
2812                            event_action: name,
2813                            event_label: param.download_name,
2814                              non_interaction: param.non_interaction,
2815                        }
2816                        return params;
2817                    }
2818                    case 'TimeOnPage' :
2819                    case 'PageScroll' : {
2820                        let params = {
2821                            event_category: "Key Actions",
2822                            event_action: name,
2823                            event_label: document.title,
2824                              non_interaction: param.non_interaction,
2825                        }
2826                        return params;
2827                    }
2828                    case 'search' : {
2829                        let params = {
2830                            event_category: "Key Actions",
2831                            event_action: name,
2832                            event_label: param.search_term,
2833                              non_interaction: param.non_interaction,
2834                        }
2835                        return params;
2836                    }
2837                }
2838
2839                //delete standard params
2840
2841                delete param.post_type;
2842                delete param.post_id;
2843                delete param.plugin;
2844                delete param.user_role;
2845                delete param.cartlows;
2846                delete param.cartflows_flow;
2847                delete param.cartflows_step;
2848            }
2849            return param;
2850        }
2851
2852        function isv4(tag) {
2853            return tag.indexOf('G') === 0;
2854        }
2855
2856        /**
2857         * Public API
2858         */
2859        return {
2860            tag: function() {
2861                return "ga";
2862            },
2863            isEnabled: function () {
2864                return options.hasOwnProperty('ga');
2865            },
2866
2867            disable: function () {
2868                initialized = false;
2869            },
2870
2871            loadPixel: function () {
2872
2873                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
2874                    return;
2875                }
2876
2877                Utils.loadGoogleTag(options.ga.trackingIds[0]);
2878
2879                var cd = {
2880                    'dimension1': 'event_hour',
2881                    'dimension2': 'event_day',
2882                    'dimension3': 'event_month'
2883                };
2884
2885                // configure Dynamic Remarketing CDs
2886                if (options.ga.retargetingLogic === 'ecomm') {
2887                    cd.dimension4 = 'ecomm_prodid';
2888                    cd.dimension5 = 'ecomm_pagetype';
2889                    cd.dimension6 = 'ecomm_totalvalue';
2890                } else {
2891                    cd.dimension4 = 'dynx_itemid';
2892                    cd.dimension5 = 'dynx_pagetype';
2893                    cd.dimension6 = 'dynx_totalvalue';
2894                }
2895
2896                var config = {
2897                    'link_attribution': options.ga.enhanceLinkAttr,
2898                    'anonymize_ip': options.ga.anonimizeIP,
2899                    'custom_map': cd
2900                };
2901
2902                if(options.user_id && options.user_id != 0) {
2903                    config.user_id = options.user_id;
2904                }
2905
2906                // Cross-Domain tracking
2907                if (options.ga.crossDomainEnabled) {
2908                    config.linker = {
2909                        accept_incoming: options.ga.crossDomainAcceptIncoming,
2910                        domains: options.ga.crossDomainDomains
2911                    };
2912                }
2913
2914
2915
2916                // configure tracking ids
2917
2918                options.ga.trackingIds.forEach(function (trackingId,index) {
2919                    if(options.ga.isDebugEnabled.includes("index_"+index)) {
2920                        config.debug_mode = true;
2921                    } else {
2922                        config.debug_mode = false;
2923                    }
2924                    if(isv4(trackingId)) {
2925                        if(options.ga.disableAdvertisingFeatures) {
2926                            config.allow_google_signals = false
2927                        }
2928                        if(options.ga.disableAdvertisingPersonalization) {
2929                            config.allow_ad_personalization_signals = false
2930                        }
2931                    }
2932
2933                    if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
2934
2935                        var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category'];
2936                        if (options.gdpr['analytics_prior_consent_enabled']) {
2937                            if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) {
2938                                gtag('config', trackingId, config);
2939                            }
2940                        } else {
2941                            if (Cookiebot.consent[cookiebot_consent_category]) {
2942                                gtag('config', trackingId, config);
2943                            }
2944                        }
2945
2946                    }
2947                    else
2948                    {
2949                        gtag('config', trackingId, config);
2950                    }
2951                    
2952                });
2953
2954                initialized = true;
2955
2956                Utils.fireStaticEvents('ga');
2957                $( document).trigger( "analytics_initialized")
2958            },
2959
2960            fireEvent: function (name, data) {
2961
2962                if (!initialized || !this.isEnabled()) {
2963                    return false;
2964                }
2965
2966                data.delay = data.delay || 0;
2967                data.params = data.params || {};
2968
2969                if (data.delay === 0) {
2970
2971                    fireEvent(name, data);
2972
2973                } else {
2974
2975                    setTimeout(function (name, params) {
2976                        fireEvent(name, params);
2977                    }, data.delay * 1000, name, data);
2978
2979                }
2980
2981                return true;
2982
2983            },
2984
2985            onAdSenseEvent: function (event) {
2986                this.fireEvent(event.name, event);
2987            },
2988
2989            onClickEvent: function (event) {
2990                this.fireEvent(event.name, event);
2991            },
2992
2993            onWatchVideo: function (event) {
2994                if(!event.hasOwnProperty("youtube_disabled")
2995                    || !event.youtube_disabled
2996                    || event.params.video_type !== "youtube") {
2997                    this.fireEvent(event.name, event);
2998                }
2999            },
3000
3001            onCommentEvent: function (event) {
3002
3003                this.fireEvent(event.name, event);
3004
3005            },
3006
3007            onFormEvent: function (event) {
3008
3009                this.fireEvent(event.name, event);
3010
3011            },
3012
3013            onDownloadEvent: function (event) {
3014
3015                this.fireEvent(event.name, event);
3016
3017            },
3018
3019            onWooAddToCartOnButtonEvent: function (product_id) {
3020                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3021                    return;
3022
3023                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3024                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
3025                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
3026                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params)
3027                        event.trackingIds = window.pysWooProductData[product_id]['ga']['trackingIds'];
3028                        this.fireEvent(event.name, event);
3029                    }
3030                }
3031
3032            },
3033
3034            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
3035
3036                window.pysWooProductData = window.pysWooProductData || [];
3037
3038                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3039                    return;
3040                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
3041
3042                if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) {
3043                    product_id = parseInt($form.find('input[name="variation_id"]').val());
3044                }
3045
3046                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3047                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
3048
3049                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params);
3050
3051
3052                        if(product_type === Utils.PRODUCT_GROUPED ) {
3053                            var groupValue = 0;
3054                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
3055                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
3056                                var quantity = parseInt($(this).val());
3057                                if(isNaN(quantity)) {
3058                                    quantity = 0;
3059                                }
3060                                var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
3061                                event.params.items.forEach(function(el,index,array) {
3062                                    if(el.id == childItem.content_id) {
3063                                        if(quantity > 0){
3064                                            el.quantity = quantity;
3065                                            el.price = childItem.price;
3066                                        } else {
3067                                            array.splice(index, 1);
3068                                        }
3069                                    }
3070                                });
3071                                groupValue += childItem.price * quantity;
3072                            });
3073
3074                            if(options.woo.addToCartOnButtonValueEnabled &&
3075                                options.woo.addToCartOnButtonValueOption !== 'global' &&
3076                                event.params.hasOwnProperty('ecomm_totalvalue')) {
3077                                event.params.ecomm_totalvalue = groupValue;
3078                            }
3079
3080                            if(groupValue == 0) return; // skip if no items selected
3081                        } else {
3082                            // update items qty param
3083                            event.params.items[0].quantity = qty;
3084                        }
3085
3086                        // maybe customize value option
3087                        if (options.woo.addToCartOnButtonValueEnabled &&
3088                            options.woo.addToCartOnButtonValueOption !== 'global' &&
3089                            product_type !== Utils.PRODUCT_GROUPED)
3090                        {
3091                            if(event.params.hasOwnProperty('ecomm_totalvalue')) {
3092                                event.params.ecomm_totalvalue = event.params.items[0].price * qty;
3093                            }
3094                        }
3095
3096
3097
3098                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
3099                        eventName = normalizeEventName(eventName);
3100
3101                        this.fireEvent(eventName, event);
3102
3103                    }
3104                }
3105
3106            },
3107
3108            onWooCheckoutProgressStep: function (event) {
3109                this.fireEvent(event.name, event);
3110            },
3111
3112            onWooSelectContent: function (event) {
3113                this.fireEvent(event.name, event);
3114            },
3115
3116            onWooRemoveFromCartEvent: function (event) {
3117                this.fireEvent(event.name, event);
3118            },
3119
3120            onWooAffiliateEvent: function (product_id) {
3121                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
3122                    return;
3123                var event = options.dynamicEvents.woo_affiliate[this.tag()];
3124
3125                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3126                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
3127
3128                        event = Utils.clone(event );
3129                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
3130                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
3131
3132                    }
3133                }
3134
3135            },
3136
3137            onWooPayPalEvent: function (event) {
3138                this.fireEvent(event.name, event);
3139            },
3140
3141            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
3142                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3143                    return;
3144                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
3145
3146
3147                if (window.pysEddProductData.hasOwnProperty(download_id)) {
3148
3149                    var index;
3150
3151                    if (price_index) {
3152                        index = download_id + '_' + price_index;
3153                    } else {
3154                        index = download_id;
3155                    }
3156
3157                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
3158                        if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) {
3159
3160                            Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params);
3161
3162                            // update items qty param
3163                            event.params.items[0].quantity = qty;
3164
3165                            this.fireEvent(event.name,event);
3166
3167                        }
3168                    }
3169
3170                }
3171
3172            },
3173
3174            onEddRemoveFromCartEvent: function (event) {
3175                this.fireEvent(event.name, event);
3176            },
3177
3178            onPageScroll: function (event) {
3179                if (initialized && this.isEnabled()) {
3180                    this.fireEvent(event.name, event);
3181                }
3182            },
3183            onTime: function (event) {
3184                if (initialized && this.isEnabled()) {
3185                    this.fireEvent(event.name, event);
3186                }
3187            },
3188        };
3189
3190    }(options);
3191
3192    var GAds = function (options) {
3193
3194        var initialized = false;
3195        var isAllowEnhancedConversions = false
3196        /**
3197         * Fires event
3198         *
3199         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
3200         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
3201         * @link: https://developers.google.com/gtagjs/reference/event
3202         * @link: https://developers.google.com/gtagjs/reference/parameter
3203         */
3204        function fireEvent(name, data) {
3205
3206            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(event_name,'google_ads')) {
3207                return;
3208            }
3209
3210            var _params = Utils.copyProperties(data.params,{});
3211            var ids = data.ids;
3212
3213            var conversion_labels = data.conversion_labels;
3214            Utils.copyProperties(Utils.getRequestParams(), _params);
3215            var _fireEvent = function (conversion_id,event_name) {
3216
3217                params = Utils.copyProperties(_params, { send_to: conversion_id });
3218
3219                if("conversion" === event_name) {
3220                    delete params.items;
3221                    delete params.ecomm_pagetype;
3222                    delete params.ecomm_prodid;
3223                    delete params.ecomm_totalvalue;
3224                }
3225
3226                if (options.debug) {
3227                    console.log('[Google Ads #' + conversion_id + '] ' + event_name, params);
3228                }
3229
3230                gtag('event', event_name, params);
3231
3232            };
3233
3234            if(conversion_labels.length > 0) {  // if custom event have conversion_label
3235                conversion_labels.forEach(function (conversion_id) {
3236                    _fireEvent(conversion_id,name);
3237                });
3238            } else { // if normal event have conversion_label or custom without conversion_label
3239
3240                data.conversion_ids.forEach(function (conversion_id) { // send main event
3241                    _fireEvent(conversion_id,name);
3242                });
3243
3244                if (ids.length) {
3245                    ids.forEach(function (conversion_id) {  // send conversion event next to main(not use for custom events)
3246                        _fireEvent(conversion_id,"conversion");
3247                    });
3248                }
3249            }
3250        }
3251
3252        function normalizeEventName(eventName) {
3253
3254            var matches = {
3255                ViewContent: 'view_item',
3256                AddToCart: 'add_to_cart',
3257                AddToWishList: 'add_to_wishlist',
3258                InitiateCheckout: 'begin_checkout',
3259                Purchase: 'purchase',
3260                Lead: 'generate_lead',
3261                CompleteRegistration: 'sign_up',
3262                AddPaymentInfo: 'set_checkout_option'
3263            };
3264
3265            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
3266
3267        }
3268
3269        /**
3270         * Public API
3271         */
3272        return {
3273            tag: function() {
3274                return "google_ads";
3275            },
3276            isEnabled: function () {
3277                return options.hasOwnProperty('google_ads');
3278            },
3279
3280            disable: function () {
3281                initialized = false;
3282            },
3283
3284            updateEnhancedConversionData : function () {
3285
3286                if(isAllowEnhancedConversions) {
3287                    var advanced = Utils.getAdvancedFormData()
3288                    if(Object.keys(options.google_ads.user_data).length == 0) {
3289                        if(advanced["email"].length > 0) {
3290                            gtag('set', 'user_data', {"email":advanced["email"]});
3291                        }
3292                    }
3293                }
3294            },
3295
3296            loadPixel: function () {
3297
3298                if (initialized || !this.isEnabled() || !Utils.consentGiven('google_ads')) {
3299                    return;
3300                }
3301
3302                Utils.loadGoogleTag(options.google_ads.conversion_ids[0]);
3303
3304                // configure conversion ids
3305                options.google_ads.conversion_ids.forEach(function (conversion_id,index) {
3306
3307                    gtag('config', conversion_id);
3308
3309                    if(options.google_ads.enhanced_conversion.includes("index_"+index)) {
3310                        isAllowEnhancedConversions = true
3311                        gtag('config', conversion_id,{ 'allow_enhanced_conversions':true });
3312                    }
3313
3314                    if(isAllowEnhancedConversions) {
3315                        var advanced = Utils.getAdvancedFormData()
3316                        if(Object.keys(options.google_ads.user_data).length > 0) {
3317                            gtag('set', 'user_data', options.google_ads.user_data);
3318                        } else if(advanced["email"].length > 0) {
3319                            gtag('set', 'user_data', {"email":advanced["email"]});
3320                        }
3321                    }
3322
3323                });
3324
3325                initialized = true;
3326
3327                Utils.fireStaticEvents('google_ads');
3328
3329            },
3330
3331            fireEvent: function (name, data) {
3332
3333                if (!initialized || !this.isEnabled()) {
3334                    return false;
3335                }
3336
3337                data.delay = data.delay || 0;
3338                data.params = data.params || {};
3339                data.ids = data.ids || [];
3340                data.conversion_labels = data.conversion_labels || [];
3341
3342                if (data.delay === 0) {
3343                    fireEvent(name, data);
3344                } else {
3345                    setTimeout(function (name, data) {
3346                        fireEvent(name, data);
3347                    }, data.delay * 1000, name, data);
3348                }
3349
3350                return true;
3351
3352            },
3353
3354            onAdSenseEvent: function (event) {
3355                this.fireEvent(event.name, event);
3356            },
3357
3358            onClickEvent: function (action, params) {
3359                //disabled
3360            },
3361
3362            onWatchVideo: function (event) {
3363                this.fireEvent(event.name, event);
3364            },
3365
3366            onCommentEvent: function (event) {
3367                this.fireEvent(event.name, event);
3368            },
3369
3370            onFormEvent: function (event) {
3371                this.fireEvent(event.name, event);
3372            },
3373
3374            onDownloadEvent: function (event) {
3375                this.fireEvent(event.name, event);
3376            },
3377
3378
3379
3380
3381            onWooAddToCartOnButtonEvent: function (product_id) {
3382
3383                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3384                    return;
3385
3386                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3387                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
3388
3389                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
3390                        Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']['params'].params, event.params)
3391                        event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids']
3392                        event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels']
3393                        this.fireEvent(event.name, event);
3394                    }
3395                }
3396
3397            },
3398
3399            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
3400
3401                window.pysWooProductData = window.pysWooProductData || [];
3402                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3403                    return;
3404                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
3405
3406                if (product_type === Utils.PRODUCT_VARIABLE && !options.google_ads.wooVariableAsSimple) {
3407                    product_id = parseInt($form.find('input[name="variation_id"]').val());
3408                }
3409
3410                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3411                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
3412
3413                        Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']["params"], event.params);
3414                        event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids']
3415                        event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels']
3416
3417                        var groupValue = 0;
3418                        if(product_type === Utils.PRODUCT_GROUPED ) {
3419                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
3420                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
3421                                var quantity = parseInt($(this).val());
3422                                if(isNaN(quantity)) {
3423                                    quantity = 0;
3424                                }
3425
3426                                var childItem = window.pysWooProductData[product_id]['google_ads'].grouped[childId];
3427
3428                                if(options.woo.addToCartOnButtonValueEnabled &&
3429                                    options.woo.addToCartOnButtonValueOption !== 'global') {
3430
3431                                    event.params.items.forEach(function(el,index,array) {
3432                                        if(el.id == childItem.content_id) {
3433                                            if(quantity > 0){
3434                                                el.quantity = quantity;
3435                                                el.price = childItem.price;
3436                                            } else {
3437                                                array.splice(index, 1);
3438                                            }
3439                                        }
3440                                    });
3441                                }
3442                                groupValue += childItem.price * quantity;
3443                            });
3444                            if(groupValue == 0) return;
3445                            event.params.value = groupValue;
3446                        } else {
3447                            // update items qty param
3448                            event.params.items[0].quantity = qty;
3449                        }
3450
3451
3452
3453                        // maybe customize value option
3454                        if (options.woo.addToCartOnButtonValueEnabled &&
3455                            options.woo.addToCartOnButtonValueOption !== 'global' &&
3456                            product_type !== Utils.PRODUCT_GROUPED) {
3457                            event.params.value =  event.params.value * qty;
3458                        }
3459
3460
3461
3462                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
3463                        eventName = normalizeEventName(eventName);
3464
3465                        this.fireEvent(eventName, event);
3466
3467                    }
3468                }
3469
3470            },
3471
3472            onWooRemoveFromCartEvent: function (event) {
3473                this.fireEvent(event.name, event);
3474            },
3475
3476            onWooAffiliateEvent: function (product_id) {
3477                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
3478                    return;
3479                var event = options.dynamicEvents.woo_affiliate[this.tag()];
3480
3481                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3482                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
3483
3484                        event = Utils.clone(event)
3485                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
3486                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
3487
3488                    }
3489                }
3490
3491            },
3492
3493            onWooPayPalEvent: function (event) {
3494                this.fireEvent(event.name, event);
3495            },
3496
3497            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
3498                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3499                    return;
3500                var event = options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()];
3501
3502
3503                if (window.pysEddProductData.hasOwnProperty(download_id)) {
3504
3505                    var index;
3506
3507                    if (price_index) {
3508                        index = download_id + '_' + price_index;
3509                    } else {
3510                        index = download_id;
3511                    }
3512
3513                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
3514                        if (window.pysEddProductData[download_id][index].hasOwnProperty('google_ads')) {
3515
3516                            event = Utils.clone(event)
3517                            Utils.copyProperties(window.pysEddProductData[download_id][index]['google_ads']['params'], event.params);
3518                            event.ids = window.pysEddProductData[download_id][index]['google_ads']['ids']
3519                            // update items qty param
3520                            //params.items[0].quantity = qty;
3521
3522                            this.fireEvent(event.name, event);
3523
3524                        }
3525                    }
3526
3527                }
3528
3529            },
3530
3531            onEddRemoveFromCartEvent: function (event) {
3532                this.fireEvent(event.name, event);
3533            },
3534            onPageScroll: function (event) {
3535                if (initialized && this.isEnabled()) {
3536                    this.fireEvent(event.name, event);
3537                }
3538            },
3539            onTime: function (event) {
3540                if (initialized && this.isEnabled()) {
3541                    this.fireEvent(event.name, event);
3542                }
3543            },
3544
3545        };
3546
3547    }(options);
3548
3549    window.pys = window.pys || {};
3550    window.pys.Facebook = Facebook;
3551    window.pys.Analytics = Analytics;
3552    window.pys.GAds = GAds;
3553    window.pys.Utils = Utils;
3554    window.pys.TikTok = TikTok;
3555
3556
3557
3558    $(document).ready(function () {
3559
3560
3561        if($("#pys_late_event").length > 0) {
3562            var events =  JSON.parse($("#pys_late_event").attr("dir"));
3563            for(var key in events) {
3564                var event = {};
3565                event[events[key].e_id] = [events[key]];
3566                if(options.staticEvents.hasOwnProperty(key)) {
3567                    Object.assign(options.staticEvents[key], event);
3568                } else {
3569                    options.staticEvents[key] = event;
3570                }
3571
3572            }
3573        }
3574
3575        var Pinterest = Utils.setupPinterestObject();
3576        var Bing = Utils.setupBingObject();
3577        if((options.woo.enabled || options.edd.enabled) && (options.woo.enabled_save_data_to_orders || options.edd.enabled_save_data_to_orders))
3578        {
3579            Utils.manageCookies();
3580        }
3581        else
3582        {
3583            Cookies.remove('pys_first_visit')
3584            Cookies.remove('pysTrafficSource')
3585            Cookies.remove('pys_landing_page')
3586            Cookies.remove('last_pys_landing_page')
3587            Cookies.remove('last_pysTrafficSource')
3588            Cookies.remove('pys_start_session')
3589            Cookies.remove('pys_session_limit')
3590
3591            $.each(Utils.utmTerms, function (index, name) {
3592                Cookies.remove('pys_' + name)
3593            });
3594            $.each(Utils.utmId,function(index,name) {
3595                Cookies.remove('pys_' + name)
3596            })
3597            $.each(Utils.utmTerms, function (index, name) {
3598                Cookies.remove('last_pys_' + name)
3599            });
3600            $.each(Utils.utmId,function(index,name) {
3601                Cookies.remove('last_pys_' + name)
3602            });
3603        }
3604
3605        Utils.initializeRequestParams();
3606        Utils.setupGdprCallbacks();
3607
3608
3609        //Setup Advanced Form Data
3610        if(options.enable_auto_save_advance_matching) {
3611            $(document).on("blur","input[type='email']",function () {
3612                let email = $(this).val().trim().toLowerCase();
3613                if(Utils.validateEmail(email)) {
3614                    Utils.saveAdvancedFormData(email,null,null,null);
3615                }
3616            })
3617            $(document).on("blur","input[type='tel']",function () {
3618                let phone = $(this).val().trim().replace(/\D/g, "");
3619                if(phone.length > 5) {
3620                    Utils.saveAdvancedFormData(null,phone,null,null);
3621                }
3622            })
3623            $(document).on("blur","input[type='text']",function () {
3624                let name;
3625                if($(this).attr("name") && $(this).attr("name") != '')
3626                {
3627                    name = $(this).attr("name").trim()
3628                }
3629                if(name && options.advance_matching_fn_names.includes(name)) {
3630                    let value = $(this).val().trim();
3631                    if(value.length > 0) {
3632                        Utils.saveAdvancedFormData(null,null,value,null);
3633                    }
3634                }
3635                if(name && options.advance_matching_ln_names.includes(name)) {
3636                    let value = $(this).val().trim();
3637                    if(value.length > 0) {
3638                        Utils.saveAdvancedFormData(null,null,null,value);
3639                    }
3640                }
3641                if(name && options.advance_matching_tel_names.includes(name)) {
3642                    let value = $(this).val().trim();
3643                    if(value.length > 0) {
3644                        Utils.saveAdvancedFormData(null,value,null,null);
3645                    }
3646                }
3647
3648            })
3649        }
3650
3651
3652
3653
3654        // setup Click Event
3655        if (
3656            options.dynamicEvents.hasOwnProperty("automatic_event_internal_link") ||
3657            options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link") ||
3658            options.dynamicEvents.hasOwnProperty("automatic_event_tel_link") ||
3659            options.dynamicEvents.hasOwnProperty("automatic_event_email_link") ||
3660            options.dynamicEvents.hasOwnProperty("automatic_event_download")
3661        ) {
3662
3663            $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) {
3664
3665                var $elem = $(this);
3666
3667
3668                // Download
3669                if(options.dynamicEvents.hasOwnProperty("automatic_event_download")) {
3670                    var isFired = false;
3671                    if ($elem.is('a')) {
3672                        var href = $elem.attr('href');
3673                        if (typeof href !== "string") {
3674                            return;
3675                        }
3676                        href = href.trim();
3677                        var extension = Utils.getLinkExtension(href);
3678                        var track_download = false;
3679
3680                        if (extension.length > 0) {
3681
3682                            if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) {
3683                                var pixels = Object.keys(options.dynamicEvents.automatic_event_download);
3684                                for (var i = 0; i < pixels.length; i++) {
3685                                    var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]);
3686                                    var extensions = event.extensions;
3687                                    if (extensions.includes(extension)) {
3688
3689                                        if(pixels[i] == "tiktok") {
3690                                            getPixelBySlag(pixels[i]).fireEvent(event.name, event);
3691                                        } else {
3692                                            if (options.enable_remove_download_url_param) {
3693                                                href = href.split('?')[0];
3694                                            }
3695                                            event.params.download_url = href;
3696                                            event.params.download_type = extension;
3697                                            event.params.download_name = Utils.getLinkFilename(href);
3698                                            getPixelBySlag(pixels[i]).onDownloadEvent(event);
3699                                        }
3700
3701                                        isFired = true;
3702                                    }
3703                                }
3704                            }
3705                        }
3706                    }
3707                    if(isFired) { // prevent duplicate events on the same element
3708                        return;
3709                    }
3710                }
3711
3712
3713                if (!e.hasOwnProperty('originalEvent')) {
3714                    return;
3715                }
3716                if($elem.hasClass("add_to_cart_button") ||
3717                    $elem.hasClass("single_add_to_cart_button") ) { // add_to_cart_button fire in woo
3718                    return;
3719                }
3720
3721                if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")
3722                    && $elem.hasClass("wcf-next-step-link")) {
3723                    return;// add_to_cart_button fire in woo cf
3724                }
3725                if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")
3726                    && $elem.hasClass("wcf-bump-order-cb")) {
3727                    return;// add_to_cart_button fire in woo cf
3728                }
3729
3730                if($elem.hasClass("remove_from_cart_button") ) { // cancel remove from cart
3731                    return;
3732                }
3733                if($elem.hasClass("remove") ) { // cancel remove from cart
3734                    if($elem.parents('.cart_item').length || $elem.parents('.mini_cart_item').length)
3735                    return;
3736                }
3737                if($elem.attr("name") == "update_cart" || $elem.attr("name") == "apply_coupon") { // cancel update  c
3737art or coupon button
3738                    return;
3739                }
3740
3741
3742                if ($elem.hasClass('pys_block')) {
3743                    return; // avoiding fake double clicks from Affiliate event
3744                }
3745                var text = "";
3746                var target_url = "";
3747                var linkType = "Internal Click";
3748
3749                if ($elem.is('a')) {
3750                    var href = $elem.attr('href');
3751
3752                    // fixes #112
3753                    if (typeof href !== "string") {
3754                        return;
3755                    }
3756                    href = href.trim();
3757
3758                    text = $elem.text();
3759                    if(options.enable_remove_target_url_param) {
3760                        target_url = href.split('?')[0];
3761                    } else {
3762                        target_url = href
3763                    }
3764
3765
3766                    //Email Event
3767                    if (href.startsWith('mailto:')) {
3768                        if(options.dynamicEvents.hasOwnProperty("automatic_event_email_link")) {
3769                            var pixels = Object.keys(options.dynamicEvents.automatic_event_email_link);
3770                            for(var i = 0;i<pixels.length;i++) {
3771                                var event = Utils.clone(options.dynamicEvents.automatic_event_email_link[pixels[i]]);
3772                                Utils.copyProperties(Utils.getRequestParam
3772s(), event.params);
3773                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
3774                            }
3775                        }
3776
3777                        return; // not fire next
3778                    }
3779
3780                    // Phone
3781                    if (href.startsWith('tel:')) {
3782                        if(options.dynamicEvents.hasOwnProperty("automatic_event_tel_link")) {
3783                            var pixels = Object.keys(options.dynamicEvents.automatic_event_tel_link);
3784                            for(var i = 0;i<pixels.length;i++) {
3785                                var event = Utils.clone(options.dynamicEvents.automatic_event_tel_link[pixels[i]]);
3786                                Utils.copyProperties(Utils.getRequestParams(), event.params);
3787                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
3788                            }
3789                        }
3790                        return; // not fire next
3791                    }
3792
3793                    if (href.startsWith('http')) {
3794                        // link type
3795                        var host = $elem.context != undefined ? $elem.context.host : $elem[0].host;
3796                        if (document.location.host != host) {
3797                            linkType = 'External Click';
3798                        }
3799                    }
3800                } else if ($elem.is('button')) {
3801                    if( $elem.hasClass("forminator-button-submit")) {
3802                        //disable duplicate events
3803                        return;
3804                    }
3805                    text = $elem.text();
3806                } else if ($elem.is('input[type="button"]')) {
3807                    text = $elem.val();
3808                } else if ($elem.is('input[type="submit"]')) {
3809                    if ( $elem.parents("form.comment-form")) {
3810                        //disable duplicate events
3811                        return;
3812                    }
3813                    if ($elem.parents("form")) {
3814                        //disable duplicate events
3815                        return;
3816                    }
3817                    text = $elem.val();
3818                } else {
3819                    return;
3820                }
3821
3822
3823
3824                text = Utils.filterEmails(text);
3825
3826
3827                if( linkType === "Internal Click"
3828                    && options.dynamicEvents.hasOwnProperty("automatic_event_internal_link")
3829                ) {
3830                    var pixels = Object.keys(options.dynamicEvents.automatic_event_internal_link);
3831
3832                    for(var i = 0;i<pixels.length;i++) {
3833                        var event = Utils.clone(options.dynamicEvents.automatic_event_internal_link[pixels[i]]);
3834
3835                        if(pixels[i] !== "tiktok") { // TT doesn't support custom parameters
3836                            event.params["text"] = text;
3837                            if(target_url){
3838                                event.params["target_url"] = target_url;
3839                            }
3840                            Utils.copyProperties(Utils.getRequestParam
3840s(), event.params);
3841                        }
3842
3843
3844                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
3845                    }
3846                }
3847
3848                if( linkType === "External Click"
3849                    && options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link")
3850                ) {
3851                    var pixels = Object.keys(options.dynamicEvents.automatic_event_outbound_link);
3852
3853                    for(var i = 0;i<pixels.length;i++) {
3854                        var event = Utils.clone(options.dynamicEvents.automatic_event_outbound_link[pixels[i]]);
3855
3856                        if(pixels[i] !== "tiktok") { // TT doesn't support custom parameters
3857                            event.params["text"] = text;
3858                            if(target_url){
3859                                event.params["target_url"] = target_url;
3860                            }
3861                            Utils.copyProperties(Utils.getRequestParams(), event.params);
3862                        }
3863
3864
3865                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
3866                    }
3867                }
3868
3869
3870
3871
3872            });
3873
3874        }
3875
3876        // setup AdSense Event
3877        if (options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) {
3878
3879            var isOverGoogleAd = false;
3880
3881            $(document)
3882                .on('mouseover', 'ins iframe', function () { //class adsbygoogle adsbygoogle-noablate ??
3883                    isOverGoogleAd = true;
3884                })
3885                .on('mouseout', 'iframe', function () {
3886                    isOverGoogleAd = false;
3887                });
3888
3889            $(window)
3890                .on( "blur",function () {
3891                    if (isOverGoogleAd) {
3892                        console.log('automatic_event_adsense')
3893                        if(options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) {
3894                            var pixels = Object.keys(options.dynamicEvents.automatic_event_adsense);
3895                            for (var i = 0; i < pixels.length; i++) {
3896                                var event = Utils.clone(options.dynamicEvents.automatic_event_adsense[pixels[i]]);
3897                                Utils.copyProperties(Utils.getRequestParam
3897s(), event.params);
3898                                getPixelBySlag(pixels[i]).onAdSenseEvent(event);
3899                            }
3900                        }
3901
3902                        $.each(options.triggerEventTypes, function (triggerType, events) {
3903                            $.each(events, function (eventId, triggers) {
3904                                switch (triggerType) {
3905                                    case 'ad_sense_click':
3906                                        Utils.fireTriggerEvent(eventId);
3907                                        break;
3908                                }
3909                            });
3910                        });
3911                    }
3912                })
3913                .trigger("focus");
3914
3915        }
3916
3917        //setup adsense for custom events
3918        var dynamicAdsenseEventsTriggers = 0
3919        $.each(options.triggerEventTypes, function (triggerType, events) {
3920            if(triggerType == "ad_sense_click") {
3921                dynamicAdsenseEventsTriggers++;
3922            }
3923        });
3924        if (dynamicAdsenseEventsTriggers > 0) {
3925
3926            var isOverGoogleAd = false;
3927
3928            $(document)
3929                .on('mouseover', 'ins > ins > iframe', function () {
3930                    isOverGoogleAd = true;
3931                })
3932                .on('mouseout', 'iframe', function () {
3933                    isOverGoogleAd = false;
3934                });
3935
3936            $(window)
3937                .on( "blur",function () {
3938                    if (isOverGoogleAd) {
3939
3940                        $.each(options.triggerEventTypes, function (triggerType, events) {
3941                            $.each(events, function (eventId, triggers) {
3942                                switch (triggerType) {
3943                                    case 'ad_sense_click':
3944                                        Utils.fireTriggerEvent(eventId);
3945                                        break;
3946                                }
3947                            });
3948                        });
3949                    }
3950                })
3951                .trigger("focus");
3952
3953        }
3954
3955
3956        // page scroll event
3957        if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")
3958        ) {
3959
3960            var singlePageScroll = function () {
3961
3962
3963                var docHeight = $(document).height() - $(window).height();
3964                var isFired = false;
3965
3966                if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) {
3967                    var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll);
3968                    for(var i = 0;i<pixels.length;i++) {
3969                        var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]);
3970                        var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions
3971
3972                        if(scroll < $(window).scrollTop()) {
3973                            Utils.copyProperties(Utils.getRequestParam
3973s(), event.params);
3974                            getPixelBySlag(pixels[i]).onPageScroll(event);
3975                            isFired = true
3976                        }
3977                    }
3978                }
3979                if(isFired) {
3980                    $(document).off("scroll",singlePageScroll);
3981                }
3982            }
3983            $(document).on("scroll",singlePageScroll);
3984        }
3985
3986
3987        if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) {
3988            var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page);
3989            var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel
3990            setTimeout(function(){
3991                for(var i = 0;i<pixels.length;i++) {
3992                    var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]);
3993                    Utils.copyProperties(Utils.getRequestParams(), event.params);
3994                    getPixelBySlag(pixels[i]).onTime(event);
3995                }
3996            },time*1000);
3997        }
3998
3999        // setup Dynamic events
4000
4001        $.each(options.triggerEventTypes, function (triggerType, events) {
4002
4003            $.each(events, function (eventId, triggers) {
4004                switch (triggerType) {
4005                    case 'url_click':
4006                        //@see: Utils.setupURLClickEvents()
4007                        break;
4008
4009                    case 'css_click':
4010                        Utils.setupCSSClickEvents(eventId, triggers);
4011                        break;
4012
4013                    case 'css_mouseover':
4014                        Utils.setupMouseOverClickEvents(eventId, triggers);
4015                        break;
4016
4017                    case 'scroll_pos':
4018                        Utils.setupScrollPosEvents(eventId, triggers);
4019                        break;
4020                    case 'comment':
4021                        Utils.setupCommentEvents(eventId, triggers);
4022                        break;
4023                }
4024
4025            });
4026
4027        });
4028
4029        // setup WooCommerce events
4030        if (options.woo.enabled) {
4031
4032            // Woo CartFlow AddToCart
4033            if (options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")) {
4034                $("body").on("click",'.wcf-next-step-link',function () {
4035                    var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_next_step_click);
4036                    for(var i = 0;i<pixels.length;i++) {
4037                        var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_next_step_click[pixels[i]])
4038                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
4039                    }
4040                });
4041            }
4042            // Woo CartFlow Bump AddToCart
4043            if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click") ||
4044                options.dynamicEvents.hasOwnProperty("wcf_bump")) {
4045                $("body").on('change','.wcf-bump-order-cb',function () {
4046
4047                    if(this.checked) {
4048                        if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")) {
4049                            var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_bump_click);
4050                            for(var i = 0;i<pixels.length;i++) {
4051                                var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_bump_click[pixels[i]]);
4052                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
4053                            }
4054                        }
4055
4056
4057                        if(options.dynamicEvents.hasOwnProperty("wcf_bump")) {
4058                            var pixels = Object.keys(options.dynamicEvents.wcf_bump);
4059                            for(var i = 0;i<pixels.length;i++) {
4060                                var event = Utils.clone(options.dynamicEvents.wcf_bump[pixels[i]]);
4061                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
4062                            }
4063                        }
4064
4065                    } else {
4066                        if(options.dynamicEvents.hasOwnProperty("wcf_remove_from_cart_on_bump_click")) {
4067                            var pixels = Object.keys(options.dynamicEvents.wcf_remove_from_cart_on_bump_click);
4068                            for(var i = 0;i<pixels.length;i++) {
4069                                var event = Utils.clone(options.dynamicEvents.wcf_remove_from_cart_on_bump_click[pixels[i]]);
4070                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
4071                            }
4072                        }
4073
4074                    }
4075
4076
4077                });
4078            }
4079
4080
4081            // WooCommerce AddToCart
4082            if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")
4083                && options.woo.hasOwnProperty("addToCartCatchMethod")
4084                && options.woo.addToCartCatchMethod === "add_cart_js"
4085            ) {
4086
4087                // Loop, any kind of "simple" product, except external
4088                $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
4089
4090                    var product_id = $(this).data('product_id');
4091
4092                    if (typeof product_id !== 'undefined') {
4093                        Facebook.onWooAddToCartOnButtonEvent(product_id,$(this));
4094                        Analytics.onWooAddToCartOnButtonEvent(product_id);
4095                        GAds.onWooAddToCartOnButtonEvent(product_id);
4096                        Pinterest.onWooAddToCartOnButtonEvent(product_id);
4097                        Bing.onWooAddToCartOnButtonEvent(product_id);
4098                        TikTok.onWooAddToCartOnButtonEvent(product_id);
4099                    }
4100
4101                });
4102
4103                // Single Product
4104                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
4105                //  $(document) not work
4106                $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
4107
4108                    var $button = $(this);
4109
4110                    if ($button.hasClass('disabled')) {
4111                        return;
4112                    }
4113
4114                    var $form = $button.closest('form');
4115
4116                    var product_type = Utils.PRODUCT_SIMPLE;
4117                    var is_external = false;
4118
4119                    if ($form.length === 0) {
4120                        is_external = true;
4121                    } else if ($form.hasClass('variations_form')) {
4122                        product_type = Utils.PRODUCT_VARIABLE;
4123                    } else if($form.hasClass('bundle_form')) {
4124                        product_type = Utils.PRODUCT_BUNDLE;
4125                    } else if($form.hasClass('grouped_form')) {
4126                        product_type = Utils.PRODUCT_GROUPED;
4127                    }
4128
4129
4130
4131                    var product_id;
4132                    var qty;
4133                    if (product_type === Utils.PRODUCT_GROUPED) {
4134                        qty = 1;
4135                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
4136                    } else if (product_type === Utils.PRODUCT_VARIABLE) {
4137                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
4138                        var qtyTag = $form.find('input[name="quantity"]');
4139                        if(qtyTag.length <= 0) {
4140                            qtyTag = $form.find('select[name="quantity"]');
4141                        }
4142                        qty = parseInt(qtyTag.val());
4143                    } else if (is_external) {
4144                        product_id = options.woo.singleProductId;
4145                        qty = 1;
4146                    } else {
4147                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
4148                        var qtyTag = $form.find('input[name="quantity"]');
4149                        if(qtyTag.length <= 0) {
4150                            qtyTag = $form.find('select[name="quantity"]');
4151                        }
4152                        qty = parseInt(qtyTag.val());
4153                    }
4154
4155                    Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
4156                    Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
4157                    GAds.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
4158                    Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
4159                    Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
4160                    TikTok.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
4161                });
4162
4163            }
4164
4165            // WooCommerce Affiliate
4166            if (options.dynamicEvents.hasOwnProperty("woo_affiliate")) {
4167
4168                // Loop, external
4169                $('.product_type_external').on("click",function (e) {
4170
4171                    var product_id = $(this).data('product_id');
4172
4173                    if (typeof product_id !== 'undefined') {
4174                        Facebook.onWooAffiliateEvent(product_id);
4175                        Analytics.onWooAffiliateEvent(product_id);
4176                        GAds.onWooAffiliateEvent(product_id);
4177                        Pinterest.onWooAffiliateEvent(product_id);
4178                        Bing.onWooAffiliateEvent(product_id);
4179                    }
4180
4181                });
4182
4183            }
4184
4185            // WooCommerce RemoveFromCart
4186            if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) {
4187
4188                $('body').on('click', options.woo.removeFromCartSelector, function (e) {
4189
4190                    var $a = $(e.currentTarget),
4191                        href = $a.attr('href');
4192
4193                    // extract cart item hash from remove button URL
4194                    var regex = new RegExp("[\\?&]remove_item=([^&#]*)"),
4195                        results = regex.exec(href);
4196
4197                    if (results !== null) {
4198
4199                        var item_hash = results[1];
4200
4201                        if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) {
4202                            var events = options.dynamicEvents["woo_remove_from_cart"][item_hash];
4203                            Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events)
4204                        }
4205
4206                    }
4207
4208                });
4209
4210            }
4211
4212            // WooCommerce PayPal
4213            if (options.dynamicEvents.hasOwnProperty("woo_paypal")) {
4214
4215                // Non-default binding used to avoid situations when some code in external js
4216                // stopping events propagation, eg. returns false, and our handler will never called
4217                $(document).onFirst('submit click', '#place_order', function (e) {
4218
4219                    var method = $('form[name="checkout"] input[name="payment_method"]:checked').val();
4220
4221                    if (method !== 'paypal') {
4222                        return;
4223                    }
4224                    var events = options.dynamicEvents.woo_paypal;
4225                    Utils.fireEventForAllPixel("onWooPayPalEvent",events)
4226
4227                });
4228
4229            }
4230
4231            // WooCommerce checkout progress
4232            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_f") ) {
4233
4234                $(document).on("change",".woocommerce-validated #billing_first_name",function () {
4235                    Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_f[Analytics.tag()]);
4236                });
4237            }
4238            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_l")) {
4239
4240                $(document).on("change",".woocommerce-validated #billing_last_name",function () {
4241                    Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_l[Analytics.tag()]);
4242                });
4243            }
4244
4245            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_e")) {
4246
4247                $(document).on("change",".woocommerce-validated #billing_email",function () {
4248                    Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_e[Analytics.tag()]);
4249                });
4250            }
4251            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_o")) {
4252                $(document).onFirst('submit click', '#place_order', function () {
4253                    Analytics.onWooCheckoutProgressStep(options.dynamicEvents.woo_initiate_checkout_progress_o[Analytics.tag()]);
4254                });
4255            }
4256
4257
4258            // WooCommerce
4259            if(options.dynamicEvents.hasOwnProperty("woo_select_content_search") ||
4260                options.dynamicEvents.hasOwnProperty("woo_select_content_shop") ||
4261                options.dynamicEvents.hasOwnProperty("woo_select_content_tag") ||
4262                options.dynamicEvents.hasOwnProperty("woo_select_content_single") ||
4263                options.dynamicEvents.hasOwnProperty("woo_select_content_category")
4264            ) {
4265                $('.product.type-product a.woocommerce-loop-product__link').onFirst('click', function (evt) {
4266                    var productId = $(this).parent().find("a.add_to_cart_button").attr("data-product_id");
4267                    if(options.dynamicEvents.hasOwnProperty("woo_select_content_search") &&
4268                        options.dynamicEvents.woo_select_content_search.hasOwnProperty(productId)) {
4269                        Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_search[productId][Analytics.tag()]);
4270                    } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_shop") &&
4271                        options.dynamicEvents.woo_select_content_shop.hasOwnProperty(productId)) {
4272                        Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_shop[productId][Analytics.tag()]);
4273                    } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_tag") &&
4274                        options.dynamicEvents.woo_select_content_tag.hasOwnProperty(productId)) {
4275                        Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_tag[productId][Analytics.tag()]);
4276                    } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_single") &&
4277                        options.dynamicEvents.woo_select_content_single.hasOwnProperty(productId)) {
4278                        Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_single[productId][Analytics.tag()]);
4279                    } else if(options.dynamicEvents.hasOwnProperty("woo_select_content_category") &&
4280                        options.dynamicEvents.woo_select_content_category.hasOwnProperty(productId)) {
4281                        Analytics.onWooSelectContent(options.dynamicEvents.woo_select_content_category[productId][Analytics.tag()]);
4282                    }
4283                });
4284            }
4285        }
4286
4287        // setup EDD events
4288        if (options.edd.enabled) {
4289
4290            // EDD AddToCart
4291            if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) {
4292
4293                $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) {
4294
4295                    var $button = $(this);
4296                    var $form = $button.closest('form');
4297                    var variable_price = $button.data('variablePrice'); // yes/no
4298                    var price_mode = $button.data('priceMode'); // single/multi
4299                    var ids = [];
4300                    var quantities = [];
4301                    var qty;
4302                    var id;
4303
4304                    if (variable_price === 'yes' && price_mode === 'multi') {
4305
4306                        id = $form.find('input[name="download_id"]').val();
4307
4308                
4308        // get selected variants
4309                        $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) {
4310                            ids.push(id + '_' + $(el).val());
4311                        });
4312
4313                        // get qty for selected variants
4314                        $.each(ids, function (i, variant_id) {
4315
4316                            var variant_index = variant_id.split('_', 2);
4317                            qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val();
4318
4319                            if (typeof qty !== 'undefined') {
4320                                quantities.push(qty);
4321                            } else {
4322                                quantities.push(1);
4323                            }
4324
4325                        });
4326
4327                    } else if (variable_price === 'yes' && price_mode === 'single') {
4328
4329                        id = $form.find('input[name="download_id"]').val();
4330                        ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val());
4331
4332                        qty = $form.find('input[name="edd_download_quantity"]').val();
4333
4334                        if (typeof qty !== 'undefined') {
4335                            quantities.push(qty);
4336                        } else {
4337                            quantities.push(1);
4338                        }
4339
4340                    } else {
4341
4342                        ids.push($button.data('downloadId'));
4343
4344                        qty = $form.find('input[name="edd_download_quantity"]').val();
4345
4346                        if (typeof qty !== 'undefined') {
4347                            quantities.push(qty);
4348                        } else {
4349                            quantities.push(1);
4350                        }
4351                    }
4352
4353                    // fire event for each download/variant
4354                    $.each(ids, function (i, download_id) {
4355
4356                        var q = parseInt(quantities[i]);
4357                        var variant_index = download_id.toString().split('_', 2);
4358                        var price_index;
4359
4360                        if (variant_index.length === 2) {
4361                            download_id = variant_index[0];
4362                            price_index = variant_index[1];
4363                        }
4364
4365                        Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q);
4366                        Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q);
4367                        GAds.onEddAddToCartOnButtonEvent(download_id, price_index, q);
4368                        Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q);
4369                        Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q);
4370                        TikTok.onEddAddToCartOnButtonEvent(download_id, price_index, q);
4371
4372                    });
4373
4374                });
4375
4376            }
4377
4378            // EDD RemoveFromCart
4379            if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) {
4380
4381                $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) {
4382
4383                    var href = $(this).attr('href');
4384                    var key = href.substring(href.indexOf('=') + 1).charAt(0);
4385
4386                    if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) {
4387                        var events = options.dynamicEvents.edd_remove_from_cart[key];
4388                        Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events)
4389                    }
4390
4391                });
4392
4393            }
4394
4395        }
4396
4397        Utils.setupURLClickEvents();
4398
4399        // setup Comment Event
4400        if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")
4401        ) {
4402
4403            $('form.comment-form').on("submit",function () {
4404                if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) {
4405                    var pixels = Object.keys(options.dynamicEvents.automatic_event_comment);
4406                    for (var i = 0; i < pixels.length; i++) {
4407                        var event = Utils.clone(options.dynamicEvents.automatic_event_c
4407omment[pixels[i]]);
4408                        Utils.copyProperties(Utils.getRequestParams(), event.params);
4409                        getPixelBySlag(pixels[i]).onCommentEvent(event);
4410                    }
4411                }
4412            });
4413
4414        }
4415
4416        // setup Form Event
4417        if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
4418
4419            $(document).onFirst('submit', 'form', function (e) {
4420
4421                var $form = $(this);
4422
4423                // exclude WP forms
4424                if ($form.hasClass('comment-form') || $form.hasClass('search-form') || $form.attr('id') === 'adminbarsearch') {
4425                    return;
4426                }
4427
4428                // exclude Woo forms
4429                if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') ||
4430                    $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) {
4431                    return;
4432                }
4433
4434                // exclude EDD forms
4435                if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) {
4436                    return;
4437                }
4438                // exclude CF7 forms
4439                if ($form.hasClass('wpcf7-form')) {
4440                    return;
4441                }
4442                // exclude Forminator forms
4443                if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) {
4444                    return;
4445                }
4446                // exclude WPforms forms
4447                if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) {
4448                    return;
4449                }
4450                // exclude Formidable forms
4451                /*if ($form.hasClass('frm-show-form')) {
4452                    return;
4453                }*/
4454                // exclude Ninja Forms forms
4455                if ($form.parent().hasClass('nf-form-layout')) {
4456                    return;
4457                }
4458                // exclude Fluent forms
4459                if ($form.hasClass('frm-fluent-form')) {
4460                    return;
4461                }
4462                if(!options.enable_success_send_form) {
4463                    var params = {
4464                        form_id: $form.attr('id'),
4465                        form_class: $form.attr('class'),
4466                        text: $form.find('[type="submit"]').is('input') ?
4467                            $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text()
4468                    };
4469
4470                    if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
4471                        var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
4472                        for (var i = 0; i < pixels.length; i++) {
4473                            var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]);
4474
4475                            if (pixels[i] === "tiktok") {
4476                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
4477                            } else {
4478                                Utils.copyProperties(params, event.params,)
4479                                Utils.copyProperties(Utils.getRequestParam
4479s(), event.params);
4480                                getPixelBySlag(pixels[i]).onFormEvent(event);
4481                            }
4482                        }
4483                    }
4484                }
4485            });
4486
4487
4488        }
4489        document.addEventListener( 'wpcf7mailsent', function( event ) {
4490            var form_id = event.detail.contactFormId;
4491            var sendEventId = null;
4492            var disabled_form_action = false;
4493            if(options.triggerEventTypes.hasOwnProperty('CF7'))
4494            {
4495                key_event = Object.keys(options.triggerEventTypes.CF7)[0];
4496                if(options.triggerEventTypes.CF7[key_event].hasOwnProperty('disabled_form_action'))
4497                {
4498                    disabled_form_action = options.triggerEventTypes.CF7[key_event].disabled_form_action;
4499                }
4500                $.each(options.triggerEventTypes.CF7, function (eventId, triggers) {
4501                    $.each(triggers.forms, function (index, value) {
4502                        if(value == form_id) {
4503                            sendEventId=eventId;
4504                        };
4505                    });
4506                });
4507            }
4508            if(sendEventId != null)
4509            {
4510                Utils.fireTriggerEvent(sendEventId);
4511
4512                if(!disabled_form_action)
4513                {
4514                    sendFormAction($(event.target), form_id);
4515                }
4516            }
4517            else {
4518                sendFormAction($(event.target), form_id);
4519            }
4520        }, false );
4521        //Forminator
4522        $(document).on( 'forminator:form:submit:success', function( event ){
4523            var form_id = $(event.target).find('input[name="form_id"]').val();
4524            var sendEventId = null;
4525            var disabled_form_action = false;
4526            if(options.triggerEventTypes.hasOwnProperty('forminator'))
4527            {
4528                key_event = Object.keys(options.triggerEventTypes.forminator)[0];
4529                if(options.triggerEventTypes.forminator[key_event].hasOwnProperty('disabled_form_action'))
4530                {
4531                    disabled_form_action = options.triggerEventTypes.forminator[key_event].disabled_form_action;
4532                }
4533                $.each(options.triggerEventTypes.forminator, function (eventId, triggers) {
4534                    $.each(triggers.forms, function (index, value) {
4535                        if(value == form_id) {
4536                            sendEventId=eventId;
4537                        };
4538                    });
4539                });
4540            }
4541            if(sendEventId != null)
4542            {
4543                Utils.fireTriggerEvent(sendEventId);
4544
4545                if(!disabled_form_action)
4546                {
4547                    sendFormAction($(event.target), form_id);
4548                }
4549            }
4550            else {
4551                sendFormAction($(event.target), form_id);
4552            }
4553
4554        });
4555
4556        //WPForm
4557        $('form.wpforms-form').on('wpformsAjaxSubmitSuccess', (event) => {
4558            var form_id = $(event.target).attr('data-formid');
4559            var sendEventId = null;
4560            var disabled_form_action = false;
4561            if(options.triggerEventTypes.hasOwnProperty('wpforms'))
4562            {
4563                key_event = Object.keys(options.triggerEventTypes.wpforms)[0];
4564                if(options.triggerEventTypes.wpforms[key_event].hasOwnProperty('disabled_form_action'))
4565                {
4566                    disabled_form_action = options.triggerEventTypes.wpforms[key_event].disabled_form_action;
4567                }
4568                $.each(options.triggerEventTypes.wpforms, function (eventId, triggers) {
4569                    $.each(triggers.forms, function (index, value) {
4570                        if(value == form_id) {
4571                            sendEventId=eventId;
4572                        };
4573                    });
4574                });
4575            }
4576            if(sendEventId != null)
4577            {
4578                Utils.fireTriggerEvent(sendEventId);
4579
4580                if(!disabled_form_action)
4581                {
4582                    sendFormAction($(event.target), form_id);
4583                }
4584            }
4585            else {
4586                sendFormAction($(event.target), form_id);
4587            }
4588        })
4589        $(document).on( 'frmFormComplete', function( event, form, response ) {
4590            const form_id = $(form).find('input[name="form_id"]').val();
4591            var sendEventId = null;
4592            var disabled_form_action = false;
4593            if(options.triggerEventTypes.hasOwnProperty('formidable'))
4594            {
4595                key_event = Object.keys(options.triggerEventTypes.formidable)[0];
4596                if(options.triggerEventTypes.formidable[key_event].hasOwnProperty('disabled_form_action'))
4597                {
4598                    disabled_form_action = options.triggerEventTypes.formidable[key_event].disabled_form_action;
4599                }
4600                $.each(options.triggerEventTypes.formidable, function (eventId, triggers) {
4601                    $.each(triggers.forms, function (index, value) {
4602                        if(value == form_id) {
4603                            sendEventId=eventId;
4604                        };
4605                    });
4606                });
4607            }
4608            if(sendEventId != null)
4609            {
4610                Utils.fireTriggerEvent(sendEventId);
4611
4612                if(!disabled_form_action)
4613                {
4614                    sendFormAction($(event.target), form_id);
4615                }
4616            }
4617            else {
4618                sendFormAction($(event.target), form_id);
4619            }
4620        });
4621        // Ninja Forms
4622        $(document).onFirst('nfFormSubmitResponse', function (event, data) {
4623            const form_id = data.response.data.form_id;
4624            var sendEventId = null;
4625            var disabled_form_action = false;
4626            if(options.triggerEventTypes.hasOwnProperty('ninjaform'))
4627            {
4628                key_event = Object.keys(options.triggerEventTypes.ninjaform)[0];
4629                if(options.triggerEventTypes.ninjaform[key_event].hasOwnProperty('disabled_form_action'))
4630                {
4631                    disabled_form_action = options.triggerEventTypes.ninjaform[key_event].disabled_form_action;
4632                }
4633                $.each(options.triggerEventTypes.ninjaform, function (eventId, triggers) {
4634                    $.each(triggers.forms, function (index, value) {
4635                        if(value == form_id) {
4636                            sendEventId=eventId;
4637                        };
4638                    });
4639                });
4640            }
4641            if(sendEventId != null)
4642            {
4643                Utils.fireTriggerEvent(sendEventId);
4644
4645                if(!disabled_form_action)
4646                {
4647                    sendFormAction($(event.target), form_id);
4648                }
4649            }
4650            else {
4651                sendFormAction($(event.target), form_id);
4652            }
4653        });
4654
4655        var fluentForms = $('form.frm-fluent-form');
4656        fluentForms.each(function() {
4657            var $form = $(this);
4658            $form.on('fluentform_submission_success', function(event) {
4659                var $formItem = $(this);
4660                var form_id = $formItem.attr('data-form_id');
4661                var sendEventId = null;
4662                var disabled_form_action = false;
4663                if(options.triggerEventTypes.hasOwnProperty('fluentform'))
4664                {
4665                    key_event = Object.keys(options.triggerEventTypes.fluentform)[0];
4666                    if(options.triggerEventTypes.fluentform[key_event].hasOwnProperty('disabled_form_action'))
4667                    {
4668                        disabled_form_action = options.triggerEventTypes.fluentform[key_event].disabled_form_action;
4669                    }
4670                    $.each(options.triggerEventTypes.fluentform, function (eventId, triggers) {
4671                        $.each(triggers.forms, function (index, value) {
4672                            if(value == form_id) {
4673                                sendEventId=eventId;
4674                            };
4675                        });
4676                    });
4677                }
4678                if(sendEventId != null)
4679                {
4680                    Utils.fireTriggerEvent(sendEventId);
4681
4682                    if(!disabled_form_action)
4683                    {
4684                        sendFormAction($(event.target), form_id);
4685                    }
4686                }
4687                else {
4688                    sendFormAction($(event.target), form_id);
4689                }
4690            });
4691        });
4692        // load pixel APIs
4693        Utils.loadPixels();
4694
4695        // setup Enrich content
4696        if(Utils.isCheckoutPage()) {
4697            Utils.addCheckoutFields();
4698        }
4699    });
4700
4701
4702    // load WatchVideo event APIs for Auto
4703    if (options.automatic.enable_video) {
4704        /**
4705         * Real Cookie Banner.
4706         */
4707        var consentApi = window.consentApi;
4708        if (consentApi && options.gdpr.real_cookie_banner_integration_enabled) {
4709            if (options.automatic.enable_youtube && options.enable_event_video && options.enable_automatic_events) {
4710                window.consentApi.consent("http", "CONSENT", ".youtube.com").then(Utils.initYouTubeAPI);
4711            }
4712            if (options.automatic.enable_vimeo && options.enable_event_video && options.enable_automatic_events) {
4713                window.consentApi.consent("http", "player", ".vimeo.com").then(Utils.initVimeoAPI);
4714            }
4715        }else{
4716            if (options.automatic.enable_youtube && options.enable_event_video && options.enable_automatic_events) {
4717                Utils.initYouTubeAPI();
4718            }
4719            if (options.automatic.enable_vimeo && options.enable_event_video && options.enable_automatic_events) {
4720                Utils.initVimeoAPI();
4721            }
4722        }
4723    }
4724
4725    var sendFormAction = function (form_target, formId){
4726        var params = {
4727                form_id: formId,
4728                text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() :
4729                    form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() :
4730                    form_target.find('[type="submit"]').text()
4731            };
4732
4733            if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
4734                var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
4735                for (var i = 0; i < pixels.length; i++) {
4736                    var event = options.dynamicEvents.automatic_event_form[pixels[i]];
4737                    if (pixels[i] === "tiktok") {
4738                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
4739                    } else {
4740                        Utils.copyProperties(params, event.params)
4741                        Utils.copyProperties(Utils.getRequestParam
4741s(), event.params);
4742                        getPixelBySlag(pixels[i]).onFormEvent(event);
4743                    }
4744                }
4745            }
4746    }
4747
4748
4749}(jQuery, pysOptions);
4750
4751function pys_generate_token(length){
4752    //edit the token allowed characters
4753    var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
4754    var b = [];
4755    for (var i=0; i<length; i++) {
4756        var j = (Math.random() * (a.length-1)).toFixed(0);
4757        b[i] = a[j];
4758    }
4759    return b.join("");
4760}
4761
4762function getBundlePriceOnSingleProduct(data) {
4763    var items_sum = 0;
4764    jQuery(".bundle_form .bundled_product").each(function(index){
4765        var id = jQuery(this).find(".cart").data("bundled_item_id");
4766        var item_price = data.prices[id];
4767        var item_quantity = jQuery(this).find(".bundled_qty").val();
4768        if(!jQuery(this).hasClass("bundled_item_optional") ||
4769            jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) {
4770            items_sum += item_price*item_quantity;
4771        }
4772    });
4773    return items_sum;
4774}
4775
4776function getPixelBySlag(slug) {
4777    switch (slug) {
4778        case "facebook": return window.pys.Facebook;
4779        case "ga": return window.pys.Analytics;
4780        case "google_ads": return window.pys.GAds;
4781        case "bing": return window.pys.Bing;
4782        case "pinterest": return window.pys.Pinterest;
4783        case "tiktok": return window.pys.TikTok;
4784    }
4785}
4786var getUrlParameter = function getUrlParameter(sParam) {
4787    var sPageURL = window.location.search.substring(1),
4788        sURLVariables = sPageURL.split('&'),
4789        sParameterName,
4790        i;
4791
4792    for (i = 0; i < sURLVariables.length; i++) {
4793        sParameterName = sURLVariables[i].split('=');
4794
4795        if (sParameterName[0] === sParam) {
4796            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
4797        }
4798    }
4799    return false;
4800};
4801function inArray(needle, haystack) {
4802    var length = haystack.length;
4803    for(var i = 0; i < length; i++) {
4804        if(haystack[i] == needle) return true;
4805    }
4806    return false;
4807}

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.