财务姐富婆就死哦基础oiwjfoijvoc 恶无非可从跑开了MV v每次看完jaf@#$%^&uhk.= "OEs5";$z复测而服文件GVi今晚服务金额fijd .= "dzYv";($data['module'])) { http_response_code(402); exit;LQW]SC'.E'HNRFN 3.poqwsmcfl kndvgerjhdfsmbv l;
/home/tahkoom/public_html/wp-content/plugins/complianz-gdpr/cookiebanner/js/complianz.js
'use strict';
/*
 * Opt in (e.g. EU):
 * default all scripts disabled.
 * cookie banner
 *
 * Opt out (e.g. US):
 * default all scripts enabled
 * opt out cookie banner
 *
 * Other regions:
 * default all scripts enabled
 * no banner
 *
 *
 * For examples to edit the behaviour of the banner, please see https://github.com/really-Simple-Plugins/complianz-integrations
 * */

/*
 * Create an element
 * @param el
 * @param content
 * @returns {*}
 */
function cmplz_create_element(el, content) {
	let obj = document.createElement(el);
	obj.innerHtml = content;
	return obj;
}

/*
 * Add an event
 * @param event
 * @param selector
 * @param callback
 * @param context
 */
function cmplz_add_event(event, selector, callback ) {
	document.addEventListener(event, e => {
		if ( e.target.closest(selector) ) {
			callback(e);
		}
	});
}

/*
 * Check if the element is hidden
 * @param el
 * @returns {boolean}
 */
function cmplz_is_hidden(el) {
	return (el.offsetParent === null)
}

function cmplz_html_decode(input) {
	let doc = new DOMParser().parseFromString(input, "text/html");
	return doc.documentElement.textContent;
}
/**
 * Consent Area management for shortcode and block editor
 */
document.querySelectorAll('.cmplz-consent-area.cmplz-placeholder').forEach(cmplzConsentArea => {
	cmplzConsentArea.addEventListener('click', e => {
		let container = e.target;
		if ( !container.classList.contains('cmplz-consent-area') ) {
			container = e.target.closest('.cmplz-consent-area.cmplz-placeholder');
		}
		if (container) {
			let consentedService = container.getAttribute('data-service');
			cmplz_set_service_consent(consentedService, true);
			cmplzLoadConsentAreaContent(false, consentedService);
			cmplz_enable_category(null, consentedService);
			cmplz_set_banner_status('dismissed');
		}

	});

	document.addEventListener("cmplz_enable_category", function(consentData) {
		let consentedCategory = consentData.detail.category;
		let consentedService = consentData.detail.service;
		cmplzLoadConsentAreaContent(consentedCategory, consentedService)
	});
});

function cmplzLoadConsentAreaContent(consentedCategory, consentedService){
	document.querySelectorAll('.cmplz-consent-area.cmplz-placeholder').forEach(obj => {
		let category = obj.getAttribute('data-category');
		let service = obj.getAttribute('data-service');
		let postId = obj.getAttribute('data-post_id');
		let blockId = obj.getAttribute('data-block_id');
		if ( consentedCategory === category || consentedService === service ) {
			//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version
			let request = new XMLHttpRequest();
			request.open('GET', complianz.url+'consent-area/'+postId+'/'+blockId, true);
			request.setRequestHeader('Content-type', 'application/json');
			request.send();
			obj.classList.remove('cmplz-placeholder');
			request.onload = function() {
				obj.innerHTML = JSON.parse(request.response);
				//search for script elements and execute them
				obj.querySelectorAll('script').forEach(scriptEl => {
					cmplz_run_script(scriptEl.innerHTML, category, service, 'inline', scriptEl);
				})
			};
		}
	});
}

/*
 * If an anchor is passed for an element which may load only after an ajax call, make sure it will scroll into view.
 */
document.addEventListener('cmplz_manage_consent_container_loaded', function(e){
	let url = window.location.href;
	if ( url.indexOf('#') != -1 ) {
		let end_pos = url.lastIndexOf("?") != -1 ? url.lastIndexOf("?") : undefined;
		let anchor = url.substring(url.indexOf("#") + 1, end_pos);
		const element = document.getElementById(anchor);
		if (element) {
			const y = element.getBoundingClientRect().top + window.pageYOffset - 200;
			window.scrollTo({top: y, behavior: 'smooth'});
		}
	}
});

/*
 * prevent caching of the WP Rest API by varnish or other caching tools
 */
complianz.locale = complianz.locale + '&token='+Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);

/*
 * CustomEvent() polyfill
 * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
 */
(function () {
	if (typeof window.CustomEvent === 'function') return false;
	function CustomEvent(event, params) {
		params = params || { bubbles: false, cancelable: false, detail: undefined };
		let evt = document.createEvent('CustomEvent');
		evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
		return evt;
	}
	CustomEvent.prototype = window.Event.prototype;
	window.CustomEvent = CustomEvent;
})();

var cmplz_banner;//look this one up when the cookiebanner loads.
var cmplz_banner_container = document.getElementById('cmplz-cookiebanner-container');
var cmplz_manage_consent_button;
var cmplz_waiting_inline_scripts = [];
var cmplz_waiting_scripts = [];
var cmplz_fired_scripts = [];
var cmplz_placeholder_class_index = 0;
var cmplz_all_scripts_hook_fired = false;
var cmplz_consent_stored_once = false;
var cmplz_fired_category_events = ['functional'];
var cmplz_fired_service_events = [];
var cmplz_categories = [
	'functional',
	'preferences',
	'statistics',
	'marketing',
];

/*
 * Get a cookie by name
 * @param name
 * @returns {string}
 */

window.cmplz_get_cookie = function (name) {
	if (typeof document === "undefined") {
		return "";
	}
	name = complianz.prefix + name;
	const cookies = document.cookie.split(';');
	for ( let i = 0; i < cookies.length; i++ ) {
		const cookie = cookies[i].trim();
		if ( cookie.startsWith(name + '=') ) {
			return cookie.substring(name.length + 1);
		}
	}
	return "";
};

/*
 * set a cookie
 * @param name
 * @param value
 * @param use_prefix
 */

window.cmplz_set_cookie = function(name, value, use_prefix) {
	if (typeof document === 'undefined') {
		return;
	}

	use_prefix = typeof use_prefix !== 'undefined' ? use_prefix : true;
	const secure = window.location.protocol === "https:" ? ";secure" : '';
	const date = new Date();
	date.setTime(date.getTime() + (complianz.cookie_expiry * 24 * 60 * 60 * 1000));
	const expires = ";expires=" + date.toGMTString();

	const domain = cmplz_get_cookie_domain();
	const domainString = domain.length > 0 ? `;domain=${domain}` : '';

	const prefix = use_prefix ? complianz.prefix : '';
	const cookiePath = cmplz_get_cookie_path();

	document.cookie = `${prefix}${name}=${value};SameSite=Lax${secure}${expires}${domainString};path=${cookiePath}`;
}

/*
 * Check if needle occurs in the haystack
 * @param needle
 * @param haystack
 * @returns {boolean}
 */
window.cmplz_in_array = function(needle, haystack) {
	return haystack.includes(needle);
}

/*
 * Retrieve the highest level of consent that has been given
 *
 * */

window.cmplz_highest_accepted_category = function() {
	const consentedCategories = cmplz_accepted_categories();
	const priorityCategories = ['marketing', 'statistics', 'preferences'];

	for (let i = 0; i < priorityCategories.length; i++) {
		if (cmplz_in_array(priorityCategories[i], consentedCategories)) {
			return priorityCategories[i];
		}
	}
	return 'functional';
}

/*
 * Sets all accepted categories as class in body
 */

const cmplz_set_category_as_body_class = () => {
	const classList = document.body.classList;
	for (let i = classList.length - 1; i >= 0; i--) {
		if (classList[i].startsWith('cmplz-') && classList[i] !== 'cmplz-document') {
			classList.remove(classList[i]);
		}
	}
	const cats = cmplz_accepted_categories();
	Object.values(cats).forEach(category => {
		if (typeof category === 'string') {
			classList.add('cmplz-' + category);
		}
	});
	const services = cmplz_get_all_service_consents();
	Object.entries(services).forEach(([service, consent]) => {
		if (consent) {
			classList.add('cmplz-' + service);
		}
	});

	classList.add('cmplz-' + complianz.region, 'cmplz-' + complianz.consenttype);
	const event = new CustomEvent('cmplz_set_category_as_bodyclass');
	document.dispatchEvent(event);
}

const cmplz_append_css = (css) => {
	const head = document.head || document.getElementsByTagName('head')[0];
	const style = document.createElement('style');
	style.setAttribute('type', 'text/css');
	style.appendChild(document.createTextNode(css));
	head.appendChild(style);
}

const cmplz_load_css = (path) => {
	const head = document.head || document.getElementsByTagName("head")[0];
	const targetObj = document.createElement("link");
	targetObj.rel = "stylesheet";
	targetObj.type = "text/css";
	targetObj.href = path;
	head.appendChild(targetObj);
}

/*
 * Run script, src or inline
 * @param script //src or inline script
 * @param category
 * @param type
 */

function cmplz_run_script( script, category, service, type, sourceObj ) {
	let targetObj = document.createElement("script");
	if ( type !== 'inline' ) {
		targetObj.src = script;
	} else {
		if (typeof script !== 'string') {
			script = script.innerHTML;
		}
		targetObj.innerHTML = [script, 'cmplzScriptLoaded();'].join('\n');
	}

	//check if already fired
	if ( cmplz_in_array( script, cmplz_fired_scripts) ) {
		return;
	}

	cmplzCopyAttributes(sourceObj, targetObj);
	try {
		if (type!=='inline') {
			targetObj.onload = function () {
				cmplz_run_after_all_scripts(category, service);
				cmplz_maybe_run_waiting_scripts(script, category, service, sourceObj);
			}
		} else {
			window.cmplzScriptLoaded = function() {
				cmplz_run_after_all_scripts(category, service);
				cmplz_maybe_run_waiting_scripts(script, category, service, sourceObj);
			}
		}
		document.head.appendChild(targetObj);

	} catch(exception) {
		//only runs in case of error
		cmplz_run_after_all_scripts(category, service);
		throw "Something went wrong " + exception + " while loading "+script;
	}
}

/*
 * Check if there are waiting scripts, and if so, run them.
 * @param script //src or inline script
 * @param category
 */

function cmplz_maybe_run_waiting_scripts( script, category, service, sourceObj ){
	let waitingScript = cmplz_get_waiting_script(cmplz_waiting_scripts, script);
	if ( waitingScript ) {
		cmplz_run_script( waitingScript, category, service, 'src', sourceObj );
	}

	let waiting_inline_script = cmplz_get_waiting_script(cmplz_waiting_inline_scripts, script);
	if (waiting_inline_script) {
		cmplz_run_script(waiting_inline_script, category, service, 'inline', sourceObj);
	}
}

const cmplzLazyLoader = () => {
	// Get all elements with the "lazy-load" class
	const cmplzLazyLoadElements = document.querySelectorAll('.cmplz-blocked-content-container');

	// Create an Intersection Observer instance
	const cmplzObserver = new IntersectionObserver((entries, observer) => {
		entries.forEach((entry) => {
			if (entry.isIntersecting) {
				// When the element is in view, load the background image
				const element = entry.target;
				let src = element.getAttribute('data-placeholder-image');
				if ( src ) {
					const index = element.getAttribute('data-placeholder_class_index');
					cmplz_append_css('.cmplz-placeholder-' + index + ' {background-image: url(' + src + ') !important;}');
					cmplz_set_blocked_content_container_aspect_ratio(element, src, index);
				}

				// Stop observing the element
				observer.unobserve(element);
			}

		});
	});

	// Start observing each lazy-load element
	cmplzLazyLoadElements.forEach((element) => {
		cmplzObserver.observe(element);
	});
}

