HEX
Server: Apache/2.4.65 (Debian)
System: Linux 88f31f35b0b8 6.1.0-38-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.147-1 (2025-08-02) x86_64
User: www-data (33)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/plugins/advanced-ads-pro/src/js/advanced-ads-pro.js
/* eslint-disable */
( function ( $ ) {
	// CFP cookies prefix
	var cname = 'advads_procfp';
	var cname_vc = 'advanced_ads_ad_clicks'; // visitor conditions

	// CFP cookies parameter ( domain/path )
	var PATH = null;
	var DOMAIN = null;

	/**
	 * wrapper for JSON.parse
	 */
	function jsonDecode( str ) {
		try {
			var res = JSON.parse( str );
			return res;
		} catch ( Ex ) {
			return null;
		}
	}

	// Max ad click conditions/ passive Cache busting.

	$( document ).on( 'advads-passive-cb-conditions', function ( e, cbs ) {
		cbs.conditions[ 'ad_clicks' ] = 'check_ad_clicks';
		cbs[ 'check_ad_clicks' ] = function ( options, ad ) {
			if ( advads.cookie_exists( cname_vc + '_' + ad.id ) ) {
				var C_vc = advads.get_cookie( cname_vc + '_' + ad.id );
				C_vc = jsonDecode( C_vc );
			}

			if ( C_vc ) {
				var now = parseInt( new Date().getTime() / 1000 );
				for ( var i in C_vc ) {
					if ( '_' + options.expiration == i ) {
						// if still valid counter and click limit reached
						if (
							C_vc[ i ][ 'ttl' ] >= now &&
							C_vc[ i ][ 'count' ] >= parseInt( options.limit )
						) {
							return false;
						}
					}
				}
			}

			return true;
		};
	} );

	var cfpTracker = function () {
		this.$elements = {};
		this.currentIFrame = false;
		this.focusLost = false;
		this.wrappers = [ '.google-auto-placed' ];
		this.attributes = {
			'data-anchor-status': 'displayed',
			'data-vignette-loaded': 'true',
		};
		this.lastClick = 0;
		this.init();
	};

	cfpTracker.prototype = {
		constructor: cfpTracker,

		init: function () {
			const that = this;
			let touchmoved;

			// increment counter on click on link
			$( document ).on( 'click', 'a[data-cfpa]', function () {
				that.onClick( parseInt( $( this ).attr( 'data-cfpa' ) ) );
			} );

			// Increment counter on blur only if an iframe has recently been hovered.
			$( window ).on( 'blur', function ( e ) {
				// Use timeout of 0 ms as a workaround to make sure that the active element has changed correctly.
				setTimeout( function () {
					if ( ! that.currentIFrame ) {
						// Loop parent nodes from the target to the delegation node to recognise iframe clicks.
						for (
							let target = document.activeElement;
							target && target !== this && target !== document;
							target = target.parentNode
						) {
							that.currentIFrame = that.checkWrappers( target );
							if ( that.currentIFrame ) {
								break;
							}
						}
					}

					if ( that.currentIFrame ) {
						that.onClick( that.currentIFrame );
						that.focusLost = true;
						top.focus();
					}
				}, 0 );
			} );

			// mouse passes over an ad that has not yet been initialized (adsense and other distant ads - OR just an ad that contains no link nor iframes)
			$( document ).on( 'mouseenter', 'div[data-cfpa]', function () {
				var id = parseInt( $( this ).attr( 'data-cfpa' ) );
				that.addElement( id );
			} );

			// Detect swipe and click on mobile devices.
			document.addEventListener(
				'touchmove',
				function () {
					touchmoved = true;
				},
				false
			);
			document.addEventListener(
				'touchstart',
				function () {
					touchmoved = false;
				},
				false
			);

			// Detect desktop and mobile clicks.
			[ 'click', 'touchend' ].forEach( function ( event ) {
				document.addEventListener( event, function ( e ) {
					// Prevent swipes and simultaneous clicks on wrapper and element as well as fast clicks in a row
					if (
						touchmoved ||
						that.getTimestamp() - that.lastClick < 1
					) {
						return;
					}
					let adId = null;
					// Loop parent nodes from the target to the delegation node.
					for (
						let target = e.target;
						target && target !== this && target !== document;
						target = target.parentNode
					) {
						// Loop all predefined wrappers to detect clicks on Google Auto Ads iframes.
						adId = that.checkWrappers( target );
						if ( adId ) {
							that.onClick( adId );
							break;
						}

						// Check if clicked element is a cfp wrapper.
						if (
							target.hasAttribute( 'data-cfpa' ) &&
							target.hasAttribute( 'data-cfptl' )
						) {
							adId = parseInt(
								target.getAttribute( 'data-cfpa' ),
								10
							);
							that.onClick( adId );
							break;
						}
					}
				} );
			} );
		},

		/**
		 * Create current timestamp
		 *
		 * @return {number}
		 */
		getTimestamp: function () {
			return Math.floor( Date.now() / 1000 );
		},

		/**
		 * Check if target element is a predefined wrapper or has Google Auto Ads attributes.
		 *
		 * @param target
		 * @returns {string|null}
		 */
		checkWrappers: function ( target ) {
			for (
				let i = 0,
					wrappersLength = this.wrappers.length,
					selector = null;
				i < wrappersLength;
				i++
			) {
				selector = this.wrappers[ i ];
				if ( target.matches && target.matches( selector ) ) {
					return selector === '.google-auto-placed'
						? 'google-auto-placed'
						: null;
				}
			}
			for ( const [ key, value ] of Object.entries( this.attributes ) ) {
				if (
					target.hasAttribute( key ) &&
					target.getAttribute( key ) === value
				) {
					return 'google-auto-placed';
				}
			}
			return null;
		},

		addElement: function ( $el ) {
			if ( false === $el instanceof jQuery ) {
				// Select the first ad since there may be multiple copies of the same ad on the page.
				$el = $( 'div[data-cfpa="' + $el + '"]' ).first();
			}

			var hasIframe = $el.find( 'iframe' ).length ? true : false;
			if ( ! hasIframe ) {
				if ( ! $el.find( 'a' ).length ) {
					// no an anchor and no iframe -- likely and ad that is not yet loaded (adsense or other ad network)
					return;
				}
			}

			var adID = parseInt( $el.attr( 'data-cfpa' ) );

			this.$elements[ adID ] = $el;

			// remove attribute from the wrapper
			$el.removeAttr( 'data-cfpa' );

			// And then move it to the first anchor or iframe found
			if ( hasIframe ) {
				$el.find( 'iframe' ).first().attr( {
					'data-cfpa': adID,
				} );
				if ( $el.attr( 'data-cfph' ) ) {
					$el.find( 'iframe' )
						.first()
						.attr( {
							'data-cfph': $el.attr( 'data-cfph' ),
						} );
				}
			} else {
				$el.find( 'a' ).not( '.advads-edit-button' ).first().attr( {
					'data-cfpa': adID,
				} );
				if ( $el.attr( 'data-cfph' ) ) {
					$el.find( 'a' )
						.not( '.advads-edit-button' )
						.first()
						.attr( {
							'data-cfph': $el.attr( 'data-cfph' ),
						} );
				}
			}
			// remove Hours attribute from the wrapper
			$el.removeAttr( 'data-cfph' );

			// update TTL field for all outdated counter (visitor conditions)
			if ( advads.cookie_exists( cname_vc + '_' + adID ) ) {
				var C_vc = advads.get_cookie( cname_vc + '_' + adID );
				C_vc = jsonDecode( C_vc );

				if ( C_vc ) {
					var now = parseInt( new Date().getTime() / 1000 ),
						cookie_modified = false;
					for ( var i in C_vc ) {
						if ( ! C_vc.hasOwnProperty( i ) ) continue;
						if ( 'exp' == i ) continue;
						if ( C_vc[ i ][ 'ttl' ] < now ) {
							var period = parseFloat( i.substr( 1 ) );
							var newTTL = C_vc[ i ][ 'ttl' ];
							while ( newTTL < now ) {
								newTTL += period * 60 * 60;
							}
							C_vc[ i ][ 'ttl' ] = newTTL;
							C_vc[ i ][ 'count' ] = 0;
							cookie_modified = true;
						}
					}
					if ( cookie_modified ) {
						var expTime = new Date( C_vc[ 'exp' ] );
						advads.set_cookie_sec(
							cname_vc + '_' + adID,
							JSON.stringify( C_vc, 'false', false ),
							parseInt( expTime.getTime() / 1000 ),
							PATH,
							DOMAIN
						);
					}
				}
			}
		},

		/**
		 * Ban the visitor
		 */
		_banVisitor: function () {
			var now = new Date();
			var d = new Date();
			d.setTime(
				d.getTime() + advadsCfpInfo.cfpBan * 24 * 60 * 60 * 1000
			);
			var ban = ( d.getTime() - now.getTime() ) / 1000;
			advads.set_cookie_sec( 'advads_pro_cfp_ban', 1, ban, PATH, DOMAIN );

			// Select ad wrappers and delete them.
			document
				.querySelectorAll( '[data-cfpw]:not([data-cfp-exclude])' )
				.forEach( function ( el ) {
					el.remove();
				} );

			this.removeEmptyWrappers();

			// Select Google AdSense Auto Ads and delete them.
			this.wrappers.forEach( function ( wrapper ) {
				jQuery( wrapper ).remove();
			} );
			for ( const [ key, value ] of Object.entries( this.attributes ) ) {
				jQuery( '[' + key + '="' + value + '"]' ).remove();
			}
		},

		/**
		 * Remove top-level wrappers that do not contain ads.
		 */
		removeEmptyWrappers: function () {
			// Select top-level wrappers that are not ads.
			document
				.querySelectorAll( '[data-cfptl]:not([data-cfpw])' )
				.forEach( function ( el ) {
					// If there are no nested ads, remove the top-level wrapper.
					if ( ! el.querySelectorAll( '[data-cfpw]' ).length ) {
						el.remove();
					}
				} );
		},

		/**
		 * Click handler.
		 *
		 * @param {string} ID Ad id.
		 */
		onClick: function ( ID ) {
			var that = this,
				// Module wide cookie
				cookieVisitor = false,
				// Visitor condition cookie.
				cookieVisitorCondition = false;
			this.lastClick = this.getTimestamp();

			if (
				'google-auto-placed' !== ID &&
				$( '[data-cfpa="' + ID + '"]' ).attr( 'data-cfph' )
			) {
				// if there are some visitor conditions, use the vc cookie
				if ( advads.cookie_exists( cname_vc + '_' + ID ) ) {
					cookieVisitorCondition = jsonDecode(
						advads.get_cookie( cname_vc + '_' + ID )
					);
				}

				const clickLimits = jsonDecode(
					$( '[data-cfpa="' + ID + '"]' ).attr( 'data-cfph' )
				);

				if ( cookieVisitorCondition ) {
					// Cookie already exists, increment each counter (keep expiration time)
					const nowInSeconds = parseInt(
						new Date().getTime() / 1000,
						10
					);
					const adWrapper = document.querySelectorAll(
						'[data-cfpw="' + ID + '"]'
					);

					for ( var h in cookieVisitorCondition ) {
						if ( ! cookieVisitorCondition.hasOwnProperty( h ) ) {
							continue;
						}
						if ( h === 'exp' ) {
							// Ignore the key that contains expiration date.
							continue;
						}

						cookieVisitorCondition[ h ][ 'count' ] =
							parseInt(
								cookieVisitorCondition[ h ][ 'count' ],
								10
							) + 1;

						if (
							cookieVisitorCondition[ h ][ 'ttl' ] >=
								nowInSeconds &&
							cookieVisitorCondition[ h ][ 'count' ] >=
								parseInt( clickLimits[ h ], 10 )
						) {
							adWrapper.forEach( function ( node ) {
								node.remove();
							} );
							// If the ad was wrapper with a top-level wrapper, try to remove it.
							that.removeEmptyWrappers();
						}
					}
					var now = new Date();
					var expiry = new Date( cookieVisitorCondition.exp );
					var expirySecs = parseInt(
						( expiry.getTime() - now.getTime() ) / 1000
					);
					advads.set_cookie_sec(
						cname_vc + '_' + ID,
						JSON.stringify(
							cookieVisitorCondition,
							'false',
							false
						),
						expirySecs,
						PATH,
						DOMAIN
					);
				} else {
					// create a new cookie
					var cval = {},
						maxHValue = 0;

					var d = new Date();
					var now = new Date();

					for ( var h in clickLimits ) {
						h = h.substring( 1 );
						if ( parseFloat( h ) > maxHValue ) {
							maxHValue = parseFloat( h );
						}
						cval[ '_' + h ] = {
							count: 1,
							ttl: parseInt(
								now.getTime() / 1000 + parseFloat( h ) * 3600,
								10
							),
						};
					}

					// use the longest hour value for the expiry time
					d.setTime( d.getTime() + maxHValue * 60 * 60 * 1000 );
					var expires = 'expires=' + d.toUTCString();
					var expirySecs = parseInt(
						( d.getTime() - now.getTime() ) / 1000
					);

					cval[ 'exp' ] = expires;
					advads.set_cookie_sec(
						cname_vc + '_' + ID,
						JSON.stringify( cval, 'false', false ),
						expirySecs,
						PATH,
						DOMAIN
					);
					if (
						1 === clickLimits[ Object.keys( clickLimits )[ 0 ] ]
					) {
						document
							.querySelectorAll( '[data-cfpw="' + ID + '"]' )
							.forEach( function ( node ) {
								node.remove();
							} );
						this.removeEmptyWrappers();
					}
				}
			}

			if ( '1' !== advadsCfpInfo.cfpEnabled ) {
				return;
			}

			// use the module wide CFP cookie
			if ( advads.cookie_exists( cname + '_' + ID ) ) {
				cookieVisitor = jsonDecode(
					advads.get_cookie( cname + '_' + ID )
				);
			}

			if ( cookieVisitor ) {
				// Cookie already exists, increment the counter (keep expiration time)
				cookieVisitor.count = parseInt( cookieVisitor.count, 10 ) + 1;
				var now = new Date();
				var expiry = new Date( cookieVisitor.exp );
				var expirySecs = ( expiry.getTime() - now.getTime() ) / 1000;
				advads.set_cookie_sec(
					cname + '_' + ID,
					JSON.stringify( cookieVisitor, 'false', false ),
					expirySecs,
					PATH,
					DOMAIN
				);
				if (
					parseInt( advadsCfpInfo.cfpClickLimit, 10 ) <=
					cookieVisitor.count
				) {
					// CFP module enabled - ban this visitor
					that._banVisitor();
				}
			} else {
				// create a new cookie
				var d = new Date();
				var now = new Date();
				d.setTime(
					d.getTime() +
						parseInt( advadsCfpInfo.cfpExpHours, 10 ) *
							60 *
							60 *
							1000
				);
				var expires = 'expires=' + d.toUTCString();
				var expirySecs = ( d.getTime() - now.getTime() ) / 1000;
				advads.set_cookie_sec(
					cname + '_' + ID,
					'{"count":1,"exp":"' + expires + '"}',
					expirySecs,
					PATH,
					DOMAIN
				);
				if ( parseInt( advadsCfpInfo.cfpClickLimit, 10 ) === 1 ) {
					// CFP module enabled - ban this visitor
					that._banVisitor();
				}
			}
		},
	};

	$( function () {
		/**
		 * Max ad click ( visitor conditions )
		 */
		window.advadsProCfp = new cfpTracker();

		// IFRAME click tracking
		$( document )
			.on( 'mouseenter', 'iframe[data-cfpa]', function ( e ) {
				var ID = parseInt( $( this ).attr( 'data-cfpa' ) );
				advadsProCfp.currentIFrame = ID;
			} )
			.on( 'mouseenter', '.google-auto-placed', function ( e ) {
				// Use the same ID for all Google AdSense Auto Ads.
				advadsProCfp.currentIFrame = 'google-auto-placed';
			} )
			.on(
				'mouseleave mouseout',
				'[data-cfpa], .google-auto-placed',
				function () {
					advadsProCfp.currentIFrame = false;
					if ( advadsProCfp.focusLost ) {
						advadsProCfp.focusLost = false;
						$( window ).trigger( 'focus' );
					}
				}
			);

		// construct all elements already present in the queue
		for ( var i in advadsCfpQueue ) {
			if ( advadsCfpQueue.hasOwnProperty( i ) ) {
				advadsProCfp.addElement( advadsCfpQueue[ i ] );
			}
		}

		advadsCfpQueue = [];

		/**
		 * Click fraud protection module.
		 */
		if ( 'undefined' == typeof window.advadsCfpInfo.cfpPath ) return;

		// get the path/domain parameter to use in cookies
		if ( '' != advadsCfpInfo.cfpPath ) {
			PATH = advadsCfpInfo.cfpPath;
		}

		if ( '' != advadsCfpInfo.cfpDomain ) {
			DOMAIN = advadsCfpInfo.cfpDomain;
		}
	} );
} )( window.jQuery );

