PageSourceSearch

https://us.edu.pl/pracownik/wp-content/cache/min/2/pracownik/wp-co…/js/complianz.js?ver=1726218718

js us.edu.pl collected 2026-09-24 08:51:38 UTC 71,590 bytes, 2,295 lines download raw bytes

1'use strict';
2/*
3 * Opt in (e.g. EU):
4 * default all scripts disabled.
5 * cookie banner
6 *
7 * Opt out (e.g. US):
8 * default all scripts enabled
9 * opt out cookie banner
10 *
11 * Other regions:
12 * default all scripts enabled
13 * no banner
14 *
15 *
16 * For examples to edit the behaviour of the banner, please see https://github.com/really-Simple-Plugins/complianz-integrations
17 * */
18
19/*
20 * Create an element
21 * @param el
22 * @param content
23 * @returns {*}
24 */
25function cmplz_create_element(el, content) {
26	let obj = document.createElement(el);
27	obj.innerHtml = content;
28	return obj;
29}
30
31/*
32 * Add an event
33 * @param event
34 * @param selector
35 * @param callback
36 * @param context
37 */
38function cmplz_add_event(event, selector, callback ) {
39	document.addEventListener(event, e => {
40		if ( e.target.closest(selector) ) {
41			callback(e);
42		}
43	});
44}
45
46/*
47 * Check if the element is hidden
48 * @param el
49 * @returns {boolean}
50 */
51function cmplz_is_hidden(el) {
52	return (el.offsetParent === null)
53}
54
55function cmplz_html_decode(input) {
56	var doc = new DOMParser().parseFromString(input, "text/html");
57	return doc.documentElement.textContent;
58}
59/*
60 * If an anchor is passed for an element which may load only after an ajax call, make sure it will scroll into view.
61 */
62document.addEventListener('cmplz_manage_consent_container_loaded', function(e){
63	let url = window.location.href;
64	if ( url.indexOf('#') != -1 ) {
65		let end_pos = url.lastIndexOf("?") != -1 ? url.lastIndexOf("?") : undefined;
66		var anchor = url.substring(url.indexOf("#") + 1, end_pos);
67		const element = document.getElementById(anchor);
68		if (element) {
69			const y = element.getBoundingClientRect().top + window.pageYOffset - 200;
70			window.scrollTo({top: y, behavior: 'smooth'});
71		}
72	}
73});
74
75/*
76 * prevent caching of the WP Rest API by varnish or other caching tools
77 */
78complianz.locale = complianz.locale + '&token='+Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);
79
80/*
81 * CustomEvent() polyfill
82 * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
83 */
84(function () {
85	if (typeof window.CustomEvent === 'function') return false;
86	function CustomEvent(event, params) {
87		params = params || { bubbles: false, cancelable: false, detail: undefined };
88		var evt = document.createEvent('CustomEvent');
89		evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
90		return evt;
91	}
92	CustomEvent.prototype = window.Event.prototype;
93	window.CustomEvent = CustomEvent;
94})();
95
96let cmplz_banner;//look this one up when the cookiebanner loads.
97let cmplz_banner_container = document.getElementById('cmplz-cookiebanner-container');
98let cmplz_manage_consent_button;
99let cmplz_waiting_inline_scripts = [];
100let cmplz_waiting_scripts = [];
101let cmplz_fired_scripts = [];
102let cmplz_placeholder_class_index = 0;
103let cmplz_all_scripts_hook_fired = false;
104let cmplz_consent_stored_once = false;
105let cmplz_categories = [
106	'functional',
107	'preferences',
108	'statistics',
109	'marketing',
110];
111
112/*
113 * Get a cookie by name
114 * @param name
115 * @returns {string}
116 */
117
118window.cmplz_get_cookie = function (name) {
119	if (typeof document === "undefined") {
120		return "";
121	}
122	name = complianz.prefix + name;
123	const value = "; " + document.cookie;
124	const parts = value.split("; " + name + "=");
125	if ( parts.length === 2 ) {
126		return parts.pop().split(";").shift();
127	}
128
129	return "";
130};
131
132/*
133 * set a cookie
134 * @param name
135 * @param value
136 * @param use_prefix
137 */
138
139window.cmplz_set_cookie = function(name, value, use_prefix) {
140	if (typeof document === 'undefined') {
141		return;
142	}
143	if (typeof use_prefix === 'undefined') {
144		use_prefix = true;
145	}
146	let secure = ";secure";
147	let date = new Date();
148	date.setTime(date.getTime() + (complianz.cookie_expiry * 24 * 60 * 60 * 1000));
149	let expires = ";expires=" + date.toGMTString();
150
151	if (window.location.protocol !== "https:") secure = '';
152
153	let domain = cmplz_get_cookie_domain();
154	if (domain.length > 0) {
155		domain = ";domain=" + domain;
156	}
157	let prefix = '';
158	if ( use_prefix ) {
159		prefix = complianz.prefix;
160	}
161	document.cookie = prefix+name + "=" + value + ";SameSite=Lax" + secure + expires + domain + ";path="+cmplz_get_cookie_path();
162}
163
164/*
165 * Check if needle occurs in the haystack
166 * @param needle
167 * @param haystack
168 * @returns {boolean}
169 */
170window.cmplz_in_array = function(needle, haystack) {
171	let length = haystack.length;
172	for(let i = 0; i < length; i++) {
173		if(haystack[i] == needle) return true;
174	}
175	return false;
176}
177
178/*
179 * Retrieve the highest level of consent that has been given
180 *
181 * */
182
183window.cmplz_highest_accepted_category = function() {
184	var consentedCategories = cmplz_accepted_categories();
185	if (cmplz_in_array( 'marketing', consentedCategories )) {
186		return 'marketing';
187	}
188
189	if (cmplz_in_array( 'statistics', consentedCategories )) {
190		return 'statistics';
191	}
192
193	if (cmplz_in_array( 'preferences', consentedCategories )) {
194		return 'preferences';
195	}
196
197	return 'functional';
198}
199
200/*
201 * Accept all categories
202 */
203window.cmplz_accept_all = function(){
204	for (var key in cmplz_categories) {
205		if ( cmplz_categories.hasOwnProperty(key) ) {
206			cmplz_set_consent(cmplz_categories[key], 'allow');
207		}
208	}
209}
210
211/*
212 * Sets all accepted categories as class in body
213 */
214
215function cmplz_set_category_as_body_class() {
216	let classList = document.body.className.split(/\s+/);
217	for (let i = 0; i < classList.length; i++) {
218		if ( classList[i].indexOf('cmplz-') !== -1 && classList[i] !== 'cmplz-document' ) {
219			document.body.classList.remove( classList[i] );
220		}
221	}
222
223	let cats = cmplz_accepted_categories();
224	for (let i in cats) {
225		if ( cats.hasOwnProperty(i) ) {
226			document.body.classList.add('cmplz-' + cats[i]);
227		}
228	}
229
230	let services = cmplz_get_all_service_consents();
231	for (let service in services) {
232		if ( services.hasOwnProperty(service) && services[service]) {
233			document.body.classList.add('cmplz-' + service);
234		}
235	}
236
237	document.body.classList.add('cmplz-' + complianz.region);
238	document.body.classList.add('cmplz-' + complianz.consenttype);
239	let event = new CustomEvent('cmplz_set_category_as_bodyclass');
240	document.dispatchEvent(event);
241}
242
243function cmplz_append_css(css){
244	let head = document.getElementsByTagName('head')[0];
245	let style = document.createElement('style');
246	style.setAttribute('type', 'text/css');
247	if (style.styleSheet) {   // IE
248		style.styleSheet.cssText = css;
249	} else {                // the world
250		style.appendChild(document.createTextNode(css));
251	}
252	head.appendChild(style);
253}
254
255function cmplz_load_css( path ) {
256	let targetObj = document.createElement("link")
257	targetObj.setAttribute("rel", "stylesheet")
258	targetObj.setAttribute("type", "text/css")
259	targetObj.setAttribute("href", path)
260	document.getElementsByTagName("head")[0].appendChild(targetObj)
261}
262
263/*
264 * Run script, src or inline
265 * @param script //src or inline script
266 * @param category
267 * @param type
268 */
269
270function cmplz_run_script( script, category, type, sourceObj ) {
271	let targetObj = document.createElement("script");
272	if ( type !== 'inline' ) {
273		targetObj.setAttribute("src", script);
274	} else {
275		if (typeof script !== 'string') {
276			script = script.innerHTML;
277		}
278		targetObj.innerHTML = [script, 'cmplzScriptLoaded();'].join('\n');
279	}
280	//check if already fired
281	if ( cmplz_in_array( script, cmplz_fired_scripts) ) {
282		return;
283	}
284
285	cmplzCopyAttributes(sourceObj, targetObj);
286
287	try {
288		if (type!=='inline') {
289			targetObj.onload = function () {
290				cmplz_run_after_all_scripts(category);
291				cmplz_maybe_run_waiting_scripts(script, category, sourceObj);
292			}
293		} else {
294			window.cmplzScriptLoaded = function() {
295				cmplz_run_after_all_scripts(category);
296				cmplz_maybe_run_waiting_scripts(script, category, sourceObj);
297			}
298		}
299		let header = document.getElementsByTagName("head")[0];
300		header.appendChild(targetObj);
301
302	} catch(exception) {
303		//only runs in case of error
304		cmplz_run_after_all_scripts(category);
305		throw "Something went wrong " + exception + " while loading "+script;
306	}
307
308}
309
310
311/*
312 * Check if there are waiting scripts, and if so, run them.
313 * @param script //src or inline script
314 * @param category
315 */
316
317function cmplz_maybe_run_waiting_scripts( script, category, sourceObj ){
318	let waitingScript = cmplz_get_waiting_script(cmplz_waiting_scripts, script);
319	if ( waitingScript ) {
320		cmplz_run_script( waitingScript, category, 'src', sourceObj );
321	}
322
323	let waiting_inline_script = cmplz_get_waiting_script(cmplz_waiting_inline_scripts, script);
324	if (waiting_inline_script) {
325		cmplz_run_script(waiting_inline_script, category, 'inline', sourceObj);
326	}
327}
328
329/*
330 * Set placeholder image as background on the parent div, set notice, and handle height.
331 *
332 * */
333
334function cmplz_set_blocked_content_container() {
335	//to prevent this function to twice run on an element, we add an attribute to each element that has been processed.
336	//then skip elements with that element.
337	document.querySelectorAll('.cmplz-image').forEach(obj => {
338		if ( obj.classList.contains('cmplz-processed') ) {
339			return;
340		}
341		obj.classList.add('cmplz-processed' );
342		let service = obj.getAttribute('data-service');
343		let category = obj.getAttribute('data-category');
344		let blocked_image_container = obj.parentElement;
345		blocked_image_container.classList.add('cmplz-blocked-content-container');
346		let curIndex = blocked_image_container.getAttribute('data-placeholder_class_index');
347		//handle browser native lazy load feature
348		if (obj.getAttribute('loading') === 'lazy' ) {
349			obj.removeAttribute('loading');
350			obj.setAttribute('data-deferlazy', 1);
351		}
352
353		if ( curIndex == null ) {
354			cmplz_placeholder_class_index++;
355			blocked_image_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index);
356			blocked_image_container.classList.add('cmplz-blocked-content-container');
357			blocked_image_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index);
358			cmplz_insert_placeholder_text(blocked_image_container, category, service);
359		}
360	});
361
362	document.querySelectorAll('.cmplz-placeholder-element').forEach(obj => {
363		if ( obj.classList.contains('cmplz-processed') ) {
364			return;
365		}
366		obj.classList.add('cmplz-processed' );
367		let service = obj.getAttribute('data-service');
368		let category = obj.getAttribute('data-category');
369
370		//we set this element as container with placeholder image
371		let blocked_content_container;
372		if ( obj.classList.contains('cmplz-iframe')) {
373			//handle browser native lazy load feature
374			if ( obj.getAttribute('loading') === 'lazy' ) {
375				obj.removeAttribute('loading');
376				obj.setAttribute('data-deferlazy', 1);
377			}
378			blocked_content_container = obj.parentElement;
379		} else {
380			blocked_content_container = obj;
381		}
382		let curIndex = blocked_content_container.getAttribute('data-placeholder_class_index');
383		//if the blocked content container class is already added, don't add it again
384		if ( curIndex == null ) {
385			cmplz_placeholder_class_index++;
386			blocked_content_container.classList.add('cmplz-placeholder-' + cmplz_placeholder_class_index);
387			blocked_content_container.classList.add('cmplz-blocked-content-container');
388			blocked_content_container.setAttribute('data-placeholder_class_index', cmplz_placeholder_class_index);
389			cmplz_insert_placeholder_text(blocked_content_container, category, service);
390			//handle image size for video
391			let src = obj.getAttribute('data-placeholder-image');
392			if (src && typeof src !== 'undefined' && src.length ) {
393				src = src.replace('url(', '').replace(')', '').replace(/\"/gi, "");
394				cmplz_append_css('.cmplz-placeholder-' + cmplz_placeholder_class_index + ' {background-image: url(' + src + ') !important;}');
395				cmplz_set_blocked_content_container_aspect_ratio(obj, src, cmplz_placeholder_class_index);
396			}
397		}
398	});
399
400	/*
401	 * 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.
402	 * 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
403	 */
404
405	if ( cmplz_has_consent('statistics') ) {
406		cmplz_enable_category('statistics');
407	}
408
409	if ( cmplz_has_consent('marketing') ) {
410		cmplz_enable_category('marketing');
411	}
412
413}
414
415function cmplz_insert_placeholder_text(container, category, service ){
416	if ( !container.querySelector( ".cmplz-blocked-content-notice" ) ) {
417		let placeholder_text = complianz.placeholdertext;
418		category = category ? category : 'marketing';
419		let body;
420		if ( typeof placeholder_text !== 'undefined' ) {
421			if ( complianz.clean_cookies == 1 ) {
422				//make service human readable
423				let service_nicename = service ? service.replace('-', ' ') : '';
424				service_nicename = service_nicename.charAt(0).toUpperCase() + service_nicename.slice(1);
425				placeholder_text = placeholder_text.replace('{service}', service_nicename);
426				body = cmplz_create_element('div', placeholder_text);
427				body.innerHTML = placeholder_text;
428				body.classList.add('cmplz-blocked-content-notice');
429				let btn = body.querySelector('button');
430				btn.setAttribute('data-service', service);
431				btn.setAttribute('data-category', category);
432				btn.setAttribute('aria-label', service);
433				let pageLinks = complianz.page_links[complianz.region];
434				let link = body.querySelector('.cmplz-links a');
435				if ( pageLinks && pageLinks.hasOwnProperty('cookie-statement') ) {
436					link.setAttribute('href', pageLinks['cookie-statement']['url']);
437					if (link.innerText === '{title}') {
438						link.innerText = pageLinks['cookie-statement']['title'];
439					}
440				}
441			} else {
442				let btn = cmplz_create_element('button', '');
443				let category_nicename = 'marketing';
444				if (complianz.categories.hasOwnProperty(category)){
445					category_nicename = complianz.categories[category];
446				}
447
448				placeholder_text = placeholder_text.replace('{category}', category_nicename);
449				btn.innerText = placeholder_text;
450				btn.classList.add('cmplz-blocked-content-notice');
451				btn.classList.add('cmplz-accept-category');
452
453				//deprecated
454				btn.classList.add('cmplz-accept-'+category);
455				btn.setAttribute('data-service', service );
456				btn.setAttribute('data-category', category );
457				btn.setAttribute('aria-label', service );
458				body=btn;
459			}
460
461			if ( container.tagName!=='VIDEO' ) {
462				container.appendChild(body);
463			} else{
464				container.parentElement.appendChild(body);
465			}
466
467		}
468	}
469}
470
471/*
472 * Set the height of an image relative to the width, depending on the image widht/height aspect ratio.
473 *
474 *
475 * */
476
477function cmplz_set_blocked_content_container_aspect_ratio(container, src, placeholder_class_index) {
478	if ( container == null ) return;
479
480	//we set the first parent div as container with placeholder image
481	let blocked_content_container = container.parentElement;
482
483	//handle image size for video
484	let img = new Image();
485	img.addEventListener("load", function () {
486		let imgWidth = this.naturalWidth;
487		let imgHeight = this.naturalHeight;
488
489		//prevent division by zero.
490		if (imgWidth === 0) imgWidth = 1;
491		let w = blocked_content_container.clientWidth;
492		let h = imgHeight * (w / imgWidth);
493
494		let heightCSS = '';
495		if (src.indexOf('placeholder.jpg') === -1) {
496			heightCSS = 'height:' + h + 'px;';
497		}
498		cmplz_append_css('.cmplz-placeholder-' + placeholder_class_index + ' {' + heightCSS + '}');
499	});
500	img.src = src;
501}
502/*
503 * Keep window aspect ratio in sync when window resizes
504 * To lower the number of times this code is executed, it is done with a timeout.
505 *
506 * */
507
508var cmplzResizeTimer;
509window.addEventListener('resize', function(event) {
510	clearTimeout(cmplzResizeTimer);
511	cmplzResizeTimer = setTimeout( cmplz_set_blocked_content_container, 500);
512}, true);
513
514/*
515 * 	we run this function also on an interval, because with ajax loaded content, the placeholders would otherwise not be handled.
516 */
517if ( complianz.block_ajax_content == 1 ) {
518	setInterval(function () {
519		cmplz_set_blocked_content_container();
520	}, 2000);
521}
522
523/*
524 * Check if there are any blocked scripts on the page
525 * @returns {boolean}
526 */
527function cmplz_has_blocked_scripts(){
528	let scriptElements = document.querySelectorAll('script[data-category], script[data-service]');
529	return scriptElements.length>0;
530}
531/*
532 * Enable scripts that were blocked
533 *
534 * */
535
536function cmplz_enable_category(category, service) {
537	if ( complianz.tm_categories == 1 && category !== '') {
538		cmplz_run_tm_event(category);
539	}
540
541	service = typeof service !== 'undefined' ? service : 'do_not_match';
542	if ( category === '' ) category = 'do_not_match';
543
544	if ( category === 'functional' ) {
545		return;
546	}
547
548	//enable cookies for integrations
549	if ( category === 'marketing' ) {
550		cmplz_set_integrations_cookies();
551	}
552
553	//remove accept cookie notice overlay
554	let selector;
555	if (service !== 'do_not_match') {
556		selector = '.cmplz-blocked-content-notice [data-service='+service+']';
557	} else {
558		selector = complianz.clean_cookies!=1 ? '.cmplz-blocked-content-notice.cmplz-accept-'+category : '.cmplz-blocked-content-notice [data-category='+category+']';
559	}
560	document.querySelectorAll(selector).forEach(obj => {
561		let blockedElementService = obj.getAttribute('data-service');
562		if (obj.parentNode.classList.contains('cmplz-blocked-content-notice')) {
563			obj = obj.parentNode;
564		}
565		//only remove if the service is not explicitly denied
566		if ( !cmplz_is_service_denied(blockedElementService) ) {
567			obj.parentNode.removeChild(obj);
568		}
569	});
570
571	document.querySelectorAll('[data-category='+category+'], [data-service='+service+']').forEach(obj => {
572		//if a category is activated, but this specific service is denied, skip.
573		let elementService = obj.getAttribute('data-service');
574		if ( cmplz_is_service_denied(elementService) ) {
575			return;
576		}
577
578		//if native class is included, it isn't blocked, so will have run already
579		if ( obj.getAttribute('data-category') === 'functional' ) {
580			return;
581		}
582
583		if ( obj.classList.contains('cmplz-activated') ) {
584			return;
585		}
586
587		let tagName = obj.tagName;
588		if (tagName==='LINK'){
589			obj.classList.add('cmplz-activated' );
590			let src = obj.getAttribute('data-href');
591			cmplz_load_css( src, category);
592		} else if (tagName ==='IMG'){
593			obj.classList.add('cmplz-activated' );
594			let src = obj.getAttribute('data-src-cmplz');
595			obj.setAttribute('src', src);
596			//handle browser native lazy load feature
597			if ( obj.getAttribute('data-deferlazy') ) {
598				obj.setAttribute('loading', 'lazy');
599			}
600			cmplz_remove_placeholder(obj);
601		}
602		else if (tagName==='IFRAME'){
603			obj.classList.add('cmplz-activated' );
604			let src = obj.getAttribute('data-src-cmplz');
605			let srcAttribute = obj.getAttribute('data-cmplz-target') ? obj.getAttribute('data-cmplz-target') : 'src';
606
607			//check if there's an autoplay value we need to pass on, if it's added later on by javascript
608			let autoplay = cmplz_get_url_parameter(obj.getAttribute(srcAttribute), 'autoplay');
609			if ( autoplay === '1' ) src = src + '&autoplay=1';
610			//handle browser native lazy load feature
611			if ( obj.getAttribute('data-deferlazy') ) {
612				obj.setAttribute('loading', 'lazy');
613			}
614
615			obj.addEventListener('load', () => {
616				cmplz_remove_placeholder(obj);
617			});
618			obj.setAttribute(srcAttribute, src);
619		} else if (obj.classList.contains('cmplz-placeholder-element')) {
620			obj.classList.add('cmplz-activated' );
621			//other services, no iframe, with placeholders
622			//remove the added classes
623			let cssIndex = obj.getAttribute('data-placeholder_class_index');
624			obj.classList.remove('cmplz-blocked-content-container');
625			obj.classList.remove('cmplz-placeholder-' + cssIndex);
626		}
627
628		let details = {};
629		details.category = category;
630		details.service = service;
631		let event = new CustomEvent('cmplz_category_enabled', { detail: details });
632		document.dispatchEvent(event);
633	});
634
635	/*
636	 * Let's activate the scripts
637	 */
638
639	//create list of waiting scripts
640	let scriptElements = document.querySelectorAll('script[data-category='+category+'], script[data-service='+service+']');
641	scriptElements.forEach(obj => {
642		let waitfor = obj.getAttribute('data-waitfor');
643		let src = obj.getAttribute('data-cmplz-src');
644		if ( waitfor ) {
645			if ( src ) {
646				cmplz_waiting_scripts[waitfor] = src;
647			} else if ( obj.innerText.length > 0 ) {
648				cmplz_waiting_inline_scripts[waitfor] = obj;
649			}
650		}
651
652		//cleanup after adding it to our waiting or scriptElements list.
653		if (obj.parentElement) {
654			obj.parentElement.removeChild(obj);
655		}
656	});
657
658	//scripts: remove text/plain, and move data-src attribute to src attribute
659	scriptElements.forEach(obj => {
660		//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
661		let script_mime_type = obj.getAttribute('type');
662		if ( obj.classList.contains('cmplz-activated') || ( !script_mime_type || script_mime_type==='text/javascript' ) ) {
663			return;
664		}
665		obj.classList.add('cmplz-activated' );
666		let src = obj.getAttribute('data-cmplz-src');
667		if ( src ) {
668			obj.removeAttribute('type');
669			//check if this src or txt is in a waiting script. If so, skip.
670			if ( cmplz_is_waiting_script(cmplz_waiting_scripts, src) ) {
671				return;
672			}
673
674			if ( obj.getAttribute('data-post_scribe_id') ) {
675				let psID = '#' + obj.getAttribute('data-post_scribe_id');
676				let postScribeObj = document.querySelector(psID);
677				if ( postScribeObj ) {
678					postScribeObj.innerHtml('');
679					postscribe(psID, '<script src=' + src + '></script>');
680				}
681			} else {
682				cmplz_run_script(src, category, 'src', obj );
683			}
684
685		} else if (obj.innerText.length > 0 ) {
686			//check if this src or txt is in a waiting script. If so, skip.
687			if (cmplz_is_waiting_script(cmplz_waiting_inline_scripts, obj.innerText )) {
688				return;
689			}
690
691			cmplz_run_script( obj.innerText, category, 'inline', obj );
692		}
693	});
694
695	//fire an event so custom scripts can hook into this.
696	let details = {};
697	details.category = category;
698	details.service = service;
699	details.categories = cmplz_accepted_categories();
700	details.services = cmplz_get_all_service_consents();
701	details.region = complianz.region;
702	let event = new CustomEvent('cmplz_enable_category', { detail: details });
703	document.dispatchEvent(event);
704	//if there are no blockable scripts at all, we still want to provide a hook
705	//in most cases, there are blocked scripts, and this code won't run yet. In that
706	//case it's run from the script activation callbacks.
707	if ( !cmplz_has_blocked_scripts() ) {
708		cmplz_run_after_all_scripts(category);
709	}
710}
711
712/*
713 * remove added classes from the blocked content container
714 *
715 * @param obj
716 */
717function cmplz_remove_placeholder(obj){
718	//we get the closest, not the parent, because a script could have inserted a div in the meantime.
719	let blocked_content_container = obj.closest('.cmplz-blocked-content-container');
720	if (blocked_content_container) {
721		let cssIndex = blocked_content_container.getAttribute('data-placeholder_class_index');
722		blocked_content_container.classList.remove('cmplz-blocked-content-container');
723		blocked_content_container.classList.remove('cmplz-placeholder-' + cssIndex);
724	}
725	obj.classList.remove('cmplz-iframe-styles');
726	obj.classList.remove('cmplz-iframe');
727	obj.classList.remove('video-wrap');
728}
729
730/*
731 * check if the passed source has a waiting script that should be executed, and return it if so.
732 * @param waiting_scripts
733 * @param src
734 * @returns {*}
735 */
736
737function cmplz_get_waiting_script( waiting_scripts, src ) {
738	for ( let waitfor in waiting_scripts ) {
739		if ( waiting_scripts.hasOwnProperty(waitfor)) {
740			if ( src.indexOf(waitfor) !== -1 ) {
741				let output = waiting_scripts[waitfor];
742				delete waiting_scripts[waitfor];
743				return output;
744			}
745		}
746	}
747
748	return false;
749}
750
751/*
752 * Because we need a key=>value array in javascript, the .length check for an empty array doesn't work.
753 * @param arr
754 * @returns {boolean}
755 */
756function cmplz_array_is_empty(arr) {
757	for (let key in arr) {
758		if (arr.hasOwnProperty(key)) {
759			return false;
760		}
761	}
762
763	return true;
764}
765
766/*
767 * Check if the passed src or script is waiting for another script and should not execute
768 * @param waiting_scripts
769 * @param srcOrScript
770 */
771
772function cmplz_is_waiting_script(waiting_scripts, srcOrScript) {
773	for (let waitfor in waiting_scripts) {
774		if ( waiting_scripts.hasOwnProperty(waitfor) ) {
775			let waitingScript = waiting_scripts[waitfor];
776			if (typeof waitingScript !== 'string') waitingScript = waitingScript.innerText;
777
778			if (srcOrScript.indexOf(waitingScript) !== -1 || waitingScript.indexOf(srcOrScript) !== -1) {
779				return true;
780			}
781		}
782	}
783	return false;
784}
785
786/*
787 * if all scripts have been executed, fire a hook.
788 */
789
790function cmplz_run_after_all_scripts(category) {
791	if (!cmplz_all_scripts_hook_fired && cmplz_array_is_empty(cmplz_waiting_inline_scripts) && cmplz_array_is_empty(cmplz_waiting_scripts) ) {
792		let event = new CustomEvent('cmplz_run_after_all_scripts', { detail: category });
793		document.dispatchEvent(event);
794		cmplz_all_scripts_hook_fired = true;
795	}
796}
797
798/*
799 * Fire an event in Tag Manager
800 *
801 *
802 * */
803
804let cmplz_fired_events = [];
805function cmplz_run_tm_event(category) {
806	if (cmplz_fired_events.indexOf(category) === -1) {
807		cmplz_fired_events.push(category);
808		window.dataLayer = window.dataLayer || [];
809		window.dataLayer.push({
810			'event': complianz.prefix+'event_'+category
811		});
812		let event = new CustomEvent('cmplz_tag_manager_event', { detail: category });
813		document.dispatchEvent(event);
814	}
815}
816
817/*
818 * Function to handle backward compatibility
819 *
820 */
821
822function cmplz_legacy(){
823	let has_recaptcha = false;
824	document.querySelectorAll('[data-service=recaptcha]').forEach(obj => {
825		obj.setAttribute('data-service', 'google-recaptcha');
826		has_recaptcha=true;
827	});
828
829	if ( has_recaptcha ) {
830		console.log('recaptcha as service name is deprecated. Please rename the service in your custom html to google-recaptcha');
831		document.body.classList.add( 'cmplz-google-recaptcha' );
832	}
833}
834
835window.conditionally_show_banner = function() {
836	//merge userdata with complianz data, in case a b testing is used with user specific cookie banner data
837	//objects are merged so user_data will override data in complianz object
838	complianz = cmplz_merge_object( complianz, cmplz_user_data );
839	//check if we need to redirect to another legal document, for a specific region
840	cmplz_maybe_auto_redirect();
841	cmplz_set_blocked_content_container();
842	cmplz_legacy();
843
844	/*
845	 * Integration with WordPress, tell what kind of consent type we're using, then fire an event
846	 */
847
848	window.wp_consent_type = complianz.consenttype;
849	let event = new CustomEvent('wp_consent_type_defined');
850	document.dispatchEvent( event );
851	event = new CustomEvent('cmplz_before_cookiebanner' );
852	document.dispatchEvent(event);
853	if ( complianz.forceEnableStats == 1 && complianz.consenttype === 'optin' ) {
854		cmplz_set_consent('statistics', 'allow');
855	}
856
857	let rev_cats = cmplz_categories.reverse();
858	for (let key in rev_cats) {
859		if ( rev_cats.hasOwnProperty(key) ) {
860			let category = cmplz_categories[key];
861			if ( cmplz_has_consent(category) ) {
862				cmplz_enable_category(category);
863			}
864		}
865	}
866	if ( cmplz_exists_service_consent() ) {
867		//if any service is enabled, allow the general services also, because some services are partially 'general'
868		cmplz_enable_category('', 'general');
869		let services = cmplz_get_services_on_page();
870		for (let key in services) {
871			if ( services.hasOwnProperty(key) ) {
872				let service = services[key].service;
873				let category = services[key].category;
874				if ( cmplz_has_service_consent( service, category )) {
875					document.querySelectorAll('.cmplz-accept-service[data-service=' + service + ']').forEach(obj => {
876						obj.checked = true;
877					});
878					cmplz_enable_category('', service);
879				}
880			}
881		}
882	}
883
884	cmplz_sync_category_checkboxes();
885	cmplz_integrations_init();
886	cmplz_check_cookie_policy_id();
887	cmplz_set_up_auto_dismiss();
888
889	//if we're on the cookie policy page, we dynamically load the applicable revoke checkbox
890	cmplz_load_manage_consent_container();
891
892	event = new CustomEvent('cmplz_cookie_banner_data', { detail: complianz });
893	document.dispatchEvent(event);
894
895	//if no categories were saved before, we do it now
896	if ( cmplz_get_cookie('saved_categories') === '' ) {
897		//for Non optin/optout visitors, and DNT users, we just track the no-warning option
898		if ( complianz.consenttype !== 'optin' && complianz.consenttype !== 'optout' ) {
899			cmplz_track_status( 'no_warning' );
900		} else if ( cmplz_do_not_track() ) {
901			cmplz_track_status('do_not_track' );
902		}
903	}
904
905	cmplz_set_category_as_body_class();
906	//fire cats event, but do not fire a track, as we do this on exit.
907	cmplz_fire_categories_event();
908	if ( !cmplz_do_not_track() ) {
909		if (complianz.consenttype === 'optin') {
910			if (complianz.forceEnableStats) {
911				cmplz_enable_category('statistics');
912			}
913			console.log('opt-in');
914			show_cookie_banner();
915		} else if (complianz.consenttype === 'optout') {
916			console.log('opt-out');
917			show_cookie_banner();
918		} else {
919			console.log('other consent type, no cookie warning');
920			//on other consent types, all scripts are enabled by default.
921			cmplz_accept_all();
922			// cmplz_fire_categories_event();
923		}
924	} else {
925		console.log('global privacy control or do not track detected: no banner.');
926		cmplz_track_status( 'do_not_track' );
927	}
928}
929
930/**
931 * Check if User has set either GPC or DNT in the browser.
932 * @returns {boolean}
933 */
934function cmplz_do_not_track(){
935	let dnt = 'doNotTrack' in navigator && navigator.doNotTrack === '1';
936	let gpc = 'globalPrivacyControl' in navigator && navigator.globalPrivacyControl;
937	return !!(complianz.do_not_track_enabled && (gpc || dnt));
938}
939
940/*
941 * Get list of services active on the page
942 * @returns {*[]}
943 */
944function cmplz_get_services_on_page(){
945	let services=[];
946	document.querySelectorAll('[data-service]').forEach(obj => {
947		let service = obj.getAttribute('data-service');
948		let category = obj.getAttribute('data-category');
949		if ( services.indexOf(service)==-1 ) {
950			services.push({
951				'category': category,
952				'service':service,
953			});
954		}
955	});
956	return services;
957}
958
959/*
960 * Run the actual cookie warning
961 *
962 * */
963
964window.show_cookie_banner = function () {
965	let disableCookiebanner = complianz.disable_cookiebanner || cmplz_is_speedbot();
966	//do not show banner when manage consent area on cookie policy is visible
967	//when users use only the shortcode, the manage consent container is not active, but the dropdown cookie policy class is.
968	//when the complianz shortcode is used, the dropdown cookie policy class is loaded late because it's loaded with javascript.
969	let tmpDismissCookiebanner = false;
970	if ( document.querySelector('#cmplz-manage-consent-container') || document.querySelector('.cmplz-dropdown-cookiepolicy') ) {
971		tmpDismissCookiebanner = true;
972	}
973
974	var fragment = document.createDocumentFragment();
975	let container = document.getElementById('cmplz-cookiebanner-container');
976	if (container) {
977		fragment.appendChild(container);
978		document.body.prepend(fragment);
979	}
980
981	let link = document.createElement("link");
982	let pageLinks = complianz.page_links[complianz.region];
983	//get correct banner, based on banner_id
984	cmplz_banner = document.querySelector('.cmplz-cookiebanner.banner-'+complianz.user_banner_id+'.'+complianz.consenttype);
985	if ( !cmplz_banner ) {
986		disableCookiebanner = true;
987	}
988	cmplz_manage_consent_button = document.querySelector('#cmplz-manage-consent .cmplz-manage-consent.manage-consent-'+complianz.user_banner_id);
989	let css_file_url = complianz.css_file.replace('{type}', complianz.consenttype ).replace('{banner_id}', complianz.user_banner_id);
990	if ( complianz.css_file.indexOf('cookiebanner/css/defaults/banner') != -1 ) {
991		console.log('Fallback default css file used. Please re-save banner settings, or check file writing permissions in uploads directory');
992	}
993
994	link.href = css_file_url;
995	link.type = "text/css";
996	link.rel = "stylesheet";
997	link.onload = function () {
998		if ( !disableCookiebanner ) {
999			cmplz_banner.classList.remove('cmplz-hidden');
1000			cmplz_manage_consent_button.classList.remove('cmplz-hidden');
1001		}
1002	}
1003	document.getElementsByTagName("head")[0].appendChild(link);
1004	if ( cmplz_banner && !disableCookiebanner ) {
1005		cmplz_banner.querySelectorAll('.cmplz-links a:not(.cmplz-external), .cmplz-buttons a:not(.cmplz-external)').forEach(obj => {
1006			let docElement = obj;
1007			docElement.classList.add('cmplz-hidden');
1008			for (let pageType in pageLinks ) {
1009				if (pageLinks.hasOwnProperty(pageType) && docElement.classList.contains(pageType)) {
1010					docElement.setAttribute('href', pageLinks[pageType]['url'] + docElement.getAttribute('data-relative_url'));
1011					if ( docElement.innerText === '{title}') {
1012						docElement.innerText = cmplz_html_decode(pageLinks[pageType]['title']);
1013					}
1014					docElement.classList.remove('cmplz-hidden');
1015				}
1016			}
1017		});
1018
1019		cmplz_set_banner_status();
1020		//we don't use the setBannerStatus function here, as we don't want to save it in a cookie now.
1021		if ( tmpDismissCookiebanner ) {
1022			cmplz_banner.classList.remove('cmplz-show');
1023			cmplz_banner.classList.add('cmplz-dismissed');
1024			cmplz_manage_consent_button.classList.remove('cmplz-dismissed');
1025			cmplz_manage_consent_button.classList.add('cmplz-show');
1026		}
1027	}
1028
1029	let event = new CustomEvent('cmplz_cookie_warning_loaded', {detail: complianz.region});
1030	document.dispatchEvent(event);
1031}
1032/*
1033 * Get the status of the banner: dismissed | show
1034 * @returns {string}
1035 */
1036window.cmplz_get_banner_status = function (){
1037	return cmplz_get_cookie('banner-status');
1038}
1039
1040/*
1041 * Set the banner status so it will be either shown or dismissed, and store it in a cookie.
1042 * @param status (optional)
1043 */
1044
1045window.cmplz_set_banner_status = function ( status ){
1046	let prevStatus = cmplz_get_cookie('banner-status');
1047	status = typeof status !== 'undefined' ? status : prevStatus;
1048	if ( status !== prevStatus ) {
1049		cmplz_set_cookie( 'banner-status', status );
1050	}
1051	if (status.length===0){
1052		status = 'show';
1053	}
1054
1055	if (status==='show') {
1056		prevStatus = 'dismissed';
1057	} else {
1058		prevStatus = 'show';
1059	}
1060
1061	if ( cmplz_banner && status.length>0 ) {
1062		cmplz_banner.classList.remove('cmplz-'+prevStatus);
1063		cmplz_banner.classList.add('cmplz-'+status );
1064		if ( cmplz_manage_consent_button ) {
1065			cmplz_manage_consent_button.classList.add('cmplz-'+prevStatus);
1066			cmplz_manage_consent_button.classList.remove('cmplz-'+status);
1067		}
1068	}
1069
1070	if ( cmplz_banner_container && complianz.soft_cookiewall ) {
1071		cmplz_banner_container.classList.remove('cmplz-'+prevStatus);
1072		cmplz_banner_container.classList.add('cmplz-'+status );
1073		cmplz_banner_container.classList.add('cmplz-soft-cookiewall');
1074	}
1075	let event = new CustomEvent('cmplz_banner_status', { detail: status });
1076	document.dispatchEvent(event);
1077	cmplz_start_clean();
1078}
1079
1080/*
1081 * Check if current visitor is a bot
1082 *
1083 * @returns {boolean}
1084 */
1085function cmplz_is_bot(){
1086	var botPattern = "(googlebot\/|Googlebot-Mobile|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)";
1087	var reBot = new RegExp(botPattern, 'i');
1088	var userAgent = navigator.userAgent;
1089	return reBot.test(userAgent);
1090}
1091/*
1092 * Check if current visitor is a speedbot
1093 *
1094 * @returns {boolean}
1095 */
1096function cmplz_is_speedbot(){
1097	var userAgent = navigator.userAgent;
1098	var speedBotPattern = "(GTmetrix|pingdom|pingbot|Lighthouse)";
1099	var speedBot = new RegExp(speedBotPattern, 'i');
1100	return speedBot.test(userAgent);
1101}
1102
1103/*
1104 * Check if there is consent for a category or service
1105 * @param category
1106 * @returns {boolean}
1107 */
1108window.cmplz_has_consent = function ( category ){
1109	if ( cmplz_is_bot() ) {
1110		return true;
1111	}
1112
1113	if ( category === 'functional' ) {
1114		return true;
1115	}
1116
1117	let has_consent, value;
1118
1119	/*
1120	 * categories
1121	 */
1122	value = cmplz_get_cookie(category);
1123	if ( (complianz.consenttype === 'optout' || complianz.consenttype === 'other') && value === '') {
1124		//if it's opt out and no cookie is set we should return true
1125		has_consent = true;
1126	} else {
1127		//all other situations, return only true if value is allow
1128		has_consent = (value === 'allow');
1129	}
1130
1131	return has_consent;
1132}
1133
1134/*
1135 * Check if a service has consent
1136 * @param service
1137 * @returns {boolean|*}
1138 */
1139window.cmplz_is_service_denied = function ( service ) {
1140	//Check if it's in the consented services cookie
1141	var consented_services_json = cmplz_get_cookie('consented_services');
1142	var consented_services;
1143	try {
1144		consented_services = JSON.parse(consented_services_json);
1145	} catch (e) {
1146		consented_services = {};
1147	}
1148
1149	if ( !consented_services.hasOwnProperty( service ) ){
1150		return false;
1151	} else {
1152		return !consented_services[service];
1153	}
1154}
1155
1156/*
1157 * Check if a service has consent
1158 * @param service
1159 * @param category
1160 * @returns {boolean|*}
1161 */
1162window.cmplz_has_service_consent = function ( service, category ) {
1163	//Check if it's in the consented services cookie
1164	var consented_services_json = cmplz_get_cookie('consented_services');
1165	var consented_services;
1166	try {
1167		consented_services = JSON.parse(consented_services_json);
1168	} catch (e) {
1169		consented_services = {};
1170	}
1171
1172	if ( !consented_services.hasOwnProperty( service ) ){
1173		//default to the category
1174		return cmplz_has_consent( category );
1175	} else {
1176		return consented_services[service];
1177	}
1178}
1179
1180/*
1181 * check if there's at least one service with consent
1182 * @returns {boolean}
1183 */
1184function cmplz_exists_service_consent(){
1185	var consented_services_json = cmplz_get_cookie('consented_services');
1186	var consented_services;
1187	try {
1188		consented_services = JSON.parse(consented_services_json);
1189		for (const key in consented_services) {
1190			if ( consented_services.hasOwnProperty(key) ) {
1191				if (consented_services[key] == true) {
1192					return true;
1193				}
1194			}
1195		}
1196	} catch (e) {
1197		return false;
1198	}
1199	return false;
1200}
1201
1202/*
1203 * Set consent for a service
1204 * @param service
1205 * @param consented
1206 */
1207function cmplz_set_service_consent( service, consented ){
1208	var consented_services_json = cmplz_get_cookie('consented_services');
1209	var consented_services;
1210	try {
1211		consented_services = JSON.parse(consented_services_json);
1212	} catch (e) {
1213		consented_services = {};
1214	}
1215	consented_services[service] = consented;
1216	cmplz_set_cookie('consented_services', JSON.stringify(consented_services) );
1217	let details = {};
1218	details.service = service;
1219	details.value = consented;
1220	details.region = complianz.region;
1221	//when the status is changed, we may need to fire scripts again, so we reset it.
1222	cmplz_all_scripts_hook_fired = false;
1223	let event = new CustomEvent('cmplz_status_change_service', { detail: details });
1224	document.dispatchEvent(event);
1225}
1226
1227/*
1228 * Remove all service consents
1229 */
1230function cmplz_clear_all_service_consents(){
1231	cmplz_set_cookie('consented_services', '');
1232}
1233
1234/*
1235 * Get all consented or denied services
1236 */
1237
1238function cmplz_get_all_service_consents(){
1239	var consented_services_json = cmplz_get_cookie('consented_services');
1240	var consented_services;
1241	try {
1242		consented_services = JSON.parse(consented_services_json);
1243	} catch (e) {
1244		consented_services = {};
1245	}
1246	return consented_services;
1247}
1248/*
1249 * Get cookie path
1250 * @returns {*}
1251 */
1252function cmplz_get_cookie_path(){
1253	return typeof complianz.cookie_path !== 'undefined' && complianz.cookie_path !== '' ? complianz.cookie_path : '/';
1254}
1255
1256/*
1257 * retrieve domain to set the cookies on
1258 * @returns {string}
1259 */
1260function cmplz_get_cookie_domain(){
1261	var domain = '';
1262	if ( complianz.set_cookies_on_root == 1 && complianz.cookie_domain.length>3){
1263		domain = complianz.cookie_domain;
1264	}
1265	if (domain.indexOf('localhost') !== -1 ) {
1266		domain = '';
1267	}
1268	return domain;
1269}
1270
1271/*
1272 * Set consent for a category
1273 * @param category
1274 * @param value
1275 */
1276window.cmplz_set_consent = function (category, value){
1277	cmplz_set_accepted_cookie_policy_id();
1278	//functional is always allow
1279	value = category==='functional' ? 'allow' : value;
1280	let previous_value = cmplz_get_cookie(category);
1281
1282	//keep checkboxes in banner and on cookie policy in sync
1283	//do this before the change check to ensure sync: https://github.com/Really-Simple-Plugins/complianz-gdpr/issues/324
1284	let checked = value === 'allow';
1285	document.querySelectorAll('input.cmplz-'+category).forEach(obj => {
1286		obj.checked = checked;
1287	});
1288
1289	//do not trigger a change event if nothing has changed.
1290	if ( previous_value === value ) {
1291		return;
1292	}
1293
1294	cmplz_set_cookie(category, value);
1295	if ( value === 'allow' ) {
1296		cmplz_enable_category(category);
1297	}
1298
1299	cmplz_wp_set_consent(category, value);
1300	if ( category === 'statistics' ) {
1301		cmplz_wp_set_consent('statistics-anonymous', 'allow');
1302	}
1303
1304	let details = new Object();
1305	details.category = category;
1306	details.value = value;
1307	details.region = complianz.region;
1308	details.categories = cmplz_accepted_categories();
1309	//when the status is changed, we may need to fire scripts again, so we reset it.
1310	cmplz_all_scripts_hook_fired = false;
1311	let event = new CustomEvent('cmplz_status_change', { detail: details });
1312	document.dispatchEvent(event);
1313	if ( category === 'marketing' && value === 'deny' && previous_value === 'allow' ) {
1314		cmplz_integrations_revoke();
1315		//give the code some time to finish, so our track status code can send a signal to the backend.
1316		setTimeout(function(){
1317			cmplz_reload_browser_compatible()
1318		}, 500);
1319	}
1320}
1321
1322/*
1323* In some browsers, like firefox, the reload does not force reload, but keeps cached data, causing e.g. Google Maps to load anyway.
1324*/
1325function cmplz_reload_browser_compatible(){
1326  	if( navigator.userAgent.toLowerCase().indexOf('firefox') > -1 ){
1327		const url = new URL(window.location.href);
1328		url.searchParams.set('cmplz-force-reload', Date.now().toString());
1329		window.location.href = url.toString();
1330    } else {
1331    	window.location.reload();
1332    }
1333}
1334
1335/*
1336 * We use ajax to check the consenttype based on region, otherwise caching could prevent the user specific warning
1337 *
1338 * */
1339
1340var cmplz_user_data = [];
1341//check if it's already stored
1342if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_user_data) {
1343	cmplz_user_data = JSON.parse(sessionStorage.cmplz_user_data);
1344}
1345
1346//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version
1347if ( complianz.geoip == 1 && (cmplz_user_data.length == 0 || (cmplz_user_data.version !== complianz.version) || (cmplz_user_data.banner_version !== complianz.banner_version)) ) {
1348
1349	var request = new XMLHttpRequest();
1350	let cmplzUserRegion = cmplz_get_url_parameter(window.location.href, 'cmplz_user_region');
1351	cmplzUserRegion = cmplzUserRegion ? '&cmplz_user_region=' + cmplzUserRegion : '';
1352	request.open('GET', complianz.url+'banner?'+complianz.locale+cmplzUserRegion, true);
1353	request.setRequestHeader('Content-type', 'application/json');
1354	request.send();
1355	request.onload = function() {
1356		cmplz_user_data = JSON.parse(request.response);
1357		sessionStorage.cmplz_user_data = JSON.stringify(cmplz_user_data);
1358		conditionally_show_banner();
1359	};
1360} else {
1361	conditionally_show_banner();
1362}
1363
1364/*
1365 *  when ab testing, or using records of consent, we want to keep track of the unique user id
1366 */
1367
1368if ( complianz.store_consent == 1 ) {
1369	var cmplz_id_cookie = cmplz_get_cookie('id');
1370	var cmplz_id_session = '';
1371	var cmplz_id = '';
1372	if (typeof (Storage) !== "undefined" && sessionStorage.cmplz_id) {
1373		cmplz_id_session = JSON.parse(sessionStorage.cmplz_id);
1374	}
1375
1376	if ( cmplz_id_cookie.length == 0 && cmplz_id_session.length > 0 ) {
1377		cmplz_id = cmplz_id_session;
1378		cmplz_set_cookie('id', cmplz_id );
1379	}
1380
1381	if ( cmplz_id_cookie.length > 0 && cmplz_id_session.length == 0 ) {
1382		cmplz_id = cmplz_id_cookie;
1383	}
1384
1385	if ( typeof (Storage) !== "undefined" ) {
1386		sessionStorage.cmplz_id = JSON.stringify(cmplz_id);
1387	}
1388}
1389
1390// visibilitychange and pagehide work in more browsers hence we check if they are supported and try to use them
1391document.addEventListener('visibilitychange', function () {
1392	if ( document.visibilityState === 'hidden' ) {
1393		cmplz_track_status_end();
1394	}
1395});
1396window.addEventListener("pagehide", cmplz_track_status_end, false );
1397window.addEventListener("beforeunload", cmplz_track_status_end, false );
1398
1399function cmplz_track_status_end(){
1400	if ( !cmplz_consent_stored_once ) {
1401		cmplz_track_status();
1402	}
1403}
1404
1405/*
1406 * This creates an API which devs can use to trigger actions in complianz.
1407 */
1408document.addEventListener('cmplz_consent_action', function (e) {
1409	cmplz_set_consent( e.detail.category , 'allow' );
1410	cmplz_fire_categories_event();
1411	cmplz_track_status();
1412});
1413
1414/*
1415 * Accept all categories
1416 */
1417window.cmplz_accept_all = function(){
1418	cmplz_clear_all_service_consents();
1419	for (var key in cmplz_categories) {
1420		if ( cmplz_categories.hasOwnProperty(key) ) {
1421			cmplz_set_consent(cmplz_categories[key], 'allow');
1422		}
1423	}
1424	cmplz_sync_category_checkboxes();
1425}
1426
1427/*
1428 * Deny all categories, and reload if needed.
1429 */
1430window.cmplz_deny_all = function(){
1431	for (var key in cmplz_categories) {
1432		if ( cmplz_categories.hasOwnProperty(key) ) {
1433			cmplz_set_consent(cmplz_categories[key], 'deny');
1434		}
1435	}
1436	var consentLevel = cmplz_highest_accepted_category();
1437	var reload = false;
1438
1439	if (consentLevel !== 'functional' || cmplz_exists_service_consent() ) {
1440		reload = true;
1441	}
1442	if ( cmplz_clear_cookies('cmplz_service') ) {
1443		reload = true;
1444	}
1445
1446	//has to be after the check if should be reloaded, otherwise that check won't work.
1447	cmplz_clear_all_service_consents();
1448	cmplz_integrations_revoke();
1449	cmplz_fire_categories_event();
1450	cmplz_track_status();
1451
1452	let event = new CustomEvent('cmplz_revoke', { detail: reload });
1453	document.dispatchEvent(event);
1454
1455	//we need to let the iab extension handle the reload, otherwise the consent revoke might not be ready yet.
1456	if ( !complianz.tcf_active && reload ) {
1457		cmplz_reload_browser_compatible();
1458	}
1459}
1460
1461/*
1462 * For both opt-in and opt-out, clicking cmplz-accept should result in accepting all categories
1463 */
1464cmplz_add_event('click', '.cmplz-accept', function(e){
1465	e.preventDefault();
1466	cmplz_accept_all();
1467	cmplz_set_banner_status('dismissed');
1468	cmplz_fire_categories_event();
1469	cmplz_track_status();
1470});
1471
1472/*
1473 *  Accept marketing cookies by clicking any other link cookie acceptance from a custom link
1474 */
1475
1476//cmplz-accept-marketing is deprecated
1477cmplz_add_event('click', '.cmplz-accept-category, .cmplz-accept-marketing', function(e){
1478	e.preventDefault();
1479	let obj = e.target;
1480	var service = obj.getAttribute('data-service');
1481	var category = obj.getAttribute('data-category');
1482	category = category ? category : 'marketing';
1483	if ( complianz.clean_cookies == 1 && typeof service !== 'undefined' && service ){
1484		cmplz_set_service_consent(service, true);
1485		cmplz_enable_category('', 'general');
1486		cmplz_enable_category('', service);
1487	} else {
1488		//we're activating a category, so do not need service activation here.
1489		// cmplz_enable_category('', 'general');
1490		cmplz_set_consent( category, 'allow' );
1491	}
1492	cmplz_set_banner_status('dismissed');
1493	cmplz_fire_categories_event();
1494	cmplz_track_status();
1495});
1496
1497/*
1498 * Accept a specific service
1499 */
1500cmplz_add_event('click', '.cmplz-accept-service', function(e){
1501	let obj = e.target;
1502	//INPUT should be handled by change event, these are checkboxes on the cookie policy
1503	let tagName = obj.tagName;
1504	if ( tagName === 'INPUT' ) {
1505		return;
1506	}
1507	let service = obj.getAttribute('data-service');
1508	if ( typeof service !== 'undefined' ){
1509		cmplz_set_service_consent(service, true);
1510		cmplz_enable_category('', 'general');
1511		cmplz_enable_category('', service);
1512	}
1513	cmplz_fire_categories_event();
1514	cmplz_track_status();
1515});
1516/*
1517 * Accept a specific service
1518 */
1519cmplz_add_event('change', '.cmplz-accept-service', function(e){
1520	let obj = e.target;
1521	let tagName = obj.tagName;
1522	let service = obj.getAttribute('data-service');
1523	if ( typeof service !== 'undefined' ) {
1524		//inputs are from the consent per service option on the cookie policy.
1525		if ( tagName === 'INPUT' ) {
1526			cmplz_set_banner_status('dismissed');
1527			if ( obj.checked ){
1528				cmplz_set_service_consent(service, true);
1529				cmplz_enable_category('', service);
1530			} else {
1531				cmplz_set_service_consent(service, false);
1532				//give our track status time to finish
1533				setTimeout(function(){
1534					cmplz_reload_browser_compatible()
1535				}, 500);
1536			}
1537			//if not input, it's a placeholder
1538		} else {
1539			e.preventDefault();
1540			cmplz_set_service_consent(service, true);
1541			cmplz_enable_category('', 'general');
1542			cmplz_enable_category('', service);
1543
1544			//give our track status time to finish
1545			setTimeout(function(){
1546				cmplz_reload_browser_compatible()
1547			}, 500);
1548		}
1549	}
1550	cmplz_fire_categories_event();
1551	cmplz_track_status();
1552});
1553
1554
1555
1556/*
1557 * On the banner, clicking a category should fire the category only after the save button is clicked.
1558 *
1559 */
1560cmplz_add_event('click', '.cmplz-save-preferences', function(e){
1561	let obj = e.target;
1562	cmplz_banner = obj.closest('.cmplz-cookiebanner');
1563	for (var key in cmplz_categories) {
1564		if ( cmplz_categories.hasOwnProperty(key) ) {
1565			var category = cmplz_categories[key];
1566			var categoryElement = cmplz_banner.querySelector('input.cmplz-' + category);
1567			if (categoryElement) {
1568				if (categoryElement.checked) {
1569					cmplz_set_consent(category, 'allow');
1570				} else {
1571					cmplz_set_consent(category, 'deny');
1572				}
1573			}
1574		}
1575	}
1576	cmplz_set_banner_status('dismissed');
1577	cmplz_fire_categories_event();
1578	cmplz_track_status();
1579});
1580
1581cmplz_add_event('click', '.cmplz-close', function(e){
1582	cmplz_set_banner_status('dismissed');
1583});
1584
1585cmplz_add_event('click', '.cmplz-view-preferences', function(e){
1586	let obj = e.target;
1587	cmplz_banner = obj.closest('.cmplz-cookiebanner');
1588	if ( cmplz_banner.querySelector('.cmplz-categories').classList.contains('cmplz-fade-in')) {
1589		cmplz_banner.classList.remove('cmplz-categories-visible');
1590		cmplz_banner.querySelector('.cmplz-categories' ).classList.remove('cmplz-fade-in');
1591		cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'block';
1592		cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'none';
1593	} else {
1594		cmplz_banner.classList.add('cmplz-categories-visible');
1595		cmplz_banner.querySelector('.cmplz-categories' ).classList.add('cmplz-fade-in');
1596		cmplz_banner.querySelector('.cmplz-view-preferences' ).style.display = 'none';
1597		cmplz_banner.querySelector('.cmplz-save-preferences' ).style.display = 'block';
1598	}
1599});
1600/*
1601 * On the cookie policy, clicking a category should fire the category immediately
1602 *
1603 */
1604cmplz_add_event('change', '.cmplz-manage-consent-container .cmplz-category', function(e){
1605	for (var key in cmplz_categories) {
1606		if ( cmplz_categories.hasOwnProperty(key) ) {
1607			var category = cmplz_categories[key];
1608			var categoryElement = document.querySelector('.cmplz-manage-consent-container input.cmplz-' + category);
1609			if (categoryElement) {
1610				if (categoryElement.checked) {
1611					cmplz_set_consent(category, 'allow');
1612				} else {
1613					cmplz_set_consent(category, 'deny');
1614				}
1615				cmplz_set_banner_status('dismissed');
1616				cmplz_fire_categories_event();
1617				cmplz_track_status();
1618			}
1619		}
1620	}
1621
1622});
1623
1624cmplz_add_event('click', '.cmplz-deny', function(e){
1625	e.preventDefault();
1626	cmplz_set_banner_status('dismissed');
1627	cmplz_deny_all();
1628
1629});
1630
1631cmplz_add_event('click', 'button.cmplz-manage-settings', function(e){
1632	e.preventDefault();
1633	var catsContainer = document.querySelector('.cmplz-cookiebanner .cmplz-categories');
1634	var saveSettings = document.querySelector('.cmplz-save-settings');
1635	var manageSettings = document.querySelector('button.cmplz-manage-settings');
1636	if ( !cmplz_is_hidden(catsContainer) ){
1637		saveSettings.style.display='none';
1638		manageSettings.style.display = 'block';
1639		catsContainer.style.display='none';
1640	} else {
1641		saveSettings.style.display = 'block';
1642		manageSettings.style.display='none';
1643		catsContainer.style.display = 'block';
1644	}
1645});
1646
1647cmplz_add_event('click', 'button.cmplz-manage-consent', function(e){
1648	e.preventDefault();
1649	cmplz_set_banner_status('show');
1650});
1651
1652/*
1653 * Handle dismiss on scroll and dismiss on timeout
1654 */
1655function cmplz_set_up_auto_dismiss() {
1656	if ( complianz.consenttype === 'optout' ) {
1657		if ( complianz.dismiss_on_scroll==1 ) {
1658			var onWindowScroll = function(evt) {
1659				if (window.pageYOffset > Math.floor(400)) {
1660					cmplz_set_banner_status('dismissed');
1661					cmplz_fire_categories_event();
1662					cmplz_track_status();
1663					window.removeEventListener('scroll', onWindowScroll);
1664					this.onWindowScroll = null;
1665				}
1666			};
1667			window.addEventListener('scroll', onWindowScroll);
1668		}
1669
1670		var delay = parseInt(complianz.dismiss_timeout);
1671		if ( delay > 0 ) {
1672			var cmplzDismissTimeout = window.setTimeout(function () {
1673				cmplz_set_banner_status('dismissed');
1674				cmplz_fire_categories_event();
1675				cmplz_track_status();
1676			}, Math.floor(delay));
1677		}
1678	}
1679}
1680
1681/*
1682 * Fire a event wich passes all consented categories
1683 * Separated from the actual category consent because we want to bundle it in one event
1684 */
1685function cmplz_fire_categories_event(){
1686	let details = new Object();
1687	details.category = cmplz_highest_accepted_category();
1688	details.categories = cmplz_accepted_categories();
1689	details.region = complianz.region;
1690	let event = new CustomEvent('cmplz_fire_categories', { detail: details });
1691	document.dispatchEvent(event);
1692}
1693/*
1694 * Track the status of current consent
1695 * @param status
1696 */
1697
1698function cmplz_track_status( status ) {
1699	var cats = [];
1700	status = typeof status !== 'undefined' ? status : false;
1701
1702	let event = new CustomEvent('cmplz_track_status', { detail: status });
1703	document.dispatchEvent(event);
1704
1705	if ( !status ) {
1706		cats = cmplz_accepted_categories();
1707	} else {
1708		cats = [status];
1709	}
1710	cmplz_set_category_as_body_class();
1711	var saved_cats, saved_services;
1712	try {saved_cats = JSON.parse(cmplz_get_cookie('saved_categories'));} catch (e) {saved_cats = {};}
1713	try {saved_services = JSON.parse(cmplz_get_cookie('saved_services'));} catch (e) {saved_services = {};}
1714	var consented_services = cmplz_get_all_service_consents();
1715
1716	//compare current cats with saved cats. When there are no changes, do nothing.
1717	if (cmplz_equals(saved_cats, cats) && cmplz_equals(saved_services, consented_services)) {
1718		return;
1719	}
1720
1721	if ( complianz.store_consent != 1 || cmplz_is_bot() || cmplz_is_speedbot() ) {
1722		return;
1723	}
1724
1725	//keep track of the fact that the status was saved at least once
1726	cmplz_set_cookie('saved_categories', JSON.stringify(cats));
1727	cmplz_set_cookie('saved_services', JSON.stringify(consented_services));
1728	cmplz_consent_stored_once = true;
1729
1730	let data;
1731	var request = new XMLHttpRequest();
1732	request.open('POST', complianz.url+'track', true);
1733	data = {
1734		'consented_categories': cats,
1735		'consented_services':consented_services,
1736		'consenttype': window.wp_consent_type,//store the source consenttype, as our complianz.consenttype will not include optinstats.
1737	};
1738
1739	request.setRequestHeader('Content-type', 'application/json');
1740	request.send(JSON.stringify(data));
1741
1742}
1743
1744/*
1745 * Get accepted categories
1746 *
1747 * @returns {string}
1748 */
1749function cmplz_accepted_categories() {
1750	var consentedCategories = cmplz_categories;
1751	var consentedTemp = [];
1752
1753	//because array filter changes keys, we make a temp arr
1754	for (var key in consentedCategories) {
1755		if ( consentedCategories.hasOwnProperty(key) ) {
1756			var category = consentedCategories[key];
1757			if (cmplz_has_consent(category)) {
1758				consentedTemp.push(category);
1759			}
1760		}
1761	}
1762
1763	consentedCategories = consentedCategories.filter(function(value, index, consentedCategories){
1764		return cmplz_in_array(value, consentedTemp);
1765	});
1766	return consentedCategories;
1767}
1768
1769/*
1770 * Enable the checkbox for each category which was enabled
1771 *
1772 * */
1773
1774function cmplz_sync_category_checkboxes() {
1775	for ( var key in cmplz_categories ) {
1776		if ( cmplz_categories.hasOwnProperty(key) ) {
1777			var category = cmplz_categories[key];
1778			if ( cmplz_has_consent(category) || category === 'functional' ) {
1779				document.querySelectorAll('input.cmplz-' + category).forEach(obj => {
1780					obj.checked = true;
1781				});
1782			} else {
1783				document.querySelectorAll('input.cmplz-' + category).forEach(obj => {
1784					obj.checked = false;
1785				});
1786			}
1787		}
1788
1789		document.querySelectorAll('.cmplz-accept-service').forEach(obj => {
1790			let service = obj.getAttribute('data-service');
1791			let category = obj.getAttribute('data-category');
1792			if ( cmplz_has_service_consent( service, category ) ) {
1793				obj.checked = true;
1794			} else if ( cmplz_is_service_denied( service ) ) {
1795				obj.checked = false;
1796			} else {
1797				//no consent on service level, check if it's category has consent.
1798				let category = obj.getAttribute('data-category' );
1799				obj.checked = !!cmplz_has_consent(category);
1800			}
1801		});
1802	}
1803}
1804
1805/*
1806 * Merge two objects
1807 *
1808 * */
1809
1810function cmplz_merge_object(userdata, ajax_data) {
1811	var output = [];
1812	//first, we fill the important data.
1813	for (key in ajax_data) {
1814		if (ajax_data.hasOwnProperty(key)) output[key] = ajax_data[key];
1815	}
1816
1817	//conditionally add static data
1818	for (var key in userdata) {
1819		//only add if not in ajax_data
1820		if (!ajax_data.hasOwnProperty(key) || typeof ajax_data[key] === 'undefined') {
1821			if (userdata.hasOwnProperty(key)) output[key] = userdata[key];
1822		}
1823	}
1824
1825	return output;
1826}
1827
1828/*
1829 * If current cookie policy has changed, reset cookie consent
1830 *
1831 * */
1832
1833function cmplz_check_cookie_policy_id() {
1834	var user_policy_id = cmplz_get_cookie('policy_id');
1835	if (user_policy_id && (complianz.current_policy_id !== user_policy_id) ) {
1836		cmplz_clear_cookies('cmplz');
1837	}
1838}
1839
1840/*
1841 * Clear all our own cookies, to make sure path issues are resolved.
1842 *
1843 *
1844 */
1845function cmplz_clear_cookies(cookie_part){
1846	var foundCookie = false;
1847
1848	if (typeof document === 'undefined') {
1849		return foundCookie;
1850	}
1851	var secure = ";secure";
1852	var date = new Date();
1853	date.setTime(date.getTime() - (24 * 60 * 60 * 1000));
1854	var expires = ";expires=" + date.toGMTString();
1855	if (window.location.protocol !== "https:") secure = '';
1856	let cookies = document.cookie.split("; ");
1857	let pathname = location.pathname;
1858	let pathParts = pathname.replace(/^\/|\/$/g, '').split('/');
1859
1860	//loop through all cookies
1861	for (var i = 0; i < cookies.length; i++) {
1862		let cookieName = cookies[i].split(";")[0].split("=")[0];
1863		let host = window.location.hostname;
1864		var domainParts = host.split(".");
1865		//if we have more than one result in the array, we can skip the last one, as it will be the .com/.org extension
1866		let skip_last = domainParts.length > 1;
1867		//if the cookie contains cookie_part, try to delete it
1868		if ( cookieName.indexOf(cookie_part) !==-1 ) {
1869			foundCookie = true;
1870			let cookieBaseDomain = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=;path=';
1871			document.cookie = cookieBaseDomain + '/';
1872			//and on paths on root
1873			while ( pathParts.length > 0) {
1874				var path = pathParts.join('/');
1875				if ( path.length>0 ) {
1876					document.cookie = cookieBaseDomain + '/' + path;
1877					document.cookie = cookieBaseDomain + '/' + path + '/';
1878				}
1879				pathParts.pop();
1880			};
1881			while ( domainParts.length > 0) {
1882				let cookieBase 		 = encodeURIComponent(cookieName) + '=;SameSite=Lax' + secure + expires +';domain=.' + domainParts.join('.') + ';path=';
1883				document.cookie = cookieBase+ '/';
1884				while (pathParts.length > 0) {
1885					var path = pathParts.join('/');
1886					if ( path.length>0 ) {
1887						document.cookie = cookieBase + '/' + path;
1888						document.cookie = cookieBase + '/' + path + '/';
1889					}
1890					pathParts.pop();
1891				};
1892
1893				domainParts.shift();
1894				//prevents setting cookies on .com/.org
1895				if (skip_last && domainParts.length==1) domainParts.shift();
1896			}
1897		}
1898	}
1899
1900	//to prevent a double reload, we preserve the cookie policy id.
1901	cmplz_set_accepted_cookie_policy_id();
1902	return foundCookie;
1903}
1904
1905/*
1906 *
1907 * If a policy is accepted, save this in the user policy id
1908 *
1909 * */
1910
1911function cmplz_set_accepted_cookie_policy_id() {
1912	cmplz_set_cookie('policy_id', complianz.current_policy_id);
1913}
1914
1915/*
1916 * For supported integrations, initialize the not consented state
1917 *
1918 * */
1919
1920function cmplz_integrations_init() {
1921	var cookiesToSet = complianz.set_cookies;
1922	//check if we have scripts that need to be set to true on init.
1923	for (var key in cookiesToSet) {
1924		if (cookiesToSet.hasOwnProperty(key) && cookiesToSet[key][1] === '1') {
1925			cmplz_set_cookie(key, cookiesToSet[key][1], false);
1926		}
1927	}
1928}
1929
1930/*
1931 * For supported integrations, revoke consent
1932 *
1933 * */
1934function cmplz_integrations_revoke() {
1935	var cookiesToSet = complianz.set_cookies;
1936	for (var key in cookiesToSet) {
1937		if (cookiesToSet.hasOwnProperty(key)) {
1938			cmplz_set_cookie(key, cookiesToSet[key][1], false);
1939			if ( cookiesToSet[key][1] == false ){
1940				cmplz_clear_cookies(key);
1941			}
1942		}
1943	}
1944}
1945
1946/*
1947 * For supported integrations, set consent
1948 *
1949 * */
1950
1951function cmplz_set_integrations_cookies() {
1952	var cookiesToSet = complianz.set_cookies;
1953	for (var key in cookiesToSet) {
1954		if (cookiesToSet.hasOwnProperty(key)) {
1955			cmplz_set_cookie(key, cookiesToSet[key][0], false);
1956		}
1957	}
1958}
1959
1960function cmplz_get_url_parameter(sPageURL, sParam) {
1961	if ( !sPageURL || typeof sPageURL === 'undefined' ) {
1962		return false;
1963	}
1964
1965	if ( sPageURL.indexOf('?')==-1) {
1966		return false;
1967	}
1968
1969	var queryString = sPageURL.split('?');
1970	if (queryString.length == 1) return false;
1971
1972	var sURLVariables = queryString[1].split('&'),
1973		sParameterName,
1974		i;
1975	for (i = 0; i < sURLVariables.length; i++) {
1976		if ( sURLVariables.hasOwnProperty(i) ) {
1977			sParameterName = sURLVariables[i].split('=');
1978			if (sParameterName[0] === sParam) {
1979				return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
1980			}
1981		}
1982	}
1983	return false;
1984}
1985
1986/*
1987 * If the parameter cmplz_region_redirect =true is passed, find the user's region, and redirect.
1988 */
1989function cmplz_maybe_auto_redirect() {
1990	var redirect = cmplz_get_url_parameter(window.location.href, 'cmplz_region_redirect');
1991	var region = cmplz_get_url_parameter(window.location.href, 'cmplz-region');
1992	if (redirect && !region) {
1993		window.location.href = window.location.href + '&cmplz-region=' + complianz.region;
1994	}
1995}
1996
1997/*
1998 * wrapper to set consent for wp consent API. If consent API is not active, do nothing
1999 * @param type
2000 * @param value
2001 */
2002function cmplz_wp_set_consent(type, value) {
2003	//wp consent api integration
2004	if (typeof wp_set_consent == 'function') {
2005		wp_set_consent(type, value);
2006	}
2007}
2008
2009var cmplz_cookie_data = [];
2010var cmplzCleanCookieInterval;
2011function cmplz_start_clean(){
2012	if ( complianz.clean_cookies == 1 ) {
2013		//check if it's already stored
2014		if (typeof (Storage) !== "undefined" ) {
2015			cmplz_cookie_data = JSON.parse( sessionStorage.getItem('cmplz_cookie_data') );
2016		}
2017		//if not stored yet, load. As features in the user object can be changed on updates, we also check for the version
2018		if ( !cmplz_cookie_data || cmplz_cookie_data.length == 0 ) {
2019			var request = new XMLHttpRequest();
2020			request.open('GET', complianz.url+'cookie_data', true);
2021			request.setRequestHeader('Content-type', 'application/json');
2022			request.send();
2023			request.onload = function() {
2024				cmplz_cookie_data = JSON.parse(request.response);
2025				sessionStorage.setItem('cmplz_cookie_data', JSON.stringify(cmplz_cookie_data) );
2026				cmplz_setup_clean_interval();
2027			};
2028		} else {
2029			cmplz_setup_clean_interval();
2030		}
2031	}
2032}
2033
2034/*
2035* Execute the cleanup of cookies
2036*/
2037function cmplz_do_cleanup(){
2038	let consent_categories = [
2039		'preferences',
2040		'statistics',
2041		'marketing',
2042	];
2043	for (var i in consent_categories) {
2044		let category = consent_categories[i];
2045		if ( !cmplz_has_consent(category) && cmplz_cookie_data.hasOwnProperty(category) ) {
2046			let services = cmplz_cookie_data[category];
2047			for (var service in services) {
2048				if ( !cmplz_has_service_consent(service, category) ) {
2049					let cookies = services[service];
2050					for (var j in cookies) {
2051						let item = cookies[j];
2052						cmplz_clear_cookies(item);
2053						cmplz_clear_storage(item);
2054					}
2055				}
2056			}
2057		}
2058	}
2059}
2060
2061function cmplz_setup_clean_interval(){
2062	// if the cookie data array is empty, return, nothing to do.
2063	if ( !cmplz_cookie_data ) {
2064		return;
2065	}
2066	//check if it's already activated
2067	if ( cmplzCleanCookieInterval ) {
2068		return;
2069	}
2070	//one straight away, then every second
2071	cmplz_do_cleanup();
2072	cmplzCleanCookieInterval = setInterval(cmplz_do_cleanup, 1000 );
2073}
2074
2075/*
2076 * Clear an item from either session or localstorage
2077 * @param item
2078 */
2079function cmplz_clear_storage(item){
2080	if (typeof (Storage) !== "undefined" ) {
2081		if ( localStorage.item ) {
2082			localStorage.removeItem(item);
2083		}
2084		if ( sessionStorage.item ) {
2085			sessionStorage.removeItem(item);
2086		}
2087	}
2088}
2089/*
2090 * Load revoke options
2091 */
2092
2093function cmplz_load_manage_consent_container() {
2094	//don't load manage html code in the block editor
2095	let manage_consent_container = document.querySelector('.cmplz-manage-consent-container');
2096	let is_block_editor = false;//document.querySelector('.wp-admin .cmplz-unlinked-mode');
2097	if ( manage_consent_container && !is_block_editor ) {
2098
2099		var request = new XMLHttpRequest();
2100		request.open('GET', complianz.url+'manage_consent_html?'+complianz.locale, true);
2101		request.setRequestHeader('Content-type', 'application/json');
2102		request.send();
2103		request.onload = function() {
2104			let html = JSON.parse(request.response);
2105			manage_consent_container.insertAdjacentHTML( 'beforeend', html );
2106			cmplz_sync_category_checkboxes();
2107			let nojavascript = document.querySelector('#cmplz-manage-consent-container-nojavascript')
2108			nojavascript.style.display = 'none';
2109			manage_consent_container.style.display = 'block';
2110			let event = new CustomEvent('cmplz_manage_consent_container_loaded');
2111			document.dispatchEvent(event);
2112		};
2113	}
2114}
2115
2116/*
2117 * Make slider radio's tabable
2118 */
2119
2120cmplz_add_event('keypress', '.cmplz-banner-slider label', function(e){
2121	var keycode = (e.keyCode ? e.keyCode : e.which);
2122	if (keycode == 32) {
2123		document.activeElement.click();
2124	}
2125});
2126
2127/*
2128 * Make close button closable with enter
2129 */
2130cmplz_add_event('keypress', '.cmplz-cookiebanner .cmplz-header .cmplz-close', function(e){
2131	var keycode = (e.keyCode ? e.keyCode : e.which);
2132	if ( keycode == 13 ) {
2133		document.activeElement.click();
2134	}
2135});
2136
2137/*
2138 * Compare two arrays
2139 * @param array
2140 * @returns {boolean}
2141 */
2142function cmplz_equals (array_1, array_2) {
2143	if ( !Array.isArray(array_1) ) {
2144		array_1 = Object.keys(array_1);
2145		array_2 = Object.keys(array_2);
2146	}
2147	// if the other array is a falsy value, return
2148	if (!array_1 || !array_2)
2149		return false;
2150
2151	// compare lengths - can save a lot of time
2152	if (array_1.length != array_2.length)
2153		return false;
2154
2155	for (var i = 0, l=array_1.length; i < l; i++) {
2156		// Check if we have nested arrays
2157		if (array_1[i] instanceof Array && array_2[i] instanceof Array) {
2158			// recurse into the nested arrays
2159			if (!cmplz_equals(array_1[i], array_2[i]))
2160				return false;
2161		}
2162		else if (array_1[i] != array_2[i]) {
2163			// Warning - two different object instances will never be equal: {x:20} != {x:20}
2164			return false;
2165		}
2166	}
2167	return true;
2168}
2169
2170/*
2171* Copy all element atributes to the new element
2172*/
2173function cmplzCopyAttributes(source, target) {
2174  return Array.from(source.attributes).forEach(attribute => {
2175  	//don't copy the type attribute
2176    let excludes = ['type', 'data-service', 'data-category', 'async'];
2177	if ( !excludes.includes(attribute.nodeName) ) {
2178		 target.setAttribute(
2179		  attribute.nodeName,
2180		  attribute.nodeValue,
2181		);
2182	}
2183  });
2184}
2185
2186/*
2187 * Hooked into jquery
2188 */
2189let cmplz_has_wp_video = document.querySelector('.cmplz-wp-video-shortcode');
2190let cmplz_times_checked = 0;
2191if ('undefined' != typeof window.jQuery) {
2192	jQuery(document).ready(function ($) {
2193		if ( cmplz_has_wp_video ) {
2194			document.addEventListener("cmplz_enable_category", function (consentData) {
2195				cmplz_activate_wp_video();
2196			});
2197
2198			var cmplzInterval = setInterval(function(){
2199				cmplz_times_checked+=1;
2200				if ( document.querySelector('.cmplz-wp-video-shortcode') && cmplz_times_checked<100) {
2201					cmplz_activate_wp_video();
2202				} else {
2203					clearInterval(cmplzInterval);
2204				}
2205			}, 500);
2206		}
2207
2208		/*
2209		 * WordPress legacy shortcode
2210		 */
2211		function cmplz_activate_wp_video(again) {
2212			if ( !document.querySelector('.cmplz-wp-video-shortcode') ) {
2213				return;
2214			}
2215			let categories = cmplz_accepted_categories();
2216			let services = cmplz_get_all_service_consents();
2217			let selectorVideo = '';
2218			let selectorVideos = [];
2219			for (var c_key in categories) {
2220				if (categories.hasOwnProperty(c_key)) {
2221					let category = categories[c_key];
2222					if (category==='functional') {
2223						break;
2224					}
2225					selectorVideos.push('.cmplz-wp-video-shortcode[data-category='+category+']');
2226				}
2227			}
2228			for (var s_key in services) {
2229				if (services.hasOwnProperty(s_key)) {
2230					selectorVideos.push('.cmplz-wp-video-shortcode[data-service=' + s_key + ']');
2231				}
2232			}
2233			selectorVideo = selectorVideos.join(',');
2234			let should_initialize_video = false;
2235			if ( selectorVideo.length>0 ) {
2236				document.querySelectorAll(selectorVideo).forEach(obj => {
2237					should_initialize_video = true;
2238					obj.setAttribute('controls', 'controls');
2239					obj.classList.add('wp-video-shortcode');
2240					obj.classList.add('cmplz-processed');
2241					obj.classList.remove('cmplz-wp-video-shortcode');
2242					obj.closest('.cmplz-wp-video').classList.remove('cmplz-wp-video');
2243
2244					let blocked_notice = obj.closest('.wp-video').querySelector('.cmplz-blocked-content-notice');
2245					if (blocked_notice) {
2246						blocked_notice.parentElement.removeChild(blocked_notice);
2247					}
2248					obj.classList.remove('cmplz-blocked-content-container');
2249				});
2250			}
2251
2252			if ( should_initialize_video ) {
2253				//in normal setup, this should work. e.g. with primavera theme not, then we init per element.
2254				if (window.wp.mediaelement) {
2255					window.wp.mediaelement.initialize()
2256				} else {
2257					let settings={};
2258					settings.videoWidth='100%';
2259					settings.videoHeight='100%';
2260					settings.enableAutosize=true;
2261					$( '.wp-video-shortcode' ).mediaelementplayer( settings );
2262				}
2263			}
2264		}
2265
2266		/*
2267		 * Activate fitvids on the parent element if active
2268		 *  a.o. Beaverbuilder
2269		 */
2270
2271		document.querySelectorAll('.cmplz-video').forEach(obj => {
2272			//turn obj into jquery object
2273			let $obj = $(obj);
2274			if (typeof $obj.parent().fitVids == 'function') {
2275				$obj.parent().fitVids();
2276			}
2277		});
2278
2279		/*
2280		 * Activate fitvids on the parent element if active
2281		 *  a.o. Beaverbuilder
2282		 */
2283		$(document).on("cmplz_category_enabled", cmplz_enable_fitvids);
2284		function cmplz_enable_fitvids(data) {
2285			document.querySelectorAll('.cmplz-video').forEach(obj => {
2286				//turn obj into jquery object
2287				let $obj = $(obj);
2288				if (typeof $obj.parent().fitVids == 'function') {
2289					$obj.parent().fitVids();
2290				}
2291			});
2292		}
2293
2294	});
2295}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.