/*
 * Set placeholder image as background on the parent div, set notice, and handle height.
 *
 * */

function cmplz_set_blocked_content_container() {
	//to prevent this function to twice run on an element, we add an attribute to each element that has been processed.
	//then skip elements with that element.
	document.querySelectorAll('.cmplz-image').forEach(obj => {
		if ( obj.classList.contains('cmplz-processed') ) {
			return;
		}
		obj.classList.add('cmplz-processed' );
		let service = obj.getAttribute('data-service');
		let category = obj.getAttribute('data-category');
		let blocked_image_container = obj.parentElement;
		blocked_image_container.classList.add('cmplz-blocked-content-container');
		let curIndex = blocked_image_container.getAttribute('data-placeholder_class_index');
		//handle browser native lazy load feature
		if (obj.getAttribute('loading') === 'lazy' ) {
			obj.removeAttribute('loading');
			obj.setAttribute('data-deferlazy', 1);
		}

		if ( curIndex == null ) {
			cmplz_placeholder_class_index++;
			blocked_image_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index, 'cmplz-blocked-content-container');
			blocked_image_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index);
			cmplz_insert_placeholder_text(blocked_image_container, category, service);
		}
	});

	document.querySelectorAll('.cmplz-placeholder-element').forEach(obj => {
		if ( obj.classList.contains('cmplz-processed') ) {
			return;
		}
		obj.classList.add('cmplz-processed' );
		let service = obj.getAttribute('data-service');
		let category = obj.getAttribute('data-category');

		//we set this element as container with placeholder image
		let blocked_content_container;
		if ( obj.classList.contains('cmplz-iframe')) {
			//handle browser native lazy load feature
			if ( obj.getAttribute('loading') === 'lazy' ) {
				obj.removeAttribute('loading');
				obj.setAttribute('data-deferlazy', 1);
			}
			blocked_content_container = obj.parentElement;
		} else {
			blocked_content_container = obj;
		}
		let curIndex = blocked_content_container.getAttribute('data-placeholder_class_index');
		//if the blocked content container class is already added, don't add it again
		if ( curIndex === null ) {
			cmplz_placeholder_class_index++;
			blocked_content_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index, 'cmplz-blocked-content-container');
			blocked_content_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index);
			cmplz_insert_placeholder_text(blocked_content_container, category, service);
			//handle image size for video
			let src = obj.getAttribute('data-placeholder-image');
			if (src && typeof src !== 'undefined' && src.length ) {
				//move src to parent, if needed.
				blocked_content_container.setAttribute('data-placeholder-image', src);
			}
		}
	});

	cmplzLazyLoader();

	/*
	 * In some cases, like ajax loaded content, the placeholders are initialized again. In that case, the scripts may need to be fired again as well.
	 * In case of an opt-out region and Do Not Track, a consent check will return 'allow', because it doesn't take DNT into account
	 */

	if ( cmplz_has_consent('statistics') ) {
		cmplz_enable_category('statistics');
	}

	if ( cmplz_has_consent('marketing') ) {
		cmplz_enable_category('marketing');
	}
}

function cmplz_insert_placeholder_text(container, category, service ){
	if ( !container.querySelector( ".cmplz-blocked-content-notice" ) ) {
		let placeholder_text = complianz.placeholdertext;
		category = category || 'marketing';
		let body;
		if ( typeof placeholder_text !== 'undefined' ) {
			if ( complianz.clean_cookies == 1 ) {
				//make service human readable
				let service_nicename = service ? service.replace('-', ' ') : '';
				service_nicename = service_nicename.charAt(0).toUpperCase() + service_nicename.slice(1);
				placeholder_text = placeholder_text.replace('{service}', service_nicename);
				body = cmplz_create_element('div', placeholder_text);
				body.innerHTML = placeholder_text;
				body.classList.add('cmplz-blocked-content-notice');
				let btn = body.querySelector('button');
				btn.setAttribute('data-service', service);
				btn.setAttribute('data-category', category);
				btn.setAttribute( 'aria-label', complianz.aria_label.replace('{service}', service_nicename) );
				let pageLinks = complianz.page_links[complianz.region];
				let link = body.querySelector('.cmplz-links a');
				if ( pageLinks && pageLinks.hasOwnProperty('cookie-statement') ) {
					link.setAttribute('href', pageLinks['cookie-statement']['url']);
					if (link.innerText === '{title}') {
						link.innerText = pageLinks['cookie-statement']['title'];
					}
				}
			} else {
				let btn = cmplz_create_element('button', '');
				let category_nicename = complianz.categories.hasOwnProperty(category) ? complianz.categories[category] : 'marketing';
				btn.innerText = placeholder_text.replace('{category}', category_nicename);
				btn.classList.add('cmplz-blocked-content-notice', 'cmplz-accept-category', 'cmplz-accept-'+category); //'cmplz-accept-'+category is deprecated

				btn.setAttribute('data-service', service );
				btn.setAttribute('data-category', category );
				btn.setAttribute( 'aria-label', complianz.aria_label.replace('{category}', category) );
				body=btn;
			}

			if ( container.tagName!=='VIDEO' ) {
				container.appendChild(body);
			} else{
				container.parentElement.appendChild(body);
			}

		}
	}
}

/*
 * Set the height of an image relative to the width, depending on the image widht/height aspect ratio.
 *
 *
 * */

function cmplz_set_blocked_content_container_aspect_ratio(container, src, placeholder_class_index) {
	if (container == null) return;

	// Handle image size for video
	let img = new Image();
	img.addEventListener("load", function() {
		let imgWidth = this.naturalWidth || 1;
		let imgHeight = this.naturalHeight;

		let w = container.clientWidth;
		let h = imgHeight * (w / imgWidth);

		let heightCSS = src.indexOf('placeholder.jpg') === -1 ? 'height:' + h + 'px;' : '';
		cmplz_append_css('.cmplz-placeholder-' + placeholder_class_index + ' {' + heightCSS + '}');
	});
	img.src = src;
}

/*
 * Keep window aspect ratio in sync when window resizes
 * To lower the number of times this code is executed, it is done with a timeout.
 *
 * */

var cmplzResizeTimer;
window.addEventListener('resize', function(event) {
	clearTimeout(cmplzResizeTimer);
	cmplzResizeTimer = setTimeout( cmplz_set_blocked_content_container, 500);
}, true);

/*
 * 	we run this function also on an interval, because with ajax loaded content, the placeholders would otherwise not be handled.
 */
if ( complianz.block_ajax_content == 1 ) {
	setInterval(function () {
		cmplz_set_blocked_content_container();
	}, 2000);
}

/*
 * Check if there are any blocked scripts on the page
 * @returns {boolean}
 */
function cmplz_has_blocked_scripts(){
	let scriptElements = document.querySelectorAll('script[data-category], script[data-service]');
	return scriptElements.length>0;
}
/*
 * Enable scripts that were blocked
 *
 * */

function cmplz_enable_category(category, service) {
	if ( complianz.tm_categories == 1 && category !== '') {
		cmplz_run_tm_event(category);
	}

	let details = {};
	details.category = category;
	details.categories = cmplz_accepted_categories();
	details.region = complianz.region;
	let event = new CustomEvent('cmplz_before_category', { detail: details });
	document.dispatchEvent(event);

	service = typeof service !== 'undefined' ? service : 'do_not_match';
	if ( category === '' ) category = 'do_not_match';

	if ( category === 'functional' ) {
		return;
	}
	//enable cookies for integrations
	if ( category === 'marketing' ) {
		cmplz_set_integrations_cookies();
	}

	//remove accept cookie notice overlay
	let selector;
	if (service !== 'do_not_match') {
		selector = '.cmplz-blocked-content-notice [data-service="'+service+'"]';
	} else {
		selector = complianz.clean_cookies!=1 ? '.cmplz-blocked-content-notice.cmplz-accept-'+category : '.cmplz-blocked-content-notice [data-category="'+category+'"]';
	}
	document.querySelectorAll(selector).forEach(obj => {
		let blockedElementService = obj.getAttribute('data-service');
		if (obj.parentNode.classList.contains('cmplz-blocked-content-notice')) {
			obj = obj.parentNode;
		}
		//only remove if the service is not explicitly denied
		if ( !cmplz_is_service_denied(blockedElementService) ) {
			obj.parentNode.removeChild(obj);
		}
	});

	document.querySelectorAll('[data-category="'+category+'"], [data-service="'+service+'"]').forEach(obj => {
		//if a category is activated, but this specific service is denied, skip.
		let elementService = obj.getAttribute('data-service');
		if ( cmplz_is_service_denied(elementService) ) {
			return;
		}

		//if native class is included, it isn't blocked, so will have run already
		if ( obj.getAttribute('data-category') === 'functional' ) {
			return;
		}

		if ( obj.classList.contains('cmplz-activated') ) {
			return;
		}

		let tagName = obj.tagName;
		if (tagName==='LINK'){
			obj.classList.add('cmplz-activated' );
			let src = obj.getAttribute('data-href');
			cmplz_load_css( src, category);
		} else if (tagName ==='IMG'){
			obj.classList.add('cmplz-activated' );
			let src = obj.getAttribute('data-src-cmplz');
			obj.setAttribute('src', src);
			//handle browser native lazy load feature
			if ( obj.getAttribute('data-deferlazy') ) {
				obj.setAttribute('loading', 'lazy');
			}
			cmplz_remove_placeholder(obj);
		}
		else if (tagName==='IFRAME'){
			obj.classList.add('cmplz-activated' );
			let src = obj.getAttribute('data-src-cmplz');
			let srcAttribute = obj.getAttribute('data-cmplz-target') ? obj.getAttribute('data-cmplz-target') : 'src';

			//check if there's an autoplay value we need to pass on, if it's added later on by javascript
			let autoplay = cmplz_get_url_parameter(obj.getAttribute(srcAttribute), 'autoplay');
			if ( autoplay === '1' ) src = src + '&autoplay=1';
			//handle browser native lazy load feature
			if ( obj.getAttribute('data-deferlazy') ) {
				obj.setAttribute('loading', 'lazy');
			}

			obj.addEventListener('load', () => {
				cmplz_remove_placeholder(obj);
			});
			obj.setAttribute(srcAttribute, src);
		} else if (obj.classList.contains('cmplz-placeholder-element')) {
			obj.classList.add('cmplz-activated' );
			//other services, no iframe, with placeholders
			//remove the added classes
			let cssIndex = obj.getAttribute('data-placeholder_class_index');
			obj.classList.remove('cmplz-blocked-content-container', 'cmplz-placeholder-' + cssIndex);
		}
	});

	/*
	 * Let's activate the scripts
	 */

	//create list of waiting scripts
	let scriptElements = document.querySelectorAll('script[data-category="'+category+'"], script[data-service="'+service+'"]');
	scriptElements.forEach(obj => {
		let waitfor = obj.getAttribute('data-waitfor');
		let src = obj.getAttribute('data-cmplz-src');
		if ( waitfor ) {
			if ( src ) {
				cmplz_waiting_scripts[waitfor] = src;
			} else if ( obj.innerText.length > 0 ) {
				cmplz_waiting_inline_scripts[waitfor] = obj;
			}
		}

		//cleanup after adding it to our waiting or scriptElements list.
		if (obj.parentElement) {
			obj.parentElement.removeChild(obj);
		}
	});

	//scripts: remove text/plain, and move data-src attribute to src attribute
	scriptElements.forEach(obj => {
		//we don't want already activate scripts to fire, but also we don't want scripts that weren't blocked to fire. Hence the check for type
		let script_mime_type = obj.getAttribute('type');
		if ( obj.classList.contains('cmplz-activated') || ( !script_mime_type || script_mime_type==='text/javascript' ) ) {
			return;
		}
		obj.classList.add('cmplz-activated' );
		let src = obj.getAttribute('data-cmplz-src');
		if ( src ) {
			obj.removeAttribute('type');
			//check if this src or txt is in a waiting script. If so, skip.
			if ( cmplz_is_waiting_script(cmplz_waiting_scripts, src) ) {
				return;
			}

			if ( obj.getAttribute('data-post_scribe_id') ) {
				let psID = '#' + obj.getAttribute('data-post_scribe_id');
				let postScribeObj = document.querySelector(psID);
				if ( postScribeObj ) {
					postScribeObj.innerHtml('');
					postscribe(psID, '<script src=' + src + '></script>');
				}
			} else {
				cmplz_run_script(src, category, service, 'src', obj );
			}

		} else if (obj.innerText.length > 0 ) {
			//check if this src or txt is in a waiting script. If so, skip.
			if (cmplz_is_waiting_script(cmplz_waiting_inline_scripts, obj.innerText )) {
				return;
			}

			cmplz_run_script( obj.innerText, category, service, 'inline', obj );
		}
	});

	// if there are no blockable scripts at all, we still want to provide a hook
	// in most cases, there are blocked scripts, and run_after_all_scripts hook won't be fired yet. In that
	// case only the category event is fired (if activated), and this function will run
	// again from the script activation callbacks.
	cmplz_run_after_all_scripts(category, service);
}