/**
 * Reload on resize.
 */
var advanced_ads_resizetimeout = 1000; // time to wait until resized window width is saved, in millisec
var advanced_ads_cookieexpires = 30; // days until the cookie expires
var advanced_ads_browser_width = advanced_ads_get_browser_width();

// Save browserWidth in a cookie if not set or not equal to current saved width.
if ( window.advads !== undefined ) {
	var cookieValue = advads.get_cookie( 'advanced_ads_visitor' );
	var info = cookieValue ? JSON.parse( cookieValue ) : {};

	if (
		! info.browser_width ||
		info.browser_width !== advanced_ads_browser_width
	) {
		advanced_ads_save_width( advanced_ads_browser_width );
	}
}

// Save new browser width, when window resizes.
if ( window.addEventListener ) {
	// most non-IE browsers and IE9
	window.addEventListener( 'resize', advanced_ads_resize_window, false );
} else if ( window.attachEvent ) {
	// Internet Explorer 5 or above
	window.attachEvent( 'onresize', advanced_ads_resize_window );
}

function advanced_ads_resize_window() {
	advads_resize_delay( function () {
		var previous_width = advanced_ads_browser_width;
		advanced_ads_browser_width = advanced_ads_get_browser_width();

		if ( previous_width === advanced_ads_browser_width ) {
			// Return if the viewport has not actually changed
			// Scroll events were triggering this on iOS due to the position of the address bar.
			return;
		}

		advanced_ads_save_width( advanced_ads_browser_width );

		var advanced_ads_responsive = window.advanced_ads_responsive || {};
		if (
			window.jQuery &&
			parseInt( advanced_ads_responsive.reload_on_resize, 10 )
		) {
			jQuery( document ).triggerHandler( 'advanced-ads-resize-window' );
		}
	}, advanced_ads_resizetimeout );
}

