PageSourceSearch

https://welcome.opencatman.com/wp-content/plugins/pixelyoursite-pro/dist/scripts/public.js?ver=12.5.0

js opencatman.com collected 2026-10-01 23:56:40 UTC 336,385 bytes, 7,583 lines download raw bytes

1/* global pysOptions */
2
3! function ($, options) {
4    if (options.debug) {
5        console.log('PYS:', options);
6    }
7
8    var uniqueId = {};
9
10    var firstVisit = false;
11
12    var isTrackEventForGA = [];
13
14    var isAdsLoad = false;
15
16    let gtm_variables = {};
17    let gtm_datalayername = "dynamicVariable";
18    var domain = '';
19    if(options.hasOwnProperty("track_cookie_for_subdomains") && options.track_cookie_for_subdomains) {
20        domain = getRootDomain(true);
21    }
22
23    /**
24     * Resolve parameter value based on mode (static or dynamic)
25     *
26     * @param {Object|string} param - Parameter object with { value, selector } or string value
27     * @returns {string|null} - Resolved value
28     */
29    function resolveParamValue(param, key = '') {
30
31        // 1️⃣ null / undefined - skip this parameter
32        if (param === null || param === undefined) {
33            return null;
34        }
35
36        // 2️⃣ primitive
37        if (typeof param !== 'object') {
38            return param;
39        }
40
41        // 3️⃣ array
42        if (Array.isArray(param)) {
43            return param.map(item => resolveParamValue(item, key));
44        }
45
46        // 4️⃣ NEW FORMAT OBJECT (config-object)
47        const isConfigObject =
48            ('value' in param || 'selector' in param || 'dynamic' in param || 'input_type' in param) &&
49            Object.keys(param).every(k =>
50                ['value','selector','dynamic','input_type','name'].includes(k)
51            );
52
53        if (isConfigObject) {
54
55            // STATIC MODE
56            const isStatic =
57                !param.dynamic ||
58                !param.selector ||
59                param.selector.trim() === '';
60
61            if (isStatic) {
62                let value = param.value ?? null;
63
64                if (param.input_type === "float" || param.input_type === "int") {
65                    value = extractNumericValue(
66                        value,
67                        param.input_type === "int"
68                    );
69                }
70
71                return value;
72            }
73
74            // DYNAMIC MODE
75            try {
76                const el = document.querySelector(param.selector);
77                if (!el) return null;
78
79                let value =
80                    el.value ??
81                    el.innerText ??
82                    el.textContent ??
83                    el.getAttribute("content") ??
84                    el.getAttribute("data-value") ??
85                    null;
86
87                if (param.input_type === "float" || param.input_type === "int") {
88                    value = extractNumericValue(
89                        value,
90                        param.input_type === "int"
91                    );
92                }
93
94                return value;
95
96            } catch {
97                return null;
98            }
99        }
100
101        // 5️⃣ Plain object (recursive traversal) - filter out null/undefined values
102        return Object.fromEntries(
103            Object.entries(param)
104                .map(([k, v]) => [k, resolveParamValue(v, k)])
105                .filter(([k, v]) => v !== null && v !== undefined)
106        );
107    }
108
109    function extractNumericValue(value, isInt=false) {
110        if (value === null || value === undefined) {
111            return null;
112        }
113        if (isInt) {
114            return parseInt(value);
115        }
116        return parseFloat(value);
117    }
118
119    var loadTags = [];
120
121    var dummyPinterest = function () {
122
123        /**
124         * Public API
125         */
126        return {
127            tag: function() {
128                return "pinterest";
129            },
130            isEnabled: function () {},
131
132            disable: function () {},
133
134            loadPixel: function () {},
135
136            fireEvent: function (name, data) {
137                return false;
138            },
139
140            onAdSenseEvent: function (event) {},
141
142            onClickEvent: function (params) {},
143
144            onWatchVideo: function (params) {},
145
146            onCommentEvent: function (event) {},
147
148            onFormEvent: function (params) {},
149
150            onDownloadEvent: function (params) {},
151
152
153
154            onWooAddToCartOnButtonEvent: function (product_id) {},
155
156            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {},
157
158            onWooRemoveFromCartEvent: function (cart_item_hash) {},
159
160            onWooAffiliateEvent: function (product_id) {},
161
162            onWooPayPalEvent: function (event) {},
163
164            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
165
166            onEddRemoveFromCartEvent: function (item) {},
167
168            onPageScroll: function (event) {},
169            onTime: function (event) {
170
171            },
172
173        }
174
175    }();
176
177    var dummyBing = function () {
178
179        /**
180         * Public API
181         */
182        return {
183            tag: function() {
184                return "bing";
185            },
186            isEnabled: function () {},
187
188            disable: function () {},
189
190            loadPixel: function () {},
191
192            fireEvent: function (name, data) {
193                return false;
194            },
195
196            onAdSenseEvent: function (event) {},
197
198            onClickEvent: function (params) {},
199
200            onWatchVideo: function (params) {},
201
202            onCommentEvent: function (event) {},
203
204            onFormEvent: function (params) {},
205
206            onDownloadEvent: function (params) {},
207
208
209            onWooAddToCartOnButtonEvent: function (product_id) {},
210
211            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {},
212
213            onWooRemoveFromCartEvent: function (cart_item_hash) {},
214
215            onWooAffiliateEvent: function (product_id) {},
216
217            onWooPayPalEvent: function (event) {},
218
219            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {},
220
221            onEddRemoveFromCartEvent: function (item) {},
222            onPageScroll: function (event) {},
223            onTime: function (event) {
224
225            },
226        }
227
228    }();
229
230	var dummyReddit = function () {
231		/**
232		 * Public API
233		 */
234		return {
235			tag: function () {
236				return "reddit";
237			},
238			isEnabled: function () {
239			},
240
241			disable: function () {
242			},
243
244			loadPixel: function () {
245			},
246
247			fireEvent: function ( name, data ) {
248				return false;
249			},
250
251			onAdSenseEvent: function ( event ) {
252			},
253
254			onClickEvent: function ( params ) {
255			},
256
257			onWatchVideo: function ( params ) {
258			},
259
260			onCommentEvent: function ( event ) {
261			},
262
263			onFormEvent: function ( params ) {
264			},
265
266			onDownloadEvent: function ( params ) {
267			},
268
269			onWooAddToCartOnButtonEvent: function ( product_id ) {
270			},
271
272			onWooAddToCartOnSingleEvent: function ( product_id, qty, product_type, is_external, $form ) {
273			},
274
275			onWooRemoveFromCartEvent: function ( cart_item_hash ) {
276			},
277
278			onWooAffiliateEvent: function ( product_id ) {
279			},
280
281			onWooPayPalEvent: function ( event ) {
282			},
283
284			onEddAddToCartOnButtonEvent: function ( download_id, price_index, qty ) {
285			},
286
287			onEddRemoveFromCartEvent: function ( item ) {
288			},
289
290			onPageScroll: function ( event ) {
291			},
292
293			onTime: function ( event ) {
294			},
295		}
296	}();
297
298    var Utils = function (options) {
299
300
301        var Pinterest = dummyPinterest;
302
303        var Bing = dummyBing;
304
305	    var Reddit = dummyReddit;
306
307        var gtag_loaded = false;
308
309        var gtm_loaded = false;
310
311        let isNewSession = checkSession();
312
313        let dataLayerName = 'dataLayerPYS';
314
315        let GTMdataLayerName = 'dataLayer';
316
317
318        function loadPixels() {
319
320            if (!options.gdpr.all_disabled_by_api) {
321                if (!options.gdpr.tiktok_disabled_by_api) {
322                    TikTok.loadPixel();
323                }
324
325                if (!options.gdpr.facebook_disabled_by_api) {
326                    Facebook.loadPixel();
327                }
328
329                if (!options.gdpr.analytics_disabled_by_api) {
330                    Analytics.loadPixel();
331                }
332
333                if (!options.gdpr.google_ads_disabled_by_api) {
334                    GAds.loadPixel();
335                }
336
337                if (!options.gdpr.analytics_disabled_by_api) {
338                    GTM.loadPixel();
339                }
340
341                if (!options.gdpr.pinterest_disabled_by_api) {
342                    Pinterest.loadPixel();
343                }
344
345                if (!options.gdpr.bing_disabled_by_api) {
346                    Bing.loadPixel();
347                }
348
349	            if (!options.gdpr.reddit_disabled_by_api) {
350		            Reddit.loadPixel();
351	            }
352
353            }
354            if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
355                if (typeof CS_Data.cs_google_analytics_consent_mode !== "undefined" && CS_Data.cs_google_analytics_consent_mode == 1) {
356                    Analytics.loadPixel();
357                }
358                if (typeof CS_Data.cs_google_ads_consent_mode !== "undefined" && CS_Data.cs_google_ads_consent_mode == 1 ) {
359                    GAds.loadPixel();
360                }
361            }
362        }
363
364        /**
365         * WATCHVIDEO UTILS
366         */
367
368        function isJSApiAttrEnabled(url) {
369            return url.indexOf('enablejsapi') > -1;
370        }
371
372        function isOriginAttrEnabled(url) {
373            return url.indexOf('origin') > -1;
374        }
375
376        // Returns key/value pairs of percentages: number of seconds to achieve
377        function getVideoCompletionMarks(duration) {
378
379            var marks = {};
380            var points = [0, 10, 50, 90, 100];
381
382            for (var i = 0; i < points.length; i++) {
383
384                var _point = points[i];
385                var _mark = _point + '%';
386                var _time = duration * _point / 100;
387
388                if (_point === 100) {
389                    _time = _time - 1;
390                }
391
392                // 10% => 123
393                marks[_mark] = Math.floor(_time);
394
395            }
396
397            return marks;
398
399        }
400
401        // Determine if the element is a YouTube video or not
402        function tagIsYouTubeVideo(tag) {
403            var src = tag.src || '';
404            return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1;
405        }
406
407        function tagIsYouTubeAsyncVideo(tag) {
408            if(tag.src && tag.src.indexOf("data:image") !== -1) return false; // video is loaded
409            var keys = Object.keys(tag.dataset);
410            for(var i = 0;i<keys.length;i++) {
411                if(keys[i].toLowerCase().indexOf("src") > -1) {
412                    var src = tag.dataset[keys[i]];
413                    return src.indexOf('youtube.com/embed/') > -1 || src.indexOf('youtube.com/v/') > -1;
414                }
415            }
416            return false; //not find src
417        }
418
419        // Turn embed objects into iframe objects and ensure they have the right parameters
420        function normalizeYouTubeIframe(tag) {
421
422            var loc = window.location;
423            var a = document.createElement('a');
424            a.href = tag.src;
425            a.hostname = 'www.youtube.com';
426            a.protocol = loc.protocol;
427            var tmpPathname = a.pathname.charAt(0) === '/' ? a.pathname : '/' + a.pathname; // IE10 shim
428
429            if (!isJSApiAttrEnabled(a.search)) {
430                a.search = (a.search.length > 0 ? a.search + '&' : '') + 'enablejsapi=1';
431            }
432
433            // for security reasons, YouTube wants an origin parameter set that matches our hostname
434            if (!isOriginAttrEnabled(a.search) && loc.hostname.indexOf('localhost') === -1) {
435
436                var port = loc.port ? ':' + loc.port : '';
437                var origin = loc.protocol + '%2F%2F' + loc.hostname + port;
438
439                a.search = a.search + '&origin=' + origin;
440
441            }
442
443            if (tag.type === 'application/x-shockwave-flash') {
444
445                var newIframe = document.createElement('iframe');
446                newIframe.height = tag.height;
447                newIframe.width = tag.width;
448                tmpPathname = tmpPathname.replace('/v/', '/embed/');
449
450                tag.parentNode.parentNode.replaceChild(newIframe, tag.parentNode);
451
452                tag = newIframe;
453
454            }
455
456            a.pathname = tmpPathname;
457
458            if (tag.src !== a.href + a.hash) {
459                tag.src = a.href + a.hash;
460            }
461
462            return tag;
463
464        }
465
466        // Add event handlers for events emitted by the YouTube API
467        function addYouTubeEvents(iframe) {
468
469            var player = YT.get(iframe.id);
470            if (!player) {
471                player = new YT.Player(iframe, {});
472            }
473
474            if (typeof iframe.pauseFlag === 'undefined') {
475
476                iframe.pauseFlag = false;
477                player.addEventListener('onStateChange', function (evt) {
478                    onYouTubePlayerStateChange(evt, iframe);
479                });
480
481            }
482
483        }
484
485        function addDynYouTubeVideos(el) {
486            // We only bind to iFrames with a YouTube URL with the enablejsapi=1 and
487            // origin=<<hostname>> parameters
488            if (el.tagName === 'IFRAME'
489                && tagIsYouTubeVideo(el)
490                && isJSApiAttrEnabled(el.src)
491                && isOriginAttrEnabled(el.src))
492            {
493                addYouTubeEvents(el);
494            }
495        }
496
497        // Event handler for events emitted from the YouTube API
498        function onYouTubePlayerStateChange(evt, iframe) {
499
500            var stateIndex = evt.data;
501            var player = evt.target;
502            var targetVideoUrl = player.getVideoUrl();
503            var targetVideoId = targetVideoUrl.match(/[?&]v=([^&#]*)/)[1]; // Extract the ID
504            var playerState = player.getPlayerState();
505            var marks = getVideoCompletionMarks(player.getDuration());
506
507            iframe.playTracker = iframe.playTracker || {};
508
509            if (playerState === YT.PlayerState.PLAYING && !iframe.timer) {
510
511                clearInterval(iframe.timer);
512
513                // check every second to see if we've hit any of our percentage viewed marks
514                iframe.timer = setInterval(function () {
515                    checkYouTubeCompletion(player, marks, iframe.videoId);
516                }, 1000);
517
518            } else {
519
520                clearInterval(iframe.timer);
521                iframe.timer = false;
522
523            }
524
525            // playlist edge-case handler
526            if (stateIndex === YT.PlayerState.PLAYING) {
527                iframe.playTracker[targetVideoId] = true;
528                iframe.videoId = targetVideoId;
529                iframe.pauseFlag = false;
530            }
531
532            if (!iframe.playTracker[iframe.videoId]) {
533                return false; // this video hasn't started yet, so this is spam
534            }
535
536            if (stateIndex === YT.PlayerState.PAUSED) {
537
538                if (!iframe.pauseFlag) {
539                    iframe.pauseFlag = true;
540                } else {
541                    return false; // we don't want to fire consecutive pause events
542                }
543
544            }
545
546        }
547
548        // Trigger event if YouTube video mark was reached
549        function checkYouTubeCompletion(player, marks, videoId) {
550
551            var currentTime = player.getCurrentTime();
552
553            player[videoId] = player[videoId] || {};
554
555            for (var key in marks) {
556
557                if (marks[key] <= currentTime && !player[videoId][key]) {
558                    player[videoId][key] = true;
559
560                    var data = player.getVideoData();
561
562                    if (key === '0%') {
563                        key = 'play';
564                    }
565
566                    var params = {
567                        video_type: 'youtube',
568                        video_id: videoId,
569                        video_title: data.title,
570                    };
571
572                    let disable_watch_video = [];
573
574                    //Custom
575                    if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) {
576                        Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
577                            triggers.forEach( function ( trigger ) {
578                                if ( trigger.type === 'youtube' && trigger.rule === videoId ) {
579
580                                    let pixels = Object.keys( options.triggerEvents[ trigger_id ] );
581                                    for ( let i = 0; i < pixels.length; i++ ) {
582                                        let event = Utils.clone( options.triggerEvents[ trigger_id ][ pixels[ i ] ] );
583
584                                        if ( trigger.disable_watch_video ) {
585                                            disable_watch_video.push( pixels[ i ] );
586                                        }
587
588                                        if ( currentTime >= marks[ trigger.value ] ) {
589											if (pixels[i] !== 'reddit') {
590												event.params["progress"] = key;
591												Utils.copyProperties( params, event.params );
592											}
593
594                                            if ( event.fired !== true ) {
595                                                if ( Utils.isEventInTimeWindow( event.name, event, 'dyn_' + pixels[ i ] + '_' + trigger_id ) ) {
596                                                    event = Utils.getFormFilledData( event );
597                                                    getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event );
598                                                    options.triggerEvents[ trigger_id ][ pixels[ i ] ].fired = true;
599                                                }
600                                            }
601                                        }
602                                    }
603                                }
604                            } )
605                        } )
606                    }
607
608                    // Auto
609                    if( options.automatic.enable_video
610                        && options.automatic.enable_youtube
611                        && options.dynamicEvents.hasOwnProperty("automatic_event_video")
612                    ) {
613                        var pixels = Object.keys(options.dynamicEvents.automatic_event_video);
614
615                        for (var i = 0; i < pixels.length; i++) {
616                            if ( disable_watch_video.includes( pixels[ i ] ) ) {
617                                continue;
618                            }
619                            var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]);
620
621							if ( pixels[ i ] !== 'reddit' ) {
622								event.params[ "progress" ] = key;
623								Utils.copyProperties(params, event.params)
624							}
625
626                            if ( pixels[i] === 'tiktok' || pixels[i] === 'reddit' ) {
627                                var time_trigger = event.automatic_event_video_trigger;
628                                if ( currentTime >= marks[time_trigger] && event.fired !== true ) {
629                                    getPixelBySlag(pixels[i]).onWatchVideo(event);
630
631                                    //tiktok and reddit watch video fire once
632                                    options.dynamicEvents.automatic_event_video[pixels[i]].fired = true;
633                                }
634                            } else {
635                                Utils.copyProperties(Utils.getRequestParam
635s(), event.params);
636                                getPixelBySlag(pixels[i]).onWatchVideo(event);
637                            }
638                        }
639                    }
640
641                    if(key == "play") {
642
643                        $.each(options.triggerEventTypes, function (triggerType, events) {
644                            $.each(events, function (eventId, triggers) {
645                                switch (triggerType) {
646                                    case 'video_play':
647                                        Utils.fireTriggerEvent(eventId);
648                                        break;
649                                }
650
651                            });
652                        });
653                    }
654
655                }
656
657            }
658
659        }
660
661        // Determine if the element is a Vimeo video or not
662        function tagIsVimeoVideo(tag) {
663            var src = tag.src || '';
664            return src.indexOf('player.vimeo.com/video/') > -1;
665        }
666
667        function tagIsAsincVimeoVideo(tag) {
668            if(tag.src) return false; // video is loaded
669            var keys = Object.keys(tag.dataset);
670            for(var i = 0;i<keys.length;i++) {
671                if(keys[i].toLowerCase().indexOf("src") > -1) {
672                    var src = tag.dataset[keys[i]];
673                    return src.indexOf('player.vimeo.com/video/') > -1;
674                }
675            }
676            return false; //not find src
677        }
678
679        function attachVimeoPlayerToTag(tag) {
680            var player = new Vimeo.Player(tag);
681
682            player.getDuration().then(function (pl,seconds) {
683                pl.pysMarks = getVideoCompletionMarks(seconds);
684            }.bind(null,player));
685
686            player.getVideoTitle().then(function (pl,title) {
687                pl.pysVideoTitle = title;
688            }.bind(null,player));
689
690            player.getVideoId().then(function (pl,id) {
691                pl.pysVideoId = id;
692            }.bind(null,player));
693
694            player.pysCompletedMarks = {};
695
696            player.on('play', function () {
697
698                if (this.pysTimer) {
699                    return;
700                }
701
702                clearInterval(this.pysTimer);
703
704                var player = this;
705
706                this.pysTimer = setInterval(function () {
707                    checkVimeoCompletion(player);
708                }, 1000);
709
710            });
711
712            player.on('pause', function () {
713                clearInterval(this.pysTimer);
714                this.pysTimer = false;
715            });
716
717            player.on('ended', function () {
718                clearInterval(this.pysTimer);
719                this.pysTimer = false;
720            });
721        }
722
723        // Trigger event if Vimeo video mark was reached
724        function checkVimeoCompletion(player) {
725
726            player.getCurrentTime().then(function (seconds) {
727
728                for (var key in player.pysMarks) {
729
730                    if (player.pysMarks[key] <= seconds && !player.pysCompletedMarks[key]) {
731
732                        player.pysCompletedMarks[key] = true;
733
734                        if (key === '0%') {
735                            key = 'play';
736                        }
737
738                        var params = {
739                            video_type: 'vimeo',
740                            video_id: player.pysVideoId,
741                            video_title: player.pysVideoTitle,
742                        };
743
744                        let disable_watch_video = [];
745
746                        //Custom
747                        if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) {
748                            Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
749                                triggers.forEach( function ( trigger ) {
750                                    if ( trigger.type === 'vimeo' && trigger.rule == player.pysVideoId ) {
751                                        let pixels = Object.keys( options.triggerEvents[ trigger_id ] );
752                                        for ( let i = 0; i < pixels.length; i++ ) {
753                                            let event = Utils.clone( options.triggerEvents[ trigger_id ][ pixels[ i ] ] );
754
755                                            if ( trigger.disable_watch_video ) {
756                                                disable_watch_video.push( pixels[ i ] );
757                                            }
758
759                                            if ( seconds >= player.pysMarks[ trigger.value ] ) {
760												if ( pixels[ i ] !== 'reddit' ) {
761													event.params[ "progress" ] = key;
762													Utils.copyProperties( params, event.params );
763                                                }
764
765                                                if ( event.fired !== true ) {
766                                                    if ( Utils.isEventInTimeWindow( event.name, event, 'dyn_' + pixels[ i ] + '_' + trigger_id ) ) {
767                                                        event = Utils.getFormFilledData( event );
768                                                        getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event );
769                                                        options.triggerEvents[ trigger_id ][ pixels[ i ] ].fired = true;
770                                                    }
771                                                }
772                                            }
773                                        }
774                                    }
775                                } )
776                            } )
777                        }
778
779                        // Auto
780                        if(options.automatic.enable_video
781                            && options.automatic.enable_vimeo
782                            && options.dynamicEvents.hasOwnProperty("automatic_event_video")
783                        ) {
784                            var pixels = Object.keys(options.dynamicEvents.automatic_event_video);
785
786                            for (var i = 0; i < pixels.length; i++) {
787                                if ( disable_watch_video.includes( pixels[ i ] ) ) {
788                                    continue;
789                                }
790
791                                var event = Utils.clone(options.dynamicEvents.automatic_event_video[pixels[i]]);
792
793								if ( pixels[i] !== 'reddit' ) {
794									event.params["progress"] = key;
795									Utils.copyProperties(params, event.params);
796								}
797
798                                if ( pixels[i] === 'tiktok' || pixels[i] === 'reddit' ) {
799                                    var time_trigger = event.automatic_event_video_trigger;
800                                    if ( seconds >= player.pysMarks[time_trigger] && event.fired !== true ) {
801                                        getPixelBySlag(pixels[i]).onWatchVideo(event);
802
803                                        //tiktok and reddit watch video fire once
804                                        options.dynamicEvents.automatic_event_video[pixels[i]].fired = true;
805                                    }
806                                } else {
807                                    Utils.copyProperties(Utils.getRequestParam
807s(), event.params);
808                                    getPixelBySlag(pixels[i]).onWatchVideo(event);
809                                }
810                            }
811                        }
812
813                        if(key == "play") {
814                            $.each(options.triggerEventTypes, function (triggerType, events) {
815                                $.each(events, function (eventId, triggers) {
816                                    switch (triggerType) {
817                                        case 'video_play':
818                                            Utils.fireTriggerEvent(eventId);
819                                            break;
820                                    }
821
822                                });
823                            });
824                        }
825                    }
826
827                }
828
829            });
830
831        }
832
833        /**
834         * COOKIES UTILS
835         */
836
837        var utmTerms = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content' ,'utm_term'];
838        var utmId = ['fbadid', 'gadid', 'padid', 'bingid'];
839        var requestParams = [];
840
841
842        function getDomain(url) {
843
844            url = url.replace(/(https?:\/\/)?(www.)?/i, '');
845
846            if (url.indexOf('/') !== -1) {
847                return url.split('/')[0];
848            }
849
850            return url;
851        }
852
853        function checkSession() {
854
855            if( Cookies.get('pys_start_session') === undefined ||
856                Cookies.get('pys_session_limit') === undefined) {
857                firstVisit = true;
858                return true
859            }
860            return false
861
862        }
863
864        function getTrafficSource() {
865
866            try {
867
868                let referrer = document.referrer.toString(),
869                    source;
870
871                let direct = referrer.length === 0;
872                let internal = direct ? false : referrer.indexOf(options.siteUrl) === 0;
873                let external = !direct && !internal;
874
875                if (external === false) {
876                    source = 'direct';
877                } else {
878                    source = referrer;
879                }
880
881                if (source !== 'direct') {
882                    // leave only domain (Issue #70)
883                    return getDomain(source);
884                } else {
885                    return source;
886                }
887
888            } catch (e) {
889                console.error(e);
890                return 'direct';
891            }
892
893        }
894
895        /**
896         * Return query variables object with where property name is query variable
897         * and property value is query variable value.
898         */
899        function getQueryVars() {
900
901            try {
902
903                var result = {},
904                    tmp = [];
905
906                window.location.search
907                    .substr(1)
908                    .split("&")
909                    .forEach(function (item) {
910
911                        tmp = item.split('=');
912
913                        if (tmp.length > 1) {
914                            result[tmp[0]] = tmp[1];
915                        }
916
917                    });
918
919                return result;
920
921            } catch (e) {
922                console.error(e);
923                return {};
924            }
925
926        }
927
928        function getLandingPageValue() {
929            let name = "pys_landing_page"
930            if(options.visit_data_model === "last_visit") {
931                name = "last_pys_landing_page"
932            }
933            if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
934                return Cookies.get(name);
935            }
936            else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficLanding){
937                return options.tracking_analytics.TrafficLanding;
938            } else{
939                return "";
940            }
941        }
942        function getTrafficSourceValue() {
943            let name = "pysTrafficSource"
944            if(options.visit_data_model === "last_visit") {
945                name = "last_pysTrafficSource"
946            }
947            if(Cookies.get(name) && Cookies.get(name) !== "undefined") {
948                return Cookies.get(name);
949            } else{
950                return "";
951            }
952        }
953
954        /**
955         * Handle alternative GCLID parameter for Safari compatibility
956         * Creates _gcl_aw cookie when alternative parameter is detected and _gcl_aw doesn't exist
957         */
958        function handleAlternativeGclid() {
959            // Check if alternative GCLID is enabled
960            if (!options.GATags || !options.GATags.gclid_alternative_enabled || !options.GATags.gclid_alternative_param) {
961                return;
962            }
963
964            // GDPR consent checks - stop if any consent filter blocks it
965            if (options.gdpr.all_disabled_by_api) {
966                return;
967            }
968            if (options.gdpr.analytics_disabled_by_api) {
969                return;
970            }
971            if (options.cookie.disabled_all_cookie) {
972                return;
973            }
974            if (options.cookie.disabled_google_alternative_id) {
975                return;
976            }
977
978            const alternativeParam = options.GATags.gclid_alternative_param;
979            const queryVars = getQueryVars();
980            
981            // Check if alternative parameter exists in URL
982            if (queryVars[alternativeParam]) {
983                const gclidValue = queryVars[alternativeParam];
984                
985                // Only create _gcl_aw cookie if it doesn't exist
986                if (!Cookies.get('_gcl_aw')) {
987                    // Create _gcl_aw cookie with the alternative parameter value in Google's format
988                    // Format: GCL.{timestamp}.{gclid_value}
989                    const timestamp = Math.floor(Date.now() / 1000);
990                    const cookieValue = 'GCL.' + timestamp + '.' + gclidValue;
991                    
992                    // Set cookie for 90 days (Google's standard)
993                    const expires = new Date();
994                    expires.setTime(expires.getTime() + (90 * 24 * 60 * 60 * 1000));
995                    
996                    Cookies.set('_gcl_aw', cookieValue, { 
997                        expires: expires, 
998                        path: '/', 
999                        domain: domain 
1000                    });
1001                    
1002                    if (options.debug) {
1003                        console.log('PYS: Created _gcl_aw cookie from alternative parameter:', alternativeParam, '=', gclidValue);
1004                    }
1005                }
1006            }
1007        }
1008
1009        function getUTMId(useLast = false) {
1010            try {
1011                let cookiePrefix = 'pys_'
1012                let terms = [];
1013                if (useLast) {
1014                    cookiePrefix = 'last_pys_'
1015                }
1016                $.each(utmId, function (index, name) {
1017                    if (Cookies.get(cookiePrefix + name)) {
1018                        terms[name] = Cookies.get(cookiePrefix + name)
1019                    }
1020                    else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtmsId[name]) {
1021                        terms[name] = filterEmails(options.tracking_analytics.TrafficUtmsId[name])
1022                    }
1023                });
1024                return terms;
1025            } catch (e) {
1026                console.error(e);
1027                return [];
1028            }
1029        }
1030        /**
1031         * Return UTM terms from request query variables or from cookies.
1032         */
1033        function getUTMs(useLast = false) {
1034
1035            try {
1036                let cookiePrefix = 'pys_'
1037                if(useLast) {
1038                    cookiePrefix = 'last_pys_'
1039                }
1040                let terms = [];
1041                $.each(utmTerms, function (index, name) {
1042                    if (Cookies.get(cookiePrefix + name)) {
1043                        let value = Cookies.get(cookiePrefix + name);
1044                        terms[name] = filterEmails(value); // do not allow email in request params (Issue #70)
1045                    }
1046                    else if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.TrafficUtms[name]) {
1047                        terms[name] = filterEmails(options.tracking_analytics.TrafficUtms[name])
1048                    }
1049                });
1050
1051                return terms;
1052
1053            } catch (e) {
1054                console.error(e);
1055                return [];
1056            }
1057
1058        }
1059
1060        function getDateTime() {
1061            var dateTime = new Array();
1062            var date = new Date(),
1063                days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
1064                months = ['January', 'February', 'March', 'April', 'May', 'June',
1065                    'July', 'August', 'September', 'October', 'November', 'December'
1066                ],
1067                hours = ['00-01', '01-02', '02-03', '03-04', '04-05', '05-06', '06-07', '07-08',
1068                    '08-09', '09-10', '10-11', '11-12', '12-13', '13-14', '14-15', '15-16', '16-17',
1069                    '17-18', '18-19', '19-20', '20-21', '21-22', '22-23', '23-24'
1070                ];
1071            dateTime.push(hours[date.getHours()]);
1072            dateTime.push(days[date.getDay()]);
1073            dateTime.push(months[date.getMonth()]);
1074            return dateTime;
1075        }
1076
1077        function filterEmails(value) {
1078            return Utils.validateEmail(value) ? undefined : value;
1079        }
1080
1081        /**
1082         * PUBLIC API
1083         */
1084        return {
1085
1086            PRODUCT_SIMPLE : 0,
1087            PRODUCT_VARIABLE : 1,
1088            PRODUCT_BUNDLE : 2,
1089            PRODUCT_GROUPED : 3,
1090            utmTerms : utmTerms,
1091            utmId : utmId,
1092            isNewSession: checkSession(),
1093            setHidePixelCookie: function(){
1094                let refresh_after_consent = false;
1095                if ( !firstVisit && options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent) {
1096                    refresh_after_consent = true;
1097                }
1098                if( !refresh_after_consent && !firstVisit) return false;
1099
1100                const url_parts = window.location.href;
1101                const url_params = new URLSearchParams(window.location.search);
1102                const matchingPixels = ["facebook", "ga", "gtm", "google_ads", "bing", "pinterest", "tiktok", "reddit"];
1103                $.each(matchingPixels, function (index, slug) {
1104                    var module = getPixelBySlag(slug);
1105                    if (module && module.isEnabled()) {
1106                        const fullUrl = window.location.href;
1107                        $.each(module.getHidePixel(), function (index, hide_info) {
1108                            for (const item of hide_info.hide_tag_contain) {
1109                                if (item && fullUrl.includes(item)) {
1110                                    let hideTagTimeInMilliseconds = hide_info.hide_tag_time * 60 * 60 * 1000;
1111                                    let expiresTime = new Date().getTime() + hideTagTimeInMilliseconds;
1112                                    Cookies.set('hide_tag_' + hide_info.pixel, true, { expires: new Date(expiresTime), path: '/' });
1113                                    break;
1114                                }
1115                            }
1116                        });
1117                    }
1118
1119                });
1120            },
1121            hideMatchingPixel: function(pixelValue, slug) {
1122                if(Cookies.get('hide_tag_'+pixelValue))
1123                {
1124                    return true;
1125                }
1126                return false;
1127            },
1128            validateEmail: function (email) {
1129                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,}))$/;
1130                return re.test(email);
1131            },
1132            fireEventForAllPixel:function(functionName,events){
1133                if (events.hasOwnProperty(Facebook.tag()))
1134                    Facebook[functionName](events[Facebook.tag()]);
1135                if (events.hasOwnProperty(Analytics.tag()))
1136                    Analytics[functionName](events[Analytics.tag()]);
1137                if (events.hasOwnProperty(GAds.tag()))
1138                    GAds[functionName](events[GAds.tag()]);
1139                if (events.hasOwnProperty(Pinterest.tag()))
1140                    Pinterest[functionName](events[Pinterest.tag()]);
1141                if (events.hasOwnProperty(Bing.tag()))
1142                    Bing[functionName](events[Bing.tag()]);
1143                if (events.hasOwnProperty(TikTok.tag()))
1144                    TikTok[functionName](events[TikTok.tag()]);
1145	            if (events.hasOwnProperty(Reddit.tag()))
1146		            Reddit[functionName](events[Reddit.tag()]);
1147
1148                if (events.hasOwnProperty(GTM.tag()))
1149                    GTM[functionName](events[GTM.tag()]);
1150            },
1151
1152            getQueryValue:function (name){
1153                return getQueryVars()[name];
1154            },
1155
1156            filterEmails: function (value) {
1157                return filterEmails(value);
1158            },
1159
1160            setupPinterestObject: function () {
1161                Pinterest = window.pys.Pinterest || Pinterest;
1162                return Pinterest;
1163            },
1164
1165            setupBingObject: function () {
1166                Bing = window.pys.Bing || Bing;
1167                return Bing;
1168            },
1169
1170	        setupRedditObject: function () {
1171		        Reddit = window.pys.Reddit || Reddit;
1172		        return Reddit;
1173	        },
1174
1175            // Clone all object members to another and return it
1176            copyProperties: function (from, to) {
1177                for (var key in from) {
1178                    if("function" == typeof from[key]) {
1179                        continue;
1180                    }
1181                    to[key] = from[key];
1182                }
1183                return to;
1184            },
1185
1186            /**
1187             * Generate unique ID
1188             *
1189             * For purchase events (woo_purchase, edd_purchase):
1190             * - Server eventID has priority (for server-browser deduplication)
1191             * - If server didn't provide eventID, generate one keyed by order_id
1192             *
1193             * For other events:
1194             * - Use existing logic with event type as key
1195             */
1196            generateUniqueId : function (event) {
1197                var eventsWithHook = [
1198                    'woo_purchase',
1199                    'woo_start_trial',
1200                    'woo_subscription_created',
1201                    'woo_subscription_renewal',
1202                    'edd_purchase',
1203                    'edd_start_trial',
1204                    'edd_subscription_created',
1205                    'edd_subscription_renewal',
1206                    'edd_license_created',
1207                    'edd_license_upgrade',
1208                    'edd_license_renewal'
1209                ];
1210
1211                // For events with server hooks: prioritize server eventID
1212                if ( eventsWithHook.includes( event.e_id ) ) {
1213                    // If server provided eventID, use it (for deduplication)
1214                    if ( event.eventID && event.eventID.length > 0 ) {
1215                        var orderKey = event.e_id;
1216                        if ( !uniqueId.hasOwnProperty( orderKey ) ) {
1217                            uniqueId[orderKey] = event.eventID;
1218                        }
1219                        return uniqueId[orderKey];
1220                    }
1221                }
1222
1223                if (
1224                    event.eventID.length == 0 ||
1225                    ( !event.isVariationTrigger &&
1226                        ( event.type == "static" && options.ajaxForServerStaticEvent ||
1227                          event.type !== "static" && options.ajaxForServerEvent )
1228                    )
1229                ) {
1230                    let idKey = event.hasOwnProperty('custom_event_post_id') ? event.custom_event_post_id : event.e_id;
1231                    if ( !uniqueId.hasOwnProperty( idKey ) ) {
1232                        uniqueId[idKey] = pys_generate_token();
1233                    }
1234                    return uniqueId[idKey];
1235                }
1236                else if ( event.eventID.length !== 0 ) {
1237                    return event.eventID;
1238                }
1239            },
1240
1241            // Flatten object for sendBeacon compatibility
1242            flattenObject: function (obj, prefix = '', res = {}) {
1243                for (const [key, value] of Object.entries(obj)) {
1244                    const prefixedKey = prefix
1245                        ? (Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}[${key}]`)
1246                        : key;
1247                    if (value !== null && typeof value === 'object' && !(value instanceof File)) {
1248                        this.flattenObject(value, prefixedKey, res);
1249                    } else {
1250                        res[prefixedKey] = value;
1251                    }
1252                }
1253                return res;
1254            },
1255
1256            sendServerAjaxRequest: function ( url, data ) {
1257                // Check if we should use REST API for TikTok or Facebook
1258                if (data.action === 'pys_tiktok_api_event' && window.pysTikTokRest) {
1259                    // Use TikTok REST API
1260                    this.sendRestAPIRequest(data, 'tiktok');
1261                    return;
1262                }
1263
1264                if (data.action === 'pys_api_event' && data.pixel === 'facebook' && window.pysFacebookRest) {
1265                    // Use Facebook REST API
1266                    this.sendRestAPIRequest(data, 'facebook');
1267                    return;
1268                }
1269
1270                // Check if sendBeacon is enabled and supported
1271                if (options.useSendBeacon && navigator.sendBeacon) {
1272                    try {
1273                        // Flatten the data object for sendBeacon compatibility
1274                        const flattenedData = this.flattenObject(data);
1275                        const formData = new URLSearchParams();
1276
1277                        // Convert flattened data to URLSearchParams
1278                        for (const [key, value] of Object.entries(flattenedData)) {
1279                            if (value !== null && value !== undefined) {
1280                                formData.append(key, value);
1281                            }
1282                        }
1283
1284                        // Try to send using sendBeacon
1285                        const success = navigator.sendBeacon(url, formData);
1286                        if (success) {
1287                            return; // Successfully sent via sendBeacon
1288                        }
1289                    } catch (e) {
1290                        // If sendBeacon fails, fall back to jQuery.ajax
1291                        if (options.debug) {
1292                            console.log('PYS: sendBeacon failed, falling back to jQuery.ajax:', e);
1293                        }
1294                    }
1295                }
1296
1297                // Fallback to jQuery.ajax
1298                jQuery.ajax( {
1299                    type: 'POST',
1300                    url: url,
1301                    data: data,
1302                    headers: {
1303                        'Cache-Control': 'no-cache'
1304                    },
1305                    success: function () {
1306                    },
1307                } );
1308            },
1309
1310            // Send event via REST API (unified function for TikTok, Facebook, and other platforms)
1311            // Replaces the old sendTikTokRestAPIRequest and sendFacebookRestAPIRequest functions
1312            sendRestAPIRequest: function (data, platform) {
1313                let restApiUrl;
1314
1315                // Get platform-specific REST API configuration
1316                switch (platform) {
1317                    case 'tiktok':
1318                        restApiUrl = window.pysTikTokRest ? window.pysTikTokRest.restApiUrl : '/wp-json/pys-tiktok/v1/event';
1319                        break;
1320                    case 'facebook':
1321                        restApiUrl = window.pysFacebookRest ? window.pysFacebookRest.restApiUrl : '/wp-json/pys-facebook/v1/event';
1322                        break;
1323                    case 'pinterest':
1324                        restApiUrl = window.pysPinterestRest ? window.pysPinterestRest.restApiUrl : '/wp-json/pys-pinterest/v1/event';
1325                        break;
1326                    default:
1327                        console.error('PYS: Unknown platform for REST API:', platform);
1328                        this.sendAjaxFallback(data);
1329                        return;
1330                }
1331
1332                // Prepare data for REST API
1333                const restApiData = {
1334                    event: data.event,
1335                    event_slug: data.event_slug,
1336                    data: JSON.stringify(data.data || {}),
1337                    ids: JSON.stringify(data.ids || []),
1338                    eventID: data.event_id || data.eventID || '',
1339                    woo_order: data.woo_order || '0',
1340                    edd_order: data.edd_order || '0'
1341                };
1342
1343                // Try to send using sendBeacon first (if enabled)
1344                if (options.useSendBeacon && navigator.sendBeacon) {
1345                    try {
1346                        const formData = new URLSearchParams();
1347                        for (const [key, value] of Object.entries(restApiData)) {
1348                            formData.append(key, value);
1349                        }
1350
1351                        if (navigator.sendBeacon(restApiUrl, formData)) {
1352                            return;
1353                        }
1354                    } catch (e) {
1355                        // sendBeacon failed, continue to fetch
1356                    }
1357                }
1358
1359                // Try to send using fetch with REST API
1360                if (window.fetch) {
1361                    const headers = {
1362                        'Content-Type': 'application/json'
1363                    };
1364
1365                    fetch(restApiUrl, {
1366                        method: 'POST',
1367                        headers: headers,
1368                        body: JSON.stringify(restApiData)
1369                    })
1370                    .then(response => {
1371                        if (!response.ok) {
1372                            throw new Error(platform + ' REST API request failed: ' + response.status);
1373                        }
1374                    })
1375                    .catch(error => {
1376                        // Fallback to AJAX if REST API fails
1377                        if (options.debug) {
1378                            console.log('PYS: ' + platform + ' REST API failed, falling back to AJAX:', error);
1379                        }
1380                        this.sendAjaxFallback(data);
1381                    });
1382                } else {
1383                    // Fallback to AJAX if fetch is not supported
1384                    this.sendAjaxFallback(data);
1385                }
1386            },
1387
1388
1389
1390            // Fallback AJAX method
1391            sendAjaxFallback: function (data) {
1392                jQuery.ajax({
1393                    type: 'POST',
1394                    url: options.ajaxUrl,
1395                    data: data,
1396                    headers: {
1397                        'Cache-Control': 'no-cache'
1398                    },
1399                    success: function () {
1400                    },
1401                });
1402            },
1403
1404            clone: function(obj) {
1405                var copy;
1406
1407                // Handle the 3 simple types, and null or undefined
1408                if (null == obj || "object" != typeof obj) return obj;
1409
1410                // Handle Date
1411                if (obj instanceof Date) {
1412                    copy = new Date();
1413                    copy.setTime(obj.getTime());
1414                    return copy;
1415                }
1416
1417                // Handle Array
1418                if (obj instanceof Array) {
1419                    copy = [];
1420                    for (var i = 0, len = obj.length; i < len; i++) {
1421                        if("function" == typeof obj[i]) {
1422                            continue;
1423                        }
1424                        copy[i] = Utils.clone(obj[i]);
1425                    }
1426                    return copy;
1427                }
1428
1429                // Handle Object
1430                if (obj instanceof Object) {
1431                    copy = {};
1432                    for (var attr in obj) {
1433                        if (obj.hasOwnProperty(attr)) {
1434                            if("function" == typeof obj[attr]) {
1435                                continue;
1436                            }
1437                            copy[attr] = Utils.clone(obj[attr]);
1438                        }
1439                    }
1440                    return copy;
1441                }
1442
1443                return obj;
1444            },
1445
1446            // Returns array of elements with given tag name
1447            getTagsAsArray: function (tag) {
1448                return [].slice.call(document.getElementsByTagName(tag));
1449            },
1450
1451
1452            initializeVideoAPIs: function (options) {
1453                let trigger_has_video_YT, trigger_has_video_Vimeo = false;
1454                if (options.hasOwnProperty('automatic') && options.automatic.enable_video) {
1455                    if ( options.triggerEventTypes.hasOwnProperty( "video_view" ) ) {
1456                        Object.entries( options.triggerEventTypes.video_view ).forEach( function ( [ trigger_id, triggers ] ) {
1457                            triggers.forEach( function ( trigger ) {
1458                                if (trigger.type === 'youtube') {
1459                                    trigger_has_video_YT = true;
1460                                }
1461                                if(trigger.type === 'vimeo'){
1462                                    trigger_has_video_Vimeo = true;
1463                                }
1464                            });
1465                        });
1466                    }
1467                    if (
1468                        options.hasOwnProperty('enable_automatic_events') &&
1469                        options.enable_automatic_events
1470                    ) {
1471                        if (options.automatic.enable_youtube || trigger_has_video_YT) {
1472                            Utils.initYouTubeAPI();
1473                        }
1474                        if (options.automatic.enable_vimeo || trigger_has_video_Vimeo) {
1475                            Utils.initVimeoAPI();
1476                        }
1477                    }
1478                }
1479            },
1480            /**
1481             * Load and initialize YouTube API
1482             *
1483             * @link: https://developers.google.com/youtube/iframe_api_reference
1484             */
1485            initYouTubeAPI: function () {
1486
1487                // maybe load YouTube JS API
1488                if (typeof window.YT === 'undefined') {
1489                    var tag = document.createElement('script');
1490                    tag.src = '//www.youtube.com/iframe_api';
1491                    var firstScriptTag = document.getElementsByTagName('script')[0];
1492                    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
1493                }
1494
1495                // initialize when API is ready
1496                if ( typeof window.onYouTubeIframeAPIReady !== 'function' ) {
1497
1498                    window.onYouTubeIframeAPIReady = function () {
1499
1500                        // collect all possible YouTube tags
1501                        var potentialVideos = Utils.getTagsAsArray( 'iframe' ).concat( 
1501Utils.getTagsAsArray( 'embed' ) );
1502
1503                        // turn videos into trackable videos with events
1504                        for ( var i = 0; i < potentialVideos.length; i++ ) {
1505                            var video = potentialVideos[ i ];
1506                            if ( tagIsYouTubeVideo( video ) ) {
1507                                var iframe = normalizeYouTubeIframe( video );
1508                                addYouTubeEvents( iframe );
1509                            } else if ( tagIsYouTubeAsyncVideo( video ) ){
1510                                video.addEventListener( "load", function ( evt ) {
1511                                    var iframe = normalizeYouTubeIframe( evt.currentTarget );
1512                                    addYouTubeEvents( iframe );
1513                                } );
1514                            }
1515                        }
1516
1517                        var targets = document.querySelectorAll( '.elementor-widget-video .elementor-wrapper' );
1518
1519                        const config = {
1520                            attributes: false,
1521                            childList: true,
1522                            subtree: true
1523                        };
1524
1525                        const callback = function ( mutationsList, observer ) {
1526                            for ( let mutation of mutationsList ) {
1527                                if ( mutation.type === 'childList' ) {
1528                                    for ( var m = 0; m < mutation.addedNodes.length; m++ ) {
1529                                        addDynYouTubeVideos( mutation.addedNodes[ m ] );
1530                                    }
1531                                }
1532                            }
1533                        };
1534                        // observe elementator widget-video and add event when it add iframe
1535                        for ( var i = 0; i < targets.length; i++ ) {
1536                            const observer = new MutationObserver( callback );
1537                            observer.observe( targets[ i ], config );//maybe remove before add
1538                        }
1539                    }
1540                }
1541            },
1542
1543            /**
1544             * Load and initialize Vimeo API
1545             *
1546             * @link: https://github.com/vimeo/player.js
1547             */
1548            initVimeoAPI: function () {
1549
1550
1551                $(document).ready(function () {
1552
1553                    var potentialVideos = Utils.getTagsAsArray('iframe').concat(Utils.getTagsAsArray('embed'));
1554
1555                    for (var i = 0; i < potentialVideos.length; i++) {
1556                        var tag = potentialVideos[i];
1557                        if (tagIsVimeoVideo(tag)) {
1558                            var nextElementHasClass = $(tag).closest('.elementor-widget-video').find('.elementor-custom-embed-image-overlay');
1559                            if(nextElementHasClass.length > 0) {
1560                                tag.addEventListener("load", function() {
1561                                    attachVimeoPlayerToTag(this);
1562                                });
1563                            }
1564                            else {
1565                                attachVimeoPlayerToTag(tag);
1566                            }
1567
1568
1569                        } else {
1570                            if (tagIsAsincVimeoVideo(tag)) {
1571                                tag.addEventListener("load", function(evt) {
1572                                    attachVimeoPlayerToTag(evt.currentTarget);
1573                                });
1574                            }
1575                        }
1576                    }
1577
1578                });
1579
1580            },
1581
1582            manageCookies: function () {
1583                // Handle alternative GCLID parameter for Safari compatibility
1584                handleAlternativeGclid();
1585                
1586                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
1587                    if (Cookiebot.consented === false && !Cookiebot.consent['marketing'] && !Cookiebot.consent['statistics']) {
1588                        return;
1589                    }
1590                }
1591
1592                let cm_consent_not_expressed = false;
1593                if ( options.gdpr.consent_magic_integration_enabled && window.CS_Data !== undefined && window.CS_Data.cs_refresh_after_consent == 1 ) {
1594                    if ( Cookies.get( 'cs_viewed_cookie_policy' ) === undefined ) {
1595                        cm_consent_not_expressed = true;
1596                    }
1597                }
1598
1599                if( !cm_consent_not_expressed && isNewSession && !options.cookie.disabled_all_cookie && !options.cookie.disabled_start_session_cookie) {
1600                    let duration = options.last_visit_duration * 60000
1601                    var now = new Date();
1602                    now.setTime(now.getTime() + duration);
1603                    Cookies.set('pys_session_limit', true,{ expires: now, path: '/',domain: domain })
1604                    Cookies.set('pys_start_session', true,{ path: '/',domain: domain });
1605                    Utils.setHidePixelCookie();
1606                }
1607
1608                if (!Cookies.get('pbid') && Facebook.isEnabled() && options.ajaxForServerEvent) {
1609                    jQuery.ajax({
1610                        url: options.ajaxUrl,
1611                        dataType: 'json',
1612                        data: {
1613                            action: 'pys_get_pbid'
1614                        },
1615                        success: function (res) {
1616                            if (res.data && res.data.pbid != false && options.send_external_id) {
1617                                if(!(options.cookie.disabled_all_cookie || options.cookie.externalID_disabled_by_api)){
1618                                    var expires = parseInt(options.external_id_expire || 180);
1619                                    Cookies.set('pbid', res.data.pbid, { expires: expires,path: '/',domain: domain });
1620                                }
1621
1622                                if(options.hasOwnProperty('facebook')) {
1623                                    options.facebook.advancedMatching = {
1624                                        ...options.facebook.advancedMatching,  // распыляем текущие значения advancedMatching
1625                                        external_id: res.data.pbid
1626                                    };
1627                                }
1628                            }
1629                        }
1630                    });
1631                } else if (Cookies.get('pbid') && Facebook.isEnabled()){
1632                    if(options.hasOwnProperty('facebook')) {
1633                        options.facebook.advancedMatching = {
1634                            ...options.facebook.advancedMatching,
1635                            external_id: Cookies.get('pbid')
1636                        };
1637                    }
1638                }
1639                let expires = parseInt(options.cookie_duration); //  days
1640                let queryVars = getQueryVars();
1641                let landing = window.location.href.split('?')[0];
1642                try {
1643                    // save data for first visit
1644                    if(Cookies.get('pys_first_visit') === undefined && (!options.cookie.disabled_all_cookie)) {
1645
1646                        if(!options.cookie.disabled_first_visit_cookie)
1647                        {
1648                            Cookies.set('pys_first_visit', true, { expires: expires, path: '/',domain: domain });
1649                        }
1650                        else {
1651                            Cookies.remove('pys_first_visit', { path: '/',domain: domain } )
1652                        }
1653
1654                        if(!options.cookie.disabled_trafficsource_cookie)
1655                        {
1656                            Cookies.set('pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
1657                        }
1658                        else {
1659                            Cookies.remove('pysTrafficSource', { path: '/',domain: domain })
1660                        }
1661
1662                        if(!options.cookie.disabled_landing_page_cookie && options.enable_lading_page_param)
1663                        {
1664                            Cookies.set('pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
1665                        }
1666                        else {
1667                            Cookies.remove('pys_landing_page', { path: '/',domain: domain })
1668                        }
1669
1670                        if(!options.cookie.disabled_utmTerms_cookie)
1671                        {
1672                            $.each(utmTerms, function (index, name) {
1673                                if (queryVars.hasOwnProperty(name)) {
1674                                    Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1675                                } else {
1676                                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
1677                                }
1678                            });
1679                        }
1680                        else {
1681                            $.each(utmTerms, function (index, name) {
1682                                Cookies.remove('pys_' + name, { path: '/',domain: domain })
1683                            });
1684                        }
1685
1686                        if(!options.cookie.disabled_utmId_cookie)
1687                        {
1688                            $.each(utmId,function(index,name) {
1689                                if (queryVars.hasOwnProperty(name)) {
1690                                    Cookies.set('pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1691                                } else {
1692                                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
1693                                }
1694                            })
1695                        }
1696                        else {
1697                            $.each(utmId, function (index, name) {
1698                                Cookies.remove('pys_' + name, { path: '/',domain: domain })
1699                            });
1700                        }
1701
1702                    }
1703                    // save data for last visit if it new session
1704                    if(isNewSession && (!options.cookie.disabled_all_cookie)) {
1705                        if(!options.cookie.disabled_trafficsource_cookie)
1706                        {
1707                            Cookies.set('last_pysTrafficSource', getTrafficSource(), { expires: expires,path: '/',domain: domain });
1708                        }
1709                        else {
1710                            Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain })
1711                        }
1712
1713                        if(!options.cookie.disabled_landing_page_cookie && options.enable_lading_page_param)
1714                        {
1715                            Cookies.set('last_pys_landing_page',landing,{ expires: expires,path: '/',domain: domain });
1716                        }
1717                        else {
1718                            Cookies.remove('last_pys_landing_page', { path: '/',domain: domain })
1719                        }
1720
1721                        if(!options.cookie.disabled_utmTerms_cookie)
1722                        {
1723                            $.each(utmTerms, function (index, name) {
1724                                if (queryVars.hasOwnProperty(name)) {
1725                                    Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1726                                }
1727                            });
1728                        }
1729                        else {
1730                            $.each(utmTerms, function (index, name) {
1731                                Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1732                            });
1733                        }
1734
1735                        if(!options.cookie.disabled_utmId_cookie)
1736                        {
1737                            $.each(utmId,function(index,name) {
1738                                if (queryVars.hasOwnProperty(name)) {
1739                                    Cookies.set('last_pys_' + name, queryVars[name], { expires: expires,path: '/',domain: domain });
1740                                }
1741                            })
1742                        }
1743                        else {
1744                            $.each(utmId, function (index, name) {
1745                                Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1746                            });
1747                        }
1748
1749                    }
1750                    if(options.cookie.disabled_start_session_cookie) {
1751                        Cookies.remove('pys_start_session', { path: '/',domain: domain })
1752                        Cookies.remove('pys_session_limit', { path: '/',domain: domain })
1753                    }
1754                    if(options.cookie.disabled_all_cookie)
1755                    {
1756                        Cookies.remove('pys_first_visit', { path: '/',domain: domain })
1757                        Cookies.remove('pysTrafficSource', { path: '/',domain: domain })
1758                        Cookies.remove('pys_landing_page', { path: '/',domain: domain })
1759                        Cookies.remove('last_pys_landing_page', { path: '/',domain: domain })
1760                        Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain })
1761                        Cookies.remove('pys_start_session', { path: '/',domain: domain })
1762                        Cookies.remove('pys_session_limit', { path: '/',domain: domain })
1763                        $.each(Utils.utmTerms, function (index, name) {
1764                            Cookies.remove('pys_' + name, { path: '/',domain: domain })
1765                        });
1766                        $.each(Utils.utmId,function(index,name) {
1767                            Cookies.remove('pys_' + name, { path: '/',domain: domain })
1768                        })
1769                        $.each(Utils.utmTerms, function (index, name) {
1770                            Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1771                        });
1772                        $.each(Utils.utmId,function(index,name) {
1773                            Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
1774                        });
1775                    }
1776                } catch (e) {
1777                    console.error(e);
1778                }
1779            },
1780
1781            initializeRequestParams: function () {
1782
1783                if (options.trackTrafficSource) {
1784                    requestParams.traffic_source = getTrafficSourceValue();
1785                }
1786
1787                if (options.trackUTMs) {
1788
1789                    var utms = getUTMs(options.visit_data_model === "last_visit");
1790
1791                    $.each(utmTerms, function (index, term) {
1792                        if (term in utms) {
1793                            requestParams[term] = utms[term];
1794                        }
1795                    });
1796
1797                }
1798
1799
1800                var dateTime = getDateTime();
1801                if(options.enable_event_time_param) {
1802                    requestParams.event_hour = dateTime[0];
1803                }
1804
1805                if(options.enable_event_day_param) {
1806                    requestParams.event_day = dateTime[1];
1807                }
1808                if(options.enable_event_month_param) {
1809                    requestParams.event_month = dateTime[2];
1810                }
1811
1812                if(options.enable_lading_page_param){
1813                    requestParams.landing_page = getLandingPageValue();
1814                }
1815            },
1816
1817            getRequestParams: function () {
1818                return requestParams;
1819            },
1820
1821            /**
1822             * DOWNLOAD DOCS
1823             */
1824
1825            getLinkExtension: function (link) {
1826
1827                // Remove anchor, query string and everything before last slash
1828                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1829                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1830                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1831
1832                // If there's a period left in the URL, then there's a extension
1833                if (link.length > 0 && link.indexOf('.') !== -1) {
1834                    link = link.substring(link.lastIndexOf(".") + 1); // Remove everything but what's after the first period
1835                    return link;
1836                } else {
1837                    return "";
1838                }
1839            },
1840
1841            getLinkFilename: function (link) {
1842
1843                // Remove anchor, query string and everything before last slash
1844                link = link.substring(0, (link.indexOf("#") === -1) ? link.length : link.indexOf("#"));
1845                link = link.substring(0, (link.indexOf("?") === -1) ? link.length : link.indexOf("?"));
1846                link = link.substring(link.lastIndexOf("/") + 1, link.length);
1847
1848                // If there's a period left in the URL, then there's a extension
1849                if (link.length > 0 && link.indexOf('.') !== -1) {
1850                    return link;
1851                } else {
1852                    return "";
1853                }
1854            },
1855
1856            /**
1857             * CUSTOM EVENTS
1858             */
1859
1860            setupMouseOverClickEvents: function (eventId, triggers) {
1861
1862                // Non-default binding used to avoid situations when some code in external js
1863                // stopping events propagation, eg. returns false, and our handler will never called
1864                document.addEventListener('mouseover', function(event) {
1865                    var matchedElements = Array.from(document.querySelectorAll(triggers));
1866                    var clickedElement = event.target;
1867                    var closestMatch = clickedElement.closest(triggers);
1868                    if (matchedElements.includes(clickedElement) || closestMatch){
1869                        if (event.target.classList.contains('pys-mouse-over-' + eventId)) {
1870                            return true;
1871                        } else {
1872                            event.target.classList.add('pys-mouse-over-' + eventId);
1873                        }
1874
1875                        Utils.fireTriggerEvent(eventId);
1876                    }
1877                });
1878
1879
1880            },
1881
1882            setupFormFieldEvents: function (eventId, triggers) {
1883                triggers.forEach(function(trigger) {
1884                    let eventType = 'input';
1885
1886                    if (['checkbox', 'radio', 'select'].includes(trigger.type)) {
1887                        eventType = 'change';
1888                    } else if (['text', 'email', 'tel'].includes(trigger.type)) {
1889                        eventType = 'blur';
1890                    }
1891
1892                    const form = document.querySelector(trigger.form);
1893                    if (!form) return;
1894
1895                    const field = form.querySelector(trigger.field); // ищем поле ТОЛЬКО внутри формы
1896                    if (!field) return;
1897
1898                    field.addEventListener(eventType, function (event) {
1899                        Utils.fireTriggerEvent(eventId);
1900                    }, true);
1901                });
1902            },
1903
1904            setupCSSClickEvents: function (eventId, triggers) {
1905                // Non-default binding used to avoid situations when some code in external js
1906                // stopping events propagation, eg. returns false, and our handler will never called
1907                // add event to document to support dyn class
1908                document.addEventListener('click', function(event) {
1909                    let matchedElements = Array.from(document.querySelectorAll(triggers)),
1910                        clickedElement = event.target,
1911                        closestMatch = clickedElement.closest(triggers);
1912
1913                    if (matchedElements.includes(clickedElement) || closestMatch){
1914                        Utils.fireTriggerEvent(eventId);
1915                    }
1916                }, true);
1917            },
1918
1919            setupURLClickEvents: function () {
1920
1921                if( !options.triggerEventTypes.hasOwnProperty('url_click') ) {
1922                    return;
1923                }
1924                // Non-default binding used to avoid situations when some code in external js
1925                // stopping events propagation, eg. returns false, and our handler will never called
1926                document.addEventListener('click', function(event) {
1927                    let anchor = event.target.closest('a');
1928
1929                    if (anchor) {
1930                        var url = anchor.getAttribute('href');
1931                        if (url) {
1932                            Object.entries(options.triggerEventTypes.url_click).forEac
1932h(function ([eventId, triggers]) {
1933                                triggers.forEach(function (trigger) {
1934                                    if (Utils.compareUrl(url, trigger.value, trigger.rule)) {
1935                                        Utils.fireTriggerEvent(eventId);
1936                                    }
1937                                });
1938                            });
1939                        }
1940                    }
1941                }, true);
1942
1943            },
1944
1945            removeUrlDomain(url) {
1946                if(url.indexOf("/#") > -1) {
1947                    url = url.substring(0, url.indexOf("/#"));
1948                }
1949                return url.replace('http://','')
1950                    .replace('https://','')
1951                    .replace('www.','')
1952                    .trim()
1953                    .replace(/^\/+/g, '')
1954
1955            },
1956
1957            compareUrl: function(base,url,rule){
1958
1959                if(url == "*" || url == '') return true;
1960
1961                base = Utils.removeUrlDomain(base)
1962                url = Utils.removeUrlDomain(url)
1963
1964                if(rule == 'match') {
1965                    return url == base;
1966                } else {
1967                    return base.indexOf(url) !== -1
1968                }
1969
1970            },
1971
1972            setupScrollPosEvents: function (eventId, triggers) {
1973
1974                var scrollPosThresholds = {},
1975                    docHeight = $(document).height() - $(window).height();
1976
1977                // convert % to absolute positions
1978                $.each(triggers, function (index, scrollPos) {
1979
1980                    // convert % to pixels
1981                    scrollPos = docHeight * scrollPos / 100;
1982                    scrollPos = Math.round(scrollPos);
1983
1984                    scrollPosThresholds[scrollPos] = eventId;
1985
1986                });
1987
1988                $(document).on("scroll",function () {
1989
1990                    var scrollPos = $(window).scrollTop();
1991
1992                    $.each(scrollPosThresholds, function (threshold, eventId) {
1993
1994                        // position has not reached yes
1995                        if (scrollPos <= threshold) {
1996                            return true;
1997                        }
1998
1999                        // fire event only once
2000                        if (eventId === null) {
2001                            return true;
2002                        } else {
2003                            scrollPosThresholds[threshold] = null;
2004                        }
2005
2006                        Utils.fireTriggerEvent(eventId);
2007
2008                    });
2009
2010                });
2011
2012            },
2013            setupCommentEvents : function (eventId,triggers) {
2014                $('form.comment-form').on("submit",function () {
2015                    Utils.fireTriggerEvent(eventId);
2016                });
2017            },
2018
2019            setupEmailLinkEvents: function ( events ) {
2020
2021                $( document ).on( 'click', 'a', function ( event ) {
2022                    let anchor = event.target.closest('a');
2023
2024                    if (anchor) {
2025                        let url = anchor.getAttribute('href');
2026                        if (url && (url.startsWith('mailto:') || url.startsWith('tel:'))) {
2027
2028                            let sendEventIds = [],
2029                                disabled_for_pixels = [],
2030                                disabled_email_action = false;
2031
2032                            $.each(events, function (eventId, trigger_group) {
2033                                url = url.replace('mailto:', '').replace('tel:', '');
2034                                trigger_group.forEach(function (triggers) {
2035                                    triggers.rules.forEach(function (trigger) {
2036                                        if (Utils.compareUrl(url, trigger.value, trigger.rule)) {
2037                                            sendEventIds.push(eventId);
2038                                            if (triggers.hasOwnProperty('disabled_email_link') && triggers.disabled_email_link) {
2039                                                disabled_email_action = true;
2040                                                if (options.triggerEvents.hasOwnProperty(eventId)) {
2041                                                    disabled_for_pixels.push(...Object.keys(options.triggerEvents[eventId]));
2042                                                }
2043                                            }
2044                                        }
2045                                    });
2046                                })
2047                            })
2048
2049                            if (sendEventIds.length > 0) {
2050                                sendEventIds.forEach(function (sendEventId) {
2051                                    Utils.fireTriggerEvent(sendEventId);
2052                                })
2053                            }
2054                            setupEmailLinks(disabled_for_pixels);
2055                        }
2056                    }
2057                } )
2058            },
2059
2060            /**
2061             * Events
2062             */
2063
2064            isEventInTimeWindow: function (eventName, event, prefix) {
2065
2066                if(event.hasOwnProperty("hasTimeWindow") && event.hasTimeWindow) {
2067                    var cookieName = prefix+"_"+eventName;
2068                    var now = new Date().getTime();
2069
2070                    if(Cookies.get(cookieName) !== undefined) {
2071
2072                        var lastTimeFire = Cookies.get(cookieName);
2073                        var fireTime = event.timeWindow * 60*60*1000;
2074
2075                        if( now - lastTimeFire > fireTime) {
2076                            Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0, path: '/'} );
2077                        } else {
2078                            return false;
2079                        }
2080                    } else {
2081                        Cookies.set(cookieName,now, { expires: event.timeWindow / 24.0, path: '/'} );
2082                    }
2083                }
2084                return true
2085            },
2086
2087            fireTriggerEvent: function (eventId) {
2088
2089                if (!options.triggerEvents.hasOwnProperty(eventId)) {
2090                    return;
2091                }
2092
2093                var event = {};
2094                var events = options.triggerEvents[eventId];
2095
2096                if (events.hasOwnProperty('facebook')) {
2097                    event = events.facebook;
2098                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_facebook_"+eventId)) {
2099                        event = Utils.getFormFilledData(event);
2100                        Facebook.fireEvent(event.name, event);
2101                    }
2102                }
2103
2104                if (events.hasOwnProperty('ga')) {
2105                    event = events.ga;
2106                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_ga_"+eventId)) {
2107                        event = Utils.getFormFilledData(event);
2108                        Analytics.fireEvent(event.name, event);
2109                    }
2110                }
2111
2112                if (events.hasOwnProperty('google_ads')) {
2113                    event = events.google_ads;
2114                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_google_ads_"+eventId)) {
2115                        event = Utils.getFormFilledData(event);
2116                        GAds.fireEvent(event.name, event);
2117                    }
2118                }
2119
2120                if (events.hasOwnProperty('pinterest')) {
2121                    event = events.pinterest;
2122                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_pinterest_"+eventId)) {
2123                        event = Utils.getFormFilledData(event);
2124                        Pinterest.fireEvent(event.name, event);;
2125                    }
2126                }
2127
2128                if (events.hasOwnProperty('bing')) {
2129                    event = events.bing;
2130                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_bing_"+eventId)) {
2131                        event = Utils.getFormFilledData(event);
2132                        Bing.fireEvent(event.name, event);;
2133                    }
2134                }
2135                if (events.hasOwnProperty('tiktok')) {
2136                    event = events.tiktok;
2137                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_tiktok_"+eventId)) {
2138                        event = Utils.getFormFilledData(event);
2139                        TikTok.fireEvent(event.name, event);
2140                    }
2141                }
2142	            if (events.hasOwnProperty('reddit')) {
2143		            event = events.reddit;
2144		            if(Utils.isEventInTimeWindow(event.name,event,"dyn_reddit_"+eventId)) {
2145			            event = Utils.getFormFilledData(event);
2146			            Reddit.fireEvent(event.name, event);
2147		            }
2148	            }
2149
2150
2151                if (events.hasOwnProperty('gtm')) {
2152                    event = events.gtm;
2153                    if(Utils.isEventInTimeWindow(event.name,event,"dyn_gtm_"+eventId)) {
2154                        event = Utils.getFormFilledData(event);
2155                        GTM.fireEvent(event.name, event);
2156                    }
2157                }
2158
2159
2160            },
2161
2162            isFirstPurchaseFire: function ($eventName,orderId,pixel) {
2163
2164                if(Cookies.get("pys_"+$eventName+"_order_id_"+pixel) == orderId) {
2165                    return false;
2166                } else {
2167                    Cookies.set("pys_"+$eventName+"_order_id_"+pixel, orderId, { expires: 1,path: '/' });
2168                }
2169                return true;
2170            },
2171
2172            fireStaticEvents: function (pixel, timeout = 0) {
2173
2174                if (options.staticEvents.hasOwnProperty(pixel)) {
2175
2176                    $.each(options.staticEvents[pixel], function (eventId, events) {
2177
2178                        //skip purchase event if this order was fired
2179                        if( options.woo.hasOwnProperty('woo_purchase_on_transaction') &&
2180                            options.woo.woo_purchase_on_transaction &&
2181                            (eventId === "woo_purchase" || eventId === "woo_purchase_category") ) {
2182                            if(!Utils.isFirstPurchaseFire(eventId,events[0].woo_order,pixel)) {
2183                                return;
2184                            }
2185                        }
2186
2187                        if( options.edd.hasOwnProperty('edd_purchase_on_transaction') &&
2188                            options.edd.edd_purchase_on_transaction &&
2189                            (eventId === "edd_purchase" || eventId === "edd_purchase_category") ) {
2190                            if(!Utils.isFirstPurchaseFire(eventId,events[0].edd_order,pixel)) {
2191                                return;
2192                            }
2193                        }
2194
2195
2196                        $.each(events, function (index, event) {
2197
2198                            event.fired = event.fired || false;
2199
2200                            if (!event.fired && Utils.isEventInTimeWindow(event.name,event,'static_' + pixel+"_")) {
2201                                event = Utils.getFormFilledData(event);
2202
2203                                var fired = false;
2204
2205                                // fire event
2206                                if ( pixel === 'tiktok' ) {
2207                                    setTimeout(function() {
2208                                        getPixelBySlag(pixel).fireEvent(event.name, event);
2209                                    }, timeout * 500);
2210                                    timeout++;
2211                                } else {
2212                                    getPixelBySlag(pixel).fireEvent(event.name, event);
2213                                }
2214
2215                                // prevent event double event firing
2216                                event.fired = fired;
2217                            }
2218                        });
2219                    });
2220                }
2221            },
2222
2223            /**
2224             * Load tag's JS
2225             *
2226             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/
2227             * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dim
2227s-mets
2228             */
2229            loadGoogleTag: function (id) {
2230
2231                if (!gtag_loaded) {
2232                    let dataLayerName = this.dataLayerName;
2233                    if(options.hasOwnProperty('GATags')){
2234                        switch (options.GATags.ga_datalayer_type) {
2235                            case 'default':
2236                                dataLayerName = 'dataLayerPYS';
2237                                break;
2238                            case 'custom':
2239                                dataLayerName = options.GATags.ga_datalayer_name;
2240                                break;
2241                            default:
2242                                dataLayerName = 'dataLayer';
2243                        }
2244                    }
2245                    this.dataLayerName = dataLayerName;
2246                    (function (window, document, src) {
2247                        var a = document.createElement('script'),
2248                            m = document.getElementsByTagName('script')[0];
2249                        a.async = 1;
2250                        a.src = src;
2251                        m.parentNode.insertBefore(a, m);
2252                    })(window, document, '//www.googletagmanager.com/gtag/js?id=' + id+'&l='+this.dataLayerName);
2253
2254                    window[dataLayerName] = window[dataLayerName] || [];
2255                    window.gtag = window.gtag || function gtag() {
2256                        window[dataLayerName].push(arguments);
2257                    };
2258
2259                    if ( options.google_consent_mode ) {
2260                        let data = {};
2261                        data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
2262                        data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
2263                        data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
2264                        data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
2265
2266                        this.loadDefaultConsent( 'consent', 'default', data );
2267                    }
2268
2269                    gtag('js', new Date());
2270                    gtag_loaded = true;
2271
2272                }
2273
2274            },
2275
2276            loadDefaultConsent: function() {
2277                window[ this.dataLayerName ].push( arguments );
2278            },
2279
2280            loadGTMScript: function (id = '') {
2281                const domain = options.gtm.gtm_container_domain ?? 'www.googletagmanager.com';
2282                const loader = options.gtm.gtm_container_identifier ?? 'gtm';
2283                const gtm_auth = options.gtm.gtm_auth ?? ''; // Set this if needed
2284                const gtm_preview = options.gtm.gtm_preview ?? ''; // Set this if needed
2285                const datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
2286
2287                window[ datalayer_name ] = window[ datalayer_name ] || [];
2288                window.gtag = window.gtag || function gtag() {
2289                    window[ datalayer_name ].push( arguments );
2290                };
2291
2292                if ( options.google_consent_mode ) {
2293                    let data = {};
2294                    data[ 'analytics_storage' ] = options.gdpr.analytics_storage.enabled ? options.gdpr.analytics_storage.value : 'granted';
2295                    data[ 'ad_storage' ] = options.gdpr.ad_storage.enabled ? options.gdpr.ad_storage.value : 'granted';
2296                    data[ 'ad_user_data' ] = options.gdpr.ad_user_data.enabled ? options.gdpr.ad_user_data.value : 'granted';
2297                    data[ 'ad_personalization' ] = options.gdpr.ad_personalization.enabled ? options.gdpr.ad_personalization.value : 'granted';
2298
2299                    this.GTMdataLayerName = datalayer_name;
2300                    this.loadDefaultGTMConsent( 'consent', 'default', data );
2301                }
2302
2303                (function(w, d, s, l, i) {
2304                    w[l] = w[l] || [];
2305                    w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
2306                    const f = d.getElementsByTagName(s)[0];
2307                    const j = d.createElement(s);
2308                    const dl = l !== 'dataLayer' ? '&l=' + l : '';
2309                    j.async = true;
2310                    j.src = 'https://' + domain + '/' + loader + '.js?id=' + i + dl;
2311                    if (gtm_auth && gtm_preview) {
2312                        j.src += '&gtm_auth=' + gtm_auth + '&gtm_preview=' + gtm_preview + '&gtm_cookies_win=x';
2313                    }
2314                    f.parentNode.insertBefore(j, f);
2315                })(window, document, 'script', datalayer_name, id);
2316
2317            },
2318
2319            loadDefaultGTMConsent: function() {
2320                window[ this.GTMdataLayerName ].push( arguments );
2321            },
2322
2323            /**
2324             * GDPR
2325             */
2326
2327            loadPixels: function () {
2328
2329                if (options.gdpr.ajax_enabled && !options.gdpr.consent_magic_integration_enabled) {
2330
2331                    // retrieves actual PYS GDPR filters values which allow to avoid cache issues
2332                    $.get({
2333                        url: options.ajaxUrl,
2334                        dataType: 'json',
2335                        data: {
2336                            action: 'pys_get_gdpr_filters_values'
2337                        },
2338                        success: function (res) {
2339
2340                            if (res.success) {
2341
2342                                options.gdpr.all_disabled_by_api = res.data.all_disabled_by_api;
2343                                options.gdpr.facebook_disabled_by_api = res.data.facebook_disabled_by_api;
2344                                options.gdpr.tiktok_disabled_by_api = res.data.tiktok_disabled_by_api;
2345                                options.gdpr.analytics_disabled_by_api = res.data.analytics_disabled_by_api;
2346                                options.gdpr.google_ads_disabled_by_api = res.data.google_ads_disabled_by_api;
2347                                options.gdpr.pinterest_disabled_by_api = res.data.pinterest_disabled_by_api;
2348                                options.gdpr.bing_disabled_by_api = res.data.bing_disabled_by_api;
2349                                options.gdpr.reddit_disabled_by_api = res.data.reddit_disabled_by_api;
2350
2351                                options.cookie.externalID_disabled_by_api = res.data.externalID_disabled_by_api;
2352                                options.cookie.disabled_all_cookie = res.data.disabled_all_cookie;
2353                                options.cookie.disabled_advanced_form_data_cookie = res.data.disabled_advanced_form_data_cookie;
2354                                options.cookie.disabled_landing_page_cookie = res.data.disabled_landing_page_cookie || !options.enable_lading_page_param;
2355                                options.cookie.disabled_first_visit_cookie = res.data.disabled_first_visit_cookie;
2356                                options.cookie.disabled_trafficsource_cookie = res.data.disabled_trafficsource_cookie;
2357                                options.cookie.disabled_utmTerms_cookie = res.data.disabled_utmTerms_cookie;
2358                                options.cookie.disabled_utmId_cookie = res.data.disabled_utmId_cookie;
2359                            }
2360                            loadPixels();
2361
2362                        }
2363                    });
2364
2365                } else {
2366                    loadPixels();
2367                }
2368
2369            },
2370
2371            consentGiven: function (pixel) {
2372
2373                /**
2374                 * Cookiebot
2375                 */
2376                if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
2377
2378                    var cookiebot_consent_category = options.gdpr['cookiebot_' + pixel + '_consent_category'];
2379
2380                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
2381                        if (Cookiebot.consented === true || Cookiebot.consent[cookiebot_consent_category]) {
2382                            return true;
2383                        }
2384                    } else {
2385                        if (Cookiebot.consent[cookiebot_consent_category]) {
2386                            return true;
2387                        }
2388                    }
2389                    return false;
2390
2391                }
2392
2393                /**
2394                 * Cookie Notice
2395                 */
2396                if (options.gdpr.cookie_notice_integration_enabled && typeof cnArgs !== 'undefined') {
2397
2398                    var cn_cookie = Cookies.get(cnArgs.cookieName);
2399
2400                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
2401                        if (typeof cn_cookie === 'undefined' || cn_cookie === 'true') {
2402                            return true;
2403                        }
2404                    } else {
2405                        if (cn_cookie === 'true') {
2406                            return true;
2407                        }
2408                    }
2409
2410                    return false;
2411
2412                }
2413
2414                /**
2415                 * Cookie Law Info
2416                 */
2417
2418                if (options.gdpr.cookie_law_info_integration_enabled) {
2419                    var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
2420                    if (options.gdpr[pixel + '_prior_consent_enabled']) {
2421                        if (typeof cli_cookie === 'undefined') return true;
2422                        if (
2423                            cli_cookie &&
2424                            (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
2425                        ) {
2426                            if (getCookieYes('analytics') === 'yes') {
2427                                return true;
2428                            }
2429                        } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
2430                            if (Cookies.get('viewed_cookie_policy') === 'yes') {
2431                                return true;
2432                            }
2433                        }
2434                    } else {
2435                        if (
2436                            cli_cookie &&
2437                            (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
2438                        ) {
2439                            if (getCookieYes('analytics') === 'yes') {
2440                                return true;
2441                            }
2442                        } else if (cli_cookie && cli_cookie === Cookies.get('viewed_cookie_policy')) {
2443                            if (Cookies.get('viewed_cookie_policy') === 'yes') {
2444                                return true;
2445                            }
2446                        }
2447                    }
2448                    return false;
2449                }
2450
2451                /**
2452                 * ConsentMagic
2453                 */
2454                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
2455
2456                    let test_prefix = CS_Data.test_prefix;
2457                    if (
2458                        ( ( typeof CS_Data.cs_google_consent_mode_enabled !== "undefined" && CS_Data.cs_google_consent_mode_enabled == 1 ) && ( pixel == 'analytics' || pixel == 'google_ads' ) )
2459                        || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode && pixel == 'facebook' )
2460                        || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode && pixel == 'reddit' )
2461                        || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled && pixel == 'bing' )
2462                    ) {
2463                        if ( CS_Data.cs_cache_enabled == 0 || ( CS_Data.cs_cache_enabled == 1 && window.CS_Cache && window.CS_Cache.check_status ) ) {
2464                            return true;
2465                        } else {
2466                            return false;
2467                        }
2468                    }
2469
2470                    if( pixel == 'facebook' && ( CS_Data.cs_script_cat.facebook == 0 || CS_Data.cs_script_cat.facebook == CS_Data.cs_necessary_cat_id ) ) {
2471                        return true;
2472                    } else if( pixel == 'bing' && ( CS_Data.cs_script_cat.bing == 0 || CS_Data.cs_script_cat.bing == CS_Data.cs_necessary_cat_id ) ) {
2473                        return true;
2474                    } else if( pixel == 'analytics' && ( CS_Data.cs_script_cat.analytics == 0 || CS_Data.cs_script_cat.analytics == CS_Data.cs_necessary_cat_id ) ) {
2475                        return true;
2476                    } else if( pixel == 'google_ads' && ( CS_Data.cs_script_cat.gads == 0 || CS_Data.cs_script_cat.gads == CS_Data.cs_necessary_cat_id ) ) {
2477                        return true;
2478                    } else if( pixel == 'pinterest' && ( CS_Data.cs_script_cat.pinterest == 0 || CS_Data.cs_script_cat.pinterest == CS_Data.cs_necessary_cat_id ) ) {
2479                        return true;
2480                    } else if( pixel == 'tiktok' && ( CS_Data.cs_script_cat.tiktok == 0 || CS_Data.cs_script_cat.tiktok == CS_Data.cs_necessary_cat_id ) ) {
2481                        return true;
2482                    } else if( pixel == 'reddit' && ( CS_Data.cs_script_cat?.reddit == 0 || CS_Data.cs_script_cat?.reddit == CS_Data.cs_necessary_cat_id ) ) {
2483		                return true;
2484	                }
2485
2486                    let substring = "cs_enabled_cookie_term",
2487                        theCookies = document.cookie.split( ';' );
2488
2489                    for ( let i = 1; i <= theCookies.length; i++ ) {
2490                        if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
2491                            let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
2492                            categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
2493                            let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
2494
2495                            if ( categoryCookie === CS_Data.cs_script_cat.facebook && pixel == 'facebook' ) {
2496                                return cs_cookie_val == 'yes';
2497                            } else if ( categoryCookie === CS_Data.cs_script_cat.bing && pixel == 'bing' ) {
2498                                return cs_cookie_val == 'yes';
2499                            } else if ( categoryCookie === CS_Data.cs_script_cat.analytics && pixel == 'analytics' ) {
2500                                return cs_cookie_val == 'yes';
2501                            } else if ( categoryCookie === CS_Data.cs_script_cat.gads && pixel == 'google_ads' ) {
2502                                return cs_cookie_val == 'yes';
2503                            } else if ( categoryCookie === CS_Data.cs_script_cat.pinterest && pixel == 'pinterest' ) {
2504                                return cs_cookie_val == 'yes';
2505                            } else if ( categoryCookie === CS_Data.cs_script_cat.tiktok && pixel == 'tiktok' ) {
2506                                return cs_cookie_val == 'yes';
2507                            } else if ( categoryCookie === CS_Data.cs_script_cat?.reddit && pixel == 'reddit' ) {
2508	                            return cs_cookie_val == 'yes';
2509                            }
2510                        }
2511                    }
2512
2513                    return false;
2514                }
2515
2516
2517                /**
2518                 * Real Cookie Banner
2519                 */
2520                if (options.gdpr.real_cookie_banner_integration_enabled) {
2521                    var consentApi = window.consentApi;
2522                    if (consentApi) {
2523                        switch (pixel) {
2524                            case "analytics":
2525                                return consentApi.consentSync("http", "_ga", "*").cookieOptIn;
2526                            case "facebook":
2527                                return consentApi.consentSync("http", "_fbp", "*").cookieOptIn;
2528                            case "pinterest":
2529  
2529                              return consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn;
2530                            case "bing":
2531                                return consentApi.consentSync("http", "_uetsid", "*").cookieOptIn;
2532                            case "google_ads":
2533                                return consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn;
2534                            case 'tiktok':
2535                                return consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn;
2536                            default:
2537                                return true;
2538                        }
2539                    }
2540                }
2541
2542                return true;
2543
2544            },
2545
2546            setupGdprCallbacks: function () {
2547
2548                let isConcent = false;
2549
2550                /**
2551                 * Cookiebot
2552                 */
2553                if ( options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined' ) {
2554                    isConcent = true;
2555                    window.addEventListener( "CookiebotOnConsentReady", function () {
2556
2557                        let consent = {
2558                            facebook: true,
2559                            ga: true,
2560                            google_ads: true,
2561                            tiktok: true,
2562                            bing: true,
2563                            pinterest: true,
2564                            gtm: true,
2565                        };
2566                        Utils.initializeVideoAPIs( options );
2567
2568                        Utils.manageCookies();
2569                        if ( Cookiebot.consent.marketing ) {
2570                            Facebook.loadPixel();
2571                            Bing.loadPixel();
2572                            Pinterest.loadPixel();
2573                            GAds.loadPixel();
2574                            TikTok.loadPixel();
2575
2576                            consent.facebook = true;
2577                            consent.bing = true;
2578                            consent.google_ads = true;
2579                            consent.pinterest = true;
2580                            consent.tiktok = true;
2581                        }
2582                        if ( Cookiebot.consent.statistics ) {
2583                            Analytics.loadPixel();
2584
2585                            consent.ga = true;
2586                            consent.gtm = true;
2587                        }
2588                        if ( !Cookiebot.consent.marketing ) {
2589                            Facebook.disable();
2590                            Pinterest.disable();
2591                            Bing.disable()
2592                            GAds.disable();
2593                            TikTok.disable();
2594
2595                            consent.facebook = false;
2596                            consent.bing = false;
2597                            consent.google_ads = false;
2598                            consent.pinterest = false;
2599                            consent.tiktok = false;
2600                        }
2601                        if ( !Cookiebot.consent.statistics ) {
2602                            Analytics.disable();
2603
2604                            consent.ga = false;
2605                            consent.gtm = false;
2606                        }
2607
2608                        Utils.setupGDPRData( consent );
2609                    } );
2610                }
2611
2612                /**
2613                 * Cookie Notice
2614                 */
2615                if ( options.gdpr.cookie_notice_integration_enabled ) {
2616                    isConcent = true;
2617                    $( document ).onFirst( 'click', '.cn-set-cookie', function () {
2618
2619                        let consent = {};
2620
2621                        if ( $( this ).data( 'cookie-set' ) === 'accept' ) {
2622
2623                            Utils.initializeVideoAPIs( options );
2624
2625                            Facebook.loadPixel();
2626                            Analytics.loadPixel();
2627                            GAds.loadPixel();
2628                            Pinterest.loadPixel();
2629                            Bing.loadPixel();
2630                            TikTok.loadPixel();
2631
2632                            consent = {
2633                                facebook: true,
2634                                ga: true,
2635                                google_ads: true,
2636                                tiktok: true,
2637                                bing: true,
2638                                pinterest: true,
2639                                gtm: true,
2640                            };
2641                        } else {
2642                            Facebook.disable();
2643                            Analytics.disable();
2644                            GAds.disable();
2645                            Pinterest.disable();
2646                            Bing.disable();
2647                            TikTok.disable();
2648
2649                            consent = {
2650                                facebook: false,
2651                                ga: false,
2652                                google_ads: false,
2653                                tiktok: false,
2654                                bing: false,
2655                                pinterest: false,
2656                                gtm: false,
2657                            };
2658                        }
2659                        Utils.setupGDPRData( consent );
2660
2661                    } );
2662
2663                    $( document ).onFirst( 'click', '.cn-revoke-cookie', function () {
2664                        Facebook.disable();
2665                        Analytics.disable();
2666                        GAds.disable();
2667                        Pinterest.disable();
2668                        Bing.disable();
2669                        TikTok.disable();
2670
2671                        let consent = {
2672                            facebook: false,
2673                            ga: false,
2674                            google_ads: false,
2675                            tiktok: false,
2676                            bing: false,
2677                            pinterest: false,
2678                            gtm: false,
2679                        };
2680                        Utils.setupGDPRData( consent );
2681
2682                    } );
2683                }
2684
2685                /**
2686                 * Cookie Law Info
2687                 */
2688                if ( options.gdpr.cookie_law_info_integration_enabled ) {
2689                    isConcent = true;
2690                    $( document ).onFirst( 'click', '#wt-cli-accept-all-btn,#cookie_action_close_header, .cky-btn-accept', function () {
2691                        Utils.initializeVideoAPIs( options );
2692                        setTimeout( function () {
2693                            let cli_cookie = Cookies.get( 'cookieyes-consent' ) ?? Cookies.get( 'wt_consent' ) ?? Cookies.get( 'viewed_cookie_policy' );
2694                            if ( typeof cli_cookie !== 'undefined' ) {
2695                                if (
2696                                    cli_cookie &&
2697                                    (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent'))
2698                                ) {
2699                                    if (getCookieYes('analytics') === 'yes') {
2700                                        Utils.manageCookies();
2701                                    }
2702                                } else if ( cli_cookie === Cookies.get( 'viewed_cookie_policy' ) && cli_cookie == 'yes' ) {
2703                                    Utils.manageCookies();
2704                                }
2705                            }
2706                        }, 1000 )
2707                        Facebook.loadPixel();
2708                        Analytics.loadPixel();
2709                        GAds.loadPixel();
2710                        Pinterest.loadPixel();
2711                        Bing.loadPixel();
2712                        TikTok.loadPixel();
2713
2714                        let consent = {
2715                            facebook: true,
2716                            ga: true,
2717                            google_ads: true,
2718                            tiktok: true,
2719                            bing: true,
2720                            pinterest: true,
2721                            gtm: true,
2722                        };
2723                        Utils.setupGDPRData( consent );
2724                    } );
2725
2726                    $( document ).onFirst( 'click', '#cookie_action_close_header_reject, .cky-btn-reject', function () {
2727                        Facebook.disable();
2728                        Analytics.disable();
2729                        GAds.disable();
2730                        Pinterest.disable();
2731                        Bing.disable();
2732                        TikTok.disable();
2733
2734                        let consent = {
2735                            facebook: false,
2736                            ga: false,
2737                            google_ads: false,
2738                            tiktok: false,
2739                            bing: false,
2740                            pinterest: false,
2741                            gtm: false,
2742                        };
2743                        Utils.setupGDPRData( consent );
2744                    } );
2745                }
2746
2747                /**
2748                 * ConsentMagic
2749                 */
2750                if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
2751                    isConcent = true;
2752                    let test_prefix = CS_Data.test_prefix,
2753                        cs_refresh_after_consent = false,
2754                        substring = "cs_enabled_cookie_term";
2755
2756                    if ( CS_Data.cs_refresh_after_consent == 1 ) {
2757                        cs_refresh_after_consent = CS_Data.cs_refresh_after_consent;
2758                    }
2759
2760                    let consent_actions = function () {
2761                        let theCookies = document.cookie.split( ';' );
2762
2763                        let consent = {
2764                            facebook: true,
2765                            ga: true,
2766                            google_ads: true,
2767                            tiktok: true,
2768                            bing: true,
2769                            pinterest: true,
2770                            gtm: true,
2771	                        reddit: true,
2772                        };
2773
2774                        for ( let i = 1; i <= theCookies.length; i++ ) {
2775                            if ( theCookies[ i - 1 ].indexOf( substring ) !== -1 ) {
2776                                let categoryCookie = theCookies[ i - 1 ].replace( 'cs_enabled_cookie_term' + test_prefix + '_', '' );
2777                                categoryCookie = Number( categoryCookie.replace( /\D+/g, "" ) );
2778                                let cs_cookie_val = Cookies.get( 'cs_enabled_cookie_term' + test_prefix + '_' + categoryCookie );
2779                                if ( cs_cookie_val == 'yes' ) {
2780
2781                                    Utils.initializeVideoAPIs( options );
2782
2783                                    if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) || ( typeof CS_Data.cs_meta_ldu_mode !== "undefined" && CS_Data.cs_meta_ldu_mode ) ) {
2784                                        Facebook.loadPixel();
2785                                    }
2786
2787                                    if ( categoryCookie === CS_Data.cs_script_cat.bing || ( typeof CS_Data.cs_bing_consent_mode !== "undefined" && CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) {
2788                                        Bing.loadPixel();
2789                                    }
2790
2791                                    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 ) ) {
2792                                        Analytics.loadPixel();
2793                                    }
2794                                    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 ) ) {
2795                                        GAds.loadPixel();
2796                                    }
2797
2798                                    if ( categoryCookie === CS_Data.cs_script_cat.pinterest ) {
2799                                        Pinterest.loadPixel();
2800                                    }
2801
2802                                    if ( categoryCookie === CS_Data.cs_script_cat.tiktok ) {
2803                                        TikTok.loadPixel();
2804                                    }
2805
2806	                                if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) || ( typeof CS_Data.cs_reddit_ldu_mode !== "undefined" && CS_Data.cs_reddit_ldu_mode ) ) {
2807		                                Reddit.loadPixel();
2808	                                }
2809                                } else {
2810                                    if ( ( categoryCookie === CS_Data.cs_script_cat.facebook ) && ( typeof CS_Data.cs_meta_ldu_mode == "undefined" || !CS_Data.cs_meta_ldu_mode ) ) {
2811                                        Facebook.disable();
2812                                        consent.facebook = false;
2813                                    }
2814
2815                                    if ( categoryCookie === CS_Data.cs_script_cat.bing && ( typeof CS_Data.cs_bing_consent_mode == "undefined" || !CS_Data.cs_bing_consent_mode.ad_storage.enabled ) ) {
2816                                        Bing.disable();
2817                                        consent.bing = false;
2818                                    }
2819
2820                                    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 ) ) {
2821                                        Analytics.disable();
2822                                        consent.ga = false;
2823                                        consent.gtm = false;
2824                                    }
2825
2826                                    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 ) ) {
2827                                        GAds.disable();
2828                                        consent.google_ads = false;
2829                                    }
2830
2831                                    if ( categoryCookie === CS_Data.cs_script_cat.pinterest ) {
2832                                        Pinterest.disable();
2833                                        consent.pinterest = false;
2834                                    }
2835
2836                                    if ( categoryCookie === CS_Data.cs_script_cat.tiktok ) {
2837                                        TikTok.disable();
2838                                        consent.tiktok = false;
2839                                    }
2840
2841	                                if ( ( categoryCookie === CS_Data.cs_script_cat.reddit ) && ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || !CS_Data.cs_reddit_ldu_mode ) ) {
2842		                                Reddit.disable();
2843		                                consent.reddit = false;
2844	                                }
2845                                }
2846                                if ( Cookies.get( 'cs_enabled_advanced_matching' ) == 'yes' ) {
2847                                    Facebook.loadPixel();
2848                                }
2849                            }
2850                        }
2851
2852                        Utils.setupGDPRData( consent );
2853                    }
2854
2855                    if ( !cs_refresh_after_consent ) {
2856                        consent_actions();
2857
2858                        $( document ).on( 'click', '.cs_action_btn', function ( e ) {
2859                            e.preventDefault();
2860
2861                            let consent = {
2862                                facebook: true,
2863                                ga: true,
2864                                google_ads: true,
2865                                tiktok: true,
2866                                bing: true,
2867                                pinterest: true,
2868                                gtm: true,
2869	                            reddit: true,
2870                            };
2871
2872                            let elm = $( this ),
2873                                button_action = elm.attr( 'data-cs_action' );
2874
2875                            if ( button_action === 'allow_all' ) {
2876
2877                                Utils.initializeVideoAPIs( options );
2878
2879                                Facebook.loadPixel();
2880                                Bing.loadPixel();
2881                                Analytics.loadPixel();
2882                                GAds.loadPixel();
2883                                Pinterest.loadPixel();
2884                                TikTok.loadPixel();
2885								Reddit.loadPixel();
2886
2887                                consent.facebook = true;
2888                                consent.bing = true;
2889                                consent.ga = true;
2890                                consent.google_ads = true;
2891                                consent.pinterest = true;
2892                                consent.tiktok = true;
2893								consent.reddit = true;
2894                                consent.gtm = true;
2895
2896                                Utils.setupGDPRData( consent );
2897
2898                            } else if ( button_action === 'disable_all' ) {
2899
2900                                if (typeof CS_Data.cs_meta_ldu_mode == "undefined" || CS_Data.cs_meta_ldu_mode == 0 ) {
2901                                    Facebook.disable();
2902                                    consent.facebook = false;
2903                                }
2904
2905                                if (typeof CS_Data.cs_bing_consent_mode == "undefined" || CS_Data.cs_bing_consent_mode.ad_storage.enabled == 0 ) {
2906                                    Bing.disable();
2907                                    consent.bing = false;
2908                                }
2909
2910                                if ( typeof CS_Data.cs_google_analytics_consent_mode == "undefined" || CS_Data.cs_google_analytics_consent_mode == 0 ) {
2911                                    Analytics.disable();
2912                                    consent.ga = false;
2913                                    consent.gtm = false;
2914                                }
2915
2916                                if ( typeof CS_Data.cs_google_ads_consent_mode == "undefined" || CS_Data.cs_google_ads_consent_mode == 0 ) {
2917                                    GAds.disable();
2918                                    consent.google_ads = false;
2919                                }
2920
2921	                            if ( typeof CS_Data.cs_reddit_ldu_mode == "undefined" || CS_Data.cs_reddit_ldu_mode == 0 ) {
2922		                            Reddit.disable();
2923		                            consent.reddit = false;
2924	                            }
2925
2926                                Pinterest.disable();
2927                                TikTok.disable();
2928
2929                                consent.pinterest = false;
2930                                consent.tiktok = false;
2931
2932                                Utils.setupGDPRData( consent );
2933                            } else if ( button_action === 'cs_confirm' ) {
2934                                consent_actions();
2935                            }
2936                        } );
2937                    }
2938                }
2939
2940                /**
2941                 * Real Cookie Banner
2942                 */
2943                if ( options.gdpr.real_cookie_banner_integration_enabled ) {
2944                    isConcent = true;
2945                    let consentApi = window.consentApi;
2946                    if ( consentApi ) {
2947                        consentApi.consent( "http", "_ga", "*" )
2948                            .then( Analytics.loadPixel.bind( Analytics ), Analytics.disable.bind( Analytics ) );
2949                        consentApi.consent( "http", "1P_JAR", ".google.com" )
2950                            .then( GAds.loadPixel.bind( GAds ), GAds.disable.bind( GAds ) );
2951                        consentApi.consent( "http", "_fbp", "*" )
2952                            .then( Facebook.loadPixel.bind( Facebook ), Facebook.disable.bind( Facebook ) );
2953                        consentApi.consent( "http", "_pinterest_sess", ".pinterest.com" )
2954                            .then( Pinterest.loadPixel.bind( Pinterest ), Pinterest.disable.bind( Pinterest ) );
2955                        consentApi.consent( "http", "_uetsid", "*" )
2956                            .then( Bing.loadPixel.bind( Bing ), Bing.disable.bind( Bing ) );
2957                        consentApi.consent( "http", "tt_webid_v2", ".tiktok.com" )
2958                            .then( TikTok.loadPixel.bind( TikTok ), TikTok.disable.bind( TikTok ) );
2959
2960                        let consent = {
2961                            facebook: true,
2962                            ga: true,
2963                            google_ads: true,
2964                            tiktok: true,
2965                            bing: true,
2966                            pinterest: true,
2967           
2967                 gtm: true,
2968                        };
2969
2970                        if (!consentApi.consentSync("http", "_ga", "*").cookieOptIn) {
2971                            consent.ga = false;
2972                            consent.gtm = false;
2973                        }
2974                        if (!consentApi.consentSync("http", "_fbp", "*").cookieOptIn) {
2975                            consent.facebook = false;
2976                        }
2977                        if (!consentApi.consentSync("http", "_pinterest_sess", ".pinterest.com").cookieOptIn) {
2978                            consent.pinterest = false;
2979                        }
2980                        if (!consentApi.consentSync("http", "_uetsid", "*").cookieOptIn) {
2981                            consent.bing = false;
2982                        }
2983                        if (!consentApi.consentSync("http", "1P_JAR", ".google.com").cookieOptIn) {
2984                            consent.google_ads = false;
2985                        }
2986                        if (!consentApi.consentSync("http", "tt_webid_v2", ".tiktok.com").cookieOptIn) {
2987                            consent.tiktok = false;
2988                        }
2989                        Utils.setupGDPRData( consent );
2990
2991                        // load WatchVideo event APIs for Auto
2992                        /**
2993                         * Real Cookie Banner.
2994                         */
2995                        if ( options.hasOwnProperty( 'automatic' ) && options.automatic.enable_video && options.automatic.enable_youtube ) {
2996                            consentApi.consent( "http", "CONSENT", ".youtube.com" ).then( Utils.initYouTubeAPI );
2997                        }
2998
2999                        if ( options.hasOwnProperty( 'automatic' ) && options.automatic.enable_video && options.automatic.enable_vimeo ) {
3000                            consentApi.consent( "http", "player", ".vimeo.com" ).then( Utils.initVimeoAPI );
3001                        }
3002                    }
3003                }
3004
3005                if ( !isConcent ) {
3006                    Utils.initializeVideoAPIs( options );
3007                }
3008            },
3009
3010            setupGDPRData: function ( consent ) {
3011                consent = window.btoa( JSON.stringify( consent ) );
3012                Cookies.set( 'pys_consent', consent, { expires: 365, path: '/', domain: domain } );
3013            },
3014
3015            /**
3016             * Enrich
3017             */
3018            isCheckoutPage: function () {
3019                return $('body').hasClass('woocommerce-checkout') || document.querySelector('.woocommerce-checkout') ||
3020                    $('body').hasClass('edd-checkout');
3021            },
3022            addCheckoutFields : function() {
3023                var utm = "";
3024                var utms = getUTMs()
3025                $.each(utmTerms, function (index, name) {
3026                    if(index > 0) {
3027                        utm+="|";
3028                    }
3029                    utm+=name+":"+utms[name];
3030                });
3031                var utmIdList = "";
3032                var utmsIds = getUTMId()
3033                $.each(utmId, function (index, name) {
3034                    if(index > 0) {
3035                        utmIdList+="|";
3036                    }
3037                    utmIdList+=name+":"+utmsIds[name];
3038                });
3039                var utmIdListLast = "";
3040                var utmsIdsLast = getUTMId(true)
3041                $.each(utmId, function (index, name) {
3042                    if(index > 0) {
3043                        utmIdListLast+="|";
3044                    }
3045                    utmIdListLast+=name+":"+utmsIdsLast[name];
3046                });
3047
3048
3049                var utmLast = "";
3050                var utmsLast = getUTMs(true)
3051                $.each(utmTerms, function (index, name) {
3052                    if(index > 0) {
3053                        utmLast+="|";
3054                    }
3055                    utmLast+=name+":"+utmsLast[name];
3056                });
3057
3058                var dateTime = getDateTime();
3059                var landing = Cookies.get('pys_landing_page');
3060                var lastLanding = Cookies.get('last_pys_landing_page');
3061                var trafic = Cookies.get('pysTrafficSource');
3062                var lastTrafic = Cookies.get('last_pysTrafficSource');
3063
3064                var $form = null;
3065                if($('body').hasClass('woocommerce-checkout')) {
3066                    $form = $("form.woocommerce-checkout");
3067                } else {
3068                    $form = $("#edd_purchase_form");
3069                }
3070                var inputs = {'pys_utm':utm,
3071                    'pys_utm_id':utmIdList,
3072                    'pys_browser_time':dateTime.join("|"),
3073                    'pys_landing':landing,
3074                    'pys_source':trafic,
3075                    'pys_order_type': $(".wcf-optin-form").length > 0 ? "wcf-optin" : "normal",
3076
3077                    'last_pys_landing':lastLanding,
3078                    'last_pys_source':lastTrafic,
3079                    'last_pys_utm':utmLast,
3080                    'last_pys_utm_id':utmIdListLast,
3081                }
3082
3083                Object.keys(inputs).forEach(function(key,index) {
3084                    $form.append("<input type='hidden' name='"+key+"' value='"+inputs[key]+"' /> ");
3085                });
3086
3087
3088            },
3089
3090            /**
3091             * Advanced From Data
3092             */
3093            saveAdvancedFormData: function ( email, phone, firstName, lastName, override = true ) {
3094
3095                if ( !options.cookie.disabled_advanced_form_data_cookie ) {
3096                    let data = Utils.getAdvancedFormData();
3097                    // Ensure data["address"] is an object
3098
3099                    if ( email != null ) {
3100                        if ( !override ) {
3101                            if ( typeof data[ "email" ] === 'undefined' || !data[ "email" ] ) {
3102                                data[ "email" ] = email;
3103                            }
3104                        } else {
3105                            data[ "email" ] = email;
3106                        }
3107
3108                        if ( typeof data[ "emails" ] === 'object' ) {
3109                            if ( override ) {
3110                                data[ "emails" ] = [ email, ...Object.values( data[ "emails" ] ) ];
3111                            } else {
3112                                data[ "emails" ] = [ ...Object.values( data[ "emails" ] ), email ];
3113                            }
3114                        } else {
3115                            data[ "emails" ] = [ email ];
3116                        }
3117                        data[ "emails" ] = [ ...new Set( data[ "emails" ] ) ];
3118                        data[ "emails" ] = data[ "emails" ].slice( 0, 3 );
3119                    }
3120
3121                    if ( phone != null ) {
3122                        if ( !override ) {
3123                            if ( typeof data[ "phone" ] === 'undefined' || !data[ "phone" ] ) {
3124                                data[ "phone" ] = phone;
3125                            }
3126                        } else {
3127                            data[ "phone" ] = phone;
3128                        }
3129
3130                        if ( typeof data[ "phones" ] === 'object' ) {
3131                            if ( override ) {
3132                                data[ "phones" ] = [ phone, ...Object.values( data[ "phones" ] ) ];
3133                            } else {
3134                                data[ "phones" ] = [ ...Object.values( data[ "phones" ] ), phone ];
3135                            }
3136                        } else {
3137                            data[ "phones" ] = [ phone ];
3138                        }
3139                        data[ "phones" ] = [ ...new Set( data[ "phones" ] ) ];
3140                        data[ "phones" ] = data[ "phones" ].slice( 0, 3 );
3141                    }
3142
3143                    if ( firstName != null ) {
3144                        if ( !override ) {
3145                            if ( typeof data[ "first_name" ] === 'undefined' || !data[ "first_name" ] ) {
3146                                data[ "first_name" ] = firstName;
3147                            }
3148                        } else {
3149                            data[ "first_name" ] = firstName;
3150                        }
3151
3152                        if ( typeof data[ "fns" ] === 'object' ) {
3153                            if ( override ) {
3154                                data[ "fns" ] = [ firstName, ...Object.values( data[ "fns" ] ) ];
3155                            } else {
3156                                data[ "fns" ] = [ ...Object.values( data[ "fns" ] ), firstName ];
3157                            }
3158                        } else {
3159                            data[ "fns" ] = [ firstName ];
3160                        }
3161                        data[ "fns" ] = [ ...new Set( data[ "fns" ] ) ];
3162                        data[ "fns" ] = data[ "fns" ].slice( 0, 2 );
3163                    }
3164
3165                    if ( lastName != null ) {
3166                        if ( !override ) {
3167                            if ( typeof data[ "last_name" ] === 'undefined' || !data[ "last_name" ] ) {
3168                                data[ "last_name" ] = lastName;
3169                            }
3170                        } else {
3171                            data[ "last_name" ] = lastName;
3172                        }
3173
3174                        if ( typeof data[ "lns" ] === 'object' ) {
3175                            if ( override ) {
3176                                data[ "lns" ] = [ lastName, ...Object.values( data[ "lns" ] ) ];
3177                            } else {
3178                                data[ "lns" ] = [ ...Object.values( data[ "fns" ] ), lastName ];
3179                            }
3180                        } else {
3181                            data[ "lns" ] = [ lastName ];
3182                        }
3183                        data[ "lns" ] = [ ...new Set( data[ "lns" ] ) ];
3184                        data[ "lns" ] = data[ "lns" ].slice( 0, 2 );
3185                    }
3186
3187                    Cookies.set( 'pys_advanced_form_data', JSON.stringify( data ), { expires: 300,path: '/',domain: domain } );
3188                } else {
3189                    Cookies.remove( 'pys_advanced_form_data', { path: '/',domain: domain } )
3190                }
3191                if(GTM.isEnabled()){
3192                    GTM.updateEnhancedConversionData();
3193                }
3194                if(Analytics.isEnabled()){
3195                    Analytics.updateEnhancedConversionData();
3196                } else if ( GAds.isEnabled() ) {
3197                    GAds.updateEnhancedConversionData();
3198                }
3199            },
3200            getAdvancedMergeFormData: function (allways_provided_data = false) {
3201                const advanced = Utils.getAdvancedFormData();
3202                let mergedData = {},
3203                    limit = options.tracking_analytics.use_multiple_provided_data || allways_provided_data ? 3 : 1,
3204                    address_limit = options.tracking_analytics.use_multiple_provided_data || allways_provided_data ? 2 : 1;
3205
3206                if ( options.tracking_analytics.use_encoding_provided_data || allways_provided_data) {
3207                    mergedData.sha256_email_address = [];
3208                    mergedData.sha256_phone_number = [];
3209                    mergedData.address = [];
3210                    if ( options.tracking_analytics.hasOwnProperty( "userData" ) ) {
3211                        if ( options.tracking_analytics.userData.hasOwnProperty( "emails" ) && Object.keys( options.tracking_analytics.userData.emails ).length > 0 ) {
3212                            Object.keys( options.tracking_analytics.userData.emails ).forEach( ( key ) => {
3213                                mergedData.sha256_email_address.push( sha256( options.tracking_analytics.userData.emails[ key ] ) );
3214                            } )
3215                        }
3216                        if ( options.tracking_analytics.userData.hasOwnProperty( "phones" ) && Object.keys( options.tracking_analytics.userData.phones ).length > 0 ) {
3217                            Object.keys( options.tracking_analytics.userData.phones ).forEach( ( key ) => {
3218                                mergedData.sha256_phone_number.push( sha256( options.tracking_analytics.userData.phones[ key ] ) );
3219                            } )
3220                        }
3221                        if ( options.tracking_analytics.userData.hasOwnProperty( "addresses" ) && Object.keys( options.tracking_analytics.userData.addresses ).length > 0 ) {
3222                            Object.keys( options.tracking_analytics.userData.addresses ).forEach( ( key ) => {
3223                                let address = Object.assign( {}, options.tracking_analytics.userData.addresses[ key ] );
3224
3225                                if ( address.first_name ) {
3226                                    address.sha256_first_name = address.first_name !== '' ? sha256( address.first_name ) : '';
3227                                    delete address.first_name;
3228                                }
3229                                if ( address.last_name ) {
3230                                    address.sha256_last_name = address.last_name !== '' ? sha256( address.last_name ) : '';
3231                                    delete address.last_name;
3232                                }
3233                                mergedData.address.push( address );
3234                            } )
3235                        }
3236                    }
3237
3238                    let data_persistency = options.data_persistency;
3239
3240                    //emails
3241                    if ( advanced.emails && Object.keys( advanced.emails ).length > 0 ) {
3242                        Object.keys( advanced.emails ).forEach( ( ke
3242y ) => {
3243                            if ( data_persistency === 'recent_data' ) {
3244                                mergedData.sha256_email_address.push( sha256( advanced.emails[ key ] ) );
3245                            } else {
3246                                mergedData.sha256_email_address.unshift( sha256( advanced.emails[ key ] ) );
3247                            }
3248                        } )
3249                    }
3250                    if ( advanced.email && advanced.email !== '' ) {
3251                        if ( data_persistency === 'recent_data' ) {
3252                            mergedData.sha256_email_address.push( sha256( advanced.email ) );
3253                        } else {
3254                            mergedData.sha256_email_address.unshift( sha256( advanced.email ) );
3255                        }
3256                    }
3257                    mergedData.sha256_email_address = [ ...new Set( mergedData.sha256_email_address ) ];
3258                    mergedData.sha256_email_address = mergedData.sha256_email_address.slice( 0, limit );
3259
3260                    //phones
3261                    if ( advanced.phones && Object.keys( advanced.phones ).length > 0 ) {
3262                        Object.keys( advanced.phones ).forEach( ( key ) => {
3263                            if ( data_persistency === 'recent_data' ) {
3264                                mergedData.sha256_phone_number.push( sha256( advanced.phones[ key ] ) );
3265                            } else {
3266                                mergedData.sha256_phone_number.unshift( sha256( advanced.phones[ key ] ) );
3267                            }
3268                        } )
3269                    }
3270                    if ( advanced.phone && advanced.phone !== '' ) {
3271                        if ( data_persistency === 'recent_data' ) {
3272                            mergedData.sha256_phone_number.push( sha256( advanced.phone ) );
3273                        } else {
3274                            mergedData.sha256_phone_number.unshift( sha256( advanced.phone ) );
3275                        }
3276                    }
3277                    mergedData.sha256_phone_number = [ ...new Set( mergedData.sha256_phone_number ) ];
3278                    mergedData.sha256_phone_number = mergedData.sha256_phone_number.slice( 0, limit );
3279
3280                    //first and last names
3281                    if ( advanced.fns && Object.keys( advanced.fns ).length > 0 ) {
3282                        Object.entries( advanced.fns ).forEach( ( item ) => {
3283                            if ( mergedData.address.length < address_limit ) {
3284                                let first_name = item[ 1 ];
3285                                let last_name = ( advanced.lns && Object.keys( advanced.lns ).length > 0 ) ? ( advanced.lns[ item[ 0 ] ] ? advanced.lns[ item[ 0 ] ] : advanced.lns[ 0 ] ) : '';
3286                                let address = {
3287                                    sha256_first_name: first_name !== '' ? sha256( first_name ) : '',
3288                                    sha256_last_name: last_name !== '' ? sha256( last_name ) : '',
3289                                    // Add other address properties here if they exist in advanced
3290                                };
3291                                mergedData.address.push( address );
3292                            }
3293                        } )
3294                    }
3295
3296                    if ( advanced.first_name || advanced.last_name ) {
3297                        if ( mergedData.address.length < address_limit ) {
3298                            let address = {
3299                                sha256_first_name: advanced.first_name !== '' ? sha256( advanced.first_name ) : '',
3300                                sha256_last_name: advanced.last_name !== '' ? sha256( advanced.last_name ) : '',
3301                                // Add other address properties here if they exist in advanced
3302                            };
3303                            mergedData.address.push( address );
3304                        }
3305                    }
3306                } else {
3307                    mergedData.email = [];
3308                    mergedData.phone_number = [];
3309                    mergedData.address = [];
3310                    if ( options.tracking_analytics.hasOwnProperty( "userData" ) ) {
3311                        if ( options.tracking_analytics.userData.hasOwnProperty( "emails" ) && Object.keys( options.tracking_analytics.userData.emails ).length > 0 ) {
3312                            Object.keys( options.tracking_analytics.userData.emails ).forEach( ( ke
3312y ) => {
3313                                mergedData.email.push( options.tracking_analytics.userData.emails[ key ] );
3314                            } )
3315                        }
3316                        if ( options.tracking_analytics.userData.hasOwnProperty( "phones" ) && Object.keys( options.tracking_analytics.userData.phones ).length > 0 ) {
3317                            Object.keys( options.tracking_analytics.userData.phones ).forEach( ( key ) => {
3318                                mergedData.phone_number.push( options.tracking_analytics.userData.phones[ key ] );
3319                            } )
3320                        }
3321                        if ( options.tracking_analytics.userData.hasOwnProperty( "addresses" ) && Object.keys( options.tracking_analytics.userData.addresses ).length > 0 ) {
3322                            Object.keys( options.tracking_analytics.userData.addresses ).forEach( ( key ) => {
3323                                mergedData.address.push( options.tracking_analytics.userData.addresses[ key ] );
3324                            } )
3325                        }
3326                    }
3327
3328                    let data_persistency = options.data_persistency;
3329
3330                    //emails
3331                    if ( advanced.emails && Object.keys( advanced.emails ).length > 0 ) {
3332                        Object.keys( advanced.emails ).forEach( ( key ) => {
3333                            if ( data_persistency === 'recent_data' ) {
3334                                mergedData.email.push( advanced.emails[ key ] );
3335                            } else {
3336                                mergedData.email.unshift( advanced.emails[ key ] );
3337                            }
3338                        } )
3339                    }
3340                    if ( advanced.email && advanced.email !== '' ) {
3341                        if ( data_persistency === 'recent_data' ) {
3342                            mergedData.email.push( advanced.email );
3343                        } else {
3344                            mergedData.email.unshift( advanced.email );
3345                        }
3346                    }
3347                    mergedData.email = [ ...new Set( mergedData.email ) ];
3348                    mergedData.email = mergedData.email.slice( 0, limit );
3349
3350                    //phones
3351                    if ( advanced.phones && Object.keys( advanced.phones ).length > 0 ) {
3352                        Object.keys( advanced.phones ).forEach( ( key ) => {
3353                            if ( data_persistency === 'recent_data' ) {
3354                                mergedData.phone_number.push( advanced.phones[ key ] );
3355                            } else {
3356                                mergedData.phone_number.unshift( advanced.phones[ key ] );
3357                            }
3358                        } )
3359                    }
3360                    if ( advanced.phone && advanced.phone !== '' ) {
3361                        if ( data_persistency === 'recent_data' ) {
3362                            mergedData.phone_number.push( advanced.phone );
3363                        } else {
3364                            mergedData.phone_number.unshift( advanced.phone );
3365                        }
3366                    }
3367                    mergedData.phone_number = [ ...new Set( mergedData.phone_number ) ];
3368                    mergedData.phone_number = mergedData.phone_number.slice( 0, limit );
3369
3370                    //first and last names
3371                    if ( advanced.fns && Object.keys( advanced.fns ).length > 0 ) {
3372                        Object.entries( advanced.fns ).forEach( ( item ) => {
3373                            if ( mergedData.address.length < address_limit ) {
3374                                let first_name = item[ 1 ];
3375                                let last_name = ( advanced.lns && Object.keys( advanced.lns ).length > 0 ) ? ( advanced.lns[ item[ 0 ] ] ? advanced.lns[ item[ 0 ] ] : advanced.lns[ 0 ] ) : '';
3376                                let address = {
3377                                    first_name: first_name || '',
3378                                    last_name: last_name || '',
3379                                    // Add other address properties here if they exist in advanced
3380                                };
3381                                mergedData.address.push( address );
3382                            }
3383                        } )
3384                    }
3385
3386                    if ( advanced.first_name || advanced.last_name ) {
3387                        if ( mergedData.address.length < address_limit ) {
3388                            let address = {
3389                                first_name: advanced.first_name || '',
3390                                last_name: advanced.last_name || '',
3391                                // Add other address properties here if they exist in advanced
3392                            };
3393                            mergedData.address.push( address );
3394                        }
3395                    }
3396                }
3397
3398                Utils.removeEmptyProperties( mergedData );
3399                return mergedData;
3400            },
3401            removeEmptyProperties : function(obj) {
3402
3403                if (obj.hasOwnProperty('address')) {
3404                    // Проходим по каждому массиву в 'address'
3405                    for (let i = 0; i < obj['address'].length; i++) {
3406                        let address1 = obj['address'][i];
3407
3408                        // Сравниваем с каждым другим массивом в 'address'
3409                        for (let j = i + 1; j < obj['address'].length; j++) {
3410                            let address2 = obj['address'][j];
3411
3412                            // Если находим дублирующиеся свойства, удаляем их из address2
3413                            for (let prop in address1) {
3414                                if (address1[prop] === address2[prop]) {
3415                                    delete address2[prop];
3416                                }
3417                            }
3418                        }
3419                    }
3420                }
3421
3422                for (let key in obj) {
3423                    if (obj[key] === null || obj[key] === undefined || obj[key] === '') {
3424                        delete obj[key];
3425                    } else if (Array.isArray(obj[key])) {
3426                        obj[key] = [...new Set(obj[key])]; // Удаление дубликатов из массива
3427                        obj[key] = obj[key].filter(item => item !== null && item !== undefined && item !== '');
3428                        // Обработка объектов внутри массивов
3429                        obj[key] = obj[key].map(item => {
3430                            if (item === null) {
3431                                return; // Пропускаем null элементы
3432                            } else if (Array.isArray(item)) {
3433                                return this.removeEmptyProperties(item);
3434                            } else if (typeof item === 'object') {
3435                                let cleanedItem = this.removeEmptyProperties(item);
3436                                if (Object.keys(cleanedItem).length > 0) {
3437                                    return cleanedItem;
3438                                }
3439                            } else {
3440                                return item;
3441                            }
3442                        });
3443                        // Удаляем пустые объекты и null из массива
3444                        obj[key] = obj[key].filter(item => item !== undefined && !(typeof item === 'object' && Object.keys(item).length === 0));
3445                        if (obj[key].length === 0) {
3446                            delete obj[key];
3447                        }
3448                    } else if (typeof obj[key] === 'object') {
3449                        this.removeEmptyProperties(obj[key]);
3450                        if (Object.keys(obj[key]).length === 0) {
3451                            delete obj[key];
3452                        }
3453                    }
3454                }
3455                return obj;
3456            },
3457            getAdvancedFormData: function () {
3458                let dataStr = Cookies.get("pys_advanced_form_data");
3459                if(dataStr === undefined) {
3460                    return {'first_name':"",'last_name':"",'email':"",'phone':"",'fns':[],'lns':[],'emails':[],'phones':[]};
3461                } else {
3462                    return JSON.parse(dataStr);
3463                }
3464            },
3465
3466            getFormFilledData: function ( event ) {
3467                // First, resolve static/dynamic parameters
3468                if (event.params && Object.keys(event.params).length > 0) {
3469                    Object.entries(event.params).forEach(([key, value]) => {
3470                        // Resolve parameter value (static or dynamic)
3471                        const resolvedValue = resolveParamValue(value, key);
3472                        if (resolvedValue !== null) {
3473                            event.params[key] = resolvedValue;
3474                        }
3475                        else {
3476                            delete event.params[key];
3477                        }
3478                    });
3479                }
3480
3481                // Then, handle dynamic fields from cookies (existing logic)
3482
3483                if ( Object.keys(options.track_dynamic_fields).length > 0 && Object.keys(event.params).length > 0 ) {
3484                    Object.entries(event.params).forEach((item) => {
3485
3486                        if ( options.track_dynamic_fields.hasOwnProperty(item[0]) ) {
3487                            let fieldData = Cookies.get('pys_dyn_field_' + item[1] );
3488
3489                            if(fieldData !== undefined && fieldData !== '') {
3490                                event.params[item[0]] = fieldData;
3491                            } else {
3492                                delete event.params[item[0]];
3493                            }
3494                        }
3495                    })
3496                }
3497                return event;
3498            }
3499
3500        };
3501
3502    }(options);
3503
3504    var TikTok = function (options) {
3505
3506        var initialized = false;
3507
3508        function fireEvent(name, event) {
3509
3510            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'tiktok')) {
3511                return;
3512            }
3513
3514            var data = event.params;
3515
3516            var ids = event.pixelIds.filter(function (pixelId) {
3517                return !Utils.hideMatchingPixel(pixelId, 'tiktok');
3518            })
3519            var params = {};
3520            Utils.copyProperties(data, params);
3521
3522            params.eventID = Utils.generateUniqueId(event);
3523
3524            if(ids.length > 0){
3525                TikTok.fireEventAPI(name, event, params);
3526            }
3527            ids.forEach(function(pixelId){
3528                if (options.debug) {
3529                    console.log('[TikTok] ' + name, params,"pixel_id",pixelId);
3530                }
3531
3532                ttq.instance(pixelId).track(name,params)
3533
3534            });
3535
3536            var customEvent = new CustomEvent('tiktok_event_sent', {
3537                detail: {
3538                    eventName: name,
3539                    params: params,
3540                    pixel_ids: ids
3541                }
3542            });
3543            window.dispatchEvent(customEvent);
3544        }
3545
3546        return {
3547            tag: function() {
3548                return "tiktok";
3549            },
3550            isEnabled: function () {
3551                return options.hasOwnProperty('tiktok');
3552            },
3553            getHidePixel: function(){
3554                if(this.isEnabled() && options.tiktok.hasOwnProperty('hide_pixels'))
3555                {
3556                    return options.tiktok.hide_pixels;
3557                }
3558                return [];
3559            },
3560            disable: function () {
3561                initialized = false;
3562            },
3563
3564            loadPixel:function () {
3565                if (initialized || !this.isEnabled() || !Utils.consentGiven('tiktok')) {
3566                    return;
3567                }
3568                for (var i = 0; i < options.tiktok.pixelIds.length; i++) {
3569                    var trackingId = options.tiktok.pixelIds[i];
3570                    if (!Utils.hideMatchingPixel(trackingId, 'tiktok')) {
3571                        !function (w, d, t) {
3572                            w.TiktokAnalyticsObject=t;
3573                            var ttq=w[t]=w[t]||[];
3574                            ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"];
3575                            ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};
3576                            for(var i=0;i<ttq.methods.length;i++)
3577                                ttq.setAndDefer(ttq,ttq.methods[i]);
3578                            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};
3579                            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)};
3580
3581                            //ttq.load('C60QSCQRVDG9JAKNPK2G');
3582                            //ttq.page();
3583                        }(window, document, 'ttq');
3584                        break;
3585                    }
3586                }
3587
3588
3589                var ids = options.tiktok.pixelIds.filter(function (pixelId) {
3590                    return !Utils.hideMatchingPixel(pixelId, 'tiktok');
3591                })
3592                ids.forEach(function (pixelId) {
3593
3594                    ttq.load(pixelId);
3595                    ttq.page();
3596                    let advancedMatching = {};
3597                    if(options.tiktok.hasOwnProperty('advanced_matching')
3598                        && Object.keys(options.tiktok.advanced_matching).length > 0) {
3599                        advancedMatching = options.tiktok.advanced_matching;
3600                        if(!advancedMatching.hasOwnProperty("external_id")){
3601                            if (Cookies.get('pbid')) {
3602                                advancedMatching["external_id"] = Cookies.get('pbid');
3603                            }
3604                        }
3605                        else if(advancedMatching.hasOwnProperty("external_id") && advancedMatching.external_id != Cookies.get('pbid'))
3606                        {
3607                            advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id;
3608                        }
3609
3610                        ttq.instance(pixelId).identify(advancedMatching)
3611                    }
3612                });
3613                initialized = true;
3614
3615                if (options.staticEvents.hasOwnProperty('tiktok')) {
3616                    var timeout = 1;
3617                    setTimeout(function (timeout) {
3618                        Utils.fireStaticEvents('tiktok', timeout);
3619                    }, 1500, timeout)
3620                }
3621            },
3622
3623            fireEvent: function (name, data) {
3624                if (!initialized || !this.isEnabled()) {
3625                    return false;
3626                }
3627                data.delay = data.delay || 0;
3628
3629                if (data.delay === 0) {
3630                    fireEvent(name, data);
3631                } else {
3632                    setTimeout(function (name, params) {
3633                        fireEvent(name, params);
3634                    }, data.delay * 1000, name, data);
3635                }
3636                return true;
3637            },
3638
3639            fireEventAPI: function (name, event, params) {
3640
3641                var ids = event.pixelIds.filter(function (pixelId) {
3642                    return !Utils.hideMatchingPixel(pixelId, 'tiktok');
3643                })
3644                var notCachedEventsIds = new Array();
3645                var isAddToCartFromJs =  options.woo.hasOwnProperty("addToCartCatchMethod")
3646                    && options.woo.addToCartCatchMethod === "add_cart_js";
3647                if(!isAddToCartFromJs) {
3648                    notCachedEventsIds.push('woo_add_to_cart_on_button_click')
3649                }
3650
3651                if(options.tiktok.serverApiEnabled) {
3652                    if(!notCachedEventsIds.includes(event.e_id)) {
3653
3654                        var isApiDisabled = options.gdpr.all_disabled_by_api ||
3655                            options.gdpr.tiktok_disabled_by_api ||
3656                            options.gdpr.cookiebot_integration_enabled ||
3657                            options.gdpr.cookie_notice_integration_enabled ||
3658                            options.gdpr.consent_magic_integration_enabled ||
3659                            options.gdpr.cookie_law_info_integration_enabled;
3660                        // Update eventID
3661
3662                        // send event from server if they were block by gdpr or need send with delay
3663                        if( options.ajaxForServerEvent || isApiDisabled || event.delay > 0 || event.type !== "static" ){
3664
3665                            var json = {
3666                                action: 'pys_tiktok_api_event',
3667                                pixel: TikTok.tag(),
3668                                event: name,
3669                                event_slug: event.e_id,
3670                                ids: ids,
3671                                data:params,
3672                                url:window.location.href,
3673                                event_id:params.eventID,
3674                                ajax_event:options.ajax_event
3675                            };
3676
3677                            let delay = 0;
3678                            try {
3679                                if (sessionStorage) {
3680                                    Object.keys(sessionStorage)
3681                                        .filter(key => key.startsWith('wc_fragments_'))
3682                                        .forEach((key) => {
3683                                            let value = sessionStorage.getItem(key);
3684                                            if (event.e_id === 'woo_add_to_cart_on_button_click') {
3685                                                delay = 2000;
3686                                            }
3687                                        });
3688                                }
3689                            } catch (error) {
3690                                console.error('sessionStorage is not accessible:', error);
3691                            }
3692
3693
3694                            if(event.hasOwnProperty('woo_order')) {
3695                                json['woo_order'] = event.woo_order;
3696                            }
3697
3698                            if(event.hasOwnProperty('edd_order')) {
3699                                json['edd_order'] = event.edd_order;
3700                            }
3701                            if (event.e_id === "automatic_event_internal_link" || event.e_id === "automatic_event_outbound_link" || name == 'PageView') {
3702                                delay = delay === 0 ? 500 : delay;
3703                                setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3704                            } else if (event.type != 'static') {
3705                                setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3706                            }
3707
3708                            if ( ( event.type == 'static' && options.ajaxForServerStaticEvent ) || ( event.hasOwnProperty( 'ajaxFire' ) && event.ajaxFire ) ) {
3709                                setTimeout( () => Utils.sendServerAjaxRequest( options.ajaxUrl, json ), delay );
3710                            }
3711                        }
3712                    }
3713                }
3714            },
3715
3716            onClickEvent: function (event) {
3717                this.fireEvent(event.name, event);
3718            },
3719
3720            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
3721
3722                window.pysWooProductData = window.pysWooProductData || [];
3723                if (!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3724                    return;
3725
3726                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3727                    if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) {
3728
3729                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
3730
3731                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()]['params'], event.params);
3732
3733                        // maybe customize value option
3734                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
3735
3736                            if (product_type === Utils.PRODUCT_BUNDLE) {
3737                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
3738                                var items_sum = getBundlePriceOnSingleProduct(data);
3739                                event.params.value = (parseFloat(data.base_price) + items_sum) * qty;
3740                            } else {
3741                                event.params.value = event.params.value * qty;
3742                            }
3743                        }
3744
3745                        event.params.quantity = qty;
3746
3747                        this.fireEvent(event.name, event);
3748
3749                    }
3750                }
3751            },
3752
3753            onWooAddToCartOnButtonEvent: function (product_id) {
3754                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3755                    return;
3756
3757                if (window.pysWooProductData.hasOwnProperty(product_id)) {
3758                    if (window.pysWooProductData[product_id].hasOwnProperty(this.tag())) {
3759                        var productData = window.pysWooProductData[product_id][this.tag()]
3760                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
3761
3762                        Utils.copyProperties(productData['params'], event.params)
3763                        event.pixelIds = productData['pixelIds'];
3764                        this.fireEvent(event.name, event);
3765                    }
3766                }
3767            },
3768
3769            onEddAddToCartOnButtonEvent : function (download_id, price_index, qty) {
3770                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
3771                    return;
3772                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
3773
3774
3775                if (window.pysEddProductData.hasOwnProperty(download_id)) {
3776
3777                    var index;
3778
3779                    if (price_index) {
3780                        index = download_id + '_' + price_index;
3781                    } else {
3782                        index = download_id;
3783                    }
3784
3785                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
3786                        if (window.pysEddProductData[download_id][index].hasOwnProperty(this.tag())) {
3787
3788                            Utils.copyProperties(window.pysEddProductData[download_id][index][this.tag()].params, event.params);
3789                            this.fireEvent(event.name,event);
3790
3791                        }
3792                    }
3793
3794                }
3795            },
3796
3797            onPageScroll: function (event) {
3798                if (initialized && this.isEnabled()) {
3799                    this.fireEvent(event.name, event);
3800                }
3801            },
3802
3803            onWatchVideo: function (event) {
3804                if (initialized && this.isEnabled() && !event.fired) {
3805                    this.fireEvent(event.name, event);
3806                }
3807            },
3808
3809            onCommentEvent: function (event) {
3810                if (initialized && this.isEnabled()) {
3811                    this.fireEvent(event.name, event);
3812                }
3813            },
3814
3815            onAdSenseEvent: function (event) {
3816                if (initialized && this.isEnabled()) {
3817                    this.fireEvent(event.name, event);
3818                }
3819            },
3820
3821            onTime: function (event) {
3822                if (initialized && this.isEnabled()) {
3823                    this.fireEvent(event.name, event);
3824                }
3825            },
3826        }
3827    }(options);
3828
3829    var Facebook = function (options) {
3830
3831        var defaultEventTypes = [
3832            'PageView',
3833            'ViewContent',
3834            'Search',
3835            'AddToCart',
3836            'AddToWishlist',
3837            'InitiateCheckout',
3838            'AddPaymentInfo',
3839            'Purchase',
3840            'Lead',
3841
3842            'Subscribe',
3843            'CustomizeProduct',
3844            'FindLocation',
3845            'StartTrial',
3846            'SubmitApplication',
3847            'Schedule',
3848            'Contact',
3849            'Donate'
3850        ];
3851
3852        var notCachedEventsIds = new Array();
3853        var isAddToCartFromJs =  options.woo.hasOwnProperty("addToCartCatchMethod")
3854            && options.woo.addToCartCatchMethod === "add_cart_js";
3855        if(!isAddToCartFromJs) {
3856            notCachedEventsIds.push('woo_add_to_cart_on_button_click')
3857        }
3858
3859        var initialized = false;
3860
3861        var genereateFbp = function (){
3862            return !Cookies.get('_fbp') ? 'fb.1.'+Date.now()+'.'+Math.floor(1000000000 + Math.random() * 9000000000) : Cookies.get('_fbp');
3863        };
3864        var genereateFbc = function (){
3865            return getUrlParameter('fbclid') ? 'fb.1.'+Date.now()+'.'+getUrlParameter('fbclid') : ''
3866        };
3867
3868        var configuredPixels = new Array();
3869        function fireEvent(name, event) {
3870
3871
3872            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'facebook')) {
3873                return;
3874            }
3875
3876            var data = event.params;
3877            var ids = event.pixelIds.filter(function (pixelId) {
3878                return !Utils.hideMatchingPixel(pixelId, 'facebook');
3879            });
3880
3881            var actionType = defaultEventTypes.includes(name) ? 'trackSingle' : 'trackSingleCustom';
3882
3883            var params = {};
3884
3885            Utils.copyProperties(data, params);
3886            Utils.copyProperties(Utils.getRequestParams(), params);
3887            Utils.copyProperties(Utils.getRequestParams(), data);
3888
3889            params = Facebook.filterParams(params);
3890
3891
3892            if(options.facebook.serverApiEnabled) {
3893                if(event.e_id === "woo_remove_from_cart" ) {
3894                    Facebook.updateEventId(event.name);
3895                    event.eventID = Facebook.getEventId(event.name);
3896                } else if(!notCachedEventsIds.includes(event.e_id)) {
3897                    var isApiDisabled = options.gdpr.all_disabled_by_api ||
3898                        options.gdpr.facebook_disabled_by_api ||
3899                        options.gdpr.cookiebot_integration_enabled ||
3900                        options.gdpr.cookie_notice_integration_enabled ||
3901                        options.gdpr.consent_magic_integration_enabled ||
3902                        options.gdpr.cookie_law_info_integration_enabled;
3903                    // Update eventID
3904
3905                    event.eventID = Utils.generateUniqueId(event);
3906
3907                    if(Cookies.get('_fbp')){
3908                        params._fbp = Cookies.get('_fbp');
3909                    }
3910                    if(Cookies.get('_fbc')){
3911                        params._fbc = Cookies.get('_fbc');
3912                    }
3913                    // send event from server if they was bloc by gdpr or need send with delay
3914                    if( options.ajaxForServerEvent || isApiDisabled ){
3915                        var json = {
3916                            action: 'pys_api_event',
3917                            pixel: 'facebook',
3918                            event: name,
3919                            event_slug: event.e_id,
3920                            ids: ids,
3921                            data:params,
3922                            url:window.location.href,
3923                            eventID:event.eventID,
3924                            ajax_event:options.ajax_event
3925                        };
3926
3927                        if(event.hasOwnProperty('woo_order')) {
3928                            json['woo_order'] = event.woo_order;
3929                        }
3930
3931                        if(event.hasOwnProperty('edd_order')) {
3932                            json['edd_order'] = event.edd_order;
3933                        }
3934
3935                        let delay = 0;
3936                        try {
3937                            if (sessionStorage) {
3938                                Object.keys(sessionStorage)
3939                                    .filter(key => key.startsWith('wc_fragments_'))
3940                                    .forEach((key) => {
3941                                        let value = sessionStorage.getItem(key);
3942                                        if (event.e_id === 'woo_add_to_cart_on_button_click') {
3943                                            delay = 2000;
3944                                        }
3945                                    });
3946                            }
3947                        } catch (error) {
3948                            console.error('sessionStorage is not accessible:', error);
3949                        }
3950
3951                        if (event.e_id === "automatic_event_internal_link" || event.e_id === "automatic_event_outbound_link") {
3952                            delay = delay === 0 ? 500 : delay;
3953                            setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3954                        } else if (event.type != 'static') {
3955                            setTimeout(() => Utils.sendServerAjaxRequest(options.ajaxUrl, json), delay);
3956                        }
3957
3958                        if ( ( event.type == 'static' && options.ajaxForServerStaticEvent ) || ( event.hasOwnProperty( 'ajaxFire' ) && event.ajaxFire ) ) {
3959                            setTimeout( () => Utils.sendServerAjaxRequest( options.ajaxUrl, json ), delay );
3960                        }
3961                    }
3962
3963                    if( event.e_id !== "automatic_event_signup" && name == "CompleteRegistration" && options.facebook.wooCRSendFromServer ) {
3964                        return;
3965                    }
3966                }
3967
3968            }
3969            delete params._fbp;
3970            delete params._fbc;
3971            if (options.debug) {
3972                console.log('[Facebook] ' + name, params,"pixel_ids",ids,"eventID",event.eventID);
3973            }
3974            // fire event for each pixel id
3975            ids.forEach(function (pixelId) {
3976                // add eventID for deduplicate events @see https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events/
3977                var args = {};
3978                if(options.facebook.serverApiEnabled && event.hasOwnProperty('eventID')) {
3979                    args.eventID = event.eventID;
3980                }
3981                Facebook.maybeInitPixel(pixelId);
3982                fbq(actionType,pixelId, name, params,args);
3983            });
3984            var customEvent = new CustomEvent('facebook_event_sent', {
3985                detail: {
3986                    eventName: name,
3987                    params: params,
3988                    pixel_ids: ids
3989                }
3990            });
3991            window.dispatchEvent(customEvent);
3992        }
3993
3994        /**
3995         * Public API
3996         */
3997        return {
3998            tag: function() {
3999                return "facebook";
4000            },
4001            isEnabled: function () {
4002                return options.hasOwnProperty('facebook');
4003            },
4004            getHidePixel: function(){
4005                if(this.isEnabled() && options.facebook.hasOwnProperty('hide_pixels'))
4006                {
4007                    return options.facebook.hide_pixels;
4008                }
4009                return [];
4010            },
4011            initEventIdCookies: function (key) {
4012                var ids = {};
4013                ids[key] = pys_generate_token(36)
4014                Cookies.set('pys_fb_event_id', JSON.stringify(ids), {path: '/',domain: domain});
4015            },
4016
4017            updateEventId:function(key) {
4018                var cooData = Cookies.get("pys_fb_event_id")
4019                if(cooData === undefined) {
4020                    this.initEventIdCookies(key);
4021                } else {
4022                    var data = JSON.parse(cooData);
4023                    data[key] = pys_generate_token(36);
4024                    Cookies.set('pys_fb_event_id', JSON.stringify(data), {path: '/',domain: domain} );
4025                }
4026            },
4027
4028            getEventId:function (key) {
4029                var data = Cookies.get("pys_fb_event_id");
4030                if(data === undefined) {
4031                    this.initEventIdCookies(key);
4032                    data = Cookies.get("pys_fb_event_id");
4033                }
4034                return JSON.parse(data)[key];
4035            },
4036
4037            disable: function () {
4038                initialized = false;
4039            },
4040
4041            filterParams: function (params) {
4042                var filteredParams = {};
4043
4044                if (options.facebook.hasOwnProperty('enabled_medical') && options.facebook.enabled_medical && options.facebook.hasOwnProperty('do_not_track_medical_param')) {
4045                    // Remove empty strings from the array
4046                    options.facebook.do_not_track_medical_param = options.facebook.do_not_track_medical_param.filter(Boolean);
4047                    for (const key in params) {
4048                        if (Array.isArray(options.facebook.do_not_track_medical_param)) {
4049                            if (!options.facebook.do_not_track_medical_param.includes(key)) {
4050                                filteredParams[key] = params[key];
4051                            }
4052                        }
4053                    }
4054                }
4055                else {
4056                    Utils.copyProperties(params, filteredParams);
4057                }
4058                return filteredParams;
4059            },
4060
4061            /**
4062             * Load pixel's JS
4063             */
4064            loadPixel: function () {
4065                if (initialized || !this.isEnabled() || !Utils.consentGiven('facebook')) {
4066                    return;
4067                }
4068
4069                ! function (f, b, e, v, n, t, s) {
4070                    if (f.fbq) return;
4071                    n = f.fbq = function () {
4072                        n.callMethod ?
4073                            n.callMethod.apply(n, arguments) : n.queue.push(arguments)
4074                    };
4075                    if (!f._fbq) f._fbq = n;
4076                    n.push = n;
4077                    n.loaded = !0;
4078                    n.version = '2.0';
4079                    n.agent = 'dvpixelyoursite';
4080                    n.queue = [];
4081                    t = b.createElement(e);
4082                    t.async = !0;
4083                    t.src = v;
4084                    s = b.getElementsByTagName(e)[0];
4085                    s.parentNode.insertBefore(t, s)
4086                }(window,
4087                    document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
4088                let expires = parseInt(options.cookie_duration);
4089                if(!Cookies.get('_fbp')) {
4090                    Cookies.set('_fbp',genereateFbp(),  { expires: expires,path: '/',domain: domain });
4091                }
4092
4093                if(getUrlParameter('fbclid')) {
4094                    Cookies.set('_fbc',genereateFbc(),  { expires: expires,path: '/',domain: domain });
4095                }
4096                var ids = options.facebook.pixelIds.filter(function (pixelId) {
4097                    return !Utils.hideMatchingPixel(pixelId, 'facebook');
4098                });
4099                // initialize default pixel
4100                ids.forEach(function (pixelId) {
4101                    Facebook.maybeInitPixel(pixelId);
4102                });
4103                initialized = true;
4104
4105                Utils.fireStaticEvents('facebook');
4106
4107            },
4108            advancedMatching: function () {
4109                if(options.facebook.advancedMatchingEnabled) {
4110                    let advancedMatchingForm = Utils.getAdvancedFormData();
4111                    let advancedMatching = {};
4112                    if(Object.keys(options.facebook.advancedMatching).length > 0) {
4113                        advancedMatching = options.facebook.advancedMatching;
4114                    }
4115
4116                    if(!advancedMatching.hasOwnProperty("em")
4117                        && advancedMatchingForm.hasOwnProperty("email") && advancedMatchingForm["email"].length > 0) {
4118                        advancedMatching["em"] = advancedMatchingForm["email"];
4119                    }
4120                    if(!advancedMatching.hasOwnProperty("ph")
4121                        && advancedMatchingForm.hasOwnProperty("phone") && advancedMatchingForm["phone"].length > 0) {
4122                        advancedMatching["ph"] = advancedMatchingForm["phone"];
4123                    }
4124                    if(!advancedMatching.hasOwnProperty("fn")
4125                        && advancedMatchingForm.hasOwnProperty("first_name") && advancedMatchingForm["first_name"].length > 0) {
4126                        advancedMatching["fn"] = advancedMatchingForm["first_name"];
4127                    }
4128                    if(!advancedMatching.hasOwnProperty("ln")
4129                        && advancedMatchingForm.hasOwnProperty("last_name") && advancedMatchingForm["last_name"].length > 0) {
4130                        advancedMatching["ln"] = advancedMatchingForm["last_name"];
4131                    }
4132                    if(!advancedMatching.hasOwnProperty("external_id")){
4133                        if (Cookies.get('pbid')) {
4134                            advancedMatching["external_id"] = Cookies.get('pbid');
4135                        }
4136                    }
4137                    else if(advancedMatching.hasOwnProperty("external_id") && advancedMatching.external_id != Cookies.get('pbid'))
4138                    {
4139                        advancedMatching["external_id"] = Cookies.get('pbid') ? Cookies.get('pbid') : advancedMatching.external_id;
4140                    }
4141
4142                    if(Object.keys(advancedMatching).length > 0) {
4143                        return advancedMatching;
4144                    }
4145                }
4146                return false
4147            },
4148            maybeInitPixel: function(pixelId) {
4149
4150                if(configuredPixels.includes(pixelId)) return;
4151
4152                if (options.facebook.removeMetadata || Utils.hideMatchingPixel(pixelId, this.tag())) {
4153                    fbq('set', 'autoConfig', false, pixelId);
4154                }
4155                let advancedMatching = Facebook.advancedMatching();
4156
4157                if ( +options.facebook.meta_ldu === 1  ) {
4158                    fbq( 'dataProcessingOptions', [ 'LDU' ], 0, 0 );
4159                }
4160
4161                if (options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined") {
4162                    if(!advancedMatching) {
4163                        fbq('init', pixelId);
4164                    } else {
4165                        var test_prefix = CS_Data.test_prefix;
4166                        var cs_advanced_matching = Cookies.get('cs_enabled_advanced_matching'+test_prefix);
4167                        if (jQuery('#cs_enabled_advanced_matching'+test_prefix).length > 0) {
4168                            if (cs_advanced_matching == 'yes') {
4169                                fbq('init', pixelId, advancedMatching);
4170                            } else {
4171                                fbq('init', pixelId);
4172                            }
4173                        } else {
4174                            fbq('init', pixelId, advancedMatching);
4175                        }
4176                    }
4177                } else {
4178                    if(!advancedMatching) {
4179                        fbq('init', pixelId);
4180                    }  else {
4181                        fbq('init', pixelId, advancedMatching);
4182                    }
4183                }
4184                configuredPixels.push(pixelId);
4185            },
4186
4187            fireEvent: function (name, data) {
4188
4189                if (!initialized || !this.isEnabled()) {
4190                    return false;
4191                }
4192
4193                data.delay = data.delay || 0;
4194                data.params = data.params || {};
4195
4196                if (data.delay === 0) {
4197
4198                    fireEvent(name, data);
4199
4200                } else {
4201
4202                    setTimeout(function (name, params) {
4203                        fireEvent(name, params);
4204                    }, data.delay * 1000, name, data);
4205
4206                }
4207
4208                return true;
4209
4210            },
4211
4212            onAdSenseEvent: function (event) {
4213                this.fireEvent(event.name, event);
4214            },
4215
4216            onClickEvent: function (event) {
4217                this.fireEvent(event.name, event);
4218            },
4219
4220            onWatchVideo: function (event) {
4221                this.fireEvent(event.name, event);
4222            },
4223
4224            onCommentEvent: function (event) {
4225                this.fireEvent(event.name, event);
4226            },
4227
4228            onFormEvent: function (event) {
4229                this.fireEvent(event.name, event);
4230            },
4231
4232            onDownloadEvent: function (event) {
4233                this.fireEvent(event.name, event);
4234
4235            },
4236
4237
4238            onWooAddToCartOnButtonEvent: function (product_id) {
4239
4240                window.pysWooProductData = window.pysWooProductData || [];
4241                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4242                    return;
4243
4244                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4245                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
4246
4247                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
4248
4249                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params)
4250                        event.pixelIds = window.pysWooProductData[product_id]['facebook']['pixelIds'];
4251                        this.fireEvent(event.name, event);
4252                    }
4253                }
4254            },
4255
4256            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
4257
4258                window.pysWooProductData = window.pysWooProductData || [];
4259                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4260                    return;
4261
4262                if (product_type === Utils.PRODUCT_VARIABLE && !options.facebook.wooVariableAsSimple) {
4263                    product_id = parseInt($form.find('input[name="variation_id"]').val());
4264                }
4265
4266                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4267                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
4268
4269                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click.facebook);
4270
4271
4272                        Utils.copyProperties(window.pysWooProductData[product_id]['facebook']['params'], event.params);
4273
4274                        var groupValue = 0;
4275                        if(product_type === Utils.PRODUCT_GROUPED ) {
4276                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
4277                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
4278                                var quantity = parseInt($(this).val());
4279                                if(isNaN(quantity)) {
4280                                    quantity = 0;
4281                                }
4282                                var childItem = window.pysWooProductData[product_id]['facebook'].grouped[childId];
4283
4284                                if(quantity == 0) {
4285                                    event.params.content_ids.forEach(function(el,index,array) {
4286                                        if(el == childItem.content_id) {
4287                                            array.splice(index, 1);
4288                                        }
4289                                    });
4290                                }
4291
4292                                if(event.params.hasOwnProperty('contents')) {
4293                                    event.params.contents.forEac
4293h(function(el,index,array) {
4294                                        if(el.id == childItem.content_id) {
4295                                            if(quantity > 0){
4296                                                el.quantity = quantity;
4297                                            } else {
4298                                                array.splice(index, 1);
4299                                            }
4300                                        }
4301                                    });
4302                                }
4303
4304
4305                                groupValue += childItem.price * quantity;
4306                            });
4307                            if(groupValue == 0) return; // skip if no items selected
4308                        }
4309
4310
4311
4312                        // maybe customize value option
4313                        if (options.woo.addToCartOnButtonValueEnabled && options.woo.addToCartOnButtonValueOption !== 'global') {
4314
4315                            if(product_type === Utils.PRODUCT_GROUPED) {
4316                                event.params.value = groupValue;
4317                            } else if(product_type === Utils.PRODUCT_BUNDLE) {
4318                                var data = $(".bundle_form .bundle_data").data("bundle_form_data");
4319                                var items_sum = getBundlePriceOnSingleProduct(data);
4320                                event.params.value = (parseFloat(data.base_price) + items_sum )* qty;
4321                            } else {
4322                                event.params.value = event.params.value * qty;
4323                            }
4324                        }
4325
4326                        // only when non Facebook for WooCommerce logic used
4327                        if (event.params.hasOwnProperty('contents') && product_type !== Utils.PRODUCT_GROUPED) {
4328                            event.params.contents[0].quantity = qty;
4329
4330                        }
4331
4332                        var event_name = is_external ? options.woo.affiliateEventName : event.name;
4333
4334                        this.fireEvent(event_name, event);
4335
4336                    }
4337                }
4338
4339            },
4340
4341            onWooRemoveFromCartEvent: function (event) {
4342                this.fireEvent(event.name, event);
4343            },
4344
4345            onWooAffiliateEvent: function (product_id) {
4346                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
4347                    return;
4348                var event = Utils.clone(options.dynamicEvents.woo_affiliate[this.tag()]);
4349
4350
4351                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4352                    if (window.pysWooProductData[product_id].hasOwnProperty('facebook')) {
4353
4354                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()].params, event.params)
4355                        this.fireEvent(options.woo.affiliateEventName, event);
4356
4357                    }
4358                }
4359
4360            },
4361
4362            onWooPayPalEvent: function (event) {
4363                this.fireEvent(event.name, event);
4364            },
4365
4366            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
4367                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4368                    return;
4369                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
4370
4371                if (window.pysEddProductData.hasOwnProperty(download_id)) {
4372
4373                    var index;
4374
4375                    if (price_index) {
4376                        index = download_id + '_' + price_index;
4377                    } else {
4378                        index = download_id;
4379                    }
4380
4381                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
4382                        if (window.pysEddProductData[download_id][index].hasOwnProperty('facebook')) {
4383
4384                            Utils.copyProperties(window.pysEddProductData[download_id][index]['facebook']["params"], event.params)
4385
4386                            // maybe customize value option
4387                            if (options.edd.addToCartOnButtonValueEnabled && options.edd.addToCartOnButtonValueOption !== 'global') {
4388                                event.params.value = event.params.value * qty;
4389                            }
4390
4391                            // update contents qty param
4392                            var contents = event.params.contents;
4393                            contents[0].quantity = qty;
4394                            event.params.contents = contents;
4395
4396                            this.fireEvent(event.name,event);
4397
4398                        }
4399                    }
4400
4401                }
4402
4403            },
4404
4405            onEddRemoveFromCartEvent: function (event) {
4406                this.fireEvent(event.name, event);
4407            },
4408            onPageScroll: function (event) {
4409                this.fireEvent(event.name, event);
4410            },
4411            onTime: function (event) {
4412                this.fireEvent(event.name, event);
4413            },
4414        };
4415
4416    }(options);
4417
4418    var Analytics = function (options) {
4419
4420        var initialized = false;
4421        var isAllowEnhancedConversions = false;
4422
4423        /**
4424         * Fires event
4425         *
4426         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
4427         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
4428         * @link: https://developers.google.com/gtagjs/reference/event
4429         * @link: https://developers.google.com/gtagjs/reference/parameter
4430         *
4431         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dim
4431s-mets
4432         *
4433         * @param name
4434         * @param data
4435         */
4436        function fireEvent(name, event) {
4437            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'ga')) {
4438                return;
4439            }
4440
4441            var eventParams = event.params;
4442            var valuesArray = Object.values(event.trackingIds);
4443            var ids = valuesArray.filter(function (pixelId) {
4444                return loadTags.some(loadTag => pixelId.startsWith(loadTag)) && !Utils.hideMatchingPixel(pixelId, 'ga') && !Utils.hideMatchingPixel(pixelId, 'google_ads');
4445            })
4446
4447            // Generate unique event_id for deduplication
4448            eventParams.event_id = Utils.generateUniqueId(event);
4449            event.eventID = Utils.generateUniqueId(event);
4450
4451            Utils.copyProperties(Utils.getRequestParams(), eventParams);
4452
4453            var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsTov4 can modify 
4453it
4454            var params = mapParamsTov4(ids,name,copyParams)
4455
4456            var _fireEvent = function (tracking_ids,name,params) {
4457
4458                params['send_to'] = tracking_ids;
4459
4460                if (options.debug) {
4461                    console.log('[Google Analytics #' + tracking_ids + '] ' + name, params);
4462                }
4463
4464                // Send via gtag
4465                gtag('event', name, params);
4466
4467                var customEvent = new CustomEvent('gtag_event_sent', {
4468                    detail: {
4469                        eventName: name,
4470                        params: params,
4471                        pixel_ids: tracking_ids
4472                    }
4473                });
4474                window.dispatchEvent(customEvent);
4475            };
4476
4477
4478            delete params.analytics_storage;
4479            delete params.ad_storage;
4480            delete params.ad_user_data;
4481            delete params.ad_personalization;
4482
4483            if(options.hasOwnProperty('google_ads')){
4484                var conversion_event_name = event.e_id;
4485                switch ( conversion_event_name ) {
4486                    case "woo_add_to_cart_on_cart_page":
4487                    case "woo_add_to_cart_on_checkout_page":
4488                    case "woo_add_to_cart_on_button_click":
4489                        conversion_event_name = 'woo_add_to_cart';
4490                        break;
4491                    case "edd_add_to_cart_on_cart_page":
4492                    case "edd_add_to_cart_on_checkout_page":
4493                    case "edd_add_to_cart_on_button_click":
4494                        conversion_event_name = 'edd_add_to_cart';
4495                        break;
4496                    case "automatic_event_adsense":
4497                    case "automatic_event_comment":
4498                    case "automatic_event_download":
4499                    case "automatic_event_email_link":
4500                    case "automatic_event_form":
4501                    case "automatic_event_internal_link":
4502                    case "automatic_event_outbound_link":
4503                    case "automatic_event_scroll":
4504                    case "automatic_event_tel_link":
4505                    case "automatic_event_time_on_page":
4506                    case "automatic_event_video":
4507                        conversion_event_name = 'automatic_event';
4508                        break;
4509                }
4510
4511                if ( conversion_event_name !== 'automatic_event' &&
4512                    typeof options.google_ads[conversion_event_name + '_conversion_track'] !== 'undefined' ) {
4513                    const conversionTrack = options.google_ads[ conversion_event_name + '_conversion_track' ];
4514
4515                    if ( conversionTrack === 'conversion' ) {
4516                        ids = ids.map(id => id.split('/')[0])
4517                    }
4518                }
4519            }
4520
4521
4522            _fireEvent(ids, name, params);
4523            if(event.hasOwnProperty('unify') && event.unify){
4524                isTrackEventForGA.push(name);
4525            }
4526        }
4527
4528        function normalizeEventName(eventName) {
4529
4530            var matches = {
4531                ViewContent: 'view_item',
4532                AddToCart: 'add_to_cart',
4533                AddToWishList: 'add_to_wishlist',
4534                InitiateCheckout: 'begin_checkout',
4535                Purchase: 'purchase',
4536                Lead: 'generate_lead',
4537                CompleteRegistration: 'sign_up',
4538                AddPaymentInfo: 'set_checkout_option'
4539            };
4540
4541            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
4542
4543        }
4544
4545        function mapParamsTov4(tag,name,param) {
4546            //GA4 automatically collects a number of parameters for all events
4547            var hasGA4Tag = false;
4548
4549            // end
4550            if (Array.isArray(tag)) {
4551                hasGA4Tag = tag.some(function (element) {
4552                    return isv4(element);
4553                });
4554            } else if(isv4(tag)) {
4555                // tag является строкой и соответствует GA4
4556                hasGA4Tag = true;
4557            }
4558            if(hasGA4Tag) {
4559                delete param.event_category;
4560                delete param.event_label;
4561                delete param.ecomm_prodid;
4562                delete param.ecomm_pagetype;
4563                delete param.ecomm_totalvalue;
4564                if(name === 'search') {
4565                    param['search'] = param.search_term;
4566                    delete param.search_term;
4567                    delete param.dynx_itemid;
4568                    delete param.dynx_pagetype;
4569                    delete param.dynx_totalvalue;
4570                }
4571            }
4572            return param;
4573        }
4574
4575        function isv4(tag) {
4576            return tag.indexOf('G') === 0;
4577        }
4578
4579        /**
4580         * Public API
4581         */
4582        return {
4583            tag: function() {
4584                return "ga";
4585            },
4586            isEnabled: function () {
4587                return options.hasOwnProperty('ga');
4588            },
4589            getHidePixel: function(){
4590                if(this.isEnabled() && options.ga.hasOwnProperty('hide_pixels'))
4591                {
4592                    return options.ga.hide_pixels;
4593                }
4594                return [];
4595            },
4596            disable: function () {
4597                initialized = false;
4598            },
4599            updateEnhancedConversionData : function () {
4600                if (!initialized || !this.isEnabled()) {
4601                    return;
4602                }
4603                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) {
4604                    var advanced = Utils.getAdvancedMergeFormData();
4605                    if (Object.keys(advanced).length > 0) {
4606                        gtag('set', 'user_data', advanced);
4607                    }
4608                }
4609            },
4610            loadPixel: function () {
4611                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
4612                    return;
4613                }
4614
4615
4616                for (var i = 0; i < options.ga.trackingIds.length; i++) {
4617                    var trackingId = options.ga.trackingIds[i];
4618                    if (!Utils.hideMatchingPixel(trackingId, 'ga')) {
4619                        Utils.loadGoogleTag(trackingId);
4620                        break;
4621                    }
4622                }
4623
4624
4625                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
4626                    var advanced = Utils.getAdvancedMergeFormData();
4627                    if(Object.keys(advanced).length > 0){
4628                        gtag('set', 'user_data', advanced);
4629                    }
4630                }
4631
4632                var config = {};
4633
4634                if(options.user_id && options.user_id != 0) {
4635                    config.user_id = options.user_id;
4636                }
4637                config.url_passthrough = options.ga.url_passthrough;
4638                // Cross-Domain tracking
4639                if (options.ga.crossDomainEnabled) {
4640                    config.linker = {
4641                        accept_incoming: options.ga.crossDomainAcceptIncoming,
4642                        domains: options.ga.crossDomainDomains
4643                    };
4644                }
4645
4646                var ids = options.ga.trackingIds.filter(function (pixelId) {
4647                    return !Utils.hideMatchingPixel(pixelId, 'ga');
4648                });
4649                loadTags.push(...ids);
4650                ids.forEach(function (trackingId,index) {
4651
4652                    var obj = options.ga.isDebugEnabled;
4653                    var searchValue = "index_"+index;
4654                    var config_for_tag = Object.assign({}, config);
4655                    config_for_tag.debug_mode = false;
4656                    config_for_tag.send_page_view = !options.ga.custom_page_view_event;
4657                    for (var key in obj) {
4658                        if (obj[key] === searchValue) {
4659                            config_for_tag.debug_mode = true;
4660                            break;
4661                        }
4662                    }
4663                    if(!config_for_tag.debug_mode)
4664                    {
4665                        delete config_for_tag.debug_mode;
4666                    }
4667
4668                    if(isv4(trackingId)) {
4669                        if(options.ga.disableAdvertisingPersonalization) {
4670                            config_for_tag.allow_ad_personalization_signals = false
4671                        }
4672                    }
4673                    if(options.ga.hasOwnProperty('additionalConfig')){
4674                        if(options.ga.additionalConfig.hasOwnProperty(trackingId) && options.ga.additionalConfig[trackingId]){
4675                            config_for_tag.first_party_collection = options.ga.additionalConfig[trackingId].first_party_collection;
4676                        }
4677
4678                    }
4679                    if(options.ga.hasOwnProperty('serverContainerUrls')){
4680                        if(options.ga.serverContainerUrls.hasOwnProperty(trackingId) && options.ga.serverContainerUrls[trackingId].enable_server_container != false){
4681                            if(options.ga.serverContainerUrls[trackingId].server_container_url != ''){
4682                                config_for_tag.server_container_url = options.ga.serverContainerUrls[trackingId].server_container_url;
4683                            }
4684                            if(options.ga.serverContainerUrls[trackingId].transport_url != ''){
4685                                config_for_tag.transport_url = options.ga.serverContainerUrls[trackingId].transport_url;
4686                            }
4687                        }
4688                    }
4689                    if (options.gdpr.cookiebot_integration_enabled && typeof Cookiebot !== 'undefined') {
4690                        var cookiebot_consent_category = options.gdpr['cookiebot_analytics_consent_category'];
4691                        if (options.gdpr['analytics_prior_consent_enabled']) {
4692                            if (Cookiebot.consented === true && Cookiebot.consent[cookiebot_consent_category]) {
4693                                gtag('config', trackingId, config_for_tag);
4694                            }
4695                        } else {
4696                            if (Cookiebot.consent[cookiebot_consent_category]) {
4697                                gtag('config', trackingId, config_for_tag);
4698                            }
4699                        }
4700                    }
4701                    else
4702                    {
4703                        gtag('config', trackingId, config_for_tag);
4704                    }
4705                });
4706                if(!isAdsLoad && GAds.isEnabled() && options.google_ads.conversion_ids.length > 0 && Utils.consentGiven('google_ads')) {
4707                    for (var i = 0; i < options.google_ads.conversion_ids.length; i++) {
4708                        var trackingId = options.google_ads.conversion_ids[i];
4709                        if (!Utils.hideMatchingPixel(trackingId, 'google_ads')) {
4710                            Utils.loadGoogleTag(trackingId);
4711                            break;
4712                        }
4713                    }
4714                    var ids = options.google_ads.conversion_ids.filter(function (pixelId) {
4715                        return !Utils.hideMatchingPixel(pixelId, 'google_ads');
4716                    });
4717                    loadTags.push(...ids);
4718                    // configure conversion ids
4719                    ids.forEach(function (conversion_id,index) {
4720
4721                        gtag('config', conversion_id);
4722
4723                        if(options.google_ads.enhanced_conversion.includes("index_"+index)) {
4724                            isAllowEnhancedConversions = true
4725                            gtag('config', conversion_id,{ 'allow_enhanced_conversions':true });
4726                        }
4727
4728                    });
4729                    isAdsLoad = true;
4730                }
4731
4732                initialized = true;
4733
4734                Utils.fireStaticEvents('ga');
4735                $( document).trigger( "analytics_initialized")
4736            },
4737
4738            fireEvent: function (name, data) {
4739
4740                if (!initialized || !this.isEnabled()) {
4741                    return false;
4742                }
4743
4744                data.delay = data.delay || 0;
4745                data.params = data.params || {};
4746
4747                if (data.delay === 0) {
4748
4749                    fireEvent(name, data);
4750
4751                } else {
4752
4753                    setTimeout(function (name, params) {
4754                        fireEvent(name, params);
4755                    }, data.delay * 1000, name, data);
4756
4757                }
4758
4759                return true;
4760
4761            },
4762
4763            onAdSenseEvent: function (event) {
4764                this.fireEvent(event.name, event);
4765            },
4766
4767            onClickEvent: function (event) {
4768                this.fireEvent(event.name, event);
4769            },
4770
4771            onWatchVideo: function (event) {
4772                if(!event.hasOwnProperty("youtube_disabled")
4773                    || !event.youtube_disabled
4774                    || event.params.video_type !== "youtube") {
4775                    this.fireEvent(event.name, event);
4776                }
4777            },
4778
4779            onCommentEvent: function (event) {
4780
4781                this.fireEvent(event.name, event);
4782
4783            },
4784
4785            onFormEvent: function (event) {
4786
4787                this.fireEvent(event.name, event);
4788
4789            },
4790
4791            onDownloadEvent: function (event) {
4792
4793                this.fireEvent(event.name, event);
4794
4795            },
4796
4797            onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) {
4798                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4799                    return;
4800
4801                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4802                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
4803                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
4804                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params)
4805                        event.trackingIds = window.pysWooProductData[product_id]['ga']['trackingIds'];
4806                        if(prod_info)
4807                        {
4808                            if(prod_info['pys_list_name_productlist_id'])
4809                            {
4810                                event.params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id']
4811                            }
4812                            if(prod_info['pys_list_name_productlist_name'])
4813                            {
4814                                event.params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name']
4815                            }
4816                        }
4817                        this.fireEvent(event.name, event);
4818                    }
4819                }
4820
4821            },
4822
4823            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) {
4824
4825                window.pysWooProductData = window.pysWooProductData || [];
4826
4827                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4828                    return;
4829                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
4830
4831                if (product_type === Utils.PRODUCT_VARIABLE && !options.ga.wooVariableAsSimple) {
4832                    product_id = parseInt($form.find('input[name="variation_id"]').val());
4833                }
4834
4835                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4836                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
4837
4838                        Utils.copyProperties(window.pysWooProductData[product_id]['ga'].params, event.params);
4839
4840
4841                        if(product_type === Utils.PRODUCT_GROUPED ) {
4842                            var groupValue = 0;
4843                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
4844                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
4845                                var quantity = parseInt($(this).val());
4846                                if(isNaN(quantity)) {
4847                                    quantity = 0;
4848                                }
4849                                var childItem = window.pysWooProductData[product_id]['ga'].grouped[childId];
4850                                event.params.items.forEach(function(el,index,array) {
4851                                    if(el.id == childItem.content_id) {
4852                                        if(quantity > 0){
4853                                            el.quantity = quantity;
4854                                            el.price = childItem.price;
4855                                        } else {
4856                                            array.splice(index, 1);
4857                                        }
4858                                    }
4859                                });
4860                                groupValue += childItem.price * quantity;
4861                            });
4862
4863                            if(options.woo.addToCartOnButtonValueEnabled &&
4864                                options.woo.addToCartOnButtonValueOption !== 'global' &&
4865                                event.params.hasOwnProperty('value')) {
4866                                event.params.value = groupValue;
4867                            }
4868
4869                            if(groupValue == 0) return; // skip if no items selected
4870                        } else {
4871                            // update items qty param
4872                            event.params.items[0].quantity = qty;
4873                        }
4874
4875                        // maybe customize value option
4876                        if (options.woo.addToCartOnButtonValueEnabled &&
4877                            options.woo.addToCartOnButtonValueOption !== 'global' &&
4878                            product_type !== Utils.PRODUCT_GROUPED)
4879                        {
4880                            if(event.params.hasOwnProperty('value')) {
4881                                event.params.value = event.params.items[0].price * qty;
4882                            }
4883                        }
4884
4885                        if(prod_info)
4886                        {
4887                            if(prod_info['pys_list_name_productlist_id'])
4888                            {
4889                                event.params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id']
4890                            }
4891                            if(prod_info['pys_list_name_productlist_name'])
4892                            {
4893                                event.params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name']
4894                            }
4895                        }
4896
4897                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
4898                        eventName = normalizeEventName(eventName);
4899
4900                        this.fireEvent(eventName, event);
4901
4902                    }
4903                }
4904
4905            },
4906
4907            onWooCheckoutProgressStep: function (event) {
4908                this.fireEvent(event.name, event);
4909            },
4910
4911            onWooSelectContent: function (event) {
4912                const select_prod_list = {};
4913
4914                if (event.params.items[0].item_list_name !== undefined) {
4915                    select_prod_list.list_name = event.params.items[0].item_list_name;
4916                }
4917
4918                if (event.params.items[0].item_list_id !== undefined) {
4919                    select_prod_list.list_id = event.params.items[0].item_list_id;
4920                }
4921                const url = new URL(window.location.href);
4922                select_prod_list.url = url.origin + url.pathname;
4923                Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' });
4924                this.fireEvent(event.name, event);
4925            },
4926
4927            onWooRemoveFromCartEvent: function (event) {
4928                this.fireEvent(event.name, event);
4929            },
4930
4931            onWooAffiliateEvent: function (product_id) {
4932                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
4933                    return;
4934                var event = options.dynamicEvents.woo_affiliate[this.tag()];
4935
4936                if (window.pysWooProductData.hasOwnProperty(product_id)) {
4937                    if (window.pysWooProductData[product_id].hasOwnProperty('ga')) {
4938
4939                        event = Utils.clone(event );
4940                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
4941                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
4942
4943                    }
4944                }
4945
4946            },
4947
4948            onWooPayPalEvent: function (event) {
4949                this.fireEvent(event.name, event);
4950            },
4951
4952            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
4953                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
4954                    return;
4955                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
4956
4957
4958                if (window.pysEddProductData.hasOwnProperty(download_id)) {
4959
4960                    var index;
4961
4962                    if (price_index) {
4963                        index = download_id + '_' + price_index;
4964                    } else {
4965                        index = download_id;
4966                    }
4967
4968                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
4969                        if (window.pysEddProductData[download_id][index].hasOwnProperty('ga')) {
4970
4971                            Utils.copyProperties(window.pysEddProductData[download_id][index]['ga'].params, event.params);
4972
4973                            // update items qty param
4974                            event.params.items[0].quantity = qty;
4975
4976                            this.fireEvent(event.name,event);
4977
4978                        }
4979                    }
4980
4981                }
4982
4983            },
4984
4985            onEddRemoveFromCartEvent: function (event) {
4986                this.fireEvent(event.name, event);
4987            },
4988
4989            onPageScroll: function (event) {
4990                if (initialized && this.isEnabled()) {
4991                    this.fireEvent(event.name, event);
4992                }
4993            },
4994            onTime: function (event) {
4995                if (initialized && this.isEnabled()) {
4996                    this.fireEvent(event.name, event);
4997                }
4998            },
4999        };
5000
5001    }(options);
5002
5003    var GAds = function (options) {
5004
5005        var initialized = false;
5006        var isAllowEnhancedConversions = false
5007        /**
5008         * Fires event
5009         *
5010         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data
5011         * @link: https://developers.google.com/analytics/devguides/collection/gtagjs/events
5012         * @link: https://developers.google.com/gtagjs/reference/event
5013         * @link: https://developers.google.com/gtagjs/reference/parameter
5014         */
5015        function fireEvent(name, data) {
5016            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(event_name,'google_ads')) {
5017                return;
5018            }
5019            var _params = Utils.copyProperties(data.params,{});
5020
5021            _params.event_id = Utils.generateUniqueId(data);
5022
5023            var ids = data.ids.filter(function (pixelId) {
5024                return !Utils.hideMatchingPixel(pixelId, 'google_ads');
5025            });
5026
5027            var conversionIds = data.hasOwnProperty('conversion_ids') ? data.conversion_ids.filter(function (conversion_id) {
5028                return !Utils.hideMatchingPixel(conversion_id, 'google_ads');
5029            }) : [];
5030            var conversion_labels = data.hasOwnProperty('conversion_labels') ? data.conversion_labels.filter(function (conversion_label) {
5031                conversion_id = conversion_label.split('/')[0];
5032                return !Utils.hideMatchingPixel(conversion_id, 'google_ads');
5033            }) : [];
5034
5035            Utils.copyProperties(Utils.getRequestParams(), _params);
5036            var _fireEvent = function (conversion_id,event_name) {
5037
5038                params = Utils.copyProperties(_params, { send_to: conversion_id });
5039
5040                if("conversion" === event_name) {
5041                    delete params.items;
5042                    delete params.ecomm_pagetype;
5043                    delete params.ecomm_prodid;
5044                    delete params.ecomm_totalvalue;
5045                }
5046
5047                if (options.debug) {
5048                    console.log('[Google Ads #' + conversion_id + '] ' + event_name, params);
5049                }
5050                gtag('event', event_name, params);
5051                var customEvent = new CustomEvent('gtag_event_sent', {
5052                    detail: {
5053                        eventName: event_name,
5054                        params: params,
5055                        pixel_ids: conversion_id
5056                    }
5057                });
5058                window.dispatchEvent(customEvent);
5059
5060            };
5061
5062
5063            if ( conversion_labels.length > 0 ) {
5064                ids = conversion_labels;
5065                if ( !isTrackEventForGA.includes( name ) ) {
5066                    _fireEvent( ids, name );
5067                }
5068            } else {
5069                var conversion_event_name = data.e_id;
5070                switch ( conversion_event_name ) {
5071                    case "woo_add_to_cart_on_cart_page":
5072                    case "woo_add_to_cart_on_checkout_page":
5073                    case "woo_add_to_cart_on_button_click":
5074                        conversion_event_name = 'woo_add_to_cart';
5075                        break;
5076                    case "edd_add_to_cart_on_cart_page":
5077                    case "edd_add_to_cart_on_checkout_page":
5078                    case "edd_add_to_cart_on_button_click":
5079                        conversion_event_name = 'edd_add_to_cart';
5080                        break;
5081                    case "automatic_event_adsense":
5082                    case "automatic_event_comment":
5083                    case "automatic_event_download":
5084                    case "automatic_event_email_link":
5085                    case "automatic_event_form":
5086                    case "automatic_event_internal_link":
5087                    case "automatic_event_outbound_link":
5088                    case "automatic_event_scroll":
5089                    case "automatic_event_tel_link":
5090                    case "automatic_event_time_on_page":
5091                    case "automatic_event_video":
5092                        conversion_event_name = 'automatic_event';
5093                        break;
5094                }
5095
5096                if ( ids.length ) {
5097                    if ( conversion_event_name !== 'automatic_event' && options.hasOwnProperty('google_ads') && options.google_ads[ conversion_event_name + '_conversion_track' ] ) {
5098                        const conversionTrack = options.google_ads[ conversion_event_name + '_conversion_track' ];
5099
5100                        if ( conversionTrack === 'conversion' ) {
5101                            _fireEvent( ids, "conversion" );
5102                            ids = conversionIds;
5103                        }
5104                    }
5105                } else {
5106                    ids = conversionIds;
5107                }
5108
5109                if ( !isTrackEventForGA.includes( name ) ) {
5110                    _fireEvent( ids, name );
5111                }
5112            }
5113        }
5114
5115        function normalizeEventName(eventName) {
5116
5117            var matches = {
5118                ViewContent: 'view_item',
5119                AddToCart: 'add_to_cart',
5120                AddToWishList: 'add_to_wishlist',
5121                InitiateCheckout: 'begin_checkout',
5122                Purchase: 'purchase',
5123                Lead: 'generate_lead',
5124                CompleteRegistration: 'sign_up',
5125                AddPaymentInfo: 'set_checkout_option'
5126            };
5127
5128            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
5129
5130        }
5131
5132        /**
5133         * Public API
5134         */
5135        return {
5136            tag: function() {
5137                return "google_ads";
5138            },
5139            isEnabled: function () {
5140                return options.hasOwnProperty('google_ads');
5141            },
5142            getHidePixel: function(){
5143                if(this.isEnabled() && options.google_ads.hasOwnProperty('hide_pixels'))
5144                {
5145                    return options.google_ads.hide_pixels;
5146                }
5147                return [];
5148            },
5149            disable: function () {
5150                initialized = false;
5151            },
5152
5153            updateEnhancedConversionData : function () {
5154
5155                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
5156                    var advanced = Utils.getAdvancedMergeFormData()
5157                    gtag('set', 'user_data', advanced);
5158                }
5159            },
5160
5161            loadPixel: function () {
5162
5163                if (initialized || !this.isEnabled() || !Utils.consentGiven('google_ads')) {
5164                    return;
5165                }
5166                var ids = options.google_ads.conversion_ids.filter(function (pixelId) {
5167                    return !Utils.hideMatchingPixel(pixelId, 'google_ads');
5168                });
5169                loadTags.push(...ids);
5170                if(!isAdsLoad && options.google_ads.conversion_ids.length > 0){
5171                    for (var i = 0; i < options.google_ads.conversion_ids.length; i++) {
5172                        var trackingId = options.google_ads.conversion_ids[i];
5173                        if (!Utils.hideMatchingPixel(trackingId, 'google_ads')) {
5174                            Utils.loadGoogleTag(trackingId);
5175                            break;
5176                        }
5177                    }
5178
5179                    // configure conversion ids
5180                    ids.forEach(function (conversion_id,index) {
5181
5182                        let config = {};
5183
5184                        if(options.google_ads.enhanced_conversion.includes("index_"+index)) {
5185                            isAllowEnhancedConversions = true;
5186                            config.allow_enhanced_conversions = true
5187                        }
5188
5189                        // Cross-Domain tracking
5190                        if (options.google_ads.crossDomainEnabled) {
5191                            config.linker = {
5192                                accept_incoming: options.google_ads.crossDomainAcceptIncoming,
5193                                domains: options.google_ads.crossDomainDomains
5194                            };
5195                        }
5196
5197                        gtag('config', conversion_id, config );
5198
5199                        if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnableuserDataEnable){
5200                            var advanced = Utils.getAdvancedMergeFormData()
5201                            gtag('set', 'user_data', advanced);
5202                        }
5203
5204                    });
5205                    isAdsLoad = true;
5206                }
5207
5208                initialized = true;
5209
5210                Utils.fireStaticEvents('google_ads');
5211
5212            },
5213
5214            fireEvent: function (name, data) {
5215
5216                if (!initialized || !this.isEnabled()) {
5217                    return false;
5218                }
5219
5220                data.delay = data.delay || 0;
5221                data.params = data.params || {};
5222                data.ids = data.ids || [];
5223                data.conversion_labels = data.conversion_labels || [];
5224
5225                if (data.delay === 0) {
5226                    fireEvent(name, data);
5227                } else {
5228                    setTimeout(function (name, data) {
5229                        fireEvent(name, data);
5230                    }, data.delay * 1000, name, data);
5231                }
5232
5233                return true;
5234
5235            },
5236
5237            onAdSenseEvent: function (event) {
5238                this.fireEvent(event.name, event);
5239            },
5240
5241            onClickEvent: function (action, params) {
5242                //disabled
5243            },
5244
5245            onWatchVideo: function (event) {
5246                this.fireEvent(event.name, event);
5247            },
5248
5249            onCommentEvent: function (event) {
5250                this.fireEvent(event.name, event);
5251            },
5252
5253            onFormEvent: function (event) {
5254                this.fireEvent(event.name, event);
5255            },
5256
5257            onDownloadEvent: function (event) {
5258                this.fireEvent(event.name, event);
5259            },
5260
5261
5262
5263
5264            onWooAddToCartOnButtonEvent: function (product_id) {
5265
5266                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5267                    return;
5268
5269                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5270                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
5271
5272                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()])
5273                        Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']['params'].params, event.params)
5274                        event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids']
5275                        event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels']
5276                        this.fireEvent(event.name, event);
5277                    }
5278                }
5279
5280            },
5281
5282            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form) {
5283
5284                window.pysWooProductData = window.pysWooProductData || [];
5285                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5286                    return;
5287                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
5288
5289                if (product_type === Utils.PRODUCT_VARIABLE && !options.google_ads.wooVariableAsSimple) {
5290                    product_id = parseInt($form.find('input[name="variation_id"]').val());
5291                }
5292
5293                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5294                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
5295
5296                        Utils.copyProperties(window.pysWooProductData[product_id]['google_ads']["params"], event.params);
5297                        event["ids"] = window.pysWooProductData[product_id]['google_ads']['ids']
5298                        event["conversion_labels"] = window.pysWooProductData[product_id]['google_ads']['conversion_labels']
5299
5300                        var groupValue = 0;
5301                        if(product_type === Utils.PRODUCT_GROUPED ) {
5302                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
5303                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
5304                                var quantity = parseInt($(this).val());
5305                                if(isNaN(quantity)) {
5306                                    quantity = 0;
5307                                }
5308
5309                                var childItem = window.pysWooProductData[product_id]['google_ads'].grouped[childId];
5310
5311                                if(options.woo.addToCartOnButtonValueEnabled &&
5312                                    options.woo.addToCartOnButtonValueOption !== 'global') {
5313
5314                                    event.params.items.forEach(function(el,index,array) {
5315                                        if(el.id == childItem.content_id) {
5316                                            if(quantity > 0){
5317                                                el.quantity = quantity;
5318                                                el.price = childItem.price;
5319                                            } else {
5320                                                array.splice(index, 1);
5321                                            }
5322                                        }
5323                                    });
5324                                }
5325                                groupValue += childItem.price * quantity;
5326                            });
5327                            if(groupValue == 0) return;
5328                            event.params.value = groupValue;
5329                        } else {
5330                            // update items qty param
5331                            event.params.items[0].quantity = qty;
5332                        }
5333
5334
5335
5336                        // maybe customize value option
5337                        if (options.woo.addToCartOnButtonValueEnabled &&
5338                            options.woo.addToCartOnButtonValueOption !== 'global' &&
5339                            product_type !== Utils.PRODUCT_GROUPED) {
5340                            event.params.value =  event.params.value * qty;
5341                        }
5342
5343
5344
5345                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
5346                        eventName = normalizeEventName(eventName);
5347
5348                        this.fireEvent(eventName, event);
5349
5350                    }
5351                }
5352
5353            },
5354
5355            onWooRemoveFromCartEvent: function (event) {
5356                this.fireEvent(event.name, event);
5357            },
5358
5359            onWooAffiliateEvent: function (product_id) {
5360                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
5361                    return;
5362                var event = options.dynamicEvents.woo_affiliate[this.tag()];
5363
5364                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5365                    if (window.pysWooProductData[product_id].hasOwnProperty('google_ads')) {
5366
5367                        event = Utils.clone(event)
5368                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
5369                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
5370
5371                    }
5372                }
5373
5374            },
5375
5376            onWooPayPalEvent: function (event) {
5377                this.fireEvent(event.name, event);
5378            },
5379
5380            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
5381                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5382                    return;
5383                var event = options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()];
5384
5385
5386                if (window.pysEddProductData.hasOwnProperty(download_id)) {
5387
5388                    var index;
5389
5390                    if (price_index) {
5391                        index = download_id + '_' + price_index;
5392                    } else {
5393                        index = download_id;
5394                    }
5395
5396                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
5397                        if (window.pysEddProductData[download_id][index].hasOwnProperty('google_ads')) {
5398
5399                            event = Utils.clone(event)
5400                            Utils.copyProperties(window.pysEddProductData[download_id][index]['google_ads']['params'], event.params);
5401                            event.ids = window.pysEddProductData[download_id][index]['google_ads']['ids']
5402                            // update items qty param
5403                            //params.items[0].quantity = qty;
5404
5405                            this.fireEvent(event.name, event);
5406
5407                        }
5408                    }
5409
5410                }
5411
5412            },
5413
5414            onEddRemoveFromCartEvent: function (event) {
5415                this.fireEvent(event.name, event);
5416            },
5417            onPageScroll: function (event) {
5418                if (initialized && this.isEnabled()) {
5419                    this.fireEvent(event.name, event);
5420                }
5421            },
5422            onTime: function (event) {
5423                if (initialized && this.isEnabled()) {
5424                    this.fireEvent(event.name, event);
5425                }
5426            },
5427
5428        };
5429
5430    }(options);
5431
5432    var GTM = function (options) {
5433
5434        var initialized = false;
5435
5436        var datalayer_name = 'dataLayer';
5437        /*
5438         * @param name
5439         * @param data
5440         */
5441        function fireEvent(name, event) {
5442            if(typeof window.pys_event_data_filter === "function" && window.pys_disable_event_filter(name,'gtm')) {
5443                return;
5444            }
5445
5446
5447            var eventParams = event.params;
5448            var data = event.params;
5449            var valuesArray = Object.values(event.trackingIds);
5450            var ids = valuesArray.filter(function (pixelId) {
5451                return !Utils.hideMatchingPixel(pixelId, 'gtm');
5452            })
5453            Utils.copyProperties(Utils.getRequestParams(), eventParams);
5454            var _fireEvent = function (tracking_id,name,params, event=null) {
5455
5456                var eventData = {};
5457                var ContainerCodeHasTag = !options.gtm.gtm_just_data_layer && tracking_id.length > 0;
5458                if(ContainerCodeHasTag) {
5459                    params['send_to'] = tracking_id;
5460                }
5461                else if(!options.gtm.gtm_just_data_layer){
5462                    return
5463                }
5464
5465                if (params.hasOwnProperty('ecommerce')) {
5466                    eventData.ecommerce = params.ecommerce;
5467                    delete params.ecommerce;
5468                }
5469
5470                var automatedParams = { ...params };
5471                [params['manualName'], 'manualName', 'triggerType'].forEach(key => delete automatedParams[key]);
5472                if(event && (!event.hasOwnProperty('hasAutoParam') || (event.hasOwnProperty('hasAutoParam') && event.hasAutoParam))) {
5473                    eventData.automatedParameters = automatedParams;
5474                }
5475
5476// Move custom parameters to eventData
5477
5478                if (params.hasOwnProperty(params['manualName'])) {
5479                    eventData[params['manualName']] = params[params['manualName']];
5480                    delete params[params['manualName']];
5481                }
5482
5483                ['manualName','triggerType'].forEach(key => {
5484                    if (params.hasOwnProperty(key)) {
5485                        eventData[key] = params[key];
5486                        delete params[key];
5487                    }
5488                });
5489
5490                eventData.manualDataLayer = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
5491
5492                eventData.event = name;
5493
5494                if (options.debug) {
5495                    if (ContainerCodeHasTag){
5496                        console.log('[Google GTM #' + tracking_id + '] ' + name, eventData);
5497                    }
5498                    else {
5499                        console.log('[Google GTM push to "'+datalayer_name+'"] ' + name, eventData);
5500                    }
5501                }
5502                window[datalayer_name].push(eventData);
5503
5504                var customEvent = new CustomEvent('gtm_event_sent', {
5505                    detail: {
5506                        eventName: name,
5507                        params: eventData,
5508                        pixel_ids: tracking_id
5509                    }
5510                });
5511                window.dispatchEvent(customEvent);
5512
5513            };
5514
5515            var copyParams = Utils.copyProperties(eventParams, {}); // copy params because mapParamsToGTM can modify it
5516
5517            var params = mapParamsToGTM(ids,name,copyParams)
5518
5519            params.event_id = Utils.generateUniqueId(event);
5520
5521            _fireEvent(ids, name, params, event);
5522        }
5523
5524        function normalizeEventName(eventName) {
5525
5526            var matches = {
5527                ViewContent: 'view_item',
5528                AddToCart: 'add_to_cart',
5529                AddToWishList: 'add_to_wishlist',
5530                InitiateCheckout: 'begin_checkout',
5531                Purchase: 'purchase',
5532                Lead: 'generate_lead',
5533                CompleteRegistration: 'sign_up',
5534                AddPaymentInfo: 'set_checkout_option'
5535            };
5536
5537            return matches.hasOwnProperty(eventName) ? matches[eventName] : eventName;
5538
5539        }
5540
5541        function mapParamsToGTM(tag,name,param) {
5542            var hasGTM = false;
5543
5544            // end
5545            if (Array.isArray(tag)) {
5546                hasGTM = tag.some(function (element) {
5547                    return isGTM(element);
5548                });
5549            } else if(isGTM(tag)) {
5550                hasGTM = true;
5551            }
5552            if(hasGTM) {
5553                delete param.event_category;
5554                delete param.event_label;
5555
5556                delete param.analytics_storage;
5557                delete param.ad_storage;
5558                delete param.ad_user_data;
5559                delete param.ad_personalization;
5560
5561                if(name === 'search') {
5562                    param['search'] = param.search_term;
5563                    delete param.search_term;
5564                    delete param.dynx_itemid;
5565                    delete param.dynx_pagetype;
5566                    delete param.dynx_totalvalue;
5567                }
5568            }
5569            return param;
5570        }
5571
5572        function isGTM(tag) {
5573            return tag.indexOf('GTM') === 0;
5574        }
5575        /**
5576         * Public API
5577         */
5578        return {
5579            tag: function() {
5580                return "gtm";
5581            },
5582            isEnabled: function () {
5583                return options.hasOwnProperty('gtm');
5584            },
5585            getHidePixel: function(){
5586                if(this.isEnabled() && options.gtm.hasOwnProperty('hide_pixels'))
5587                {
5588                    return options.gtm.hide_pixels;
5589                }
5590                return [];
5591            },
5592            disable: function () {
5593                initialized = false;
5594            },
5595            updateEnhancedConversionData : function () {
5596                if (!initialized || !this.isEnabled()) {
5597                    return;
5598                }
5599                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable) {
5600                    var advanced = Utils.getAdvancedMergeFormData(true);
5601                    if (Object.keys(advanced).length > 0) {
5602                        window[datalayer_name].push({'user_data' : advanced});
5603                    }
5604                }
5605            },
5606            loadPixel: function () {
5607
5608                if (initialized || !this.isEnabled() || !Utils.consentGiven('analytics')) {
5609                    return;
5610                }
5611                datalayer_name = options.gtm.gtm_dataLayer_name ?? 'dataLayer';
5612
5613                for (var i = 0; i < options.gtm.trackingIds.length; i++) {
5614                    var trackingId = options.gtm.trackingIds[i];
5615                    if (!Utils.hideMatchingPixel(trackingId, 'gtm') && !options.gtm.gtm_just_data_layer) {
5616                        console.log('[PYS] Google Tag Manager container code loaded');
5617                        Utils.loadGTMScript(trackingId);
5618                        break;
5619                    }
5620                }
5621
5622                if(options.gtm.gtm_just_data_layer) {
5623                    console.warn && console.warn("[PYS] Google Tag Manager container code placement set to OFF !!!");
5624                    console.warn && console.warn("[PYS] Data layer codes are active but GTM container must be loaded using custom coding !!!");
5625                    if(options.gtm.trackingIds.length == 0){
5626                        Utils.loadGTMScript();
5627                    }
5628                }
5629
5630                if(options.hasOwnProperty("tracking_analytics") && options.tracking_analytics.hasOwnProperty("userDataEnable") && options.tracking_analytics.userDataEnable){
5631                    var advanced = Utils.getAdvancedMergeFormData(true);
5632                    if(Object.keys(advanced).length > 0){
5633                        window[datalayer_name].push({'user_data' : advanced});
5634                    }
5635                }
5636
5637
5638                var config = {};
5639
5640                if(options.user_id && options.user_id != 0) {
5641                    config.user_id = options.user_id;
5642                }
5643
5644                // Cross-Domain tracking
5645
5646                var ids = options.gtm.trackingIds.filter(function (pixelId) {
5647                    return !Utils.hideMatchingPixel(pixelId, 'gtm');
5648                });
5649
5650
5651                initialized = true;
5652
5653                Utils.fireStaticEvents('gtm');
5654            },
5655
5656            fireEvent: function (name, data) {
5657
5658                if (!initialized || !this.isEnabled()) {
5659                    return false;
5660                }
5661
5662                data.delay = data.delay || 0;
5663                data.params = data.params || {};
5664
5665                if (data.delay === 0) {
5666
5667                    fireEvent(name, data);
5668
5669                } else {
5670
5671                    setTimeout(function (name, params) {
5672                        fireEvent(name, params);
5673                    }, data.delay * 1000, name, data);
5674
5675                }
5676
5677                return true;
5678
5679            },
5680
5681            onAdSenseEvent: function (event) {
5682                this.fireEvent(event.name, event);
5683            },
5684
5685            onClickEvent: function (event) {
5686                this.fireEvent(event.name, event);
5687            },
5688
5689            onWatchVideo: function (event) {
5690                if(!event.hasOwnProperty("youtube_disabled")
5691                    || !event.youtube_disabled
5692                    || event.params.video_type !== "youtube") {
5693                    this.fireEvent(event.name, event);
5694                }
5695            },
5696
5697            onCommentEvent: function (event) {
5698
5699                this.fireEvent(event.name, event);
5700
5701            },
5702
5703            onFormEvent: function (event) {
5704
5705                this.fireEvent(event.name, event);
5706
5707            },
5708
5709            onDownloadEvent: function (event) {
5710
5711                this.fireEvent(event.name, event);
5712
5713            },
5714
5715            onWooAddToCartOnButtonEvent: function (product_id, prod_info = null) {
5716                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5717                    return;
5718                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5719                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
5720                        var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
5721                        Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params)
5722                        event.trackingIds = window.pysWooProductData[product_id]['gtm']['trackingIds'];
5723
5724
5725                        if(prod_info)
5726                        {
5727                            item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0];
5728
5729                            if(prod_info['pys_list_name_productlist_id'])
5730                            {
5731                                item['item_list_id'] = prod_info['pys_list_name_productlist_id']
5732                            }
5733                            if(prod_info['pys_list_name_productlist_name'])
5734                            {
5735                                item['item_list_name'] =prod_info['pys_list_name_productlist_name']
5736                            }
5737                        }
5738                        this.fireEvent(event.name, event);
5739                    }
5740                }
5741
5742            },
5743
5744            onWooAddToCartOnSingleEvent: function (product_id, qty, product_type, is_external, $form, prod_info) {
5745                window.pysWooProductData = window.pysWooProductData || [];
5746
5747                if(!options.dynamicEvents.woo_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5748                    return;
5749                var event = Utils.clone(options.dynamicEvents.woo_add_to_cart_on_button_click[this.tag()]);
5750
5751                if (product_type === Utils.PRODUCT_VARIABLE && !options.gtm.wooVariableAsSimple) {
5752                    product_id = parseInt($form.find('input[name="variation_id"]').val());
5753                }
5754
5755                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5756                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
5757
5758                        Utils.copyProperties(window.pysWooProductData[product_id]['gtm'].params, event.params);
5759
5760                        params = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce : event.params;
5761
5762                        if(product_type === Utils.PRODUCT_GROUPED ) {
5763                            var groupValue = 0;
5764                            $form.find(".woocommerce-grouped-product-list .qty").each(function(index){
5765                                var childId = $(this).attr('name').replaceAll("quantity[","").replaceAll("]","");
5766                                var quantity = parseInt($(this).val());
5767                                if(isNaN(quantity)) {
5768                                    quantity = 0;
5769                                }
5770                                var childItem = window.pysWooProductData[product_id]['gtm'].grouped[childId];
5771
5772                                params.items.forEach(function(el,index,array) {
5773                                    if(el.id == childItem.content_id) {
5774                                        if(quantity > 0){
5775                                            el.quantity = quantity;
5776                                            el.price = childItem.price;
5777                                        } else {
5778                                            array.splice(index, 1);
5779                                        }
5780                                    }
5781                                });
5782                                groupValue += childItem.price * quantity;
5783                            });
5784
5785
5786
5787                            if(options.woo.addToCartOnButtonValueEnabled &&
5788                                options.woo.addToCartOnButtonValueOption !== 'global' &&
5789                                params.hasOwnProperty('value')) {
5790                                params.value = groupValue;
5791                            }
5792
5793                            if(groupValue == 0) return; // skip if no items selected
5794                        } else {
5795                            // update items qty param
5796                            params.items[0].quantity = qty;
5797                        }
5798
5799                        // maybe customize value option
5800                        if (options.woo.addToCartOnButtonValueEnabled &&
5801                            options.woo.addToCartOnButtonValueOption !== 'global' &&
5802                            product_type !== Utils.PRODUCT_GROUPED)
5803                        {
5804                            if(params.hasOwnProperty('value')) {
5805                                params.value = params.items[0].price * qty;
5806                            }
5807                        }
5808
5809                        if(prod_info)
5810                        {
5811                            if(prod_info['pys_list_name_productlist_id'])
5812                            {
5813                                params.items[0]['item_list_id'] = prod_info['pys_list_name_productlist_id']
5814                            }
5815                            if(prod_info['pys_list_name_productlist_name'])
5816                            {
5817                                params.items[0]['item_list_name'] =prod_info['pys_list_name_productlist_name']
5818                            }
5819                        }
5820
5821                        var eventName = is_external ? options.woo.affiliateEventName : event.name;
5822                        eventName = normalizeEventName(eventName);
5823
5824                        this.fireEvent(eventName, event);
5825
5826                    }
5827                }
5828
5829            },
5830
5831            onWooCheckoutProgressStep: function (event) {
5832                this.fireEvent(event.name, event);
5833            },
5834
5835            onWooSelectContent: function (event) {
5836                const select_prod_list = {};
5837
5838                if (event.params.items[0].item_list_name !== undefined) {
5839                    select_prod_list.list_name = event.params.items[0].item_list_name;
5840                }
5841
5842                if (event.params.items[0].item_list_id !== undefined) {
5843                    select_prod_list.list_id = event.params.items[0].item_list_id;
5844                }
5845                const url = new URL(window.location.href);
5846                select_prod_list.url = url.origin + url.pathname;
5847                Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' });
5848                this.fireEvent(event.name, event);
5849            },
5850
5851            onWooRemoveFromCartEvent: function (event) {
5852                this.fireEvent(event.name, event);
5853            },
5854
5855            onWooAffiliateEvent: function (product_id) {
5856                if(!options.dynamicEvents.woo_affiliate.hasOwnProperty(this.tag()))
5857                    return;
5858                var event = options.dynamicEvents.woo_affiliate[this.tag()];
5859
5860                if (window.pysWooProductData.hasOwnProperty(product_id)) {
5861                    if (window.pysWooProductData[product_id].hasOwnProperty('gtm')) {
5862
5863                        event = Utils.clone(event );
5864                        Utils.copyProperties(window.pysWooProductData[product_id][this.tag()], event.params)
5865                        this.fireEvent(normalizeEventName(options.woo.affiliateEventName), event);
5866
5867                    }
5868                }
5869
5870            },
5871
5872            onWooPayPalEvent: function (event) {
5873                this.fireEvent(event.name, event);
5874            },
5875
5876            onEddAddToCartOnButtonEvent: function (download_id, price_index, qty) {
5877                if(!options.dynamicEvents.edd_add_to_cart_on_button_click.hasOwnProperty(this.tag()))
5878                    return;
5879                var event = Utils.clone(options.dynamicEvents.edd_add_to_cart_on_button_click[this.tag()]);
5880
5881
5882                if (window.pysEddProductData.hasOwnProperty(download_id)) {
5883
5884                    var index;
5885
5886                    if (price_index) {
5887                        index = download_id + '_' + price_index;
5888                    } else {
5889                        index = download_id;
5890                    }
5891
5892                    if (window.pysEddProductData[download_id].hasOwnProperty(index)) {
5893                        if (window.pysEddProductData[download_id][index].hasOwnProperty('gtm')) {
5894
5895                            Utils.copyProperties(window.pysEddProductData[download_id][index]['gtm'].params, event.params);
5896                            item = event.params.hasOwnProperty('ecommerce') ? event.params.ecommerce.items[0] : event.params.items[0];
5897                            // update items qty param
5898                            item.quantity = qty;
5899
5900                            this.fireEvent(event.name,event);
5901
5902                        }
5903                    }
5904
5905                }
5906
5907            },
5908
5909            onEddRemoveFromCartEvent: function (event) {
5910                this.fireEvent(event.name, event);
5911            },
5912
5913            onPageScroll: function (event) {
5914                if (initialized && this.isEnabled()) {
5915                    this.fireEvent(event.name, event);
5916                }
5917            },
5918            onTime: function (event) {
5919                if (initialized && this.isEnabled()) {
5920                    this.fireEvent(event.name, event);
5921                }
5922            },
5923        };
5924
5925    }(options);
5926
5927    var getPixelBySlag = function getPixelBySlag(slug) {
5928        switch (slug) {
5929            case "facebook": return window.pys.Facebook;
5930            case "ga": return window.pys.Analytics;
5931            case "gtm": return window.pys.GTM;
5932            case "google_ads": return window.pys.GAds;
5933            case "bing": return window.pys.Bing;
5934            case "pinterest": return window.pys.Pinterest;
5935            case "tiktok": return window.pys.TikTok;
5936            case "reddit": return window.pys.Reddit;
5937        }
5938    }
5939
5940    window.pys = window.pys || {};
5941    window.pys.Facebook = Facebook;
5942    window.pys.Analytics = Analytics;
5943    window.pys.GAds = GAds;
5944    window.pys.GTM = GTM;
5945    window.pys.Utils = Utils;
5946    window.pys.TikTok = TikTok;
5947    window.pys.getPixelBySlag = getPixelBySlag;
5948
5949    // Allow external scripts (e.g. generatePixelCode fragments) to refresh
5950    // the uniqueId cache for a given event key, so that each new add_to_cart
5951    // action gets a fresh shared ID across all pixels.
5952    window.pys.setEventUniqueId = function(idKey, newId) {
5953        uniqueId[idKey] = newId;
5954    };
5955
5956    // Export getPixelBySlag globally for backward compatibility
5957    window.getPixelBySlag = getPixelBySlag;
5958
5959
5960
5961    $(document).ready(function () {
5962
5963        if(Cookies.get('form_track'))
5964        {
5965            Cookies.remove('form_track')
5966        }
5967
5968        if($("#pys_late_event").length > 0) {
5969            var dirAttr = $("#pys_late_event").attr("dir");
5970            if (dirAttr) {
5971                try {
5972                    var events = JSON.parse(dirAttr);
5973                } catch (e) {
5974                    console.warn("Invalid JSON in pys_late_event dir attribute:", e);
5975                }
5976            } else {
5977                console.warn("pys_late_event dir attribute is undefined or empty");
5978            }
5979            if (events) {
5980                for (var platform in events) {
5981                    if (events.hasOwnProperty(platform)) {
5982                        var platformEvents = events[platform];
5983                        platformEvents.forEach(function (event) {
5984                            var eventData = {};
5985                            eventData[event.e_id] = [event];
5986                            if (options.staticEvents.hasOwnProperty(platform)) {
5987                                Object.assign(options.staticEvents[platform], eventData);
5988                            } else {
5989                                options.staticEvents[platform] = eventData;
5990                            }
5991                        });
5992                    }
5993                }
5994            }
5995        }
5996
5997        var Pinterest = Utils.setupPinterestObject();
5998        var Bing = Utils.setupBingObject();
5999	    var Reddit = Utils.setupRedditObject();
6000        if(options.hasOwnProperty('cookie'))
6001        {
6002            if(options.cookie.externalID_disabled_by_api || options.cookie.disabled_all_cookie)
6003            {
6004                Cookies.remove('pbid')
6005            }
6006            if(options.cookie.disabled_advanced_form_data_cookie || options.cookie.disabled_all_cookie)
6007            {
6008                Cookies.remove('pys_advanced_form_data')
6009            }
6010
6011            if(options.cookie.disabled_landing_page_cookie || !options.enable_lading_page_param || options.cookie.disabled_all_cookie)
6012            {
6013                Cookies.remove('pys_landing_page', { path: '/',domain: domain })
6014                Cookies.remove('last_pys_landing_page', { path: '/',domain: domain })
6015            }
6016            if(options.cookie.disabled_trafficsource_cookie || options.cookie.disabled_all_cookie)
6017            {
6018                Cookies.remove('pysTrafficSource', { path: '/',domain: domain })
6019                Cookies.remove('last_pysTrafficSource', { path: '/',domain: domain })
6020            }
6021            if(options.cookie.disabled_first_visit_cookie || options.cookie.disabled_all_cookie)
6022            {
6023                Cookies.remove('pys_first_visit', { path: '/',domain: domain })
6024
6025            }
6026            if(options.cookie.disabled_utmTerms_cookie || options.cookie.disabled_all_cookie)
6027            {
6028                $.each(Utils.utmTerms, function (index, name) {
6029                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
6030                });
6031                $.each(Utils.utmTerms, function (index, name) {
6032                    Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
6033                });
6034            }
6035            if(options.cookie.disabled_utmId_cookie || options.cookie.disabled_all_cookie)
6036            {
6037                $.each(Utils.utmId,function(index,name) {
6038                    Cookies.remove('pys_' + name, { path: '/',domain: domain })
6039                })
6040                $.each(Utils.utmId,function(index,name) {
6041                    Cookies.remove('last_pys_' + name, { path: '/',domain: domain })
6042                });
6043            }
6044        }
6045
6046        if (options.gdpr.cookie_law_info_integration_enabled) {
6047            var cli_cookie = Cookies.get('cookieyes-consent') ?? Cookies.get('wt_consent') ?? Cookies.get('viewed_cookie_policy');
6048
6049            if (typeof cli_cookie !== 'undefined') {
6050                if (cli_cookie === Cookies.get('cookieyes-consent') || cli_cookie === Cookies.get('wt_consent')) {
6051                    if (getCookieYes('analytics') === 'yes') {
6052                        Utils.manageCookies();
6053                    }
6054                } else if (cli_cookie === Cookies.get('viewed_cookie_policy') && cli_cookie == 'yes') {
6055                    Utils.manageCookies();
6056                }
6057            }
6058        }
6059
6060        if ( options.gdpr.consent_magic_integration_enabled && typeof CS_Data !== "undefined" ) {
6061            if ( CS_Data.cs_script_cat.pys == CS_Data.cs_necessary_cat_id || CS_Data.cs_script_cat.pys == 0 ) {
6062                Utils.manageCookies();
6063            } else if ( Cookies.get( 'cs_enabled_cookie_term' + CS_Data.test_prefix + '_' + CS_Data.cs_script_cat.pys ) == 'yes' ) {
6064                Utils.manageCookies();
6065            }
6066        } else {
6067            Utils.manageCookies();
6068        }
6069
6070        Utils.initializeRequestParams();
6071        Utils.setupGdprCallbacks();
6072
6073        if ( options.enable_auto_save_advance_matching ) {
6074            let override = options.data_persistency == 'recent_data';
6075
6076            //Setup Advanced Form Data
6077            if ( options.advance_matching_form.enable_advance_matching_forms ) {
6078                $( document ).on( "blur", "input[type='email']", function () {
6079                    let email = $( this ).val().trim().toLowerCase();
6080                    if ( Utils.validateEmail( email ) ) {
6081                        Utils.saveAdvancedFormData( email, null, null, null, override );
6082                    }
6083                } )
6084                $( document ).on( "blur", "input[type='tel']", function () {
6085                    let phone = $( this ).val().trim().replace( /\D/g, "" );
6086                    if ( phone.length > 5 ) {
6087                        Utils.saveAdvancedFormData( null, phone, null, null, override );
6088                    }
6089                } )
6090                $( document ).on( "blur", "input[type='text']", function () {
6091                    let name;
6092                    if ( $( this ).attr( "name" ) && $( this ).attr( "name" ) != '' ) {
6093                        name = $( this ).attr( "name" ).trim()
6094                    }
6095                    if ( name && options.advance_matching_form.advance_matching_fn_names.includes( name ) ) {
6096                        let value = $( this ).val().trim();
6097                        if ( value.length > 0 ) {
6098                            Utils.saveAdvancedFormData( null, null, value, null, override );
6099                        }
6100                    }
6101                    if ( name && options.advance_matching_form.advance_matching_ln_names.includes( name ) ) {
6102                        let value = $( this ).val().trim();
6103                        if ( value.length > 0 ) {
6104                            Utils.saveAdvancedFormData( null, null, null, value, override );
6105                        }
6106                    }
6107                    if ( name && options.advance_matching_form.advance_matching_tel_names.includes( name ) ) {
6108                        let value = $( this ).val().trim();
6109                        if ( value.length > 0 ) {
6110                            Utils.saveAdvancedFormData( null, value, null, null, override );
6111                        }
6112                    }
6113                    if ( name && options.advance_matching_form.advance_matching_em_names.includes( name ) ) {
6114                        let email = $( this ).val().trim().toLowerCase();
6115
6116                        if ( Utils.validateEmail( email ) ) {
6117                            Utils.saveAdvancedFormData( email, null, null, null, false );
6118                        }
6119                    }
6120                } )
6121            }
6122
6123            //Setup Advanced Url Data
6124            if ( Object.keys( options.advance_matching_url ).length > 0 && options.advance_matching_url.enable_advance_matching_url ) {
6125                const url_params = new URLSearchParams( window.location.search );
6126                url_params.forEach( ( value, key ) => {
6127                    if ( options.advance_matching_url.advance_matching_fn_names.includes( key ) ) {
6128                        Utils.saveAdvancedFormData( null, null, value.trim(), null, override );
6129                    }
6130
6131                    if ( options.advance_matching_url.advance_matching_ln_names.includes( key ) ) {
6132                        Utils.saveAdvancedFormData( null, null, null, value.trim(), override );
6133                    }
6134
6135                    if ( options.advance_matching_url.advance_matching_tel_names.includes( key ) ) {
6136                        Utils.saveAdvancedFormData( null, value.trim(), null, null, override );
6137                    }
6138
6139                    if ( options.advance_matching_url.advance_matching_em_names.includes( key ) ) {
6140                        let email = value.trim().toLowerCase()
6141                        if ( Utils.validateEmail( email ) ) {
6142                            Utils.saveAdvancedFormData( email, null, null, null, override );
6143                        }
6144                    }
6145                } );
6146            }
6147        }
6148
6149        // setup Click Event
6150        if (
6151            options.dynamicEvents.hasOwnProperty("automatic_event_internal_link") ||
6152            options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link") ||
6153            options.dynamicEvents.hasOwnProperty("automatic_event_tel_link") ||
6154            options.dynamicEvents.hasOwnProperty("automatic_event_email_link") ||
6155            options.dynamicEvents.hasOwnProperty("automatic_event_download")
6156        ) {
6157
6158            $(document).onFirst('click', 'a, button, input[type="button"], input[type="submit"]', function (e) {
6159
6160                var $elem = $(this);
6161
6162
6163                // Download
6164                if(options.dynamicEvents.hasOwnProperty("automatic_event_download")) {
6165                    var isFired = false;
6166                    if ($elem.is('a')) {
6167                        var href = $elem.attr('href');
6168                        if (typeof href !== "string") {
6169                            return;
6170                        }
6171                        href = href.trim();
6172                        var extension = Utils.getLinkExtension(href);
6173                        var track_download = false;
6174
6175                        if (extension.length > 0) {
6176
6177                            if(options.dynamicEvents.hasOwnProperty("automatic_event_download") ) {
6178                                var pixels = Object.keys(options.dynamicEvents.automatic_event_download);
6179                                for (var i = 0; i < pixels.length; i++) {
6180                                    var event = Utils.clone(options.dynamicEvents.automatic_event_download[pixels[i]]);
6181                                    var extensions = event.extensions;
6182                                    if (extensions.includes(extension)) {
6183
6184                                        if(pixels[i] == "tiktok" || pixels[i] == "reddit") {
6185                                            getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6186                                        } else {
6187                                            if (options.enable_remove_download_url_param) {
6188                                                href = href.split('?')[0];
6189                                            }
6190                                            event.params.download_url = href;
6191                                            event.params.download_type = extension;
6192                                            event.params.download_name = Utils.getLinkFilename(href);
6193                                            getPixelBySlag(pixels[i]).onDownloadEvent(event);
6194                                        }
6195
6196                                        isFired = true;
6197                                    }
6198                                }
6199                            }
6200                        }
6201                    }
6202                    if(isFired) { // prevent duplicate events on the same element
6203                        return;
6204                    }
6205                }
6206
6207
6208                if (!e.hasOwnProperty('originalEvent')) {
6209                    return;
6210                }
6211                if($elem.hasClass("add_to_cart_button") ||
6212                    $elem.hasClass("single_add_to_cart_button") ) { // add_to_cart_button fire in woo
6213                    return;
6214                }
6215
6216                if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")
6217                    && $elem.hasClass("wcf-next-step-link")) {
6218                    return;// add_to_cart_button fire in woo cf
6219                }
6220                if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")
6221                    && $elem.hasClass("wcf-bump-order-cb")) {
6222                    return;// add_to_cart_button fire in woo cf
6223                }
6224
6225                if($elem.hasClass("remove_from_cart_button") ) { // cancel remove from cart
6226                    return;
6227                }
6228                if($elem.hasClass("remove") ) { // cancel remove from cart
6229                    if($elem.parents('.cart_item').length || $elem.parents('.mini_cart_item').length)
6230                        return;
6231                }
6232                if($elem.attr("name") == "update_cart" || $elem.attr("name") == "apply_coupon") { // cancel update  c
6232art or coupon button
6233                    return;
6234                }
6235
6236
6237                if ($elem.hasClass('pys_block')) {
6238                    return; // avoiding fake double clicks from Affiliate event
6239                }
6240                var text = "";
6241                var target_url = "";
6242                var linkType = "Internal Click";
6243
6244                if ($elem.is('a')) {
6245                    var href = $elem.attr('href');
6246
6247                    // fixes #112
6248                    if (typeof href !== "string") {
6249                        return;
6250                    }
6251                    href = href.trim();
6252
6253                    text = $elem.contents().filter(function() {
6254                        return this.nodeType === 3; // Фильтруем только текстовые узлы
6255                    }).text().trim();
6256                    if(options.enable_remove_target_url_param) {
6257                        target_url = href.split('?')[0];
6258                    } else {
6259                        target_url = href
6260                    }
6261
6262
6263                    //Email Event
6264                    if ( href.startsWith( 'mailto:' ) ) {
6265                        if ( options.triggerEventTypes.hasOwnProperty( "email_link" ) ) {
6266                            return;
6267                        } else {
6268                            setupEmailLinks();
6269                        }
6270
6271                        return; // not fire next
6272                    }
6273
6274                    // Phone
6275                    if (href.startsWith('tel:')) {
6276                        if(options.dynamicEvents.hasOwnProperty("automatic_event_tel_link")) {
6277                            var pixels = Object.keys(options.dynamicEvents.automatic_event_tel_link);
6278                            for(var i = 0;i<pixels.length;i++) {
6279                                var event = Utils.clone(options.dynamicEvents.automatic_event_tel_link[pixels[i]]);
6280                                if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6281                                    Utils.copyProperties(Utils.getRequestParam
6281s(), event.params);
6282                                }
6283                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6284                            }
6285                        }
6286                        return; // not fire next
6287                    }
6288
6289                    if (href.startsWith('http')) {
6290                        // link type
6291                        var host = $elem.context != undefined ? $elem.context.host : $elem[0].host;
6292                        if (document.location.host != host) {
6293                            linkType = 'External Click';
6294                        }
6295                    }
6296                } else if ($elem.is('button')) {
6297                    if( $elem.hasClass("forminator-button-submit")) {
6298                        //disable duplicate events
6299                        return;
6300                    }
6301                    text = $elem.contents().filter(function() {
6302                        return this.nodeType === 3; // Фильтруем только текстовые узлы
6303                    }).text().trim();
6304                } else if ($elem.is('input[type="button"]')) {
6305                    text = $elem.val();
6306                } else if ($elem.is('input[type="submit"]')) {
6307                    if ( $elem.parents("form.comment-form")) {
6308                        //disable duplicate events
6309                        return;
6310                    }
6311                    if ($elem.parents("form")) {
6312                        //disable duplicate events
6313                        return;
6314                    }
6315                    text = $elem.val();
6316                } else {
6317                    return;
6318                }
6319
6320
6321
6322                text = Utils.filterEmails(text);
6323
6324
6325                if( linkType === "Internal Click"
6326                    && options.dynamicEvents.hasOwnProperty("automatic_event_internal_link")
6327                ) {
6328                    var pixels = Object.keys(options.dynamicEvents.automatic_event_internal_link);
6329
6330                    for(var i = 0;i<pixels.length;i++) {
6331                        var event = Utils.clone(options.dynamicEvents.automatic_event_internal_link[pixels[i]]);
6332
6333	                    if(pixels[i] !== "tiktok" && pixels[i] !== "reddit") { // TT and reddit don't support custom parameters
6334                            event.params["text"] = text;
6335                            if(target_url){
6336                                event.params["target_url"] = target_url;
6337                            }
6338                            Utils.copyProperties(Utils.getRequestParam
6338s(), event.params);
6339                        }
6340
6341
6342                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6343                    }
6344                }
6345
6346                if( linkType === "External Click"
6347                    && options.dynamicEvents.hasOwnProperty("automatic_event_outbound_link")
6348                ) {
6349                    var pixels = Object.keys(options.dynamicEvents.automatic_event_outbound_link);
6350
6351                    for(var i = 0;i<pixels.length;i++) {
6352                        var event = Utils.clone(options.dynamicEvents.automatic_event_outbound_link[pixels[i]]);
6353
6354                        if(pixels[i] !== "tiktok" && pixels[i] !== "reddit") { // TT and reddit don't support custom parameters
6355                            event.params["text"] = text;
6356                            if(target_url){
6357                                event.params["target_url"] = target_url;
6358                            }
6359                            Utils.copyProperties(Utils.getRequestParams(), event.params);
6360                        }
6361
6362
6363                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6364                    }
6365                }
6366
6367
6368
6369
6370            });
6371
6372        }
6373
6374        // setup AdSense Event
6375        if (options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) {
6376
6377            var isOverGoogleAd = false;
6378
6379            $(document)
6380                .on('mouseover', 'ins iframe', function () { //class adsbygoogle adsbygoogle-noablate ??
6381                    isOverGoogleAd = true;
6382                })
6383                .on('mouseout', 'iframe', function () {
6384                    isOverGoogleAd = false;
6385                });
6386
6387            $(window)
6388                .on( "blur",function () {
6389                    if (isOverGoogleAd) {
6390                        if(options.dynamicEvents.hasOwnProperty("automatic_event_adsense")) {
6391                            var pixels = Object.keys(options.dynamicEvents.automatic_event_adsense);
6392                            for (var i = 0; i < pixels.length; i++) {
6393                                var event = Utils.clone(options.dynamicEvents.automatic_event_adsense[pixels[i]]);
6394                                if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6395                                    Utils.copyProperties(Utils.getRequestParam
6395s(), event.params);
6396                                }
6397                                getPixelBySlag(pixels[i]).onAdSenseEvent(event);
6398                            }
6399                        }
6400
6401                        $.each(options.triggerEventTypes, function (triggerType, events) {
6402                            $.each(events, function (eventId, triggers) {
6403                                switch (triggerType) {
6404                                    case 'ad_sense_click':
6405                                        Utils.fireTriggerEvent(eventId);
6406                                        break;
6407                                }
6408                            });
6409                        });
6410                    }
6411                })
6412                .trigger("focus");
6413
6414        }
6415
6416        //setup adsense for custom events
6417        var dynamicAdsenseEventsTriggers = 0
6418        $.each(options.triggerEventTypes, function (triggerType, events) {
6419            if(triggerType == "ad_sense_click") {
6420                dynamicAdsenseEventsTriggers++;
6421            }
6422        });
6423        if (dynamicAdsenseEventsTriggers > 0) {
6424
6425            var isOverGoogleAd = false;
6426
6427            $(document)
6428                .on('mouseover', 'ins > ins > iframe', function () {
6429                    isOverGoogleAd = true;
6430                })
6431                .on('mouseout', 'iframe', function () {
6432                    isOverGoogleAd = false;
6433                });
6434
6435            $(window)
6436                .on( "blur",function () {
6437                    if (isOverGoogleAd) {
6438
6439                        $.each(options.triggerEventTypes, function (triggerType, events) {
6440                            $.each(events, function (eventId, triggers) {
6441                                switch (triggerType) {
6442                                    case 'ad_sense_click':
6443                                        Utils.fireTriggerEvent(eventId);
6444                                        break;
6445                                }
6446                            });
6447                        });
6448                    }
6449                })
6450                .trigger("focus");
6451
6452        }
6453
6454
6455        // page scroll event
6456        if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")
6457        ) {
6458
6459            var singlePageScroll = function () {
6460
6461
6462                var docHeight = $(document).height() - $(window).height();
6463                var isFired = false;
6464
6465                if (options.dynamicEvents.hasOwnProperty("automatic_event_scroll")) {
6466                    var pixels = Object.keys(options.dynamicEvents.automatic_event_scroll);
6467                    for(var i = 0;i<pixels.length;i++) {
6468                        var event = Utils.clone(options.dynamicEvents.automatic_event_scroll[pixels[i]]);
6469                        var scroll = Math.round(docHeight * event.scroll_percent / 100)// convert % to absolute positions
6470
6471                        if(scroll < $(window).scrollTop()) {
6472                            if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6473                                Utils.copyProperties(Utils.getRequestParam
6473s(), event.params);
6474                            }
6475                            getPixelBySlag(pixels[i]).onPageScroll(event);
6476                            isFired = true
6477                        }
6478                    }
6479                }
6480                if(isFired) {
6481                    $(document).off("scroll",singlePageScroll);
6482                }
6483            }
6484            $(document).on("scroll",singlePageScroll);
6485        }
6486
6487
6488        if (options.dynamicEvents.hasOwnProperty("automatic_event_time_on_page")) {
6489            var pixels = Object.keys(options.dynamicEvents.automatic_event_time_on_page);
6490            var time = options.dynamicEvents.automatic_event_time_on_page[pixels[0]].time_on_page; // the same for all pixel
6491            setTimeout(function(){
6492                for(var i = 0;i<pixels.length;i++) {
6493                    var event = Utils.clone(options.dynamicEvents.automatic_event_time_on_page[pixels[i]]);
6494                    if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
6495                        Utils.copyProperties(Utils.getRequestParam
6495s(), event.params);
6496                    }
6497                    getPixelBySlag(pixels[i]).onTime(event);
6498                }
6499            },time*1000);
6500        }
6501
6502        // setup Dynamic events
6503
6504        $.each(options.triggerEventTypes, function (triggerType, events) {
6505
6506            $.each(events, function (eventId, triggers) {
6507                switch (triggerType) {
6508                    case 'url_click':
6509                        //@see: Utils.setupURLClickEvents()
6510                        break;
6511
6512                    case 'css_click':
6513                        Utils.setupCSSClickEvents(eventId, triggers);
6514                        break;
6515
6516                    case 'css_mouseover':
6517                        Utils.setupMouseOverClickEvents(eventId, triggers);
6518                        break;
6519
6520                    case 'scroll_pos':
6521                        Utils.setupScrollPosEvents(eventId, triggers);
6522                        break;
6523                    case 'comment':
6524                        Utils.setupCommentEvents(eventId, triggers);
6525                        break;
6526                    case 'video_view':
6527                        //@see: Utils.checkYouTubeCompletion() and Utils.addYouTubeEvents()
6528                        break;
6529
6530                    case 'form_field':
6531                        Utils.setupFormFieldEvents(eventId, triggers);
6532                        break;
6533                }
6534
6535            });
6536
6537            if ( triggerType == "email_link" ) {
6538                Utils.setupEmailLinkEvents( events )
6539            }
6540
6541        });
6542
6543        // setup WooCommerce events
6544        if (options.woo.enabled) {
6545
6546            // Woo CartFlow AddToCart
6547            if (options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_next_step_click")) {
6548                $("body").on("click",'.wcf-next-step-link',function () {
6549                    var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_next_step_click);
6550                    for(var i = 0;i<pixels.length;i++) {
6551                        var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_next_step_click[pixels[i]])
6552                        getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6553                    }
6554                });
6555            }
6556            // Woo CartFlow Bump AddToCart
6557            if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click") ||
6558                options.dynamicEvents.hasOwnProperty("wcf_bump")) {
6559                $("body").on('change','.wcf-bump-order-cb',function () {
6560
6561                    if(this.checked) {
6562                        if(options.dynamicEvents.hasOwnProperty("wcf_add_to_cart_on_bump_click")) {
6563                            var pixels = Object.keys(options.dynamicEvents.wcf_add_to_cart_on_bump_click);
6564                            for(var i = 0;i<pixels.length;i++) {
6565                                var event = Utils.clone(options.dynamicEvents.wcf_add_to_cart_on_bump_click[pixels[i]]);
6566                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6567                            }
6568                        }
6569
6570
6571                        if(options.dynamicEvents.hasOwnProperty("wcf_bump")) {
6572                            var pixels = Object.keys(options.dynamicEvents.wcf_bump);
6573                            for(var i = 0;i<pixels.length;i++) {
6574                                var event = Utils.clone(options.dynamicEvents.wcf_bump[pixels[i]]);
6575                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6576                            }
6577                        }
6578
6579                    } else {
6580                        if(options.dynamicEvents.hasOwnProperty("wcf_remove_from_cart_on_bump_click")) {
6581                            var pixels = Object.keys(options.dynamicEvents.wcf_remove_from_cart_on_bump_click);
6582                            for(var i = 0;i<pixels.length;i++) {
6583                                var event = Utils.clone(options.dynamicEvents.wcf_remove_from_cart_on_bump_click[pixels[i]]);
6584                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
6585                            }
6586                        }
6587
6588                    }
6589
6590
6591                });
6592            }
6593
6594
6595            // WooCommerce AddToCart
6596            if (options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")
6597                && options.woo.hasOwnProperty("addToCartCatchMethod")
6598                && options.woo.addToCartCatchMethod === "add_cart_js"
6599            ) {
6600                // Loop, any kind of "simple" product, except external
6601                $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
6602
6603                    var $button = $(this);
6604                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6605                    var product_id = $(this).data('product_id');
6606                    Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' })
6607                    var product_id = $(this).data('product_id');
6608                    if (typeof product_id !== 'undefined') {
6609
6610                        if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){
6611                            var tmpEventID = pys_generate_token();
6612                            $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
6613                                tag.eventID = tmpEventID;
6614                                // Also refresh the uniqueId cache so server-API path
6615                                // (ajaxForServerStaticEvent) gets the same fresh ID.
6616                                var idKey = tag.hasOwnProperty('custom_event_post_id') ? tag.custom_event_post_id : tag.e_id;
6617                                uniqueId[idKey] = tmpEventID;
6618                            });
6619                        }
6620
6621                        Facebook.onWooAddToCartOnButtonEvent(product_id,$(this));
6622                        Analytics.onWooAddToCartOnButtonEvent(product_id, $prod_info);
6623                        GTM.onWooAddToCartOnButtonEvent(product_id, $prod_info);
6624                        GAds.onWooAddToCartOnButtonEvent(product_id);
6625                        Pinterest.onWooAddToCartOnButtonEvent(product_id);
6626                        Bing.onWooAddToCartOnButtonEvent(product_id);
6627                        TikTok.onWooAddToCartOnButtonEvent(product_id);
6628                        Reddit.onWooAddToCartOnButtonEvent(product_id);
6629                    }
6630
6631                });
6632
6633                // Single Product
6634                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
6635                //  $(document) not work
6636                $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
6637
6638                    var $button = $(this);
6639                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6640                    var product_id = $(this).data('product_id');
6641                    Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' })
6642                    if ($button.hasClass('disabled')) {
6643                        return;
6644                    }
6645
6646                    var $form = $button.closest('form');
6647
6648                    var product_type = Utils.PRODUCT_SIMPLE;
6649                    var is_external = false;
6650
6651                    if ($form.length === 0) {
6652                        is_external = true;
6653                    } else if ($form.hasClass('variations_form')) {
6654                        product_type = Utils.PRODUCT_VARIABLE;
6655                    } else if($form.hasClass('bundle_form')) {
6656                        product_type = Utils.PRODUCT_BUNDLE;
6657                    } else if($form.hasClass('grouped_form')) {
6658                        product_type = Utils.PRODUCT_GROUPED;
6659                    }
6660
6661
6662
6663                    var product_id;
6664                    var qty = 1;
6665                    if (product_type === Utils.PRODUCT_GROUPED) {
6666                        qty = 1;
6667                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
6668                    } else if (product_type === Utils.PRODUCT_VARIABLE) {
6669                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
6670                        var qtyTag = $form.find('input[name="quantity"]');
6671                        if(qtyTag.length <= 0) {
6672                            qtyTag = $form.find('select[name="quantity"]');
6673                        }
6674                        qty = parseInt(qtyTag.val());
6675                    } else if (is_external) {
6676                        product_id = options.woo.singleProductId;
6677                        qty = 1;
6678                    } else {
6679                        product_id = parseInt($form.find('*[name="add-to-cart"]').val());
6680                        var qtyTag = $form.find('input[name="quantity"]');
6681                        if(qtyTag.length <= 0) {
6682                            qtyTag = $form.find('select[name="quantity"]');
6683                        }
6684                        qty = parseInt(qtyTag.val());
6685                    }
6686
6687                    //
6688                    if(options.dynamicEvents.hasOwnProperty("woo_add_to_cart_on_button_click")){
6689                        var tmpEventID = pys_generate_token();
6690                        $.each(options.dynamicEvents.woo_add_to_cart_on_button_click, function (i, tag) {
6691                            tag.eventID = tmpEventID;
6692                            // Also refresh the uniqueId cache so server-API path
6693                            // (ajaxForServerStaticEvent) gets the same fresh ID.
6694                            var idKey = tag.hasOwnProperty('custom_event_post_id') ? tag.custom_event_post_id : tag.e_id;
6695                            uniqueId[idKey] = tmpEventID;
6696                        });
6697                    }
6698
6699                    Facebook.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6700                    Analytics.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form, $prod_info);
6701                    GTM.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form, $prod_info);
6702                    GAds.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6703                    Pinterest.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6704                    Bing.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6705                    TikTok.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6706                    Reddit.onWooAddToCartOnSingleEvent(product_id, qty, product_type, is_external, $form);
6707                });
6708
6709            } else {
6710                $('.add_to_cart_button:not(.product_type_variable,.product_type_bundle,.single_add_to_cart_button)').on("click",function (e) {
6711                    var $button = $(this);
6712                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6713                    var product_id = $(this).data('product_id');
6714                    Cookies.set('productlist', JSON.stringify($prod_info), { expires: 1,path: '/' })
6715                });
6716
6717                // Single Product
6718                // tap try to https://stackoverflow.com/questions/30990967/on-tap-click-event-firing-twice-how-to-avoid-it
6719                //  $(document) not work
6720                $('body').onFirst('click','button.single_add_to_cart_button,.single_add_to_cart_button',function (e) {
6721
6722                    var $button = $(this);
6723                    var $prod_info = $button.siblings('.pys_list_name_productdata').data();
6724                    Cookies.set('productlist', $prod_info, { expires: 1,path: '/' })
6725                });
6726            }
6727
6728            // WooCommerce Affiliate
6729            if (options.dynamicEvents.hasOwnProperty("woo_affiliate")) {
6730
6731                // Loop, external
6732                $('.product_type_external').on("click",function (e) {
6733
6734                    var product_id = $(this).data('product_id');
6735
6736                    if (typeof product_id !== 'undefined') {
6737                        Facebook.onWooAffiliateEvent(product_id);
6738                        Analytics.onWooAffiliateEvent(product_id);
6739                        GTM.onWooAffiliateEvent(product_id);
6740                        GAds.onWooAffiliateEvent(product_id);
6741                        Pinterest.onWooAffiliateEvent(product_id);
6742                        Bing.onWooAffiliateEvent(product_id);
6743                    }
6744
6745                });
6746
6747            }
6748
6749            // WooCommerce RemoveFromCart
6750            if (options.dynamicEvents.hasOwnProperty("woo_remove_from_cart")) {
6751
6752                $('body').on('click', options.woo.removeFromCartSelector, function (e) {
6753
6754                    var $a = $(e.currentTarget),
6755                        href = $a.attr('href');
6756
6757                    // extract cart item hash from remove button URL
6758                    var regex = new RegExp("[\\?&]remove_item=([^&#]*)"),
6759                        results = regex.exec(href);
6760
6761                    if (results !== null) {
6762
6763                        var item_hash = results[1];
6764
6765                        if (options.dynamicEvents["woo_remove_from_cart"].hasOwnProperty(item_hash)) {
6766                            var events = options.dynamicEvents["woo_remove_from_cart"][item_hash];
6767                            Utils.fireEventForAllPixel("onWooRemoveFromCartEvent",events)
6768                        }
6769
6770                    }
6771
6772                });
6773
6774            }
6775
6776            // WooCommerce PayPal
6777            if (options.dynamicEvents.hasOwnProperty("woo_paypal")) {
6778
6779                // Non-default binding used to avoid situations when some code in external js
6780                // stopping events propagation, eg. returns false, and our handler will never called
6781                $(document).onFirst('submit click', '#place_order', function (e) {
6782
6783                    var method = $('form[name="checkout"] input[name="payment_method"]:checked').val();
6784
6785                    if (method !== 'paypal') {
6786                        return;
6787                    }
6788                    var events = options.dynamicEvents.woo_paypal;
6789                    Utils.fireEventForAllPixel("onWooPayPalEvent",events)
6790
6791                });
6792
6793            }
6794
6795            // WooCommerce checkout progress
6796            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_f") ) {
6797
6798                $(document).on("change",".woocommerce-validated #billing_first_name",function () {
6799                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_f);
6800                    for (var i = 0; i < pixels.length; i++) {
6801                        var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_f[pixels[i]]);
6802                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6803                    }
6804                });
6805            }
6806            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_l")) {
6807
6808                $(document).on("change",".woocommerce-validated #billing_last_name",function () {
6809                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_l);
6810                    for (var i = 0; i < pixels.length; i++) {
6811                        var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_l[pixels[i]]);
6812                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6813                    }
6814                });
6815            }
6816
6817            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_e")) {
6818
6819                $(document).on("change",".woocommerce-validated #billing_email",function () {
6820                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_e);
6821                    for (var i = 0; i < pixels.length; i++) {
6822                    
6822    var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_e[pixels[i]]);
6823                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6824                    }
6825                });
6826            }
6827            if(options.dynamicEvents.hasOwnProperty("woo_initiate_checkout_progress_o")) {
6828                $(document).onFirst('submit click', '#place_order', function () {
6829                    var shippingMethodFull = $('[name="shipping_method[0]"]:checked').val();
6830                    var shippingMethod = shippingMethodFull ? shippingMethodFull.split(':')[0] : '';
6831                    var pixels = Object.keys(options.dynamicEvents.woo_initiate_checkout_progress_o);
6832                    for (var i = 0; i < pixels.length; i++) {
6833                        var event = Utils.clone(options.dynamicEvents.woo_initiate_checkout_progress_o[pixels[i]]);
6834                        // Add shipping_method to event params
6835                        event.params = event.params || {};
6836                        event.params.checkout_option = shippingMethod;
6837                        getPixelBySlag(pixels[i]).onWooCheckoutProgressStep(event);
6838                    }
6839                });
6840            }
6841
6842
6843            // WooCommerce
6844
6845            $('.product.type-product a.woocommerce-loop-product__link').onFirst('click', function (evt) {
6846                var productId = $(this).closest('.product').find(".add_to_cart_button").attr("data-product_id");
6847                var eventTypes = ["woo_select_content_search", "woo_select_content_shop", "woo_select_content_tag", "woo_select_content_single", "woo_select_content_category"];
6848                var isEventFired = false;
6849
6850                for (var i = 0; i < eventTypes.length; i++) {
6851                    var eventType = eventTypes[i];
6852                    if (options.dynamicEvents.hasOwnProperty(eventType) && options.dynamicEvents[eventType].hasOwnProperty(productId)) {
6853                        if(Analytics.isEnabled()){
6854                            Analytics.onWooSelectContent(options.dynamicEvents[eventType][productId][Analytics.tag()]);
6855                        }
6856                        if(GTM.isEnabled()){
6857                            GTM.onWooSelectContent(options.dynamicEvents[eventType][productId][GTM.tag()]);
6858                        }
6859                        isEventFired = true;
6860                        break;
6861                    }
6862                }
6863
6864                if (!isEventFired) {
6865                    let prod_info = $(this).parent().find('.pys_list_name_productdata').data();
6866                    if (prod_info) {
6867                        const select_prod_list = {};
6868                        if (prod_info['pys_list_name_productlist_name']) {
6869                            select_prod_list.list_name = prod_info['pys_list_name_productlist_name']
6870                        }
6871                        if (prod_info['pys_list_name_productlist_id']) {
6872                            select_prod_list.list_id = prod_info['pys_list_name_productlist_id']
6873                        }
6874                        const url = new URL(window.location.href);
6875                        select_prod_list.url = url.origin + url.pathname;
6876                        Cookies.set('select_prod_list', JSON.stringify(select_prod_list), { expires: 1,path: '/' });
6877                    }
6878                }
6879            });
6880
6881        }
6882
6883        // setup EDD events
6884        if (options.edd.enabled) {
6885
6886            // EDD AddToCart
6887            if (options.dynamicEvents.hasOwnProperty("edd_add_to_cart_on_button_click")) {
6888
6889                $('form.edd_download_purchase_form .edd-add-to-cart').on("click",function (e) {
6890
6891                    var $button = $(this);
6892                    var $form = $button.closest('form');
6893                    var variable_price = $button.data('variablePrice'); // yes/no
6894                    var price_mode = $button.data('priceMode'); // single/multi
6895                    var ids = [];
6896                    var quantities = [];
6897                    var qty;
6898                    var id;
6899
6900                    if (variable_price === 'yes' && price_mode === 'multi') {
6901
6902                        id = $form.find('input[name="download_id"]').val();
6903
6904                        // get selected variants
6905                        $.each($form.find('input[name="edd_options[price_id][]"]:checked'), function (i, el) {
6906                            ids.push(id + '_' + $(el).val());
6907                        });
6908
6909                        // get qty for selected variants
6910                        $.each(ids, function (i, variant_id) {
6911
6912                            var variant_index = variant_id.split('_', 2);
6913                            qty = $form.find('input[name="edd_download_quantity_' + variant_index[1] + '"]').val();
6914
6915                            if (typeof qty !== 'undefined') {
6916                                quantities.push(qty);
6917                            } else {
6918                                quantities.push(1);
6919                            }
6920
6921                        });
6922
6923                    } else if (variable_price === 'yes' && price_mode === 'single') {
6924
6925                        id = $form.find('input[name="download_id"]').val();
6926                        ids.push(id + '_' + $form.find('input[name="edd_options[price_id][]"]:checked').val());
6927
6928                        qty = $form.find('input[name="edd_download_quantity"]').val();
6929
6930                        if (typeof qty !== 'undefined') {
6931                            quantities.push(qty);
6932                        } else {
6933                            quantities.push(1);
6934                        }
6935
6936                    } else {
6937
6938                        ids.push($button.data('downloadId'));
6939
6940                        qty = $form.find('input[name="edd_download_quantity"]').val();
6941
6942                        if (typeof qty !== 'undefined') {
6943                            quantities.push(qty);
6944                        } else {
6945                            quantities.push(1);
6946                        }
6947                    }
6948
6949                    // fire event for each download/variant
6950                    $.each(ids, function (i, download_id) {
6951
6952                        var q = parseInt(quantities[i]);
6953                        var variant_index = download_id.toString().split('_', 2);
6954                        var price_index;
6955
6956                        if (variant_index.length === 2) {
6957                            download_id = variant_index[0];
6958                            price_index = variant_index[1];
6959                        }
6960
6961                        Facebook.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6962                        Analytics.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6963                        GTM.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6964                        GAds.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6965                        Pinterest.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6966                        Bing.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6967                        TikTok.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6968                        Reddit.onEddAddToCartOnButtonEvent(download_id, price_index, q);
6969
6970                    });
6971
6972                });
6973
6974            }
6975
6976            // EDD RemoveFromCart
6977            if (options.dynamicEvents.hasOwnProperty("edd_remove_from_cart") ) {
6978
6979                $('form#edd_checkout_cart_form .edd_cart_remove_item_btn').on("click",function (e) {
6980
6981                    var href = $(this).attr('href');
6982                    var key = href.substring(href.indexOf('=') + 1).charAt(0);
6983
6984                    if (options.dynamicEvents.edd_remove_from_cart.hasOwnProperty(key)) {
6985                        var events = options.dynamicEvents.edd_remove_from_cart[key];
6986                        Utils.fireEventForAllPixel("onEddRemoveFromCartEvent",events)
6987                    }
6988
6989                });
6990
6991            }
6992
6993        }
6994
6995        Utils.setupURLClickEvents();
6996
6997        // setup Comment Event
6998        if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")
6999        ) {
7000
7001            $('form.comment-form').on("submit",function () {
7002                if (options.dynamicEvents.hasOwnProperty("automatic_event_comment")) {
7003                    var pixels = Object.keys(options.dynamicEvents.automatic_event_comment);
7004                    for (var i = 0; i < pixels.length; i++) {
7005                        var event = Utils.clone(options.dynamicEvents.automatic_event_comment[pixels[i]]);
7006                        if ( pixels[i] !== 'tiktok' && pixels[i] !== 'reddit') {
7007                            Utils.copyProperties(Utils.getRequestParam
7007s(), event.params);
7008                        }
7009                        getPixelBySlag(pixels[i]).onCommentEvent(event);
7010                    }
7011                }
7012            });
7013
7014        }
7015
7016        // setup Form Event
7017        if ( options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
7018
7019            $(document).onFirst('submit', 'form', function (e) {
7020
7021                var $form = $(this);
7022
7023                // exclude WP forms
7024                const formClass = $form.attr('class') || '';
7025                const formRole = ($form.attr('role') || '').toLowerCase();
7026                const formId = $form.attr('id');
7027
7028                if (
7029                    $form.hasClass('comment-form') ||
7030                    $form.hasClass('search-form') ||
7031                    $form.hasClass('woocommerce-ordering') ||
7032                    formClass.toLowerCase().includes('search') || formClass.toLowerCase().includes('add-to-cart') ||
7033                    formRole === 'search' ||
7034                    formId === 'adminbarsearch'
7035                ) {
7036                    return;
7037                }
7038
7039                // exclude Woo forms
7040                if ($form.hasClass('woocommerce-product-search') || $form.hasClass('cart') || $form.hasClass('woocommerce-cart-form') ||
7041                    $form.hasClass('woocommerce-shipping-calculator') || $form.hasClass('checkout') || $form.hasClass('checkout_coupon')) {
7042                    return;
7043                }
7044
7045                // exclude EDD forms
7046                if ($form.hasClass('edd_form') || $form.hasClass('edd_download_purchase_form')) {
7047                    return;
7048                }
7049                // exclude CF7 forms
7050                if ($form.hasClass('wpcf7-form')) {
7051                    return;
7052                }
7053                // exclude Gravity forms
7054                if ($form.attr('id') && $form.attr('id').includes('gform')) {
7055                    var target = $form.attr('target');
7056                    if (target && target.indexOf('gform_ajax_frame') !== -1) {
7057                        return;
7058                    }
7059                }
7060                // exclude Forminator forms
7061                if ($form.hasClass('forminator-custom-form') || $form.hasClass('forminator_ajax')) {
7062                    return;
7063                }
7064                // exclude WPforms forms
7065                if ($form.hasClass('wpforms-form') || $form.hasClass('wpforms-ajax-form')) {
7066                    return;
7067                }
7068                // exclude Formidable forms
7069                /*if ($form.hasClass('frm-show-form')) {
7070                    return;
7071                }*/
7072                // exclude Ninja Forms forms
7073                if ($form.parent().hasClass('nf-form-layout')) {
7074                    return;
7075                }
7076                // exclude Fluent forms
7077                if ($form.hasClass('frm-fluent-form')) {
7078                    return;
7079                }
7080
7081                // exclude WS form forms
7082                if ($form.hasClass('wsf-form') ) {
7083                    return;
7084                }
7085
7086                // exclude WS form forms
7087                if ( $form.hasClass( 'elementor-form' ) ) {
7088                    return;
7089                }
7090
7091                if(!options.enable_success_send_form) {
7092                    var params = {
7093                        form_id: $form.attr('id'),
7094                        form_class: $form.attr('class') ? $form.attr('class') : $form.attr('id'),
7095                        text: $form.find('[type="submit"]').is('input') ?
7096                            $form.find('[type="submit"]').val() : $form.find('[type="submit"]').text()
7097                    };
7098
7099                    if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
7100                        var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
7101                        for (var i = 0; i < pixels.length; i++) {
7102                            var event = Utils.clone(options.dynamicEvents.automatic_event_form[pixels[i]]);
7103
7104                            if (pixels[i] === "tiktok" || pixels[i] === "reddit") {
7105                                getPixelBySlag(pixels[i]).fireEvent(event.name, event);
7106                            } else {
7107                                Utils.copyProperties(params, event.params,)
7108                                Utils.copyProperties(Utils.getRequestParam
7108s(), event.params);
7109                                getPixelBySlag(pixels[i]).onFormEvent(event);
7110                            }
7111                        }
7112                    }
7113                }
7114            });
7115
7116
7117        }
7118
7119        jQuery(document).on('elementor/popup/show', function(event) {
7120            for (var i = 0; i < jQuery(".wpcf7-form").length; i++) {
7121                wpcf7.init(jQuery(".wpcf7-form")[i]);
7122            }
7123        });
7124
7125        document.addEventListener( 'wpcf7mailsent', function ( event ) {
7126            let form_id = event.detail.contactFormId,
7127                sendEventId = null,
7128                disabled_form_action = false,
7129                form_submit_mode = 'both';
7130            if ( options.triggerEventTypes.hasOwnProperty( 'CF7' ) ) {
7131                $.each( options.triggerEventTypes.CF7, function ( eventId, triggers ) {
7132                    $.each( triggers, function ( index, trigger ) {
7133                        $.each( trigger.forms, function ( i, value ) {
7134                            if ( value == form_id ) {
7135                                sendEventId = eventId;
7136                                disabled_form_action = trigger.disabled_form_action;
7137                                form_submit_mode = trigger.form_submit_mode || 'both';
7138                            }
7139                        } )
7140                    } );
7141                } );
7142            }
7143            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7144                Utils.fireTriggerEvent( sendEventId );
7145            }
7146            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7147
7148        }, false );
7149
7150        //GravityForm
7151        jQuery( document ).on( 'gform_confirmation_loaded', function ( event, formId ) {
7152            let form_id = formId,
7153                sendEventId = null,
7154                disabled_form_action = false,
7155                form_submit_mode = 'both';
7156            if ( options.triggerEventTypes.hasOwnProperty( 'gravity' ) ) {
7157                $.each( options.triggerEventTypes.gravity, function ( eventId, triggers ) {
7158                    $.each( triggers, function ( index, trigger ) {
7159                        $.each( trigger.forms, function ( i, value ) {
7160                            if ( value == form_id ) {
7161                                disabled_form_action = trigger.disabled_form_action;
7162                                sendEventId = eventId;
7163                                form_submit_mode = trigger.form_submit_mode || 'both';
7164                            }
7165                        } )
7166                    } );
7167                } );
7168            }
7169
7170            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7171                Utils.fireTriggerEvent( sendEventId );
7172            }
7173            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7174            jQuery( document ).off( 'gform_confirmation_loaded' );
7175        } );
7176        //Forminator
7177        $( document ).on( 'forminator:form:submit:success', function ( event ) {
7178
7179            let form_id = $( event.target ).find( 'input[name="form_id"]' ).val(),
7180                sendEventId = null,
7181                disabled_form_action = false,
7182                form_submit_mode = 'both';
7183            if ( options.triggerEventTypes.hasOwnProperty( 'forminator' ) ) {
7184                $.each( options.triggerEventTypes.forminator, function ( eventId, triggers ) {
7185                    $.each( triggers, function ( index, trigger ) {
7186                        $.each( trigger.forms, function ( i, value ) {
7187                            if ( value == form_id ) {
7188                                disabled_form_action = trigger.disabled_form_action;
7189                                sendEventId = eventId;
7190                                form_submit_mode = trigger.form_submit_mode || 'both';
7191                            }
7192                        } )
7193                    } );
7194                } );
7195            }
7196            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7197                Utils.fireTriggerEvent( sendEventId );
7198            }
7199            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7200        } );
7201
7202        //WPForm
7203        $( 'form.wpforms-form' ).on( 'wpformsAjaxSubmitSuccess', ( event ) => {
7204
7205            let form_id = $( event.target ).attr( 'data-formid' ),
7206                sendEventId = null,
7207                disabled_form_action = false,
7208                form_submit_mode = 'both';
7209
7210            if ( options.triggerEventTypes.hasOwnProperty( 'wpforms' ) ) {
7211                $.each( options.triggerEventTypes.wpforms, function ( eventId, triggers ) {
7212                    $.each( triggers, function ( index, trigger ) {
7213                        $.each( trigger.forms, function ( i, value ) {
7214                            if ( value == form_id ) {
7215                                sendEventId = eventId;
7216                                disabled_form_action = trigger.disabled_form_action;
7217                                form_submit_mode = trigger.form_submit_mode || 'both';
7218                            }
7219                        } )
7220                    } );
7221                } );
7222            }
7223            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7224                Utils.fireTriggerEvent( sendEventId );
7225            }
7226            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7227        } )
7228
7229        $( document ).on( 'frmFormComplete', function ( event, form, response ) {
7230            const form_id = $( form ).find( 'input[name="form_id"]' ).val();
7231            let sendEventId = null,
7232                disabled_form_action = false,
7233                form_submit_mode = 'both';
7234            if ( options.triggerEventTypes.hasOwnProperty( 'formidable' ) ) {
7235                $.each( options.triggerEventTypes.formidable, function ( eventId, triggers ) {
7236                    $.each( triggers, function ( index, trigger ) {
7237                        $.each( trigger.forms, function ( i, value ) {
7238                            if ( value == form_id ) {
7239                                disabled_form_action = trigger.disabled_form_action;
7240                                sendEventId = eventId;
7241                                form_submit_mode = trigger.form_submit_mode || 'both';
7242                            }
7243                        } )
7244                    } );
7245                } );
7246            }
7247            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7248                Utils.fireTriggerEvent( sendEventId );
7249            }
7250            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7251
7252        } );
7253
7254        // Ninja Forms
7255        $( document ).onFirst( 'nfFormSubmitResponse', function ( event, data ) {
7256            const form_id = data.response.data.form_id;
7257            let sendEventId = null,
7258                disabled_form_action = false,
7259                form_submit_mode = 'both';
7260            if ( options.triggerEventTypes.hasOwnProperty( 'ninjaform' ) ) {
7261                $.each( options.triggerEventTypes.ninjaform, function ( eventId, triggers ) {
7262                    $.each( triggers, function ( index, trigger ) {
7263                        $.each( trigger.forms, function ( i, value ) {
7264                            if ( value == form_id ) {
7265                                disabled_form_action = trigger.disabled_form_action;
7266                                sendEventId = eventId;
7267                                form_submit_mode = trigger.form_submit_mode || 'both';
7268                            }
7269                        } )
7270                    } );
7271                } );
7272            }
7273            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7274                Utils.fireTriggerEvent( sendEventId );
7275            }
7276            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7277        } );
7278
7279
7280        $(document).on('fluentform_submission_success', function ( event, data ) {
7281            if(!data || !data.form){
7282                return;
7283            }
7284            let $form = data.form; // Submitted form
7285            let config = data.config; // Form configuration
7286            let response = data.response; // Server response
7287
7288
7289            let $formItem = $form;
7290            let form_id = config.id;
7291            let sendEventId = null,
7292                disabled_form_action = false,
7293                form_submit_mode = 'both';
7294            if ( options.triggerEventTypes.hasOwnProperty( 'fluentform' ) ) {
7295                $.each( options.triggerEventTypes.fluentform, function ( eventId, triggers ) {
7296                    $.each( triggers, function ( index, trigger ) {
7297                        $.each( trigger.forms, function ( i, value ) {
7298                            if ( value == form_id ) {
7299                                disabled_form_action = trigger.disabled_form_action;
7300                                sendEventId = eventId;
7301                                form_submit_mode = trigger.form_submit_mode || 'both';
7302                            }
7303                        } )
7304                    } );
7305                } );
7306            }
7307
7308            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7309                Utils.fireTriggerEvent( sendEventId );
7310            }
7311            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7312        } );
7313
7314        //WSForm
7315        $( document ).on( 'wsf-submit-complete', ( event, form_object, form_id ) => {
7316            let sendEventId = null,
7317                disabled_form_action = false,
7318                form_submit_mode = 'both';
7319            if ( options.triggerEventTypes.hasOwnProperty( 'wsform' ) ) {
7320                $.each( options.triggerEventTypes.wsform, function ( eventId, triggers ) {
7321                    $.each( triggers, function ( index, trigger ) {
7322                        $.each( trigger.forms, function ( i, value ) {
7323                            if ( value == form_id ) {
7324                                disabled_form_action = trigger.disabled_form_action;
7325                                sendEventId = eventId;
7326                                form_submit_mode = trigger.form_submit_mode || 'both';
7327                            }
7328                        } )
7329                    } );
7330                } );
7331            }
7332
7333            if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7334                Utils.fireTriggerEvent( sendEventId );
7335            }
7336            sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7337        } )
7338
7339        // Elementor Forms
7340        let forms = document.querySelectorAll( '.elementor-form' );
7341        // Apply the observer to each form
7342        forms.forEach( function ( form ) {
7343            observeElementorForm( form );
7344        } );
7345
7346        // watching Elementor Popup forms
7347        let observer = new MutationObserver( function ( mutationsList, observer ) {
7348            for ( let i = 0; i < mutationsList.length; i++ ) {
7349                let popupForm = document.querySelector( '[class*="elementor-popup"] form' );
7350                if ( popupForm ) {
7351                    observeElementorForm( popupForm );
7352                    observer.disconnect();
7353                    break;
7354                }
7355            }
7356        } );
7357        observer.observe( document.body, { childList: true, subtree: true } );
7358
7359        // load pixel APIs
7360        Utils.loadPixels();
7361
7362        // setup Enrich content
7363        if(Utils.isCheckoutPage()) {
7364            Utils.addCheckoutFields();
7365        }
7366        if(options.woo.hasOwnProperty('woo_view_content_variation_is_selected') && options.woo.woo_view_content_variation_is_selected) {
7367            handleWooViewContentVariation()
7368        }
7369
7370    });
7371
7372
7373    function handleWooViewContentVariation() {
7374        var form = $('form.variations_form');
7375
7376        form.on('change', 'select', function() {
7377            var selectedAttributes = {};
7378            form.find('select').each(function() {
7379                var attributeName = $(this).data('attribute_name') || $(this).attr('name');
7380                var attributeValue = $(this).val();
7381                if (attributeValue) {
7382                    selectedAttributes[attributeName] = attributeValue;
7383                }
7384            });
7385
7386            $.ajax({
7387                url: options.ajaxUrl,
7388                type: 'POST',
7389                data: {
7390                    action: 'get_variation_info',
7391                    product_id: form.data('product_id'), // Передаем ID основного товара
7392                    attributes: selectedAttributes
7393                },
7394                success: function(response) {
7395                    if (response.success) {
7396                        $.each(response.data, function(slug) {
7397                            $.each(response.data[slug], function(index, event) {
7398                                event.isVariationTrigger = true;
7399                                getPixelBySlag(slug).fireEvent(event.name, event);
7400                            });
7401                        });
7402                    } else {
7403                        console.log('Error retrieving data:', response.data);
7404                    }
7405                }
7406            });
7407        });
7408    }
7409    var sendFormAction = function (form_target, formId, customEventId = null, disabled = false, form_submit_mode = 'both'){
7410        // Check submit mode - skip automatic event if reload_only
7411        if (disabled == true || form_submit_mode === 'reload_only' ) {
7412            return;
7413        }
7414        
7415        var params = {
7416            form_id: formId,
7417            text: form_target.find('[type="submit"]').is('input') ? form_target.find('[type="submit"]').val() :
7418                form_target.find('.forminator-button-submit').text() != '' ? form_target.find('.forminator-button-submit').text() :
7419                    form_target.find('[type="submit"]').text()
7420        };
7421
7422        if (options.dynamicEvents.hasOwnProperty("automatic_event_form")) {
7423            var pixels = Object.keys(options.dynamicEvents.automatic_event_form);
7424            for (var i = 0; i < pixels.length; i++) {
7425
7426                if ( disabled && customEventId && typeof options.triggerEvents[customEventId][pixels[i]] !== 'undefined') {
7427                    continue;
7428                }
7429                var event = options.dynamicEvents.automatic_event_form[pixels[i]];
7430                if (pixels[i] === "tiktok" || pixels[i] === "reddit") {
7431                    getPixelBySlag(pixels[i]).fireEvent(event.name, event);
7432                } else {
7433                    Utils.copyProperties(params, event.params)
7434                    Utils.copyProperties(Utils.getRequestParams(), event.params);
7435                    getPixelBySlag(pixels[i]).onFormEvent(event);
7436                }
7437            }
7438        }
7439    }
7440
7441    var setupEmailLinks = function ( disabled_for_pixels = [] ) {
7442        if ( options.dynamicEvents.hasOwnProperty( "automatic_event_email_link" ) ) {
7443            var pixels = Object.keys( options.dynamicEvents.automatic_event_email_link );
7444            for ( var i = 0; i < pixels.length; i++ ) {
7445                if ( disabled_for_pixels.indexOf(pixels[ i ]) === -1 ) {
7446                    var event = Utils.clone( options.dynamicEvents.automatic_event_email_link[ pixels[ i ] ] );
7447                    if ( pixels[ i ] !== 'tiktok' && pixels[ i ] !== 'reddit' ) {
7448                        Utils.copyProperties( Utils.getRequestParams(), event.params );
7449                    }
7450                    getPixelBySlag( pixels[ i ] ).fireEvent( event.name, event );
7451                }
7452            }
7453        }
7454    }
7455
7456    //Elementor Forms Observer
7457    var observeElementorForm = function ( form ) {
7458        let observer = new MutationObserver( function ( mutations ) {
7459
7460            for ( let i = 0; i < mutations.length; i++ ) {
7461                let mutation = mutations[ i ];
7462
7463                if ( mutation.type === 'childList' || mutation.type === 'attributes' ) {
7464                    if ( $( form ).find( '.elementor-message-success' ).length > 0 ) {
7465
7466                        let form_id = $( form ).attr( 'id' );
7467                        if ( !form_id ) {
7468                            form_id = $( form ).find( 'input[name="form_id"]' ).val();
7469                        }
7470
7471                        let sendEventId = null,
7472                            disabled_form_action = false,
7473                            form_submit_mode = 'both';
7474                        if ( options.triggerEventTypes.hasOwnProperty( 'elementor_form' ) ) {
7475                            $.each( options.triggerEventTypes.elementor_form, function ( eventId, triggers ) {
7476                                $.each( triggers, function ( index, trigger ) {
7477                                    $.each( trigger.forms, function ( i, value ) {
7478                                        if ( value == form_id ) {
7479                                            disabled_form_action = trigger.disabled_form_action;
7480                                            sendEventId = eventId;
7481                                            form_submit_mode = trigger.form_submit_mode || 'both';
7482                                        }
7483                                    })
7484                                } );
7485                            } );
7486                        }
7487                        if ( sendEventId != null && ( form_submit_mode === 'both' || form_submit_mode === 'ajax_only' ) ) {
7488                            Utils.fireTriggerEvent( sendEventId );
7489                        }
7490                        sendFormAction( $( event.target ), form_id, sendEventId, disabled_form_action, form_submit_mode );
7491
7492                        observer.disconnect();
7493                        break;
7494                    }
7495                }
7496            }
7497        } );
7498
7499        // Start observing the form for changes
7500        observer.observe( form, {
7501            attributes: true,
7502            childList: true,
7503            subtree: true
7504        } );
7505    }
7506
7507}(jQuery, pysOptions);
7508
7509
7510function pys_generate_token() {
7511    return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
7512        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
7513    );
7514}
7515function getBundlePriceOnSingleProduct(data) {
7516    var items_sum = 0;
7517    jQuery(".bundle_form .bundled_product").each(function(index){
7518        var id = jQuery(this).find(".cart").data("bundled_item_id");
7519        var item_price = data.prices[id];
7520        var item_quantity = jQuery(this).find(".bundled_qty").val();
7521        if(!jQuery(this).hasClass("bundled_item_optional") ||
7522            jQuery(this).find(".bundled_product_optional_checkbox input").prop('checked')) {
7523            items_sum += item_price*item_quantity;
7524        }
7525    });
7526    return items_sum;
7527}
7528function getUrlParameter(sParam) {
7529    var sPageURL = window.location.search.substring(1),
7530        sURLVariables = sPageURL.split('&'),
7531        sParameterName,
7532        i;
7533
7534    for (i = 0; i < sURLVariables.length; i++) {
7535        sParameterName = sURLVariables[i].split('=');
7536
7537        if (sParameterName[0] === sParam) {
7538            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
7539        }
7540    }
7541    return false;
7542};
7543function inArray(needle, haystack) {
7544    var length = haystack.length;
7545    for(var i = 0; i < length; i++) {
7546        if(haystack[i] == needle) return true;
7547    }
7548    return false;
7549}
7550
7551function getCookieYes(key) {
7552    const cookiesObj = document.cookie
7553        .split(";")
7554        .reduce((ac, cv) => {
7555            const [k, v] = cv.split("=");
7556            if (k && v) ac[k.trim()] = v;
7557            return ac;
7558        }, {});
7559    const consentCookie = cookiesObj["cookieyes-consent"] || cookiesObj["wt_consent"];
7560    if (!consentCookie) return undefined;
7561    const { [key]: value } = consentCookie
7562        .split(",")
7563        .reduce((obj, pair) => {
7564            const [k, v] = pair.split(":");
7565            if (k && v) obj[k] = v;
7566            return obj;
7567        }, {});
7568    return value;
7569}
7570
7571function getRootDomain(useSubdomain = false) {
7572    const hostname = window.location.hostname; // Get the current hostname
7573    // Check if tldjs is defined before using it
7574    if (typeof tldjs === "undefined") {
7575        console.warn("tldjs is not defined");
7576        return hostname; // Return hostname as a fallback
7577    }
7578
7579    const rootDomain = tldjs.getDomain(hostname); // Use tldjs to extract the root domain
7580
7581    // Return the root domain with or without a leading dot based on useSubdomain
7582    return rootDomain ? (useSubdomain ? '.' + rootDomain : rootDomain) : hostname;
7583}

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.