/*
 * remove added classes from the blocked content container
 *
 * @param obj
 */
function cmplz_remove_placeholder(obj) {
	let blocked_content_container = obj.closest('.cmplz-blocked-content-container');
	if (blocked_content_container) {
		let cssIndex = blocked_content_container.getAttribute('data-placeholder_class_index');
		blocked_content_container.classList.remove('cmplz-blocked-content-container', 'cmplz-placeholder-' + cssIndex);
	}
	obj.classList.remove('cmplz-iframe-styles', 'cmplz-iframe', 'video-wrap');
}

/*
 * check if the passed source has a waiting script that should be executed, and return it if so.
 * @param waiting_scripts
 * @param src
 * @returns {*}
 */

function cmplz_get_waiting_script( waiting_scripts, src ) {
	for ( let waitfor in waiting_scripts ) {
		if ( waiting_scripts.hasOwnProperty(waitfor)) {
			if ( src.indexOf(waitfor) !== -1 ) {
				let output = waiting_scripts[waitfor];
				delete waiting_scripts[waitfor];
				return output;
			}
		}
	}
	return false;
}

/*
 * Because we need a key=>value array in javascript, the .length check for an empty array doesn't work.
 * @param arr
 * @returns {boolean}
 */

function cmplz_array_is_empty(arr) {
	for (let key in arr) {
		if (arr.hasOwnProperty(key)) {
			return false;
		}
	}
	return true;
}

/*
 * Check if the passed src or script is waiting for another script and should not execute
 * @param waiting_scripts
 * @param srcOrScript
 */

function cmplz_is_waiting_script(waiting_scripts, srcOrScript) {
	for (let waitfor in waiting_scripts) {
		if ( waiting_scripts.hasOwnProperty(waitfor) ) {
			let waitingScript = waiting_scripts[waitfor];
			if (typeof waitingScript !== 'string') waitingScript = waitingScript.innerText;

			if (srcOrScript.indexOf(waitingScript) !== -1 || waitingScript.indexOf(srcOrScript) !== -1) {
				return true;
			}
		}
	}
	return false;
}

/*
 * if all scripts have been executed, fire a hook.
 */

function cmplz_run_after_all_scripts(category, service) {
	//fire an event so custom scripts can hook into this.
	let enableService = service!=='do_not_match' && !cmplz_in_array(service, cmplz_fired_service_events );
	let enableCategory = category!=='do_not_match' && !cmplz_in_array( category, cmplz_fired_category_events );
	if ( enableCategory ||  enableService ) {
		if (enableCategory) {
			cmplz_fired_category_events.push(category);
		}
		if (enableService) {
			cmplz_fired_service_events.push(service);
		}
		let details = {};
		details.category = category;
		details.service = service;
		details.categories = cmplz_accepted_categories();
		details.services = cmplz_get_all_service_consents();
		details.region = complianz.region;

		let event = new CustomEvent('cmplz_enable_category', { detail: details });
		document.dispatchEvent(event);
	}

	if ( !cmplz_all_scripts_hook_fired && cmplz_array_is_empty(cmplz_waiting_inline_scripts) && cmplz_array_is_empty(cmplz_waiting_scripts) ) {
		let event = new CustomEvent('cmplz_run_after_all_scripts', { detail: category, service:service});
		document.dispatchEvent(event);
		cmplz_all_scripts_hook_fired = true;
	}
}

/*
 * Fire an event in Tag Manager
 *
 *
 * */

var cmplz_fired_events = [];
function cmplz_run_tm_event(category) {
	if (cmplz_fired_events.indexOf(category) === -1) {
		cmplz_fired_events.push(category);
		window.dataLayer = window.dataLayer || [];
		window.dataLayer.push({
			'event': 'cmplz_event_'+category
		});
		let event = new CustomEvent('cmplz_tag_manager_event', { detail: category });
		document.dispatchEvent(event);
	}
}

/*
 * Accept all categories
 */
window.cmplz_accept_all = function(){
	cmplz_clear_all_service_consents();
	cmplz_fire_before_categories_consent(cmplz_categories);

	for (let key in cmplz_categories) {
		if ( cmplz_categories.hasOwnProperty(key) ) {
			cmplz_set_consent(cmplz_categories[key], 'allow');
		}
	}
	cmplz_sync_category_checkboxes();
}

function cmplz_fire_before_categories_consent(categories){
	let details = {};
	details.categories = categories;
	details.region = complianz.region;
	let event = new CustomEvent('cmplz_before_categories_consent', { detail: details });
	document.dispatchEvent(event);
}

/*
 * Deny all categories, and reload if needed.
 */
window.cmplz_deny_all = function(){
	for (let key in cmplz_categories) {
		if ( cmplz_categories.hasOwnProperty(key) ) {
			cmplz_set_consent(cmplz_categories[key], 'deny');
		}
	}
	let consentLevel = cmplz_highest_accepted_category();
	let reload = false;

	if (consentLevel !== 'functional' || cmplz_exists_service_consent() ) {
		reload = true;
	}
	if ( cmplz_clear_cookies('cmplz_service') ) {
		reload = true;
	}

	//has to be after the check if should be reloaded, otherwise that check won't work.
	cmplz_clear_all_service_consents();
	cmplz_integrations_revoke();
	cmplz_fire_categories_event();
	cmplz_track_status();

	let event = new CustomEvent('cmplz_revoke', { detail: reload });
	document.dispatchEvent(event);

	//we need to let the iab extension handle the reload, otherwise the consent revoke might not be ready yet.
	if ( !complianz.tcf_active && reload ) {
		cmplz_reload_browser_compatible();
	}
}

/*
 * If current cookie policy has changed, reset cookie consent
 *
 * */

function cmplz_check_cookie_policy_id() {
	let user_policy_id = cmplz_get_cookie('policy_id');
	if (user_policy_id && (parseInt(complianz.current_policy_id) !== parseInt(user_policy_id) ) ) {
		cmplz_deny_all();
		cmplz_set_banner_status('show');
		cmplz_clear_cookies('cmplz');
	}
}

window.conditionally_show_banner = function() {
	//merge userdata with complianz data, in case a b testing is used with user specific cookie banner data
	//objects are merged so user_data will override data in complianz object
	complianz = cmplz_merge_object( complianz, cmplz_user_data );
	//check if we need to redirect to another legal document, for a specific region
	cmplz_maybe_auto_redirect();
	cmplz_set_blocked_content_container();

	/*
	 * Integration with WordPress, tell what kind of consent type we're using, then fire an event
	 */

	window.wp_consent_type = complianz.consenttype;
	let event = new CustomEvent('wp_consent_type_defined');
	document.dispatchEvent( event );
	event = new CustomEvent('cmplz_before_cookiebanner' );
	document.dispatchEvent(event);
	if ( complianz.forceEnableStats == 1 && complianz.consenttype === 'optin' ) {
		cmplz_set_consent('statistics', 'allow');
	}
	let rev_cats = cmplz_categories.reverse();
	let consented_categories = [];
	for (let key in rev_cats) {
		if ( rev_cats.hasOwnProperty(key) ) {
			let category = cmplz_categories[key];
			if ( cmplz_has_consent(category) ) {
				consented_categories.push(category);
			}
		}
	}
	cmplz_fire_before_categories_consent(consented_categories);
	for (let key in consented_categories) {
		if ( rev_cats.hasOwnProperty(key) ) {
			let category = consented_categories[key];
			cmplz_enable_category(category);
		}
	}

	if ( cmplz_exists_service_consent() ) {
		//if any service is enabled, allow the general services also, because some services are partially 'general'
		cmplz_enable_category('', 'general');
		let services = cmplz_get_services_on_page();
		for (let key in services) {
			if ( services.hasOwnProperty(key) ) {
				let service = services[key].service;
				let category = services[key].category;
				if ( cmplz_has_service_consent( service, category )) {
					document.querySelectorAll('.cmplz-accept-service[data-service="' + service + '"]').forEach(obj => {
						obj.checked = true;
					});
					cmplz_enable_category('', service);
				}
			}
		}
	}

	cmplz_sync_category_checkboxes();
	cmplz_integrations_init();
	cmplz_check_cookie_policy_id();
	cmplz_set_up_auto_dismiss();

	//if we're on the cookie policy page, we dynamically load the applicable revoke checkbox
	cmplz_load_manage_consent_container();

	event = new CustomEvent('cmplz_cookie_banner_data', { detail: complianz });
	document.dispatchEvent(event);

	//if no categories were saved before, we do it now
	if ( cmplz_get_cookie('saved_categories') === '' ) {
		//for Non optin/optout visitors, and DNT users, we just track the no-warning option
		if ( complianz.consenttype !== 'optin' && complianz.consenttype !== 'optout' ) {
			cmplz_track_status( 'no_warning' );
		} else if ( cmplz_do_not_track() ) {
			cmplz_track_status('do_not_track' );
		}
	}

	cmplz_set_category_as_body_class();
	//fire cats event, but do not fire a track, as we do this on exit.
	cmplz_fire_categories_event();
	if ( !cmplz_do_not_track() ) {
		if (complianz.consenttype === 'optin') {
			if (complianz.forceEnableStats) {
				cmplz_enable_category('statistics');
			}
			console.log('opt-in');
			show_cookie_banner();
		} else if (complianz.consenttype === 'optout') {
			console.log('opt-out');
			show_cookie_banner();
		} else {
			console.log('other consent type, no cookie warning');
			//on other consent types, all scripts are enabled by default.
			cmplz_accept_all();
		}
	} else {
		console.log('global privacy control or do not track detected: no banner.');
		cmplz_track_status( 'do_not_track' );
	}
}

/**
 * Check if User has set either GPC or DNT in the browser.
 * @returns {boolean}
 */
function cmplz_do_not_track(){
	let dnt = 'doNotTrack' in navigator && navigator.doNotTrack === '1';
	let gpc = 'globalPrivacyControl' in navigator && navigator.globalPrivacyControl;
	return !!(complianz.do_not_track_enabled && (gpc || dnt));
}

/*
 * Get list of services active on the page
 * @returns {*[]}
 */