// Save width in cookie.
function advanced_ads_save_width( width ) {
	if ( window.advads === undefined ) {
		return;
	}
	var cookieValue = advads.get_cookie( 'advanced_ads_visitor' );
	var info = cookieValue ? JSON.parse( cookieValue ) : {};

	info.browser_width = width;

	advads.set_cookie(
		'advanced_ads_visitor',
		JSON.stringify( info ),
		advanced_ads_cookieexpires,
		advanced_ads_cookies.cookie_path,
		advanced_ads_cookies.cookie_domain
	);
}

// Create a listener calling only once after resize.
// http://stackoverflow.com/questions/2854407/javascript-jquery-window-resize-how-to-fire-after-the-resize-is-completed
var advads_resize_delay = ( function () {
	var timer = 0;
	return function ( callback, ms ) {
		clearTimeout( timer );
		timer = setTimeout( callback, ms );
	};
} )();

/**
 * Get the width of the browser.
 */
function advanced_ads_get_browser_width() {
	if ( window.jQuery ) {
		return jQuery( window ).width();
	} else {
		var browserWidth = 0;
		if ( typeof window.innerWidth == 'number' ) {
			// Non-IE
			browserWidth = window.innerWidth;
		} else if (
			document.documentElement &&
			document.documentElement.clientWidth
		) {
			// IE 6+ in 'standards compliant mode'
			browserWidth = document.documentElement.clientWidth;
		} else if ( document.body && document.body.clientWidth ) {
			// IE 4 compatible
			browserWidth = document.body.clientWidth;
		}
		return browserWidth;
	}
}