PageSourceSearch

https://cloudytees.com/wp-content/plugins/pixelyoursite-pro/dist/scripts/public.js?ver=12.4.1.1

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

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.