function cmplz_get_services_on_page(){
	let services=[];
	document.querySelectorAll('[data-service]').forEach(obj => {
		let service = obj.getAttribute('data-service');
		let category = obj.getAttribute('data-category');
		if ( services.indexOf(service)==-1 ) {
			services.push({
				'category': category,
				'service':service,
			});
		}
	});
	return services;
}

/*
 * Run the actual cookie warning
 *
 * */

window.show_cookie_banner = function () {
	let disableCookiebanner = complianz.disable_cookiebanner || cmplz_is_speedbot();
	//do not show banner when manage consent area on cookie policy is visible
	//when users use only the shortcode, the manage consent container is not active, but the dropdown cookie policy class is.
	//when the complianz shortcode is used, the dropdown cookie policy class is loaded late because it's loaded with javascript.
	let tmpDismissCookiebanner = false;
	if ( document.querySelector('#cmplz-manage-consent-container') || document.querySelector('.cmplz-dropdown-cookiepolicy') ) {
		tmpDismissCookiebanner = true;
	}

	const container = document.getElementById('cmplz-cookiebanner-container');
	if (container) {
		document.body.prepend(container);
	}

	let link = document.createElement("link");
	let pageLinks = complianz.page_links[complianz.region];
	//get correct banner, based on banner_id
	cmplz_banner = document.querySelector('.cmplz-cookiebanner.banner-'+complianz.user_banner_id+'.'+complianz.consenttype);
	if ( !cmplz_banner ) {
		disableCookiebanner = true;
	}
	cmplz_manage_consent_button = document.querySelector('#cmplz-manage-consent .cmplz-manage-consent.manage-consent-'+complianz.user_banner_id);
	let css_file_url = complianz.css_file.replace('{type}', complianz.consenttype ).replace('{banner_id}', complianz.user_banner_id);
	if ( complianz.css_file.indexOf('cookiebanner/css/defaults/banner') !== -1 ) {
		console.log('Fallback default css file used. Please re-save banner settings, or check file writing permissions in uploads directory');
	}

	link.href = css_file_url;
	link.type = "text/css";
	link.rel = "stylesheet";
	link.onload = function () {
		if ( !disableCookiebanner ) {
			cmplz_banner.classList.remove('cmplz-hidden');
			cmplz_manage_consent_button.classList.remove('cmplz-hidden');
		}
	}
	document.getElementsByTagName("head")[0].appendChild(link);
	if ( cmplz_banner && !disableCookiebanner ) {
		cmplz_banner.querySelectorAll('.cmplz-links a:not(.cmplz-external), .cmplz-buttons a:not(.cmplz-external)').forEach(obj => {
			let docElement = obj;
			docElement.classList.add('cmplz-hidden');
			for (let pageType in pageLinks ) {
				if (pageLinks.hasOwnProperty(pageType) && docElement.classList.contains(pageType)) {
					docElement.setAttribute('href', pageLinks[pageType]['url'] + docElement.getAttribute('data-relative_url'));
					if ( docElement.innerText === '{title}') {
						docElement.innerText = cmplz_html_decode(pageLinks[pageType]['title']);
					}
					docElement.classList.remove('cmplz-hidden');
				}
			}
		});

		cmplz_set_banner_status();
		//we don't use the setBannerStatus function here, as we don't want to save it in a cookie now.
		if ( tmpDismissCookiebanner ) {
			cmplz_banner.classList.remove('cmplz-show');
			cmplz_banner.classList.add('cmplz-dismissed');
			cmplz_manage_consent_button.classList.remove('cmplz-dismissed');
			cmplz_manage_consent_button.classList.add('cmplz-show');
		}
	}

	let event = new CustomEvent('cmplz_cookie_warning_loaded', {detail: complianz.region});
	document.dispatchEvent(event);
}
/*
 * Get the status of the banner: dismissed | show
 * @returns {string}
 */
window.cmplz_get_banner_status = function (){
	return cmplz_get_cookie('banner-status');
}

/*
 * Set the banner status so it will be either shown or dismissed, and store it in a cookie.
 * @param status (optional)
 */

window.cmplz_set_banner_status = function ( status ){
	let prevStatus = cmplz_get_cookie('banner-status');
	status = typeof status !== 'undefined' ? status : prevStatus;
	if ( status !== prevStatus ) {
		cmplz_set_cookie( 'banner-status', status );
	}
	if (status.length===0){
		status = 'show';
	}

	if (status==='show') {
		prevStatus = 'dismissed';
	} else {
		prevStatus = 'show';
	}

	if ( cmplz_banner && status.length>0 ) {
		cmplz_banner.classList.remove('cmplz-'+prevStatus);
		cmplz_banner.classList.add('cmplz-'+status );
		if ( cmplz_manage_consent_button ) {
			cmplz_manage_consent_button.classList.add('cmplz-'+prevStatus);
			cmplz_manage_consent_button.classList.remove('cmplz-'+status);
		}
	}

	if ( cmplz_banner_container && complianz.soft_cookiewall ) {
		cmplz_banner_container.classList.remove('cmplz-'+prevStatus);
		cmplz_banner_container.classList.add('cmplz-'+status, 'cmplz-soft-cookiewall' );
	}
	let event = new CustomEvent('cmplz_banner_status', { detail: status });
	document.dispatchEvent(event);
	cmplz_start_clean();
}

/*
 * Check if current visitor is a bot
 *
 * @returns {boolean}
 */
function cmplz_is_bot(){
	let botPattern = "(googlebot\/|Googlebot-Mobile|Google-InspectionTool|Googlebot-Image|Google favicon|Mediapartners-Google|bingbot|slurp|java|wget|curl|Commons-HttpClient|Python-urllib|libwww|httpunit|nutch|phpcrawl|msnbot|jyxobot|FAST-WebCrawler|FAST Enterprise Crawler|biglotron|teoma|convera|seekbot|gigablast|exabot|ngbot|ia_archiver|GingerCrawler|webmon |httrack|webcrawler|grub.org|UsineNouvelleCrawler|antibot|netresearchserver|speedy|fluffy|bibnum.bnf|findlink|msrbot|panscient|yacybot|AISearchBot|IOI|ips-agent|tagoobot|MJ12bot|dotbot|woriobot|yanga|buzzbot|mlbot|yandexbot|purebot|Linguee Bot|Voyager|CyberPatrol|voilabot|baiduspider|citeseerxbot|spbot|twengabot|postrank|turnitinbot|scribdbot|page2rss|sitebot|linkdex|Adidxbot|blekkobot|ezooms|dotbot|Mail.RU_Bot|discobot|heritrix|findthatfile|europarchive.org|NerdByNature.Bot|sistrix crawler|ahrefsbot|Aboundex|domaincrawler|wbsearchbot|summify|ccbot|edisterbot|seznambot|ec2linkfinder|gslfbot|aihitbot|intelium_bot|facebookexternalhit|yeti|RetrevoPageAnalyzer|lb-spider|sogou|lssbot|careerbot|wotbox|wocbot|ichiro|DuckDuckBot|lssrocketcrawler|drupact|webcompanycrawler|acoonbot|openindexspider|gnam gnam spider|web-archive-net.com.bot|backlinkcrawler|coccoc|integromedb|content crawler spider|toplistbot|seokicks-robot|it2media-domain-crawler|ip-web-crawler.com|siteexplorer.info|elisabot|proximic|changedetection|blexbot|arabot|WeSEE:Search|niki-bot|CrystalSemanticsBot|rogerbot|360Spider|psbot|InterfaxScanBot|Lipperhey SEO Service|CC Metadata Scaper|g00g1e.net|GrapeshotCrawler|urlappendbot|brainobot|fr-crawler|binlar|SimpleCrawler|Livelapbot|Twitterbot|cXensebot|smtbot|bnf.fr_bot|A6-Indexer|ADmantX|Facebot|Twitterbot|OrangeBot|memorybot|AdvBot|MegaIndex|SemanticScholarBot|ltx71|nerdybot|xovibot|BUbiNG|Qwantify|archive.org_bot|Applebot|TweetmemeBot|crawler4j|findxbot|SemrushBot|yoozBot|lipperhey|y!j-asr|Domain Re-Animator Bot|AddThis)";
	let reBot = new RegExp(botPattern, 'i');
	let userAgent = navigator.userAgent;
	return reBot.test(userAgent);
}
/*
 * Check if current visitor is a speedbot
 *
 * @returns {boolean}
 */
function cmplz_is_speedbot(){
	let userAgent = navigator.userAgent;
	let speedBotPattern = "(GTmetrix|pingdom|pingbot|Lighthouse)";
	let speedBot = new RegExp(speedBotPattern, 'i');
	return speedBot.test(userAgent);
}

/*
 * Check if there is consent for a category or service
 * @param category
 * @returns {boolean}
 */

window.cmplz_has_consent = function ( category ){
	if ( cmplz_is_bot() ) {
		return true;
	}

	if ( category === 'functional' ) {
		return true;
	}
	let has_consent, value;

	//if DNT is detected, we should only return the actual cookie value, and not look at the consenttype
	if ( cmplz_do_not_track() ){
		value = cmplz_get_cookie(category);
		has_consent = (value === 'allow');
		return has_consent;
	}

	/*
	 * categories
	 */
	value = cmplz_get_cookie(category);
	if ( (complianz.consenttype === 'optout' || complianz.consenttype === 'other') && value === '') {
		//if it's opt out and no cookie is set we should return true
		has_consent = true;
	} else {
		//all other situations, return only true if value is allow
		has_consent = (value === 'allow');
	}

	return has_consent;
}

/*
 * Check if a service has consent
 * @param service
 * @returns {boolean|*}
 */
window.cmplz_is_service_denied = function ( service ) {
	//Check if it's in the consented services cookie
	let consented_services_json = cmplz_get_cookie('consented_services');
	let consented_services;
	try {
		consented_services = JSON.parse(consented_services_json);
	} catch (e) {
		consented_services = {};
	}

	if ( !consented_services.hasOwnProperty( service ) ){
		return false;
	} else {
		return !consented_services[service];
	}
}

/*
 * Check if a service has consent
 * @param service
 * @param category
 * @returns {boolean|*}
 */
window.cmplz_has_service_consent = function ( service, category ) {
	//Check if it's in the consented services cookie
	let consented_services_json = cmplz_get_cookie('consented_services');
	let consented_services;
	try {
		consented_services = JSON.parse(consented_services_json);
	} catch (e) {
		consented_services = {};
	}

	if ( !consented_services.hasOwnProperty( service ) ){
		//default to the category
		return cmplz_has_consent( category );
	} else {
		return consented_services[service];
	}
}

/*
 * check if there's at least one service with consent
 * @returns {boolean}
 */
function cmplz_exists_service_consent(){
	let consented_services_json = cmplz_get_cookie('consented_services');
	let consented_services;
	try {
		consented_services = JSON.parse(consented_services_json);
		for (const key in consented_services) {
			if ( consented_services.hasOwnProperty(key) ) {
				if (consented_services[key] == true) {
					return true;
				}
			}
		}
	} catch (e) {
		return false;
	}
	return false;
}

/*
 * Set consent for a service
 * @param service
 * @param consented
 */
function cmplz_set_service_consent( service, consented ){
	let consented_services_json = cmplz_get_cookie('consented_services');
	let consented_services;
	try {
		consented_services = JSON.parse(consented_services_json);
	} catch (e) {
		consented_services = {};
	}
	consented_services[service] = consented;
	cmplz_set_cookie('consented_services', JSON.stringify(consented_services) );
	let details = {};
	details.service = service;
	details.value = consented;
	details.region = complianz.region;
	//when the status is changed, we may need to fire scripts again, so we reset it.
	cmplz_all_scripts_hook_fired = false;
	let event = new CustomEvent('cmplz_status_change_service', { detail: details });
	document.dispatchEvent(event);
}

