/*! * CookieConsent v2.8.0 * https://www.github.com/orestbida/cookieconsent * Author Orest Bida * Released under the MIT License */ (function(){ 'use strict'; /** * @param {HTMLElement} [root] - [optional] element where the cookieconsent will be appended * @returns {Object} cookieconsent object with API */ var c_consent = function(root){ /** * CHANGE THIS FLAG FALSE TO DISABLE console.log() */ var ENABLE_LOGS = false; var _config = { 'mode': 'opt-in', // 'opt-in', 'opt-out' 'current_lang': 'en', 'auto_language': null, 'autorun': true, // run as soon as loaded 'cookie_name': 'cc_cookie', 'cookie_expiration': 182, // default: 6 months (in days) 'cookie_domain': window.location.hostname, // default: current domain 'cookie_path': '/', 'cookie_same_site': 'Lax', 'use_rfc_cookie': false, 'autoclear_cookies': true, 'revision': 0, 'branding': true, 'script_selector': 'data-cookiecategory' }; var /** * Object which holds the main methods/API (.show, .run, ...) */ _cookieconsent = {}, /** * Global user configuration object */ user_config, /** * Internal state variables */ saved_cookie_content = {}, cookie_data = null, cookie_consent_accepted = false, consent_modal_exists = false, consent_modal_visible = false, settings_modal_visible = false, clicked_inside_modal = false, current_modal_focusable, all_table_headers, all_blocks, consent_uuid, c_consent_token, // Helper callback functions // (avoid calling "user_config['onAccept']" all the time) onAccept, onChange, onFirstAction, revision_enabled = false, valid_revision = true, revision_message = '', // State variables for the autoclearCookies function changed_settings = [], reload_page = false; /** * Accept type: * - "all" * - "necessary" * - "custom" * @type {string} */ var accept_type; /** * Contains all accepted categories * @type {string[]} */ var accepted_categories = []; /** * Contains all non-accepted (rejected) categories * @type {string[]} */ var rejected_categories = []; /** * Contains all categories enabled by default * @type {string[]} */ var default_enabled_categories = []; // Don't run plugin (to avoid indexing its text content) if bot detected var is_bot = false; /** * Save reference to the last focused element on the page * (used later to restore focus when both modals are closed) */ var last_elem_before_modal; var last_consent_modal_btn_focus; /** * Both of the arrays below have the same structure: * [0] => holds reference to the FIRST focusable element inside modal * [1] => holds reference to the LAST focusable element inside modal */ var consent_modal_focusable = []; var settings_modal_focusable = []; /** * Keep track of enabled/disabled categories * @type {boolean[]} */ var toggle_states = []; /** * Stores all available categories * @type {string[]} */ var all_categories = []; /** * Keep track of readonly toggles * @type {boolean[]} */ var readonly_categories = []; /** * Pointers to main dom elements (to avoid retrieving them later using document.getElementById) */ var /** @type {HTMLElement} */ html_dom = document.documentElement, /** @type {HTMLElement} */ main_container, /** @type {HTMLElement} */ all_modals_container, /** @type {HTMLElement} */ consent_modal, /** @type {HTMLElement} */ consent_modal_title, /** @type {HTMLElement} */ consent_modal_description, /** @type {HTMLElement} */ consent_primary_btn, /** @type {HTMLElement} */ consent_secondary_btn, /** @type {HTMLElement} */ consent_buttons, /** @type {HTMLElement} */ consent_modal_inner, /** @type {HTMLElement} */ settings_container, /** @type {HTMLElement} */ settings_inner, /** @type {HTMLElement} */ settings_title, /** @type {HTMLElement} */ settings_close_btn, /** @type {HTMLElement} */ settings_blocks, /** @type {HTMLElement} */ new_settings_blocks, /** @type {HTMLElement} */ settings_buttons, /** @type {HTMLElement} */ settings_save_btn, /** @type {HTMLElement} */ settings_accept_all_btn, /** @type {HTMLElement} */ settings_reject_all_btn; /** * Update config settings * @param {Object} user_config */ var _loadScript = function(u){ var s = document.createElement("script"); s.type = "text/javascript"; s.src = u; document.head.appendChild(s); } _cookieconsent.clearCookies = function() { var arrCookies = document.cookie.split(';'), arrPaths = location.pathname.replace(/^\//, '').split('/'), // remove leading '/' and split any existing paths arrTemplate = [ 'expires=Thu, 01-Jan-1970 00:00:01 GMT', 'path={path}', 'domain=' + window.location.host, 'secure=' ]; // array of cookie settings in order tested and found most useful in establishing a "delete" for (var i in arrCookies) { var strCookie = arrCookies[i]; if (typeof strCookie == 'string' && strCookie.indexOf('=') >= 0) { var strName = strCookie.split('=')[0]; // the cookie name for (var j=1;j<=arrTemplate.length;j++) { if (document.cookie.indexOf(strName) < 0) break; // if this is true, then the cookie no longer exist else { var strValue = strName + '=; ' + arrTemplate.slice(0, j).join('; ') + ';'; // made using the temp array of settings, putting it together piece by piece as loop rolls on if (j == 1) document.cookie = strValue; else { for (var k=0;k<=arrPaths.length;k++) { if (document.cookie.indexOf(strName) < 0) break; // if this is true, then the cookie no longer exist else { var strPath = arrPaths.slice(0, k).join('/') + '/'; // builds path line strValue = strValue.replace('{path}', strPath); document.cookie = strValue; } } } } } } } _cookieconsent.show(); return true; } var _initAll = function (_conf){ const c = JSON.parse(_getCookie(_conf.cookie_name, 'one', true) || "{}"); if(Object.keys(c).length === 0){ // _cookieconsent.clearCookies(); } window.dataLayer = window.dataLayer || [], window.gtag = () => { window.dataLayer.push(arguments); }; window.gtag('js', new Date()); window.gtag('config', _conf['ga_id']); window.gtag("consent", "default", { ad_storage: "denied", analytics_storage: "denied", wait_for_update: 500 }); if(_conf['ga_id'] != undefined && _conf['ga_id'] != ""){ _loadScript('https://www.googletagmanager.com/gtag/js?id=' + _conf['ga_id']); } const _data = { ad_storage: c.level && c.level.includes("marketing") ? "granted" : "denied", analytics_storage: c.level && c.level.includes("analytics") ? "granted" : "denied" }; window.gtag('consent', 'update', _data); } var _setConfig = function(_user_config){ /** * Make user configuration globally available */ user_config = _user_config; _log("CookieConsent [CONFIG]: received_config_settings ", user_config); if(typeof user_config['c_consent_token'] === "string") c_consent_token = user_config['c_consent_token']; if(typeof user_config['cookie_expiration'] === "number") _config.cookie_expiration = user_config['cookie_expiration']; if(typeof user_config['cookie_necessary_only_expiration'] === "number") _config.cookie_necessary_only_expiration = user_config['cookie_necessary_only_expiration']; if(typeof user_config['autorun'] === "boolean") _config.autorun = user_config['autorun']; if(typeof user_config['cookie_domain'] === "string") _config.cookie_domain = user_config['cookie_domain']; if(typeof user_config['cookie_same_site'] === "string") _config.cookie_same_site = user_config['cookie_same_site']; if(typeof user_config['cookie_path'] === "string") _config.cookie_path = user_config['cookie_path']; if(typeof user_config['cookie_name'] === "string") _config.cookie_name = user_config['cookie_name']; if(typeof user_config['privacy'] === "string") _config.privacy = user_config['privacy']; if(typeof user_config['privacy_link'] === "string") _config.privacy_link = user_config['privacy_link']; if(typeof user_config['branding'] === "boolean") _config.branding = user_config['branding']; /* if(typeof user_config['onAccept'] === "function") onAccept = user_config['onAccept']; */ if(typeof user_config['onFirstAction'] === "function") onFirstAction = user_config['onFirstAction']; if(typeof user_config['onChange'] === "function") onChange = user_config['onChange']; if(user_config['mode'] === 'opt-out') _config.mode = 'opt-out'; if(typeof user_config['revision'] === "number"){ user_config['revision'] > -1 && (_config.revision = user_config['revision']); revision_enabled = true; } if(typeof user_config['autoclear_cookies'] === "boolean") _config.autoclear_cookies = user_config['autoclear_cookies']; if(user_config['use_rfc_cookie'] === true) _config.use_rfc_cookie = true; if(user_config['hide_from_bots'] === true){ is_bot = navigator && ((navigator.userAgent && /bot|crawl|spider|slurp|teoma/i.test(navigator.userAgent)) || navigator.webdriver); } _config.page_scripts = user_config['page_scripts'] === true; _config.page_scripts_order = user_config['page_scripts_order'] !== false; //[WARNING] Will be removed in v3 if (user_config['auto_language'] === 'browser' || user_config['auto_language'] === true) { _config.auto_language = 'browser'; } else if (user_config['auto_language'] === 'document') { _config.auto_language = 'document'; } _log("CookieConsent [LANG]: auto_language strategy is '" + _config.auto_language + "'"); _config.current_lang = _resolveCurrentLang(user_config.languages, user_config['current_lang']); } var _uuidv4 = function(){ return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, function(c){ return (c ^ (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) }); } /** * Add an onClick listeners to all html elements with data-cc attribute */ var _addDataButtonListeners = function(elem){ var _a = 'accept-'; var show_settings = _getElements('c-settings'); var accept_all = _getElements(_a + 'all'); var accept_necessary = _getElements(_a + 'necessary'); var accept_selection = _getElements(_a + 'selection'); for(var i=0; i} */ function _getElements(data_role){ return (elem || document).querySelectorAll('a[data-cc="' + data_role + '"], button[data-cc="' + data_role + '"]'); } /** * Helper function: accept and then hide modals * @param {PointerEvent} e source event * @param {string} [accept_type] */ function _acceptAction(e, accept_type){ e.preventDefault ? e.preventDefault() : e.returnValue = false; _cookieconsent.accept(accept_type); _cookieconsent.hideSettings(); _cookieconsent.hide(); } } /** * Get a valid language (at least 1 must be defined) * @param {string} lang - desired language * @param {Object} all_languages - all defined languages * @returns {string} validated language */ var _getValidatedLanguage = function(lang, all_languages){ if(Object.prototype.hasOwnProperty.call(all_languages, lang)){ return lang; }else if(_getKeys(all_languages).length > 0){ if(Object.prototype.hasOwnProperty.call(all_languages, _config.current_lang)){ return _config.current_lang ; }else{ return _getKeys(all_languages)[0]; } } } /** * Save reference to first and last focusable elements inside each modal * to prevent losing focus while navigating with TAB */ var _getModalFocusableData = function(){ /** * Note: any of the below focusable elements, which has the attribute tabindex="-1" AND is either * the first or last element of the modal, won't receive focus during "open/close" modal */ var allowed_focusable_types = ['[href]', 'button', 'input', 'details', '[tabindex="0"]']; function _getAllFocusableElements(modal, _array){ var focus_later=false, focus_first=false; // ie might throw exception due to complex unsupported selector => a:not([tabindex="-1"]) try{ var focusable_elems = modal.querySelectorAll(allowed_focusable_types.join(':not([tabindex="-1"]), ')); var attr, len=focusable_elems.length, i=0; while(i < len){ attr = focusable_elems[i].getAttribute('data-focus'); if(!focus_first && attr === "1"){ focus_first = focusable_elems[i]; }else if(attr === "0"){ focus_later = focusable_elems[i]; if(!focus_first && focusable_elems[i+1].getAttribute('data-focus') !== "0"){ focus_first = focusable_elems[i+1]; } } i++; } }catch(e){ return modal.querySelectorAll(allowed_focusable_types.join(', ')); } /** * Save first and last elements (used to lock/trap focus inside modal) */ _array[0] = focusable_elems[0]; _array[1] = focusable_elems[focusable_elems.length - 1]; _array[2] = focus_later; _array[3] = focus_first; } /** * Get settings modal'S all focusable elements * Save first and last elements (used to lock/trap focus inside modal) */ _getAllFocusableElements(settings_inner, settings_modal_focusable); /** * If consent modal exists, do the same */ if(consent_modal_exists){ _getAllFocusableElements(consent_modal, consent_modal_focusable); } } var _createConsentModal = function(lang){ if(user_config['force_consent'] === true) _addClass(html_dom, 'force--consent'); // Create modal if it doesn't exist if(!consent_modal){ consent_modal = _createNode('div'); var consent_modal_inner_inner = _createNode('div'); var overlay = _createNode('div'); consent_modal.id = 'cm'; consent_modal_inner_inner.id = 'c-inr-i'; overlay.id = 'cm-ov'; consent_modal.setAttribute('role', 'dialog'); consent_modal.setAttribute('aria-modal', 'true'); consent_modal.setAttribute('aria-hidden', 'false'); consent_modal.setAttribute('aria-labelledby', 'c-ttl'); consent_modal.setAttribute('aria-describedby', 'c-txt'); // Append consent modal to main container all_modals_container.appendChild(consent_modal); all_modals_container.appendChild(overlay); /** * Make modal by default hidden to prevent weird page jumps/flashes (shown only once css is loaded) */ consent_modal.style.visibility = overlay.style.visibility = "hidden"; overlay.style.opacity = 0; } // Use insertAdjacentHTML instead of innerHTML var consent_modal_title_value = user_config.languages[lang]['consent_modal']['title']; // Add title (if valid) if(consent_modal_title_value){ if(!consent_modal_title){ consent_modal_title = _createNode('div'); consent_modal_title.id = 'c-ttl'; consent_modal_title.setAttribute('role', 'heading'); consent_modal_title.setAttribute('aria-level', '2'); consent_modal_inner_inner.appendChild(consent_modal_title); } consent_modal_title.innerHTML = consent_modal_title_value; } var description = user_config.languages[lang]['consent_modal']['description']; if(revision_enabled){ if(!valid_revision){ description = description.replace("{{revision_message}}", revision_message || user_config.languages[lang]['consent_modal']['revision_message'] || ""); }else{ description = description.replace("{{revision_message}}", ""); } } if(!consent_modal_description){ consent_modal_description = _createNode('div'); consent_modal_description.id = 'c-txt'; consent_modal_inner_inner.appendChild(consent_modal_description); } if(typeof user_config['privacy'] === "string"){ var privacy_button = _createNode('a'); privacy_button.className = "cc-link-a"; privacy_button.setAttribute('href', user_config['privacy_link']); privacy_button.textContent = user_config['privacy']; consent_modal_inner_inner.appendChild(privacy_button); } if(typeof user_config['impressum'] === "string"){ var impressum_button = _createNode('a'); impressum_button.className = "cc-link-a"; impressum_button.setAttribute('href', user_config['impressum_link']); impressum_button.textContent = user_config['impressum']; consent_modal_inner_inner.appendChild(impressum_button); } // Set description content consent_modal_description.innerHTML = description; var primary_btn_data = user_config.languages[lang]['consent_modal']['primary_btn'], // accept current selection secondary_btn_data = user_config.languages[lang]['consent_modal']['secondary_btn'], branding = user_config.branding; // Add primary button if not falsy if(primary_btn_data){ if(!consent_primary_btn){ consent_primary_btn = _createNode('button'); consent_primary_btn.id = 'c-p-bn'; consent_primary_btn.className = "c-bn"; var _accept_type; if(primary_btn_data['role'] === 'accept_all') _accept_type = 'all' _addEvent(consent_primary_btn, "click", function(){ _cookieconsent.hide(); _log("CookieConsent [ACCEPT]: cookie_consent was accepted!"); _cookieconsent.accept(_accept_type); }); } consent_primary_btn.textContent = user_config.languages[lang]['consent_modal']['primary_btn']['text']; } // Add secondary button if not falsy if(secondary_btn_data){ if(!consent_secondary_btn){ consent_secondary_btn = _createNode('button'); consent_secondary_btn.id = 'c-s-bn'; consent_secondary_btn.className = "c-bn c_link"; if(secondary_btn_data['role'] === 'accept_necessary'){ consent_secondary_btn.textContent = user_config.languages[lang]['consent_modal']['secondary_btn']['text']; _addEvent(consent_secondary_btn, 'click', function(){ _cookieconsent.hide(); _cookieconsent.accept([]); // accept necessary only }); }else{ consent_secondary_btn.textContent = user_config.languages[lang]['einstellungen']; _addEvent(consent_secondary_btn, 'click', function(){ _cookieconsent.showSettings(0); }); } } } if(branding && branding == true){ var consent_homepage = _createNode('a'); consent_homepage.id = 'c-s-hp'; consent_homepage.className = "c_link"; consent_homepage.href = "https://www.cookieconsent.sk"; consent_homepage.textContent = "www.cookieconsent.sk"; } // Swap buttons var gui_options_data = user_config['gui_options']; if(!consent_modal_inner){ consent_modal_inner = _createNode('div'); consent_modal_inner.id = 'c-inr'; consent_modal_inner.appendChild(consent_modal_inner_inner); } if(!consent_buttons){ consent_buttons = _createNode('div'); consent_buttons.id = "c-bns"; if(gui_options_data && gui_options_data['consent_modal'] && gui_options_data['consent_modal']['swap_buttons'] === true){ secondary_btn_data && consent_buttons.appendChild(consent_secondary_btn); primary_btn_data && consent_buttons.appendChild(consent_primary_btn); consent_buttons.className = 'swap'; }else{ primary_btn_data && consent_buttons.appendChild(consent_primary_btn); secondary_btn_data && consent_buttons.appendChild(consent_secondary_btn); consent_homepage && consent_buttons.appendChild(consent_homepage); } (primary_btn_data || secondary_btn_data ) && consent_modal_inner.appendChild(consent_buttons); consent_modal.appendChild(consent_modal_inner); } consent_modal_exists = true; } var _createSettingsModal = function(lang){ /** * Create all consent_modal elements */ if(!settings_container){ settings_container = _createNode('div'); var settings_container_valign = _createNode('div'); var settings = _createNode('div'); var settings_container_inner = _createNode('div'); settings_inner = _createNode('div'); settings_title = _createNode('div'); var settings_header = _createNode('div'); settings_close_btn = _createNode('button'); var settings_close_btn_container = _createNode('div'); settings_blocks = _createNode('div'); var overlay = _createNode('div'); var holder = _createNode('div'); holder.className = "cc-rockmenu cc-animate"; var settings_button = _createNode('button'); settings_button.className = "rolling cc-link"; settings_button.setAttribute('data-cc', 'c-settings'); settings_button.setAttribute('href', '#'); var figure = _createNode('figure'); figure.className = "rolling_icon"; var icon = _createNode('img'); icon.src = "https://cdn.cookieconsent.sk/piktogram.svg"; icon.style.width = "52px"; icon.style.padding = "3px 3px"; var settings_text = _createNode('span'); settings_text.textContent = user_config.languages[lang]['manage_cookie_consent']; figure.appendChild(icon); settings_button.appendChild(figure); settings_button.appendChild(settings_text); holder.appendChild(settings_button); document.body.appendChild(holder); /** * Set ids */ settings_container.id = 's-cnt'; settings_container_valign.id = "c-vln"; settings_container_inner.id = "c-s-in"; settings.id = "cs"; settings_title.id = 's-ttl'; settings_inner.id = 's-inr'; settings_header.id = "s-hdr"; settings_blocks.id = 's-bl'; settings_close_btn.id = 's-c-bn'; overlay.id = 'cs-ov'; settings_close_btn_container.id = 's-c-bnc'; settings_close_btn.className = 'c-bn'; settings_container.setAttribute('role', 'dialog'); settings_container.setAttribute('aria-modal', 'true'); settings_container.setAttribute('aria-hidden', 'true'); settings_container.setAttribute('aria-labelledby', 's-ttl'); settings_title.setAttribute('role', 'heading'); settings_container.style.visibility = overlay.style.visibility = "hidden"; overlay.style.opacity = 0; settings_close_btn_container.appendChild(settings_close_btn); // If 'esc' key is pressed inside settings_container div => hide settings _addEvent(settings_container_valign, 'keydown', function(evt){ evt = evt || window.event; if (evt.keyCode === 27) { _cookieconsent.hideSettings(0); } }, true); _addEvent(settings_close_btn, 'click', function(){ _cookieconsent.hideSettings(0); }); }else{ new_settings_blocks = _createNode('div'); new_settings_blocks.id = 's-bl'; } // Add label to close button settings_close_btn.setAttribute('aria-label', user_config.languages[lang]['settings_modal']['close_btn_label'] || 'Close'); all_blocks = user_config.languages[lang]['settings_modal']['blocks']; all_table_headers = user_config.languages[lang]['settings_modal']['cookie_table_headers']; var n_blocks = all_blocks.length; // Set settings modal title settings_title.innerHTML = user_config.languages[lang]['settings_modal']['title']; // Create settings modal content (blocks) for(var i=0; i retrieve category states from cookie * Otherwise use states defined in the user_config. object */ if(cookie_consent_accepted){ if(_inArray(saved_cookie_content['level'], cookie_category) > -1){ block_switch.checked = true; !new_settings_blocks && toggle_states.push(true); }else{ !new_settings_blocks && toggle_states.push(false); } }else if(toggle_data['enabled']){ block_switch.checked = true; !new_settings_blocks && toggle_states.push(true); /** * Keep track of categories enabled by default (useful when mode=='opt-out') */ if(toggle_data['enabled']) !new_settings_blocks && default_enabled_categories.push(cookie_category); }else{ !new_settings_blocks && toggle_states.push(false); } !new_settings_blocks && all_categories.push(cookie_category); /** * Set toggle as readonly if true (disable checkbox) */ if(toggle_data['readonly']){ block_switch.disabled = true; _addClass(block_switch_span, 'c-ro'); !new_settings_blocks && readonly_categories.push(true); }else{ !new_settings_blocks && readonly_categories.push(false); } _addClass(block_table_container, 'b-acc'); _addClass(block_title_container, 'b-bn'); _addClass(block_section, 'b-ex'); block_table_container.id = accordion_id; block_table_container.setAttribute('aria-hidden', 'true'); block_switch_label.appendChild(block_switch); block_switch_label.appendChild(block_switch_span); block_switch_label.appendChild(label_text_span); block_title_container.appendChild(block_switch_label); /** * On button click handle the following :=> aria-expanded, aria-hidden and act class for current block */ isExpandable && (function(accordion, block_section, btn){ _addEvent(block_title_btn, 'click', function(){ if(!_hasClass(block_section, 'act')){ _addClass(block_section, 'act'); btn.setAttribute('aria-expanded', 'true'); accordion.setAttribute('aria-hidden', 'false'); }else{ _removeClass(block_section, 'act'); btn.setAttribute('aria-expanded', 'false'); accordion.setAttribute('aria-hidden', 'true'); } }, false); })(block_table_container, block_section, block_title_btn); }else{ /** * If block is not a button (no toggle defined), * create a simple div instead */ if(title_data){ var block_title = _createNode('div'); block_title.className = 'b-tl'; block_title.setAttribute('role', 'heading'); block_title.setAttribute('aria-level', '3'); block_title.insertAdjacentHTML('beforeend', title_data); block_title_container.appendChild(block_title); } } title_data && block_section.appendChild(block_title_container); description_data && block_table_container.appendChild(block_desc); // if cookie table found, generate table for this block if(!remove_cookie_tables && typeof cookie_table_data !== 'undefined'){ var tr_tmp_fragment = document.createDocumentFragment(); /** * Use custom table headers */ for(var p=0; p ~faster value retrieval) var curr_block = all_blocks[i]; // If current block has a toggle for opt in/out if(Object.prototype.hasOwnProperty.call(curr_block, "toggle")){ // if current block has a cookie table, an off toggle, // and its preferences were just changed => delete cookies var category_just_disabled = _inArray(changed_settings, curr_block['toggle']['value']) > -1; if( !toggle_states[++count] && Object.prototype.hasOwnProperty.call(curr_block, "cookie_table") && (clearOnFirstAction || category_just_disabled) ){ var curr_cookie_table = curr_block['cookie_table']; // Get first property name var ckey = _getKeys(all_table_headers[0])[0]; // Get number of cookies defined in cookie_table var clen = curr_cookie_table.length; // set "reload_page" to true if reload=on_disable if(curr_block['toggle']['reload'] === 'on_disable') category_just_disabled && (reload_page = true); // for each row defined in the cookie table for(var j=0; j filter cookie array if(is_regex){ for(var n=0; n -1) found_cookies.push(all_cookies_array[found_index]); } _log("CookieConsent [AUTOCLEAR]: search cookie: '" + curr_cookie_name + "', found:", found_cookies); // If cookie exists -> delete it if(found_cookies.length > 0){ _eraseCookies(found_cookies, curr_cookie_path, domains); curr_block['toggle']['reload'] === 'on_clear' && (reload_page = true); } } } } } } /** * Set toggles/checkboxes based on accepted categories and save cookie * @param {string[]} accepted_categories - Array of categories to accept */ var _saveCookiePreferences = function(accepted_categories){ changed_settings = []; // Retrieve all toggle/checkbox values var category_toggles = document.querySelectorAll('.c-tgl') || []; // If there are opt in/out toggles ... if(category_toggles.length > 0){ for(var i=0; i 0) _autoclearCookies(); if(!consent_uuid) consent_uuid = _uuidv4(); saved_cookie_content = { "level": accepted_categories, "revision": _config.revision, "data": cookie_data, "rfc_cookie": _config.use_rfc_cookie, "consent_uuid": consent_uuid } // save cookie with preferences 'level' (only if never accepted or settings were updated) if(!cookie_consent_accepted || changed_settings.length > 0 || !valid_revision){ valid_revision = true; /** * Update accept type */ accept_type = _getAcceptType(_getCurrentCategoriesState()); _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content)); _cookieconsent.logConsent(accepted_categories.includes("necessary") ? 1 : 0, accepted_categories.includes("analytics") ? 1 : 0, accepted_categories.includes("marketing") ? 1 : 0, ); _manageExistingScripts(); } if(!cookie_consent_accepted){ /** * Delete unused/"zombie" cookies the very-first time */ if(_config.autoclear_cookies) _autoclearCookies(true); if(typeof onFirstAction === 'function') onFirstAction(_cookieconsent.getUserPreferences(), saved_cookie_content); if(typeof onAccept === 'function') onAccept(saved_cookie_content); cookie_consent_accepted = true; if(_config.mode === 'opt-in') return; } // fire onChange only if settings were changed if(typeof onChange === "function" && changed_settings.length > 0) onChange(saved_cookie_content, changed_settings); /** * reload page if needed */ if(reload_page) window.location.reload(); } /** * Function to run after css load * @callback cssLoaded */ /** * Load style via ajax in background (and then show modal) * @param {string} css_path * @param {cssLoaded} callback */ var _loadCSS = function(css_path, callback){ // Enable if given path is string and non empty var enable = typeof css_path === 'string' && css_path !== ""; if(enable && !document.getElementById('cc--style')){ // Create style tag var style = _createNode('style'); // ad an id so that in SPA apps (react-like) the style doesn't get loaded multiple times when plugin is called style.id = 'cc--style'; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if(this.readyState === 4 && this.status === 200){ // Necessary for 2 && (browser_lang = browser_lang[0]+browser_lang[1]); _log("CookieConsent [LANG]: detected_browser_lang = '"+ browser_lang + "'"); return browser_lang.toLowerCase() } /** * Trap focus inside modal and focus the first * focusable element of current active modal */ var _handleFocusTrap = function(){ var tabbedOutsideDiv = false; var tabbedInsideModal = false; _addEvent(document, 'keydown', function(e){ e = e || window.event; // If is tab key => ok if(e.key !== 'Tab') return; // If there is any modal to focus if(current_modal_focusable){ // If reached natural end of the tab sequence => restart if(e.shiftKey){ if (document.activeElement === current_modal_focusable[0]) { current_modal_focusable[1].focus(); e.preventDefault(); } }else{ if (document.activeElement === current_modal_focusable[1]) { current_modal_focusable[0].focus(); e.preventDefault(); } } // If have not yet used tab (or shift+tab) and modal is open ... // Focus the first focusable element if(!tabbedInsideModal && !clicked_inside_modal){ tabbedInsideModal = true; !tabbedOutsideDiv && e.preventDefault(); if(e.shiftKey){ if(current_modal_focusable[3]){ if(!current_modal_focusable[2]){ current_modal_focusable[0].focus(); }else{ current_modal_focusable[2].focus(); } }else{ current_modal_focusable[1].focus(); } }else{ if(current_modal_focusable[3]){ current_modal_focusable[3].focus(); }else{ current_modal_focusable[0].focus(); } } } } !tabbedInsideModal && (tabbedOutsideDiv = true); }); if(document.contains){ _addEvent(main_container, 'click', function(e){ e = e || window.event; /** * If click is on the foreground overlay (and not inside settings_modal), * hide settings modal * * Notice: click on div is not supported in IE */ if(settings_modal_visible){ if(!settings_inner.contains(e.target)){ _cookieconsent.hideSettings(0); clicked_inside_modal = false; }else{ clicked_inside_modal = true; } }else if(consent_modal_visible){ if(consent_modal.contains(e.target)){ clicked_inside_modal = true; } } }, true); } } /** * Manage each modal's layout * @param {Object} gui_options */ var _guiManager = function(gui_options, only_consent_modal){ // If gui_options is not object => exit if(typeof gui_options !== 'object') return; var consent_modal_options = gui_options['consent_modal']; var settings_modal_options = gui_options['settings_modal']; /** * Helper function which adds layout and * position classes to given modal * * @param {HTMLElement} modal * @param {string[]} allowed_layouts * @param {string[]} allowed_positions * @param {string} layout * @param {string[]} position */ function _setLayout(modal, allowed_layouts, allowed_positions, allowed_transitions, layout, position, transition){ position = (position && position.split(" ")) || []; // Check if specified layout is valid if(_inArray(allowed_layouts, layout) > -1){ // Add layout classes _addClass(modal, layout); // Add position class (if specified) if(!(layout === 'bar' && position[0] === 'middle') && _inArray(allowed_positions, position[0]) > -1){ for(var i=0; i -1) && _addClass(modal, transition); } if(consent_modal_exists && consent_modal_options){ _setLayout( consent_modal, ['box', 'bar', 'cloud'], ['top', 'middle', 'bottom'], ['zoom', 'slide'], consent_modal_options['layout'], consent_modal_options['position'], consent_modal_options['transition'] ); } if(!only_consent_modal && settings_modal_options){ _setLayout( settings_container, ['bar'], ['left', 'right'], ['zoom', 'slide'], settings_modal_options['layout'], settings_modal_options['position'], settings_modal_options['transition'] ); } } /** * Returns true if cookie category is accepted by the user * @param {string} cookie_category * @returns {boolean} */ _cookieconsent.allowedCategory = function(cookie_category){ if(cookie_consent_accepted || _config.mode === 'opt-in') var allowed_categories = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || '{}')['level'] || [] else // mode is 'opt-out' var allowed_categories = default_enabled_categories; return _inArray(allowed_categories, cookie_category) > -1; } /** * "Init" method. Will run once and only if modals do not exist */ _cookieconsent.run = function(user_config){ if(!document.getElementById('cc_div')){ _initAll(user_config); // configure all parameters _setConfig(user_config); // if is bot, don't run plugin if(is_bot) return; // Retrieve cookie value (if set) saved_cookie_content = JSON.parse(_getCookie(_config.cookie_name, 'one', true) || "{}"); consent_uuid = saved_cookie_content['consent_uuid']; cookie_consent_accepted = saved_cookie_content['level'] !== undefined; /** * Immediately retrieve the 'data' field from cookie * (since this value is allowed to be accessed/used before the .run method) */ cookie_data = saved_cookie_content['data'] !== undefined ? saved_cookie_content['data'] : null; // Compare current revision with the one retrieved from cookie valid_revision = typeof user_config['revision'] === "number" ? cookie_consent_accepted ? user_config['revision'] > -1 ? saved_cookie_content['revision'] === _config.revision : true : true : true; // If invalid revision or cookie is empty => create consent modal consent_modal_exists = (!cookie_consent_accepted || !valid_revision); // Generate cookie-settings dom (& consent modal) _createCookieConsentHTML(); _loadCSS(user_config['theme_css'], function(){ _getModalFocusableData(); _guiManager(user_config['gui_options']); _addDataButtonListeners(); if(_config.autorun && consent_modal_exists){ _cookieconsent.show(user_config['delay'] || 0); } // Add class to enable animations/transitions setTimeout(function(){_addClass(main_container, 'c--anim');}, 30); // Accessibility :=> if tab pressed => trap focus inside modal setTimeout(function(){_handleFocusTrap();}, 100); }); if(cookie_consent_accepted && valid_revision){ var rfc_prop_exists = typeof saved_cookie_content['rfc_cookie'] === "boolean"; /* * Convert cookie to rfc format (if `use_rfc_cookie` is enabled) */ if(!rfc_prop_exists || (rfc_prop_exists && saved_cookie_content['rfc_cookie'] !== _config.use_rfc_cookie)){ saved_cookie_content['rfc_cookie'] = _config.use_rfc_cookie; _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content)); } /** * Update accept type */ accept_type = _getAcceptType(_getCurrentCategoriesState()); _manageExistingScripts(); if(typeof onAccept === 'function') onAccept(saved_cookie_content); }else if(_config.mode === 'opt-out'){ _log("CookieConsent [CONFIG] mode='" + _config.mode + "', default enabled categories:", default_enabled_categories); _manageExistingScripts(default_enabled_categories); } }else{ _log("CookieConsent [NOTICE]: cookie consent already attached to body!"); } } /** * Show settings modal (with optional delay) * @param {number} delay */ _cookieconsent.showSettings = function(delay){ setTimeout(function() { _addClass(html_dom, "show--settings"); settings_container.setAttribute('aria-hidden', 'false'); settings_modal_visible = true; /** * Set focus to the first focusable element inside settings modal */ setTimeout(function(){ // If there is no consent-modal, keep track of the last focused elem. if(!consent_modal_visible){ last_elem_before_modal = document.activeElement; }else{ last_consent_modal_btn_focus = document.activeElement; } if (settings_modal_focusable.length === 0) return; if(settings_modal_focusable[3]){ settings_modal_focusable[3].focus(); }else{ settings_modal_focusable[0].focus(); } current_modal_focusable = settings_modal_focusable; }, 200); _log("CookieConsent [SETTINGS]: show settings_modal"); }, delay > 0 ? delay : 0); } var onAccept = function(cookie){ if (cookie.level.includes("analytics")) { gtag('consent', 'update', { 'analytics_storage': 'granted' }); console.log("analytics"); } if (cookie.level.includes('marketing')) { gtag('consent', 'update', { 'ad_storage': 'granted' }); console.log("marketing"); if(typeof(fbq) === "function"){ fbq('consent', 'grant'); } } dataLayer.push({ event : 'cc_consent_updated' }); } var onChange = function(cookie, changed_categories){ if (cookie.level.includes('analytics')) { gtag('consent', 'update', { 'analytics_storage': 'granted' }); } if (!cookie.level.includes('analytics')) { gtag('consent', 'update', { 'analytics_storage': 'denied' }); } if (cookie.level.includes('advertising')) { gtag('consent', 'update', { 'ad_storage': 'granted' }); if(typeof(fbq) === "function"){ fbq('consent', 'grant'); } } if (!cookie.level.includes('advertising')) { gtag('consent', 'update', { 'ad_storage': 'denied' }); if(typeof(fbq) === "function"){ fbq('consent', 'revoke'); } } dataLayer.push({ event : 'cc_consent_updated' }); } /** * This function handles the loading/activation logic of the already * existing scripts based on the current accepted cookie categories * * @param {string[]} [must_enable_categories] */ var _manageExistingScripts = function(must_enable_categories){ if(!_config.page_scripts) return; // get all the scripts with "cookie-category" attribute var scripts = document.querySelectorAll('script[' + _config.script_selector + ']'); var sequential_enabled = _config.page_scripts_order; var accepted_categories = must_enable_categories || saved_cookie_content['level'] || []; _log("CookieConsent [SCRIPT_MANAGER]: sequential loading:", sequential_enabled); /** * Load scripts (sequentially), using a recursive function * which loops through the scripts array * @param {Element[]} scripts scripts to load * @param {number} index current script to load */ var _loadScripts = function(scripts, index){ if(index < scripts.length){ var curr_script = scripts[index]; var curr_script_category = curr_script.getAttribute(_config.script_selector); /** * If current script's category is on the array of categories * accepted by the user => load script */ if(_inArray(accepted_categories, curr_script_category) > -1){ curr_script.type = 'text/javascript'; curr_script.removeAttribute(_config.script_selector); // get current script data-src var src = curr_script.getAttribute('data-src'); // some scripts (like ga) might throw warning if data-src is present src && curr_script.removeAttribute('data-src'); // create fresh script (with the same code) var fresh_script = _createNode('script'); fresh_script.textContent = curr_script.innerHTML; // Copy attributes over to the new "revived" script (function(destination, source){ var attributes = source.attributes; var len = attributes.length; for(var i=0; i the next script will not be loaded // until the current's script onload event triggers if(fresh_script.readyState) { // only required for IE <9 fresh_script.onreadystatechange = function() { if (fresh_script.readyState === "loaded" || fresh_script.readyState === "complete" ) { fresh_script.onreadystatechange = null; _loadScripts(scripts, ++index); } }; }else{ // others fresh_script.onload = function(){ fresh_script.onload = null; _loadScripts(scripts, ++index); }; } }else{ // if sequential option is disabled // treat current script as inline (without onload event) src = false; } } // Replace current "sleeping" script with the new "revived" one curr_script.parentNode.replaceChild(fresh_script, curr_script); /** * If we managed to get here and scr is still set, it means that * the script is loading/loaded sequentially so don't go any further */ if(src) return; } // Go to next script right away _loadScripts(scripts, ++index); } } _loadScripts(scripts, 0); } /** * Save custom data inside cookie * @param {object|string} new_data * @param {string} [mode] * @returns {boolean} */ var _setCookieData = function(new_data, mode){ var set = false; /** * If mode is 'update': * add/update only the specified props. */ if(mode === 'update'){ cookie_data = _cookieconsent.get('data'); var same_type = typeof cookie_data === typeof new_data; if(same_type && typeof cookie_data === "object"){ !cookie_data && (cookie_data = {}); for(var prop in new_data){ if(cookie_data[prop] !== new_data[prop]){ cookie_data[prop] = new_data[prop] set = true; } } }else if((same_type || !cookie_data) && cookie_data !== new_data){ cookie_data = new_data; set = true; } }else{ cookie_data = new_data; set = true; } if(set){ saved_cookie_content['data'] = cookie_data; _setCookie(_config.cookie_name, JSON.stringify(saved_cookie_content)); } return set; } /** * Forcefully set a specific revision and show consent modal * @param {number} new_revision * @param {boolean} [prompt_consent] * @returns {boolean} */ var _setRevision = function(new_revision, prompt_consent, message){ // If plugin has been initialized and new revision is valid if( main_container && typeof new_revision === "number" && saved_cookie_content['revision'] !== new_revision ){ revision_enabled = true; revision_message = message; valid_revision = false; _config.revision = new_revision; // Show consent modal ? if(prompt_consent === true){ _createConsentModal(user_config); _guiManager(user_config['gui_options'], true); _getModalFocusableData(); _cookieconsent.show(); }else { // If revision was modified, save cookie with the new revision _cookieconsent.accept(); } return true; } return false; } /** * Helper method to set a variety of fields * @param {string} field * @param {object} data * @returns {boolean} */ _cookieconsent.set = function(field, data){ switch(field){ case 'data': return _setCookieData(data['value'], data['mode']); case 'revision': return _setRevision(data['value'], data['prompt_consent'], data['message']); //[WARNING] Will be removed in v3 default: return false; } } /** * Retrieve data from existing cookie * @param {string} field * @param {string} [cookie_name] * @returns {any} */ _cookieconsent.get = function(field, cookie_name){ var cookie = JSON.parse(_getCookie(cookie_name || _config.cookie_name, 'one', true) || "{}"); return cookie[field]; } /** * Read current configuration value * @returns {any} */ _cookieconsent.getConfig = function(field){ return _config[field] || user_config[field]; } /** * Obtain accepted and rejected categories * @returns {{accepted: string[], rejected: string[]}} */ var _getCurrentCategoriesState = function(){ // get accepted categories accepted_categories = saved_cookie_content['level'] || []; // calculate rejected categories (all_categories - accepted_categories) rejected_categories = all_categories.filter(function(category){ return (_inArray(accepted_categories, category) === -1); }); return { accepted: accepted_categories, rejected: rejected_categories } } /** * Calculate "accept type" given current categories state * @param {{accepted: string[], rejected: string[]}} currentCategoriesState * @returns {string} */ var _getAcceptType = function(currentCategoriesState){ var type = 'custom'; // number of categories marked as necessary/readonly var necessary_categories_length = readonly_categories.filter(function(readonly){ return readonly === true; }).length; // calculate accept type based on accepted/rejected categories if(currentCategoriesState.accepted.length === all_categories.length) type = 'all'; else if(currentCategoriesState.accepted.length === necessary_categories_length) type = 'necessary' return type; } /** * @typedef {object} userPreferences * @property {string} accept_type * @property {string[]} accepted_categories * @property {string[]} rejected_categories */ /** * Retrieve current user preferences (summary) * @returns {userPreferences} */ _cookieconsent.getUserPreferences = function(){ var currentCategoriesState = _getCurrentCategoriesState(); var accept_type = _getAcceptType(currentCategoriesState); return { 'accept_type': accept_type, 'accepted_categories': currentCategoriesState.accepted, 'rejected_categories': currentCategoriesState.rejected } } /** * Function which will run after script load * @callback scriptLoaded */ /** * Dynamically load script (append to head) * @param {string} src * @param {scriptLoaded} callback * @param {string[]} attrs */ _cookieconsent.loadScript = function(src, callback, attrs){ var function_defined = typeof callback === 'function'; // Load script only if not already loaded if(!document.querySelector('script[src="' + src + '"]')){ var script = _createNode('script'); // if an array is provided => add custom attributes if(attrs && attrs.length > 0){ for(var i=0; i run callback onload if(function_defined){ if(script.readyState) { // only required for IE <9 script.onreadystatechange = function() { if ( script.readyState === "loaded" || script.readyState === "complete" ) { script.onreadystatechange = null; callback(); } }; }else{ //Others script.onload = callback; } } script.src = src; /** * Append script to head */ (document.head ? document.head : document.getElementsByTagName('head')[0]).appendChild(script); }else{ function_defined && callback(); } } /** * Manage dynamically loaded scripts: https://github.com/orestbida/cookieconsent/issues/101 * If plugin has already run, call this method to enable * the newly added scripts based on currently selected preferences */ _cookieconsent.updateScripts = function(){ _manageExistingScripts(); } /** * Show cookie consent modal (with delay parameter) * @param {number} delay */ _cookieconsent.show = function(delay, force = false){ if(consent_modal_exists || force == true){ setTimeout(function() { _addClass(html_dom, "show--consent"); /** * Update attributes/internal statuses */ consent_modal.setAttribute('aria-hidden', 'false'); consent_modal_visible = true; setTimeout(function(){ last_elem_before_modal = document.activeElement; current_modal_focusable = consent_modal_focusable; }, 200); _log("CookieConsent [MODAL]: show consent_modal"); }, delay > 0 ? delay : 0); } } /** * Hide consent modal */ _cookieconsent.hide = function(){ if(consent_modal_exists){ _removeClass(html_dom, "show--consent"); consent_modal.setAttribute('aria-hidden', 'true'); consent_modal_visible = false; setTimeout(function(){ //restore focus to the last page element which had focus before modal opening last_elem_before_modal.focus(); current_modal_focusable = null; }, 200); _log("CookieConsent [MODAL]: hide"); } } /** * Hide settings modal */ _cookieconsent.hideSettings = function(){ _removeClass(html_dom, "show--settings"); settings_modal_visible = false; settings_container.setAttribute('aria-hidden', 'true'); setTimeout(function(){ /** * If consent modal is visible, focus him (instead of page document) */ if(consent_modal_visible){ last_consent_modal_btn_focus && last_consent_modal_btn_focus.focus(); current_modal_focusable = consent_modal_focusable; }else{ /** * Restore focus to last page element which had focus before modal opening */ last_elem_before_modal && last_elem_before_modal.focus(); current_modal_focusable = null; } clicked_inside_modal = false; }, 200); _log("CookieConsent [SETTINGS]: hide settings_modal"); } /** * Accept cookieconsent function API * @param {string[]|string} _categories - Categories to accept * @param {string[]} [_exclusions] - Excluded categories [optional] */ _cookieconsent.accept = function(_categories, _exclusions){ var categories = _categories || undefined; var exclusions = _exclusions || []; var to_accept = []; /** * Get all accepted categories * @returns {string[]} */ var _getCurrentPreferences = function(){ var toggles = document.querySelectorAll('.c-tgl') || []; var states = []; for(var i=0; i= 1){ for(i=0; i 0){ for(var i=0; i<_cookies.length; i++){ this.validCookie(_cookies[i]) && cookies.push(_cookies[i]); } }else{ this.validCookie(_cookies) && cookies.push(_cookies); } _eraseCookies(cookies, _path, domains); } /** * Set cookie, by specifying name and value * @param {string} name * @param {string} value */ var _setCookie = function(name, value) { var cookie_expiration = _config.cookie_expiration; if(typeof _config.cookie_necessary_only_expiration === 'number' && accept_type === 'necessary') cookie_expiration = _config.cookie_necessary_only_expiration; value = _config.use_rfc_cookie ? encodeURIComponent(value) : value; var date = new Date(); date.setTime(date.getTime() + (1000 * (cookie_expiration * 24 * 60 * 60))); var expires = "; expires=" + date.toUTCString(); var cookieStr = name + "=" + (value || "") + expires + "; Path=" + _config.cookie_path + ";"; cookieStr += " SameSite=" + _config.cookie_same_site + ";"; // assures cookie works with localhost (=> don't specify domain if on localhost) if(window.location.hostname.indexOf(".") > -1){ cookieStr += " Domain=" + _config.cookie_domain + ";"; } if(window.location.protocol === "https:") { cookieStr += " Secure;"; } document.cookie = cookieStr; _log("CookieConsent [SET_COOKIE]: cookie "+ name + "='" + value + "' was set! Expires after " + cookie_expiration + " days"); } /** * Get cookie value by name, * returns the cookie value if found (or an array * of cookies if filter provided), otherwise empty string: "" * @param {string} name * @param {string} filter - 'one' or 'all' * @param {boolean} get_value - set to true to obtain its value * @returns {string|string[]} */ var _getCookie = function(name, filter, get_value) { var found; if(filter === 'one'){ found = document.cookie.match("(^|;)\\s*" + name + "\\s*=\\s*([^;]+)"); found = found ? (get_value ? found.pop() : name) : ""; if(found && name === _config.cookie_name){ try{ found = JSON.parse(found) }catch(e){ try { found = JSON.parse(decodeURIComponent(found)) } catch (e) { // if I got here => cookie value is not a valid json string found = {}; } } found = JSON.stringify(found); } }else if(filter === 'all'){ // array of names of all existing cookies var cookies = document.cookie.split(/;\s*/); found = []; for(var i=0; i 'onclick' */ elem.attachEvent("on" + event, fn); } } /** * Get all prop. keys defined inside object * @param {Object} obj */ var _getKeys = function(obj){ if(typeof obj === "object"){ var keys = [], i = 0; for (keys[i++] in obj); return keys; } } /** * Append class to the specified dom element * @param {HTMLElement} elem * @param {string} classname */ var _addClass = function (elem, classname){ if(elem.classList) elem.classList.add(classname) else{ if(!_hasClass(elem, classname)) elem.className += ' '+classname; } } /** * Remove specified class from dom element * @param {HTMLElement} elem * @param {string} classname */ var _removeClass = function (el, className) { el.classList ? el.classList.remove(className) : el.className = el.className.replace(new RegExp('(\\s|^)' + className + '(\\s|$)'), ' '); } /** * Check if html element has class * @param {HTMLElement} el * @param {string} className */ var _hasClass = function(el, className) { if (el.classList) { return el.classList.contains(className); } return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')); } return _cookieconsent; }; var init = 'initCookieConsent'; /** * Make CookieConsent object accessible globally */ if(typeof window[init] !== 'function'){ window[init] = c_consent } var i = document.getElementsByTagName("head")[0]; var n = document.createElement("link"); n.rel = "stylesheet"; n.type = "text/css"; n.href = "https://cdn.cookieconsent.sk/css/c_consent.css"; i.appendChild(n); })(); /* iframemanager v1.0 Author Orest Bida Released under the MIT License */ (function() { var e = { o: {}, S: [], T: [], u: null, i: null, v: null, l: null, W: function(a) { return { D: a.dataset.id, I: a.dataset.title, m: a.dataset.thumbnail, ba: a.dataset.params, K: a.hasAttribute("data-thumbnailpreload"), j: a, J: null, s: !1, R: !1, A: !0 } }, X: function(a, b) { var c = this.o[a]; a = c.length; if ("IntersectionObserver" in window) for (var d = new IntersectionObserver(function(g) { g.forEach(function(k) { k.isIntersecting && (e.O(b, c[k.target.dataset.index]), d.unobserve(k.target)) }) }), f = 0; f < a; f++) d.observe(c[f].j); else for (f = 0; f < a; f++) e.O(b, c[f]) }, acceptService: function(a) { function b(f, g) { e.F(g.cookie.name) || e.Z(g.cookie); e.N(f, g) } if ("all" === a) for (var c = this.l.length, d = 0; d < c; d++) a = this.l[d], b(a, this.v[a]); else - 1 < this.l.indexOf(a) && b(a, this.v[a]) }, rejectService: function(a) { function b(f, g) { e.F(g.cookie.name) && e.U(g.cookie); e.$(f, g) } if ("all" === a) { this.u = null; for (var c = this.l.length, d = 0; d < c; d++) a = this.l[d], b(a, this.v[a]) } else - 1 < this.l.indexOf(a) && b(a, this.v[a]) }, O: function(a, b) { function c(d) { b.J.style.backgroundImage = "url('" + d + "')"; var f = new Image; f.onload = function() { b.J.classList.add("loaded") }; f.src = d } "string" === typeof b.m ? (b.K && this.H(b.m), "" !== b.m && c(b.m)) : "function" === typeof a ? a(b.D, function(d) { e.P(d); b.K && this.H(d); c(d) }) : "string" === typeof a && (a = a.replace("{data-id}", b.D), this.P(a), b.K && this.H(a), c(a)) }, B: function(a, b) { if (!a.s) { a.h = this.g("iframe"); var c = a.ba || b.iframe && b.iframe.params, d = b.embedUrl.replace("{data-id}", a.D); a.h.loading = "lazy"; a.I && (a.h.title = a.I); b.iframe && b.iframe.allow && (a.h.allow = b.iframe.allow); c && (d = "ap:" === c.substring(0, 3) ? d + c.substring(3) : d + ("?" + c)); a.h.src = encodeURI(d); a.h.onload = function() { a.j.classList.add("c-h-b"); a.h.onload = void 0; b.iframe && "function" === typeof b.iframe.onload && b.iframe.onload(a.D, this) }; a.s = !0; a.j.appendChild(a.h) } }, Y: function(a) { a.h.parentNode.removeChild(a.h); a.s = !1 }, C: function(a) { a.A && (a.j.classList.add("c-h-n"), a.A = !1) }, aa: function(a) { a.A || (a.j.classList.remove("c-h-n", "c-h-b"), a.A = !0) }, F: function(a) { return (a = document.cookie.match("(^|;)\\s*" + a + "\\s*=\\s*([^;]+)")) ? a.pop() : "" }, Z: function(a) { var b = new Date, c = a.path || "/", d = a.sameSite || "Lax", f = a.domain || location.hostname; b.setTime(b.getTime() + 864E5 * (a.expiration || 182)); a = a.name + "=1; expires=" + b.toUTCString() + "; Path=" + c + ";"; a += " SameSite=" + d + ";"; - 1 < f.indexOf(".") && (a += " Domain=" + f + ";"); "https:" === location.protocol && (a += " Secure;"); document.cookie = a }, U: function(a) { document.cookie = a.name + "=; Path=" + (a.path || "/") + "; Domain=" + (a.domain || location.hostname) + "; Expires=Thu, 01 Jan 1970 00:00:01 GMT;" }, G: function(a) { if ("object" === typeof a) { var b = [], c = 0; for (b[c++] in a); return b } }, P: function(a) { a = a.split("://"); var b = a[0]; if (("http" == b || "https" == b) && (a = a[1] && a[1].split("/")[0] || !1) && a !== location.hostname && -1 === this.S.indexOf(a)) { var c = this.g("link"); c.rel = "preconnect"; c.href = b + "://" + a; document.head.appendChild(c); this.S.push(a) } }, H: function(a) { if (a && -1 === this.T.indexOf(a)) { var b = this.g("link"); b.rel = "preload"; b.as = "image"; b.href = a; document.head.appendChild(b); this.T.push(a) } }, g: function(a) { return document.createElement(a) }, L: function(a, b, c) { for (var d = this.o[a], f = d.length, g = 0; g < f; g++)(function(k) { var h = d[k]; if (!h.R) { k = b.languages[e.i].loadBtn; var C = b.languages[e.i].notice, D = b.languages[e.i].loadAllBtn, p = document.createDocumentFragment(), q = e.g("div"), u = e.g("span"), v = e.g("p"), l = e.g("button"), m = e.g("button"), n = e.g("span"), w = e.g("div"), z = e.g("div"), x = e.g("div"), r = e.g("div"), t = e.g("div"); l.type = m.type = "button"; n.className = "cc-text"; l.type = m.type = "button"; n.className = "cc-text"; x.className = "c-bg-i"; h.J = x; z.className = "c-ld"; if ("string" !== typeof h.m || "" !== h.m) w.className = "c-bg"; var A = h.I, B = document.createDocumentFragment(); if (A) { var y = e.g("span"); y.className = "c-tl"; y.insertAdjacentHTML("beforeend", A); B.appendChild(y) } l.textContent = k; m.textContent = D; n.appendChild(B); q && n.insertAdjacentHTML("beforeend", C || ""); u.appendChild(n); r.className = "c-t-cn"; u.className = "c-n-t"; v.className = "c-n-c"; q.className = "c-nt"; t.className = "c-n-a"; l.className = "c-l-b"; m.className = "c-la-b"; t.appendChild(l); t.appendChild(m); r.appendChild(u); r.appendChild(t); v.appendChild(r); q.appendChild(v); l.addEventListener("click", function() { e.C(h); e.B(h, b) }); m.addEventListener("click", function() { e.C(h); e.B(h, b); e.acceptService(a) }); w.appendChild(x); p.appendChild(q); (b.thumbnailUrl || h.m) && p.appendChild(w); p.appendChild(z); c && h.j.classList.add("c-h-n"); h.j.appendChild(p); h.R = !0 } })(g) }, N: function(a, b) { var c = this.o[a]; a = c.length; if ("IntersectionObserver" in window) { this.u = new IntersectionObserver(function(f) { for (var g = 0; g < f.length && null !== e.u; ++g) f[g].isIntersecting && function(k) { setTimeout(function() { var h = f[k].target.dataset.index; e.B(c[h], b); e.C(c[h]) }, 50 * k); e.u.unobserve(f[k].target) }(g) }); for (var d = 0; d < a; d++) c[d].s || this.u.observe(c[d].j) } else for (d = 0; d < a; d++)(function(f) { e.B(c[d], b); e.C(c[f]) })(d) }, $: function(a) { a = this.o[a]; for (var b = a.length, c = 0; c < b; c++) { var d = c; a[c].A || (a[c].s && e.Y(a[c]), e.aa(a[d])) } }, M: function(a, b) { if (b.hasOwnProperty(a)) return a; if (0 < this.G(b).length) return b.hasOwnProperty(this.i) ? this.i : this.G(b)[0] }, V: function() { var a = navigator.language || navigator.browserLanguage; 2 < a.length && (a = a[0] + a[1]); return a.toLowerCase() }, run: function(a) { var b = a.services; this.v = b; var c = this.G(b); this.l = c; var d = c.length; if (0 !== d) { this.i = a.currLang; var f = b[c[0]].languages; !0 === a.autoLang ? this.i = this.M(this.V(), f) : "string" === typeof a.currLang && (this.i = this.M(a.currLang, f)); for (a = 0; a < d; a++) { f = c[a]; this.o[f] = []; var g = document.querySelectorAll('div[data-service="' + f + '"]'), k = g.length; if (0 !== k) { for (var h = 0; h < k; h++) g[h].dataset.index = h, this.o[f].push(this.W(g[h])); g = b[f]; this.F(g.cookie.name) ? (this.L(f, g, !0), this.N(f, g)) : this.L(f, g, !1); this.X(f, g.thumbnailUrl) } } } } }; window.iframemanager = function() { window.iframemanager = void 0; return e } })(); function youtube_parser(url){ var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/; return (url.match(p)) ? RegExp.$1 : false ; } function meteoblue_parser(url){ var p = /^(?:https?:\/\/)?(?:www\.)?(?:meteoblue\.com\/|snow-forecast\.com\/)(?:\S+)$/; return (url.match(p)) ? true : false ; } function maps_parser(url){ var p = /^(?:https?:\/\/)?(?:www\.)?(?:maps\.google\.com\/)(?:\S+)$/; return (url.match(p)) ? true : false ; } function windy_parser(url){ var p = /^(?:https?:\/\/)?(?:www\.)?(?:embed\.windy\.com\/)(?:\S+)$/; return (url.match(p)) ? true : false ; } function iframe_parser(url){ var p = /^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)/igm; return (url.match(p)) ? RegExp.$1 : false ; } function changeIframeToDiv(){ var i, frames, to_remove = []; frames = document.getElementsByTagName("iframe"); for (i = 0; i < frames.length; ++i){ let youtube_id = youtube_parser(frames[i].src); let meteoblue = meteoblue_parser(frames[i].src); let mapsurl = maps_parser(frames[i].src); let windy = windy_parser(frames[i].src); if(youtube_id != false){ frames[i].classList.add("to_remove"); let width = frames[i].width; let height = frames[i].height; let div_youtube = document.createElement('div'); div_youtube.setAttribute('data-service', 'youtube'); div_youtube.setAttribute('data-id', youtube_id); div_youtube.setAttribute('data-autoscale', true); if((width != undefined && width != '') && (height != undefined && height != '')){ div_youtube.setAttribute('style', `width: ${width}px; height: ${height}px;`); }else{ div_youtube.setAttribute('style', frames[i].style.cssText); } frames[i].parentNode.appendChild(div_youtube); } if(meteoblue != false){ frames[i].classList.add("to_remove"); let width = frames[i].width; let height = frames[i].height; let div_meteo = document.createElement('div'); div_meteo.setAttribute('data-service', 'meteoblue'); div_meteo.setAttribute('data-id', frames[i].src); div_meteo.setAttribute('data-autoscale', true); if((width != undefined && width != '') && (height != undefined && height != '')){ div_meteo.setAttribute('style', `width: ${width}px; height: ${height}px;`); }else{ div_meteo.setAttribute('style', frames[i].style.cssText); } frames[i].parentNode.appendChild(div_meteo); } if(mapsurl != false){ frames[i].classList.add("to_remove"); let width = frames[i].width; let height = frames[i].height; let div_maps = document.createElement('div'); div_maps.setAttribute('data-service', 'google_maps'); div_maps.setAttribute('data-id', frames[i].src); div_maps.setAttribute('data-autoscale', true); if((width != undefined && width != '') && (height != undefined && height != '')){ div_maps.setAttribute('style', `width: ${width}px; height: ${height}px;`); }else{ div_maps.setAttribute('style', frames[i].style.cssText); } frames[i].parentNode.appendChild(div_maps); } if(windy != false){ frames[i].classList.add("to_remove"); let width = frames[i].width; let height = frames[i].height; let div_windy = document.createElement('div'); div_windy.setAttribute('data-service', 'windy'); div_windy.setAttribute('data-id', frames[i].src); div_windy.setAttribute('data-autoscale', true); if((width != undefined && width != '') && (height != undefined && height != '')){ div_windy.setAttribute('style', `width: ${width}px; height: ${height}px;`); }else{ div_windy.setAttribute('style', frames[i].style.cssText); } frames[i].parentNode.appendChild(div_windy); } } const frames_to_remove = document.querySelectorAll('.to_remove'); frames_to_remove.forEach(frame => { frame.remove(); }); } changeIframeToDiv();document.head.insertAdjacentHTML('beforeend', ``);document.head.insertAdjacentHTML('beforeend', ``);var mng = iframemanager();var cc = initCookieConsent();mng.run({"currLang":"at","services":{"youtube":{"embedUrl":"https:\/\/www.youtube-nocookie.com\/embed\/{data-id}","thumbnailUrl":"https:\/\/i3.ytimg.com\/vi\/{data-id}\/hqdefault.jpg","iframe":{"allow":"accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;"},"cookie":{"name":"cc_youtube"},"languages":{"at":{"notice":"Dieser Inhalt wird von einem Drittanbieter gehostet. Mit dem Anzeigen der externen Inhalte akzeptieren Sie die Nutzungsbedingungen<\/a> of youtube.com.","loadBtn":"Videos laden","loadAllBtn":"Frag nicht nochmal"}}},"meteoblue":{"embedUrl":"{data-id}","thumbnailUrl":"","iframe":{"allow":""},"cookie":{"name":"cc_meteoblue"},"languages":{"at":{"notice":"This content is hosted by a third party. By showing the external content you accept the terms and conditions<\/a> of meteoblue.com.","loadBtn":"Load","loadAllBtn":"Don't ask again"}}},"google_maps":{"embedUrl":"{data-id}","thumbnailUrl":"","iframe":{"allow":""},"cookie":{"name":"cc_google_maps"},"languages":{"at":{"notice":"This content is hosted by a third party. By showing the external content you accept the terms and conditions<\/a> of google.maps.com.","loadBtn":"Load map","loadAllBtn":"Don't ask again"}}},"windy":{"embedUrl":"{data-id}","thumbnailUrl":"","iframe":{"allow":""},"cookie":{"name":"cc_windy"},"languages":{"at":{"notice":"This content is hosted by a third party. By showing the external content you accept the terms and conditions<\/a> of google.maps.com.","loadBtn":"Load Windy","loadAllBtn":"Don't ask again"}}},"vimeo":{"embedUrl":"https:\/\/player.vimeo.com\/video\/{data-id}","thumbnailUrl":"function(id, setThumbnail){\n \n var url = \"https:\/\/vimeo.com\/api\/v2\/video\/\" + id + \".json\";\n var xhttp = new XMLHttpRequest();\n \n xhttp.onreadystatechange = function() {\n if (this.readyState == 4 && this.status == 200) {\n var src = JSON.parse(this.response)[0].thumbnail_large;\n setThumbnail(src);\n }\n };\n\n xhttp.open(\"GET\", url, true);\n xhttp.send();\n }","iframe":{"allow":"accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;"},"cookie":{"name":"cc_vimeo"},"languages":{"at":{"notice":"Dieser Inhalt wird von einem Drittanbieter gehostet. Mit dem Anzeigen der externen Inhalte akzeptieren Sie die Nutzungsbedingungen<\/a> of vimeo.com.","loadBtn":"Videos laden","loadAllBtn":"Frag nicht nochmal"}}}}});var cc_config = {"domain":"https:\/\/www.bubustoffe.at","autorun":true,"mode":"opt-in","cookie_expiration":182,"cookie_name":"cContentCookie","cookie_path":"\/","use_rfc_cookie":false,"force_consent":false,"current_lang":"at","auto_language":null,"hide_from_bots":false,"autoclear_cookies":false,"remove_cookie_tables":false,"page_scripts":false,"gui_options":{"consent_modal":{"layout":"box","position_vertical":"middle","position_horizontal":"center","transition":"slide","position":"middle center"},"settings_modal":{"layout":"box","position":"left","transition":"zoom"}},"branding":false,"ga_id":"G-6PESKCHN0E","c_consent_token":"512917d56a708352","languages":{"at":{"manage_cookie_consent":"Cookie-Einstellungen verwalten","consent_modal":{"title":"Cookies und Datenschutzeinstellungen","description":"Wir can this zur Analyse unserer Besucherdaten platzieren, um unsere Website zu \u00fcberarbeiten, personalisierte Inhalte anwijder und Ihnen ein gr\u00e4chtiges Website-Erlebnis zu bieten. F\u00fcr weitere Informationen zu den von uns verwendenten Cookies \u00f6ffnen Sie die Einstellungen.