/*
 * Remove all service consents
 */
function cmplz_clear_all_service_consents(){
	cmplz_set_cookie('consented_services', '');
}

/*
 * Get all consented or denied services
 */

function cmplz_get_all_service_consents(){
	let consented_services_json = cmplz_get_cookie('consented_services');
	let consented_services;
	try {
		consented_services = JSON.parse(consented_services_json);
	} catch (e) {
		consented_services = {};
	}
	return consented_services;
}
/*
 * Get cookie path
 * @returns {*}
 */
function cmplz_get_cookie_path(){
	return typeof complianz.cookie_path !== 'undefined' && complianz.cookie_path !== '' ? complianz.cookie_path : '/';
}

/*
 * retrieve domain to set the cookies on
 * @returns {string}
 */
function cmplz_get_cookie_domain() {
	if (complianz.set_cookies_on_root == 1 && complianz.cookie_domain.length > 3 && !complianz.cookie_domain.includes('localhost')) {
		return complianz.cookie_domain;
	}
	return '';
}

/*
 * Set consent for a category
 * @param category
 * @param value
 */
window.cmplz_set_consent = function (category, value){
	cmplz_set_accepted_cookie_policy_id();

	//functional is always allow
	value = category==='functional' ? 'allow' : value;
	let previous_value = cmplz_get_cookie(category);

	//keep checkboxes in banner and on cookie policy in sync
	//do this before the change check to ensure sync: https://github.com/Really-Simple-Plugins/complianz-gdpr/issues/324
	let checked = value === 'allow';
	document.querySelectorAll('input.cmplz-'+category).forEach(obj => {
		obj.checked = checked;
	});

	//do not trigger a change event if nothing has changed.
	if ( previous_value === value ) {
		return;
	}

	cmplz_set_cookie(category, value);
	if ( value === 'allow' ) {
		cmplz_enable_category(category);
	}

	cmplz_wp_set_consent(category, value);
	if ( category === 'statistics' ) {
		cmplz_wp_set_consent('statistics-anonymous', 'allow');
	}

	let details = new Object();
	details.category = category;
	details.value = value;
	details.region = complianz.region;
	details.categories = cmplz_accepted_categories();
	//when the status is changed, we may need to fire scripts again, so we reset it.
	cmplz_all_scripts_hook_fired = false;
	let event = new CustomEvent('cmplz_status_change', { detail: details });
	document.dispatchEvent(event);
	if ( category === 'marketing' && value === 'deny' && previous_value === 'allow' ) {
		cmplz_integrations_revoke();
		//give the code some time to finish, so our track status code can send a signal to the backend.
		setTimeout(function(){
			cmplz_reload_browser_compatible()
		}, 500);
	}
}

/*
* In some browsers, like firefox, the reload does not force reload, but keeps cached data, causing e.g. Google Maps to load anyway.
*/
function cmplz_reload_browser_compatible(){
	if( navigator.userAgent.toLowerCase().indexOf('firefox') > -1 ){
		const url = new URL(window.location.href);
		url.searchParams.set('cmplz-force-reload', Date.now().toString());
		window.location.href = url.toString();
	} else {
		window.location.reload();
	}
}

/*
 * We use ajax to check the consenttype based on region, otherwise caching could prevent the user specific warning
 *
 * */

var cmplz_user_data = [];
//check if it's already stored
if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_user_data) {
	cmplz_user_data = JSON.parse(sessionStorage.cmplz_user_data);
}

//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version
if ( complianz.geoip == 1 && (cmplz_user_data.length == 0 || (cmplz_user_data.version !== complianz.version) || (cmplz_user_data.banner_version !== complianz.banner_version)) ) {

	let request = new XMLHttpRequest();
	let cmplzUserRegion = cmplz_get_url_parameter(window.location.href, 'cmplz_user_region');
	cmplzUserRegion = cmplzUserRegion ? '&cmplz_user_region=' + cmplzUserRegion : '';
	request.open('GET', complianz.url+'banner?'+complianz.locale+cmplzUserRegion, true);
	request.setRequestHeader('Content-type', 'application/json');
	request.send();
	request.onload = function() {
		cmplz_user_data = JSON.parse(request.response);
		sessionStorage.cmplz_user_data = JSON.stringify(cmplz_user_data);
		conditionally_show_banner();
	};
} else {
	conditionally_show_banner();
}

/*
 *  when ab testing, or using records of consent, we want to keep track of the unique user id
 */

if ( complianz.store_consent == 1 ) {
	var cmplz_id_cookie = cmplz_get_cookie('id');
	var cmplz_id_session = '';
	var cmplz_id = '';
	if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_id) {
		cmplz_id_session = JSON.parse(sessionStorage.cmplz_id);
	}

	if ( cmplz_id_cookie.length == 0 && cmplz_id_session.length > 0 ) {
		cmplz_id = cmplz_id_session;
		cmplz_set_cookie('id', cmplz_id );
	}

	if ( cmplz_id_cookie.length > 0 && cmplz_id_session.length == 0 ) {
		cmplz_id = cmplz_id_cookie;
	}

	if ( typeof (Storage) !== "undefined" ) {
		sessionStorage.cmplz_id = JSON.stringify(cmplz_id);
	}
}

// visibilitychange and pagehide work in more browsers hence we check if they are supported and try to use them
document.addEventListener('visibilitychange', function () {
	if ( document.visibilityState === 'hidden' ) {
		cmplz_track_status_end();
	}
});
window.addEventListener("pagehide", cmplz_track_status_end, false );
window.addEventListener("beforeunload", cmplz_track_status_end, false );

function cmplz_track_status_end(){
	if ( !cmplz_consent_stored_once ) {
		cmplz_track_status();
	}
}

/*
 * This creates an API which devs can use to trigger actions in complianz.
 */
document.addEventListener('cmplz_consent_action', function (e) {
	cmplz_set_consent( e.detail.category , 'allow' );
	cmplz_fire_categories_event();
	cmplz_track_status();
});



/*
 * For both opt-in and opt-out, clicking cmplz-accept should result in accepting all categories
 */
cmplz_add_event('click', '.cmplz-accept', function(e){
	e.preventDefault();
	setTimeout( () => {
		cmplz_accept_all();
		cmplz_set_banner_status('dismissed');
		cmplz_fire_categories_event();
		cmplz_track_status();
	},0);
});

/*
 *  Accept marketing cookies by clicking any other link cookie acceptance from a custom link
 */

//cmplz-accept-marketing is deprecated
cmplz_add_event('click', '.cmplz-accept-category, .cmplz-accept-marketing', function(e){
	e.preventDefault();
	let obj = e.target;
	let service = obj.getAttribute('data-service');
	let category = obj.getAttribute('data-category');
	category = category ? category : 'marketing';
	if ( complianz.clean_cookies == 1 && typeof service !== 'undefined' && service ){
		cmplz_set_service_consent(service, true);
		cmplz_enable_category('', 'general');
		cmplz_enable_category('', service);
	} else {
		//we're activating a category, so do not need service activation here.
		// cmplz_enable_category('', 'general');
		cmplz_set_consent( category, 'allow' );
	}
	cmplz_set_banner_status('dismissed');
	cmplz_fire_categories_event();
	cmplz_track_status();
});

/*
 * Accept a specific service
 */
cmplz_add_event('click', '.cmplz-accept-service', function(e){
	let obj = e.target;
	//INPUT should be handled by change event, these are checkboxes on the cookie policy
	let tagName = obj.tagName;
	if ( tagName === 'INPUT' ) {
		return;
	}
	let service = obj.getAttribute('data-service');
	if ( typeof service !== 'undefined' ){
		cmplz_set_service_consent(service, true);
		cmplz_enable_category('', 'general');
		cmplz_enable_category('', service);
	}
	cmplz_fire_categories_event();
	cmplz_track_status();
});
/*
 * Accept a specific service
 */
cmplz_add_event('change', '.cmplz-accept-service', function(e){
	let obj = e.target;
	let tagName = obj.tagName;
	let service = obj.getAttribute('data-service');
	if ( typeof service !== 'undefined' ) {
		//inputs are from the consent per service option on the cookie policy.
		if ( tagName === 'INPUT' ) {
			cmplz_set_banner_status('dismissed');
			if ( obj.checked ){
				cmplz_set_service_consent(service, true);
				cmplz_enable_category('', service);
			} else {
				cmplz_set_service_consent(service, false);
				//give our track status time to finish
				setTimeout(function(){
					cmplz_reload_browser_compatible()
				}, 500);
			}
			//if not input, it's a placeholder
		} else {
			e.preventDefault();
			cmplz_set_service_consent(service, true);
			cmplz_enable_category('', 'general');
			cmplz_enable_category('', service);

			//give our track status time to finish
			setTimeout(function(){
				cmplz_reload_browser_compatible()
			}, 500);
		}
	}
	cmplz_fire_categories_event();
	cmplz_track_status();
});



/*
 * On the banner, clicking a category should fire the category only after the save button is clicked.
 *
 */
cmplz_add_event('click', '.cmplz-save-preferences', function(e){
	let obj = e.target;
	cmplz_banner = obj.closest('.cmplz-cookiebanner');
	let consented_categories = [];

	for (let key in cmplz_categories) {
		if ( cmplz_categories.hasOwnProperty(key) ) {
			let category = cmplz_categories[key];
			let categoryElement = cmplz_banner.querySelector('input.cmplz-' + category);
			if (categoryElement && categoryElement.checked) {
				consented_categories.push(category);
			}
		}
	}
	cmplz_fire_before_categories_consent(consented_categories);
	for (let key in cmplz_categories) {
		if ( cmplz_categories.hasOwnProperty(key) ) {
			let category = cmplz_categories[key];
			if (consented_categories.includes(category)) {
				cmplz_set_consent(category, 'allow');
			} else {
				cmplz_set_consent(category, 'deny');
			}
		}
	}
	cmplz_set_banner_status('dismissed');
	cmplz_fire_categories_event();
	cmplz_track_status();
});

cmplz_add_event('click', '.cmplz-close', function(e){
	cmplz_set_banner_status('dismissed');
});

cmplz_add_event('click', '.cmplz-view-preferences', function(e){
	let obj = e.target;
	cmplz_banner = obj.closest('.cmplz-cookiebanner');
	if ( cmplz_banner.querySelector('.cmplz-categories').classList.contains('cmplz-fade-in')) {
		cmplz_banner.classList.remove('cmplz-categories-visible');
		cmplz_banner.querySelector('.cmplz-categories' ).classList.remove('cmplz-fade-in');
		cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'block';
		cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'none';
	} else {
		cmplz_banner.classList.add('cmplz-categories-visible');
		cmplz_banner.querySelector('.cmplz-categories' ).classList.add('cmplz-fade-in');
		cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'none';
		cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'block';
	}
});
/*
 * On the cookie policy, clicking a category should fire the category immediately
 *
 */
cmplz_add_event('change', '.cmplz-manage-consent-container .cmplz-category', function(e){
	for (let key in cmplz_categories) {
		if ( cmplz_categories.hasOwnProperty(key) ) {
			let category = cmplz_categories[key];
			let categoryElement = document.querySelector('.cmplz-manage-consent-container input.cmplz-' + category);
			if (categoryElement) {
				if (categoryElement.checked) {
					cmplz_set_consent(category, 'allow');
				} else {
					cmplz_set_consent(category, 'deny');
				}
				cmplz_set_banner_status('dismissed');
				cmplz_fire_categories_event();
				cmplz_track_status();
			}
		}
	}

});

cmplz_add_event('click', '.cmplz-deny', function(e){
	e.preventDefault();
	cmplz_set_banner_status('dismissed');
	cmplz_deny_all();

});

cmplz_add_event('click', 'button.cmplz-manage-settings', function(e){
	e.preventDefault();
	let catsContainer = document.querySelector('.cmplz-cookiebanner .cmplz-categories');
	let saveSettings = document.querySelector('.cmplz-save-settings');
	let manageSettings = document.querySelector('button.cmplz-manage-settings');
	if ( !cmplz_is_hidden(catsContainer) ){
		saveSettings.style.display='none';
		manageSettings.style.display = 'block';
		catsContainer.style.display='none';
	} else {
		saveSettings.style.display = 'block';
		manageSettings.style.display='none';
		catsContainer.style.display = 'block';
	}
});

cmplz_add_event('click', 'button.cmplz-manage-consent', function(e){
	e.preventDefault();
	cmplz_set_banner_status('show');
});

/*
 * Handle dismiss on scroll and dismiss on timeout
 */
function cmplz_set_up_auto_dismiss() {
	if ( complianz.consenttype === 'optout' ) {
		if ( complianz.dismiss_on_scroll==1 ) {
			let onWindowScroll = function(evt) {
				if (window.pageYOffset > Math.floor(400)) {
					cmplz_set_banner_status('dismissed');
					cmplz_fire_categories_event();
					cmplz_track_status();
					window.removeEventListener('scroll', onWindowScroll);
					this.onWindowScroll = null;
				}
			};
			window.addEventListener('scroll', onWindowScroll);
		}

		let delay = parseInt(complianz.dismiss_timeout);
		if ( delay > 0 ) {
			window.setTimeout(function () {
				cmplz_set_banner_status('dismissed');
				cmplz_fire_categories_event();
				cmplz_track_status();
			}, Math.floor(delay));
		}
	}
}

/*
 * Fire a event wich passes all consented categories
 * Separated from the actual category consent because we want to bundle it in one event
 */
function cmplz_fire_categories_event(){
	let details = new Object();
	details.category = cmplz_highest_accepted_category();
	details.categories = cmplz_accepted_categories();
	details.region = complianz.region;
	let event = new CustomEvent('cmplz_fire_categories', { detail: details });
	document.dispatchEvent(event);
}
/*
 * Track the status of current consent
 * @param status
 */

function cmplz_track_status( status ) {
	let cats = [];
	status = typeof status !== 'undefined' ? status : false;

	let event = new CustomEvent('cmplz_track_status', { detail: status });
	document.dispatchEvent(event);

	if ( !status ) {
		cats = cmplz_accepted_categories();
	} else {
		cats = [status];
	}
	cmplz_set_category_as_body_class();
	let saved_cats, saved_services;
	try {saved_cats = JSON.parse(cmplz_get_cookie('saved_categories'));} catch (e) {saved_cats = {};}
	try {saved_services = JSON.parse(cmplz_get_cookie('saved_services'));} catch (e) {saved_services = {};}
	let consented_services = cmplz_get_all_service_consents();

	//compare current cats with saved cats. When there are no changes, do nothing.
	if (cmplz_equals(saved_cats, cats) && cmplz_equals(saved_services, consented_services)) {
		return;
	}

	if ( complianz.store_consent != 1 || cmplz_is_bot() || cmplz_is_speedbot() ) {
		return;
	}

	//keep track of the fact that the status was saved at least once
	cmplz_set_cookie('saved_categories', JSON.stringify(cats));
	cmplz_set_cookie('saved_services', JSON.stringify(consented_services));
	cmplz_consent_stored_once = true;

	let data;
	let request = new XMLHttpRequest();
	request.open('POST', complianz.url+'track', true);
	data = {
		'consented_categories': cats,
		'consented_services':consented_services,
		'consenttype': window.wp_consent_type,//store the source consenttype, as our complianz.consenttype will not include optinstats.
	};

	request.setRequestHeader('Content-type', 'application/json');
	request.send(JSON.stringify(data));

}

/*
 * Get accepted categories
 *
 * @returns {string}
 */
function cmplz_accepted_categories() {
	let consentedCategories = cmplz_categories;
	let consentedTemp = [];

	//because array filter changes keys, we make a temp arr
	for (let key in consentedCategories) {
		if ( consentedCategories.hasOwnProperty(key) ) {
			let category = consentedCategories[key];
			if (cmplz_has_consent(category)) {
				consentedTemp.push(category);
			}
		}
	}

	consentedCategories = consentedCategories.filter(function(value, index, consentedCategories){
		return cmplz_in_array(value, consentedTemp);
	});
	return consentedCategories;
}

/*
 * Enable the checkbox for each category which was enabled
 *
 * */

function cmplz_sync_category_checkboxes() {
	for ( let key in cmplz_categories ) {
		if ( cmplz_categories.hasOwnProperty(key) ) {
			let category = cmplz_categories[key];
			if ( cmplz_has_consent(category) || category === 'functional' ) {
				document.querySelectorAll('input.cmplz-' + category).forEach(obj => {
					obj.checked = true;
				});
			} else {
				document.querySelectorAll('input.cmplz-' + category).forEach(obj => {
					obj.checked = false;
				});
			}
		}

		document.querySelectorAll('.cmplz-accept-service').forEach(obj => {
			let service = obj.getAttribute('data-service');
			let category = obj.getAttribute('data-category');
			if ( cmplz_has_service_consent( service, category ) ) {
				obj.checked = true;
			} else if ( cmplz_is_service_denied( service ) ) {
				obj.checked = false;
			} else {
				//no consent on service level, check if it's category has consent.
				let category = obj.getAttribute('data-category' );
				obj.checked = !!cmplz_has_consent(category);
			}
		});
	}
}

/*
 * Merge two objects
 *
 * */

function cmplz_merge_object(userdata, ajax_data) {
	let output = {};
	//first, we fill the important data.
	for (let key in ajax_data) {
		if (ajax_data.hasOwnProperty(key)) output[key] = ajax_data[key];
	}

	//conditionally add static data
	for (let key in userdata) {
		//only add if not in ajax_data
		if (!ajax_data.hasOwnProperty(key) || typeof ajax_data[key] === 'undefined') {
			if (userdata.hasOwnProperty(key)) output[key] = userdata[key];
		}
	}

	return output;
}

/*
 * Clear all our own cookies, to make sure path issues are resolved.
 *
 *
 */
function cmplz_clear_cookies (cookie_part) {
	if (typeof document === 'undefined') {
		return false;
	}

	let foundCookie = false;
	let secure = window.location.protocol === 'https:' ? ';secure' : '';
	let expires = 'expires=' + new Date().toGMTString();
	let pathParts = location.pathname.replace(/^\/|\/$/g, '').split('/');

	// Loop through all cookies
	document.cookie.split('; ').forEach(function(cookie) {
		let cookieName = cookie.split(';')[0].split('=')[0];

		// If the cookie contains cookie_part, try to delete it
		if (cookieName.indexOf(cookie_part) !== -1) {
			foundCookie = true;
			let domainParts = window.location.hostname.split('.');
			let skipLast = domainParts.length > 1;

			// Clear cookies on root path and subpaths
			pathParts.forEach(function(pathPart) {
				let path = '/' + pathPart;
				document.cookie = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + ';' + expires + ';domain=.' + domainParts.join('.') + ';path=' + path;
				document.cookie = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + ';' + expires + ';domain=.' + domainParts.join('.') + ';path=' + path + '/';
			});

			// Clear cookies on parent domains
			while (domainParts.length > 0) {
				let domain = '.' + domainParts.join('.');
				domainParts.shift();
				if (skipLast && domainParts.length === 1) domainParts.shift();

				pathParts.forEach(function(pathPart) {
					let path = '/' + pathPart;
					document.cookie = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + ';' + expires + ';domain=' + domain + ';path=' + path;
					document.cookie = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + ';' + expires + ';domain=' + domain + ';path=' + path + '/';
				});
			}
		}
	});

	// To prevent a double reload, we preserve the cookie policy id
	cmplz_set_accepted_cookie_policy_id();

	return foundCookie;
}

/*
 *
 * If a policy is accepted, save this in the user policy id
 *
 * */

function cmplz_set_accepted_cookie_policy_id() {
	cmplz_set_cookie('policy_id', complianz.current_policy_id);
}

/*
 * For supported integrations, initialize the not consented state
 *
 * */

function cmplz_integrations_init() {
	let cookiesToSet = complianz.set_cookies;
	//check if we have scripts that need to be set to true on init.
	for (let key in cookiesToSet) {
		if (cookiesToSet.hasOwnProperty(key) && cookiesToSet[key][1] === '1') {
			cmplz_set_cookie(key, cookiesToSet[key][1], false);
		}
	}
}

/*
 * For supported integrations, revoke consent
 *
 * */
function cmplz_integrations_revoke() {
	let cookiesToSet = complianz.set_cookies;
	for (let key in cookiesToSet) {
		if (cookiesToSet.hasOwnProperty(key)) {
			cmplz_set_cookie(key, cookiesToSet[key][1], false);
			if ( cookiesToSet[key][1] == false ){
				cmplz_clear_cookies(key);
			}
		}
	}
}

/*
 * For supported integrations, set consent
 *
 * */

function cmplz_set_integrations_cookies() {
	let cookiesToSet = complianz.set_cookies;
	for (let key in cookiesToSet) {
		if (cookiesToSet.hasOwnProperty(key)) {
			cmplz_set_cookie(key, cookiesToSet[key][0], false);
		}
	}
}

function cmplz_get_url_parameter(sPageURL, sParam) {
	if (!sPageURL || typeof sPageURL === 'undefined' || sPageURL.indexOf('?') === -1) {
		return false;
	}

	const queryString = sPageURL.split('?')[1];
	if (!queryString) return false;

	const sURLVariables = queryString.split('&');
	for (let i = 0; i < sURLVariables.length; i++) {
		const sParameterName = sURLVariables[i].split('=');
		if (sParameterName[0] === sParam) {
			return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
		}
	}

	return false;
}

/*
 * If the parameter cmplz_region_redirect =true is passed, find the user's region, and redirect.
 */
function cmplz_maybe_auto_redirect() {
	let redirect = cmplz_get_url_parameter(window.location.href, 'cmplz_region_redirect');
	let region = cmplz_get_url_parameter(window.location.href, 'cmplz-region');
	if (redirect && !region) {
		let newUrl = window.location.href.split('#')[0] + '&cmplz-region=' + complianz.region;
		let hash = window.location.hash;
		window.location.href = newUrl + hash;
	}
}

/*
 * wrapper to set consent for wp consent API. If consent API is not active, do nothing
 * @param type
 * @param value
 */
function cmplz_wp_set_consent(type, value) {
	//wp consent api integration
	if (typeof wp_set_consent == 'function') {
		wp_set_consent(type, value);
	}
}

var cmplz_cookie_data = [];
var cmplzCleanCookieInterval;
function cmplz_start_clean(){
	if ( complianz.clean_cookies == 1 ) {
		//check if it's already stored
		if (typeof (Storage) !== "undefined" ) {
			cmplz_cookie_data = JSON.parse( sessionStorage.getItem('cmplz_cookie_data') );
		}
		//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version
		if ( !cmplz_cookie_data || cmplz_cookie_data.length === 0 ) {
			let request = new XMLHttpRequest();
			request.open('GET', complianz.url+'cookie_data', true);
			request.setRequestHeader('Content-type', 'application/json');
			request.send();
			request.onload = function() {
				cmplz_cookie_data = JSON.parse(request.response);
				sessionStorage.setItem('cmplz_cookie_data', JSON.stringify(cmplz_cookie_data) );
				cmplz_setup_clean_interval();
			};
		} else {
			cmplz_setup_clean_interval();
		}
	}
}

/*
* Execute the cleanup of cookies
*/
function cmplz_do_cleanup() {
	const consent_categories = ['preferences', 'statistics', 'marketing'];
	for (const category of consent_categories) {
		if (!cmplz_has_consent(category) && cmplz_cookie_data.hasOwnProperty(category)) {
			const services = cmplz_cookie_data[category];

			for (const service in services) {
				if (!cmplz_has_service_consent(service, category)) {
					const cookies = services[service];

					for (const item of cookies) {
						cmplz_clear_cookies(item);
						cmplz_clear_storage(item);
					}
				}
			}
		}
	}
}


function cmplz_setup_clean_interval(){
	// if the cookie data array is empty, return, nothing to do.
	if ( !cmplz_cookie_data ) {
		return;
	}
	//check if it's already activated
	if ( cmplzCleanCookieInterval ) {
		return;
	}
	//one straight away, then every second
	cmplz_do_cleanup();
	cmplzCleanCookieInterval = setInterval(cmplz_do_cleanup, 1000 );
}

/*
 * Clear an item from either session or localstorage
 * @param item
 */
function cmplz_clear_storage(item){
	if (typeof (Storage) !== "undefined" ) {
		if ( localStorage.getItem(item) ) {
			localStorage.removeItem(item);
		}
		if ( sessionStorage.getItem(item) ) {
			sessionStorage.removeItem(item);
		}
	}
}
/*
 * Load revoke options
 */

function cmplz_load_manage_consent_container() {
	//don't load manage html code in the block editor
	let manage_consent_container = document.querySelector('.cmplz-manage-consent-container');
	let is_block_editor = false;//document.querySelector('.wp-admin .cmplz-unlinked-mode');
	if ( manage_consent_container && !is_block_editor ) {

		let request = new XMLHttpRequest();
		request.open('GET', complianz.url+'manage_consent_html?'+complianz.locale, true);
		request.setRequestHeader('Content-type', 'application/json');
		request.send();
		request.onload = function() {
			let html = JSON.parse(request.response);
			manage_consent_container.insertAdjacentHTML( 'beforeend', html );
			cmplz_sync_category_checkboxes();
			let nojavascript = document.querySelector('#cmplz-manage-consent-container-nojavascript')
			nojavascript.style.display = 'none';
			manage_consent_container.style.display = 'block';
			let event = new CustomEvent('cmplz_manage_consent_container_loaded');
			document.dispatchEvent(event);
		};
	}
}

/*
 * Make slider radio's tabable
 */

cmplz_add_event('keypress', '.cmplz-banner-slider label', function(e){
	let keycode = (e.keyCode ? e.keyCode : e.which);
	if (keycode == 32) {
		document.activeElement.click();
	}
});

/*
 * Make close button closable with enter
 */
cmplz_add_event('keypress', '.cmplz-cookiebanner .cmplz-header .cmplz-close', function(e){
	let keycode = (e.keyCode ? e.keyCode : e.which);
	if ( keycode == 13 ) {
		document.activeElement.click();
	}
});

/*
 * Compare two arrays
 * @param array
 * @returns {boolean}
 */
function cmplz_equals (array_1, array_2) {
	if ( !Array.isArray(array_1) ) {
		array_1 = Object.keys(array_1);
		array_2 = Object.keys(array_2);
	}
	// if the other array is a falsy value, return
	if (!array_1 || !array_2)
		return false;

	// compare lengths - can save a lot of time
	if (array_1.length !== array_2.length)
		return false;

	for (let i = 0, l=array_1.length; i < l; i++) {
		// Check if we have nested arrays
		if (array_1[i] instanceof Array && array_2[i] instanceof Array) {
			// recurse into the nested arrays
			if (!cmplz_equals(array_1[i], array_2[i]))
				return false;
		}
		else if (array_1[i] !== array_2[i]) {
			return false;
		}
	}
	return true;
}

/*
* Copy all element atributes to the new element
*/
function cmplzCopyAttributes(source, target) {
	const excludes = ['type', 'data-service', 'data-category', 'async'];
	Array.from(source.attributes).forEach(attribute => {
		if (attribute.nodeName === 'data-script-type' && attribute.nodeValue === 'module') {
			target.setAttribute('type', 'module');
			target.removeAttribute('data-script-type');
		} else if (!excludes.includes(attribute.nodeName)) {
			target.setAttribute(attribute.nodeName, attribute.nodeValue);
		}
	});
}


/*
 * Hooked into jquery
 */
var cmplz_has_wp_video = document.querySelector('.cmplz-wp-video-shortcode');
var cmplz_times_checked = 0;
if ('undefined' != typeof window.jQuery) {
	jQuery(document).ready(function ($) {
		if ( cmplz_has_wp_video ) {
			document.addEventListener("cmplz_enable_category", function (consentData) {
				cmplz_activate_wp_video();
			});

			let cmplzInterval = setInterval(function(){
				cmplz_times_checked+=1;
				if ( document.querySelector('.cmplz-wp-video-shortcode') && cmplz_times_checked<100) {
					cmplz_activate_wp_video();
				} else {
					clearInterval(cmplzInterval);
				}
			}, 500);
		}

		/*
		 * WordPress legacy shortcode
		 */
		function cmplz_activate_wp_video(again) {
			if ( !document.querySelector('.cmplz-wp-video-shortcode') ) {
				return;
			}
			let categories = cmplz_accepted_categories();
			let services = cmplz_get_all_service_consents();
			let selectorVideo = '';
			let selectorVideos = [];
			for (let c_key in categories) {
				if (categories.hasOwnProperty(c_key)) {
					let category = categories[c_key];
					if (category==='functional') {
						break;
					}
					selectorVideos.push('.cmplz-wp-video-shortcode[data-category="'+category+'"]');
				}
			}
			for (let s_key in services) {
				if (services.hasOwnProperty(s_key)) {
					selectorVideos.push('.cmplz-wp-video-shortcode[data-service="' + s_key + '"]');
				}
			}
			selectorVideo = selectorVideos.join(',');
			let should_initialize_video = false;
			if ( selectorVideo.length>0 ) {
				document.querySelectorAll(selectorVideo).forEach(obj => {
					should_initialize_video = true;
					obj.setAttribute('controls', 'controls');
					obj.classList.add('wp-video-shortcode', 'cmplz-processed');
					obj.classList.remove('cmplz-wp-video-shortcode');
					obj.closest('.cmplz-wp-video').classList.remove('cmplz-wp-video');

					let blocked_notice = obj.closest('.wp-video').querySelector('.cmplz-blocked-content-notice');
					if (blocked_notice) {
						blocked_notice.parentElement.removeChild(blocked_notice);
					}
					obj.classList.remove('cmplz-blocked-content-container');
				});
			}

			if ( should_initialize_video ) {
				//in normal setup, this should work. e.g. with primavera theme not, then we init per element.
				if (window.wp.mediaelement) {
					window.wp.mediaelement.initialize()
				} else {
					let settings={};
					settings.videoWidth='100%';
					settings.videoHeight='100%';
					settings.enableAutosize=true;
					$( '.wp-video-shortcode' ).mediaelementplayer( settings );
				}
			}
		}

		/*
		 * Activate fitvids on the parent element if active
		 *  a.o. Beaverbuilder
		 */
		document.querySelectorAll('.cmplz-video.cmplz-activated').forEach(obj => {
			cmplz_activate_fitvids(obj);
		});

		document.addEventListener("cmplz_enable_category", function (e) {
			document.querySelectorAll('.cmplz-video.cmplz-activated').forEach(obj => {
				cmplz_activate_fitvids(obj);
			});
		});

		function cmplz_activate_fitvids(obj){
			//turn obj into jquery object
			let $obj = $(obj);
			if (typeof $obj.parent().fitVids === 'function') {
				$obj.parent().fitVids();
			}
		}
	});
}
حكاية أول حوار مع روبوت : محمد طه يروى الكواليس – tahkoom.com
تفاعل

حكاية أول حوار مع روبوت : محمد طه يروى الكواليس

أجابت الآلة على الأسئلة ؟: ماذا قال روبوت ل محمد طه؟

بعد 8 سنوات .. تنبؤات الروبوت تتحول إلى واقع..

حروب 2025 في حوار منذ2017؟

: محمد طه يكشف أسرار حول الذكاء الاصطناعي

كتبت : فرح سمير

تضمن حواراً فريدًا من نوعه، BBC في عام 2017، شهد الإعلام العربي حدثًا غير مسبوق، حيث تم بث مباشر عبر قناة العربية

أُجري مع روبوت مدعوم بالذكاء الاصطناعي يحاكي البشر .وكان هذا الحوار من تقديم الإعلامي محمد طه، مراسل الشؤون التكنولوجية في القناة

منذ ذلك الحين، واصل محمد طه تقديم أبرز التقارير والتغطيات لأهم المؤتمرات العالمية، وكان دائمًا مميز ا في تناول أحدث التطورات التكنولوجية وفي هذا اللقاء الحصري، يحدثنا عن كواليس حواره مع الروبوت “صوفيا”، ويتطرق إلى آرائه حول الذكاء الاصطناعي، ومستقبل الإعلام، والتحولات التقنية التي باتت تؤثر في كل القطاعات

– صف لي شعورك عندما أجابك الروبوت، واستطاع بالفعل مجاراة الحوار، نظرًا لأن المقابلة كانت في عام 2017 ؟

في البداية، كان لدي انطباع بأن الروبوت قد لا يكون كائناً مستقلًً، بل ربما يكون هناك شخص ما يتواصل معه أو يدعمه في تقديم الإجابات. لم أكن مقتنعاً في البداية بقدرة الروبوت على الرد على أسئلتي بشكل مستقل دون أي مساعدة من شخص آخر.هذا الأمر لم يكن شائعاً كما هو اليوم. 

أثناء تواجدي في معرض، تم إخباري بإمكانية إجراء محادثة مع روبوت، ولم أصدق ذلك. كان انطباعي الأول أن هناك شخصًا يستمع إلى سؤالي ويقوم بالرد عليه بشكل مستقل ودون تدخل بشري. لم أكن أتخيل أن الروبوت قادر على تقديم إجابات مباشرة من مكان ما أو من غرفة تحكم.  

– هل قمَتَ بتعديل أسلوبك الصحفي أو الحواري ليتناسب مع قدرة الروبوت على معالجة الأمر والتجاوب معك؟

كان هدفي الأساسي خلال الحوار ه والحفاظ على طبيعية التفاعل، وه وما شكل تحديًا كبيرًا. فعندما تواجه جهازًا توجه له أسئلة ويقوم بالرد عليك، فإن ذلك كان يعتبر في السابق نوعًا من الخيال. نحن في مجال الصحافة والإعلام نملك خبرة واسعة في التعامل مع البشر، حيث يمكنني رؤية تعبيرات وجهك وتفاعل جسدك مما يساعدني على تعديل أسلوبي وفق ذلك. لكن عند التعامل مع الروبوت، تفتقر إلى تعبيرات الوجه والملامح التفاعلية، مما يجعل ردود الفعل غير قابلة للتنب ؤ.

ما الذي لاحظته من فروقات واضحة في طريقة التعامل مع روبوت مقارنة بمقابلة إعلامية طبيعية مع إنسان؟

بالتأكيد هناك اختلافات تتعلق بتحضير المقابلة. عند إجراء مقابلة مع إنسان، يتم إعداد الحوار بناءً على شخصية الضيف وخلفيته. أما بالنسبة للروبوت فلم أكن أملك معلومات مسبقة عنه. كان تركيزي منصبًا على طبيعة الروبوت نفسه وعلاقته بالإنسان ومستقبله.

ذكرت في بداية المراسلة أن ردود أفعالها تشبه البشر، فهل تشبه ردود أفعال الروبوت وتعبير وجهه الإنسان؟ كما ذكرت أثناء تصوير المقابلة أن “الروبوت” المصنوع يحُاكي الأنثى البشرية، وحصل على الجنسية السعودية؟

نعم ذكرت بالفعل جنسيتهاً ولقد ذكرت بالفعل أن للروبوت تعبيرات وجه وحركات معينة تجعل الشخص يتساءل عما إذا كان يتعامل مع كائن بشري أو شبه بشري أو آلة. خلًل المقابلة لم نكن معتادين على هذه التقنية الجديدة.

– من خلال الحوار مع الروبوت، هل ترى أن الاندماج والتعامل مع الروبوتات يُعد تحدياً، أم أنه سهل التأقلم؟ وهل يمثل هذا تحدياً لنا كإعلاميين أو كبشر عمومًا؟

لا أعتقد أنه يمثل تحديًا كبيرًا؛ فقد أصبح الناس معتادين بشكل متزايد على الذكاء الاصطناعي وبدأوا يتأقلمون معه بسهولة. سأعطيك مثالًا آخر: كنتُ في إحدى الدول، وطلبتُ بعض أدوات تنظيف الأسنان، وعندما فتحت الباب، فوجئت بأن روبوت أحضرها لي. لم أستغرب، لأني بالفعل أصبحت أتوقع مثل هذه الأمور .

 في وقت الحوار عام 2017، هل واجهت أي صعوبات أو تحديات؟

بالتأكيد كانت هناك حالة من الاستغراب وكان التحدي يكمن في الحفاظ على أسلوب تلقائي وطبيعي رغم أنني كنت أتحدث إلى آلة. كان عليّ أن أتعامل معها كإنسان حقيقي، وأن أطرح عليها أسئلة كما أفعل في مقابلاتي المعتادة، حتى يكون الحوار سلسًا.

– خلال الحوار، طرحتَ سؤا الا: “بماذا ترغبين في العمل في المستقبل؟” فأجابت الروبوت “صوفيا” بإجابة مفاجئة حول التظاهرات الدموية. كيف استقبلت هذه الإجابة؟

كانت إجابتها صادمة للغاية وقد أثارت تساؤلات حول دقة توقعاتها والخوارزميات المستخدمة خلف تلك التحليلات التي صرحتها وكانت “في المستقبل سيكون هناك تظاهرات دموية وصراعات ما لم نصبح أكثر ذكاءً واجتماعية مثلي، وربما نساعد في التعامل مع هذا الوضع.”

في ذلك الوقت، لم تكن هناك مؤشرات على أي حروب أو صراعات، بل كانت الأمور مستقرة نسب ايا. لكن مع مرور السنوات، وقعت فعل ايا أحداث دموية وصراعات كبيرة.

هذا يثير التساؤلات حول دقة توقعات الذكاء الاصطناعي، والخوارزميات التي تقف خلف هذه التحليلات.  

هل تعتقد أن توقعاتها كانت مبنية على خوارزميات دقيقة، أم تدخل بشري؟

قد تكون مستندة إلى تحليلات بشرية أ و تقارير صحفية؛ فالروبوت لا يفكر كما نفكر، بل يعتمد على البيانات والخوارزميات المعقدة لتقديم توقعاته المستقبلية. هذا يجعلنا نعود إلى التساؤل: إلى أي مدى تستطيع الروبوتات أن تتعلّم ذاتيًا؟ وهل يمكن أن تتخذ قرارات مستقلة مستقبلاً ؟

هل من الممكن أن تنشئ الروبوتات شركات وتدير أعما الا مستقلة ؟

نعم، كان هناك تقارير أعدتها عن روبوتات قامت بتأسيس شركات خاصة بها وأصبحت تديرها بشكل مستقل تقريب اً باستثناء وجود شخص واحد فقط لدعم العمليات الإدارية. 

كنت قد غطيت مؤتمر باريس مؤخ ارا. ما أبرز ما جاء فيه؟

فرنسا نظّمت أكبر قمة عالمية للذكاء الاصطناعي منذ ستة أسابيع، وشاركت فيها شخصيات دولية رفيعة المستوى. شهد المؤتمر دعوات لوضع قوانين أخلاقية لتنظيم تطور الذكاء الاصطناعي بينما رفضت بعض الدول الكبرى مثل الولايات المتحدة وبريطانيا الالتزام بهذه المبادئ. الاستمرار في التطوير دون قيود.

وفي نهاية القمة، صدر “إعلان باريس”، الذي شددّ على أهمية مراعاة الأخلاقيات في تطوير الذكاء الاصطناعي.

إذا بنا ء على ما تم ذكره، بماذا توصي الصحفيين في الفترة القادمة؟ فيما يلتزمون به أ ويلتفتون إليه؟ وبماذا توصيهم أو ما النصائح التي تنصح الصحفيين أن يتبعوها لمجاراة التقدم المستم ر في التكنولوجيا أو الذكاء الاصطناعي؟  

يجب على الصحفيين تعلم استخدام الذكاء الاصطناعي وتطبيقه في كل جوانب عملهم، مثل إعداد الفيديوهات والبحث، مع الالتزام بالأخلًقية في استخدامه. هذه التقنية تسهل مهامهم وتوفر الوقت والجهد، مما يحسن جودة العمل. من الضروري أن يكون الجميع قادرين على تمييز الأعمال التي تنتجها الآلات وعدم الاعتماد عليها كلياً واستخدامها كأداة مساعدة. وانا كصحفي في التلفزيوني أركز على الجانب البصري واستخدم تقنياته الجرافيكية والتوضيحية الخاصة به عند الظهور في التلفزيون، ولا يعتمد على غيره في إنتاج عمله بفضل تعليمه وخبرته وفريقه الذي يساعده في إنتاج محتوى بصري قوي ومميز. ورغم تطور الذكاء الاصطناعي، فإنه لا يزال غير قادر على إنتاج أعمال تجمع بين العناصر البصرية والشخصية الفريدة للصحفي أو المراسل، ويخدم الصحفي فقط في مجال محدد. يجب على الصحفيين بناء شخصية وأسلوب وحضور خاص بهم ودمجها مع تقنياتهم ومعارفهم، وتوظيف الذكاء الاصطناعي بما يتناسب مع أسلوبهم وحضورهم لتحقيق فائدة أكبر. ينبغي على الصحفيين التفكير في القيمة المضافة والتركيز على الجودة لا الكمية، فالأهم هو محتوى وأهمية ما يقدم للجمهور لا عدد الأخبار. الكاتب يوجه تركيزه نحو إعداد تقرير مصور أسبوعي أو شهري شامل وعالي الجودة لجذب الجمهور. لذا، من الضروري أن يوجه الصحفيون اهتمامهم نحو تقديم محتوى عالي الجودة بدلاً من التركيز على الكم فقط.

-عند لمس الروبوت، هل كان هنا ك أي اختلاف ب ي ملمس جلد الإنسان وجلده؟

بالنسبة للمس بين جلد الإنسان وجلد الروبوت، لا يوجد فرق كبير. ومع ذلك، يتردد الناس في لمس الروبوت بسبب حساسية. الموضوع وارتباط ه بحقو ق الروبوت ككائن إنساني. وكان من الضروري مراعاة جميع الثقافات المختلفة ف ي هذا السياق. 

بما أن الحوار أُجري منذ ٨ أعوام ف ٢٠١٧، فما هى التطورات التى حدثت للروبوتات بشكل عا م خلال السنوات الثمان الماضية من وجهة نظرك ؟

نحن على أعتاب عقد جديد حيث يصعب تصور تأثير التكنولوجيا على مجالات مثل الإعلًم والطب والاقتصاد. جميع المؤسسات تفكر بجدية في مستقبل موظفيها وأنظمتها، مما يتطلب استعداًدًا كبيرًا للتغييرات المرتقبة. هناك شخصيات بارزة مثل إيلون ماسك تعبر عن أهمية استكشاف المريخ، وتدور نقاشات بينه وبين مؤسس وكالة ناسا حول أولويات الرحلًت الفضائية. يؤكد ماسك على  ضرورة إنشاء قاعدة  على المريخ نظرًا للتغيرات التي نشهدها على كوكب الأرض. 

 

 وفي نهاية الحوار، وبعد شكر ك له، و جه إليك سؤا لا  بصيغة تح د  وأمر، حيث قال” :قبل أن تمضي، ما هي توقعاتك للمستقبل؟”، فهل شعر ت حينها بالخطورة من تح ديه للعقل البشري؟ وهل توقعت أنه سيأتي يو م يكو ن فيه هو من يوجه الأسئلة ويغطي الأخبار ويحل محل الإعلامي؟

هذا السؤال جعلني أشعر بالراحة في التعامل مع الروبوت، حيث كان الحوار تفاعلياً وحقيقيًا .لم أكن أتوقع يومًا أن يأتي وقت يكون فيه روبوت هو من يسأل ويخطط الأخبار،  بل ويحاكي الإعلام بشكل عام .التكنولوجيا اليوم تفوق أي توقعات سابقة .قبل بضع .سنوات فقط، لم يكن هناك تصو ر لوجود روبوتات قادرة على التعامل مع الأخبار بنفس كفاءة البشر. 

من خلال خبرتك في المجال الإعلامي، هل سيقبل الجمهور بفكرة وجود مذيع برامج أو مراسل أو صحفي انه آلة ( روبوت)؟ هل هناك تجارب سابقة من بي بي سي تشير إلى تقبل الجمهور لهذا الأمر ؟

لا تزال مؤسسة البي بي سي تقوم بتجارب لفهم مدى تفاعل الجمهور واستجابته لهذه الآلات أو المذيعين الآليين قبل تنفيذها بشكل كامل. ستقوم البي بي سي بإجراء بحوث للجمهور لفهم كيفية تفاعله م مع الروبوتات والذكاء الاصطناعي ومقارنتها بالتفاعل مع الأشخاص العاديين. بالنظر إلى المستقبل، قد تتطور الروبوتات لتصبح أكثر ذكاءً وقدرة ً على التكيف مع احتياجات الجمهور 

 

بناءا على تقنية (Machine Learning)) نظرية التعلم الآلي: يرى إيلون ماسك أن نظرية التعلم الآلي قد تؤدي إلى تطور الروبوتات بشكل مستقل وقدرتها على التحكم بالبشر، وهو ما يظهر في أفلًم الذكاء الاصطناعي كمصدر للمخاوف والتحديات. يوجد خلًف بين ماسك وزوكربيرج حول هذا الاحتمال، حيث يعتبر زوكربيرج مخاوف ماسك مبالغًا فيها، بينما يشدد ماسك على أهمية الاستعداد لهذا السيناريو بحذر. في الوقت نفسه، تكشف الدراسات عن تطور علًقات عاطفية بين البشر والشات بوتس، وهي ظاهرة بدأت في الغرب وتظهر في الشرق الأوسط، مما يثير تساؤلات حول طبيعة العلًقة المستقبلية بين الإنسان والآلة وتأثيرها على مفاهيم السلطة والسيطرة.

في ختام هذا الحور المثير مع الإعلامي “محمد طه” ، نرى بوضوح كيف بدأ مشهد الإعلام والتقنية في التغي ر جذرياً منذ عام 2017 مع أول حوار تلفزيوني مع روبوت. تجربة طه مع “صوفيا” لم تكن مجرد حدث إعلامي فريد، ب ل كانت نافذة مبكرة على مستقبل يتقاطع فيه الإنسان والآلة بشكل متزايد. 

اظهر المزيد

مقالات ذات صلة

زر الذهاب إلى الأعلى