1(function (window, document) { 2 "use strict"; 3 4 var config = {}; 5 var callbacks = []; 6 var activatedScripts = {}; 7 var categories = []; 8 var root = null; 9 var banner = null; 10 var modal = null; 11 var reopenButton = null; 12 var lastFocusedBeforeModal = null; 13 14 function refreshConfig() { 15 config = window.EasyDNNCookieConsentConfig || {}; 16 categories = config.categories || []; 17 } 18 19 function categoryKey(category) { 20 return category ? (category.CategoryKey || category.categoryKey || "") : ""; 21 } 22 23 function categoryRequired(category) { 24 return !!(category && (category.IsRequired || category.isRequired)); 25 } 26 27 function eachCategory(callback) { 28 for (var i = 0; i < categories.length; i += 1) { 29 callback(categories[i]); 30 } 31 } 32 33 function isConfiguredCategory(key) { 34 var found = false; 35 eachCategory(function (category) { 36 if (String(categoryKey(category)).toLowerCase() === String(key || "").toLowerCase()) { 37 found = true; 38 } 39 }); 40 return found; 41 } 42 43 function isCategoryAllowed(consent, key) { 44 key = String(key || "").toLowerCase(); 45 if (key === "necessary") { 46 return true; 47 } 48 49 return !!(key && isConfiguredCategory(key) && consent && consent[key] === true); 50 } 51 52 function getComplianceMode() { 53 var value = String(config.complianceMode || "").toLowerCase(); 54 if (value === "eu" || value === "us" || value === "strict-global") { 55 return value; 56 } 57 58 return "eu"; 59 } 60 61 function isGpcDetected() { 62 if (config.gpcDetected === true) { 63 return true; 64 } 65 66 try { 67 return !!(window.navigator && window.navigator.globalPrivacyControl === true); 68 } catch (ignore) { 69 return false; 70 } 71 } 72 73 function shouldApplyGpcOptOut() { 74 var mode = getComplianceMode(); 75 return isGpcDetected() && (mode === "us" || mode === "strict-global"); 76 } 77 78 function isPrivacyChoicesEnabled() { 79 var mode = getComplianceMode(); 80 return mode === "us" || mode === "strict-global"; 81 } 82 83 function createDefaultUsPrivacy() { 84 return { 85 doNotSellOrShare: false, 86 targetedAdvertisingOptOut: false, 87 gpc: false 88 }; 89 } 90 91 function ensureUsPrivacy(consent) { 92 consent = consent || {}; 93 var current = consent.usPrivacy || {}; 94 consent.usPrivacy = { 95 doNotSellOrShare: current.doNotSellOrShare === true, 96 targetedAdvertisingOptOut: current.targetedAdvertisingOptOut === true, 97 gpc: current.gpc === true 98 }; 99 return consent; 100 } 101 102 function hasAppliedGpcState(consent) { 103 return !!(consent 104 && consent.marketing === false 105 && consent.usPrivacy 106 && consent.usPrivacy.gpc === true 107 && consent.usPrivacy.doNotSellOrShare === true 108 && consent.usPrivacy.targetedAdvertisingOptOut === true); 109 } 110 111 function hasUsPrivacyMarketingOptOut(consent) { 112 consent = ensureUsPrivacy(consent); 113 return !!(consent.usPrivacy.gpc 114 || consent.usPrivacy.doNotSellOrShare 115 || consent.usPrivacy.targetedAdvertisingOptOut); 116 } 117 118 function applyGpcToConsent(consent) { 119 consent = ensureUsPrivacy(consent); 120 if (shouldApplyGpcOptOut()) { 121 consent.marketing = false; 122 consent.usPrivacy.gpc = true; 123 consent.usPrivacy.doNotSellOrShare = true; 124 consent.usPrivacy.targetedAdvertisingOptOut = true; 125 } 126 return consent; 127 } 128 129 function applyUsPrivacyToConsent(consent) { 130 consent = ensureUsPrivacy(consent); 131 if (isPrivacyChoicesEnabled()) { 132 applyGpcToConsent(consent); 133 if (hasUsPrivacyMarketingOptOut(consent)) { 134 consent.marketing = false; 135 } 136 } 137 return consent; 138 } 139 140 function copyUsPrivacy(source, target) { 141 target = ensureUsPrivacy(target); 142 source = ensureUsPrivacy(source || {}); 143 target.usPrivacy.doNotSellOrShare = source.usPrivacy.doNotSellOrShare; 144 target.usPrivacy.targetedAdvertisingOptOut = source.usPrivacy.targetedAdvertisingOptOut; 145 target.usPrivacy.gpc = source.usPrivacy.gpc; 146 return target; 147 } 148 149 function defaultConsent(optionalValue) { 150 var consent = { 151 version: String(config.consentVersion || "1"), 152 timestamp: new Date().toISOString() 153 }; 154 155 eachCategory(function (category) { 156 var key = categoryKey(category); 157 if (!key) { 158 return; 159 } 160 161 consent[key] = categoryRequired(category) ? true : !!optionalValue; 162 }); 163 164 if (typeof consent.necessary === "undefined") { 165 consent.necessary = true; 166 } 167 168 consent.usPrivacy = createDefaultUsPrivacy(); 169 return applyUsPrivacyToConsent(consent); 170 } 171 172 function readCookie(name) { 173 var cookieName = encodeURIComponent(name) + "="; 174 var parts = document.cookie ? document.cookie.split(";") : []; 175 for (var i = 0; i < parts.length; i += 1) { 176 var item = parts[i].replace(/^\s+/, ""); 177 if (item.indexOf(cookieName) === 0) { 178 return item.substring(cookieName.length); 179 } 180 } 181 return null; 182 } 183 184 function parseConsent() { 185 var raw = readCookie(config.cookieName || "easy_dnn_cookie_consent"); 186 if (!raw) { 187 return null; 188 } 189 190 try { 191 var parsed = JSON.parse(decodeURIComponent(raw)); 192 if (!parsed || String(parsed.version) !== String(config.consentVersion || "1")) { 193 return null; 194 } 195 if (parsed.necessary !== true) { 196 return null; 197 } 198 return ensureUsPrivacy(parsed); 199 } catch (ignore) { 200 return null; 201 } 202 } 203 204 function writeConsent(consent) { 205 var days = parseInt(config.cookieExpiryDays, 10); 206 if (!days || days < 1) { 207 days = 180; 208 } 209 210 consent.version = String(config.consentVersion || "1"); 211 consent.necessary = true; 212 applyUsPrivacyToConsent(consent); 213 consent.timestamp = new Date().toISOString(); 214 215 var expires = new Date(); 216 expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000); 217 218 var cookie = encodeURIComponent(config.cookieName || "easy_dnn_cookie_consent") + "=" + encodeURIComponent(JSON.stringify(consent)); 219 cookie += "; expires=" + expires.toUTCString() + "; path=/; SameSite=Lax"; 220 if (window.location.protocol === "https:") { 221 cookie += "; Secure"; 222 } 223 document.cookie = cookie; 224 } 225 226 function trim(value) { 227 return String(value || "").replace(/^\s+|\s+$/g, ""); 228 } 229 230 function getCookieNames() { 231 var cookies = document.cookie ? document.cookie.split(";") : []; 232 var names = []; 233 for (var i = 0; i < cookies.length; i += 1) { 234 var part = cookies[i]; 235 var index = part.indexOf("="); 236 var name = index >= 0 ? part.substring(0, index) : part;
237 name = trim(name); 238 if (name) { 239 names.push(name); 240 } 241 } 242 243 return names; 244 } 245 246 function cookieRuleMatches(rule, cookieName) { 247 if (!rule || !cookieName) { 248 return false; 249 } 250 251 var ruleName = rule.name || rule.cookieName || ""; 252 var matchType = String(rule.matchType || "exact").toLowerCase(); 253 if (!ruleName || isConsentCookie(cookieName)) { 254 return false; 255 } 256 257 if (matchType === "prefix") { 258 return cookieName.indexOf(ruleName) === 0; 259 } 260 261 return cookieName === ruleName; 262 } 263 264 function deleteCookieByName(name, path, domain) { 265 if (!name || isConsentCookie(name)) { 266 return; 267 } 268 269 var expires = "Thu, 01 Jan 1970 00:00:00 GMT"; 270 var base = name + "=; expires=" + expires + "; path=" + (path || "/"); 271 document.cookie = base; 272 273 if (domain) { 274 document.cookie = base + "; domain=" + domain; 275 } 276 277 if (!domain && window.location && window.location.hostname) { 278 var host = window.location.hostname; 279 document.cookie = base + "; domain=" + host; 280 if (host.indexOf(".") >= 0) { 281 document.cookie = base + "; domain=." + host; 282 } 283 } 284 } 285 286 function applyCookieRules(consent, reason) { 287 var rules = config.cookieRules || []; 288 var names = getCookieNames(); 289 for (var r = 0; r < rules.length; r += 1) { 290 var rule = rules[r]; 291 var category = rule ? (rule.category || rule.categoryKey) : ""; 292 if (!category || category === "necessary") { 293 continue; 294 } 295 296 var shouldDelete = false; 297 if (reason === "reject" && rule.deleteOnReject) { 298 shouldDelete = true; 299 } 300 if (reason === "withdraw" && rule.deleteOnWithdraw) { 301 shouldDelete = true; 302 } 303 if (rule.deleteWhenCategoryDisabled && consent && consent[category] !== true) { 304 shouldDelete = true; 305 } 306 if (!shouldDelete) { 307 continue; 308 } 309 310 for (var i = 0; i < names.length; i += 1) { 311 if (cookieRuleMatches(rule, names[i])) { 312 deleteCookieByName(names[i], rule.path || "/", rule.domain || ""); 313 } 314 } 315 } 316 } 317 318 function isConsentCookie(name) { 319 return String(name || "").toLowerCase() === String(config.cookieName || "easy_dnn_cookie_consent").toLowerCase(); 320 } 321 322 function show(element) { 323 if (element) { 324 element.hidden = false; 325 } 326 } 327 328 function hide(element) { 329 if (element) { 330 element.hidden = true; 331 } 332 } 333 334 function isVisible(element) { 335 if (!element || element.hidden) { 336 return false; 337 } 338 339 var style = window.getComputedStyle ? window.getComputedStyle(element) : null; 340 if (style && (style.display === "none" || style.visibility === "hidden")) { 341 return false; 342 } 343 344 return element.getClientRects().length > 0; 345 } 346 347 function getFocusableElements(container) { 348 var selector = "button,input,select,textarea,a[href],[tabindex]:not([tabindex='-1'])"; 349 var elements = container ? container.querySelectorAll(selector) : []; 350 var focusable = []; 351 for (var i = 0; i < elements.length; i += 1) { 352 if (!elements[i].disabled && isVisible(elements[i])) { 353 focusable.push(elements[i]); 354 } 355 } 356 return focusable; 357 } 358 359 function focusFirstInModal() { 360 var focusable = getFocusableElements(modal); 361 if (focusable.length > 0) { 362 focusable[0].focus(); 363 } else if (modal) { 364 modal.focus(); 365 } 366 } 367 368 function trapModalFocus(event) { 369 if (!modal || modal.hidden || event.key !== "Tab") { 370 return; 371 } 372 373 var focusable = getFocusableElements(modal); 374 if (focusable.length === 0) { 375 event.preventDefault(); 376 return; 377 } 378 379 var first = focusable[0]; 380 var last = focusable[focusable.length - 1]; 381 if (!modal.contains(document.activeElement)) { 382 event.preventDefault(); 383 first.focus(); 384 } else if (event.shiftKey && (document.activeElement === first || document.activeElement === modal)) { 385 event.preventDefault(); 386 last.focus(); 387 } else if (!event.shiftKey && (document.activeElement === last || document.activeElement === modal)) { 388 event.preventDefault(); 389 first.focus(); 390 } 391 } 392 393 function focusBannerAction() { 394 if (!banner || banner.hidden) { 395 return; 396 } 397 398 var preferred = banner.querySelector("[data-edcc-open-preferences]") 399 || banner.querySelector("[data-edcc-reject-all]") 400 || banner.querySelector("[data-edcc-accept-all]"); 401 if (preferred && isVisible(preferred)) { 402 preferred.focus(); 403 } 404 } 405 406 function restoreFocus() { 407 if (reopenButton && !reopenButton.hidden && isVisible(reopenButton)) { 408 reopenButton.focus(); 409 return; 410 } 411 412 if (lastFocusedBeforeModal && document.documentElement.contains(lastFocusedBeforeModal) && isVisible(lastFocusedBeforeModal)) { 413 lastFocusedBeforeModal.focus(); 414 } 415 } 416 417 function selectTab(tabName, focusTab) { 418 if (!modal || !tabName) { 419 return; 420 } 421 422 var tabs = modal.querySelectorAll("[data-edcc-tab]"); 423 var panels = modal.querySelectorAll("[data-edcc-tab-panel]"); 424 for (var i = 0; i < tabs.length; i += 1) { 425 var isActive = tabs[i].getAttribute("data-edcc-tab") === tabName; 426 tabs[i].setAttribute("aria-selected", isActive ? "true" : "false"); 427 if (isActive) { 428 tabs[i].classList.add("edcc-modal__tab--active"); 429 if (focusTab) { 430 tabs[i].focus(); 431 } 432 } else { 433 tabs[i].classList.remove("edcc-modal__tab--active"); 434 } 435 } 436 437 for (var p = 0; p < panels.length; p += 1) { 438 var isPanelActive = panels[p].getAttribute("data-edcc-tab-panel") === tabName; 439 panels[p].hidden = !isPanelActive; 440 if (isPanelActive) { 441 panels[p].classList.add("edcc-modal__tabPanel--active"); 442 } else { 443 panels[p].classList.remove("edcc-modal__tabPanel--active"); 444 } 445 } 446 } 447 448 function moveTab(currentTab, direction) { 449 if (!modal || !currentTab) { 450 return; 451 } 452 453 var tabs = modal.querySelectorAll("[data-edcc-tab]"); 454 if (!tabs.length) { 455 return; 456 } 457 458 var currentIndex = 0; 459 for (var i = 0; i < tabs.length; i += 1) { 460 if (tabs[i] === currentTab) { 461 currentIndex = i; 462 break; 463 } 464 } 465 466 var nextIndex = currentIndex; 467 if (direction === "first") { 468 nextIndex = 0; 469 } else if (direction === "last") { 470 nextIndex = tabs.length - 1; 471 } else { 472 nextIndex = (currentIndex + direction + tabs.length) % tabs.length; 473 } 474 475 selectTab(tabs[nextIndex].getAttribute("data-edcc-tab"), true); 476 } 477 478 function syncToggles(consent) { 479 consent = applyUsPrivacyToConsent(consent); 480 var toggles = document.querySelectorAll("[data-edcc-category-toggle]"); 481 for (var i = 0; i < toggles.length; i += 1) { 482 var key = toggles[i].getAttribute("data-edcc-category-toggle"); 483 toggles[i].checked = key === "necessary" || !!(consent && consent[key]); 484 } 485 } 486 487 function writePrivacyChoicesToUi(consent) { 488 if (!isPrivacyChoicesEnabled()) { 489 return; 490 } 491 492 consent = applyUsPrivacyToConsent(consent); 493 var doNotSell = document.querySelector("[data-edcc-us-privacy='doNotSellOrShare']"); 494 var targetedAds = document.querySelector("[data-edcc-us-privacy='targetedAdvertisingOptOut']"); 495 var locked = shouldApplyGpcOptOut(); 496 if (doNotSell) { 497 doNotSell.checked = consent.usPrivacy.doNotSellOrShare === true; 498 doNotSell.disabled = locked; 499 doNotSell.setAttribute("aria-disabled", locked ? "true" : "false"); 500 } 501 if (targetedAds) { 502 targetedAds.checked = consent.usPrivacy.targetedAdvertisingOptOut === true; 503 targetedAds.disabled = locked; 504 targetedAds.setAttribute("aria-disabled", locked ? "true" : "false"); 505 } 506 507 renderPrivacyChoicesLockedNotice(); 508 } 509 510 function readPrivacyChoicesFromUi(previous) { 511 var privacy = createDefaultUsPrivacy(); 512 previous = ensureUsPrivacy(previous || {}); 513 privacy.gpc = previous.usPrivacy.gpc === true; 514 515 if (!isPrivacyChoicesEnabled()) { 516 return privacy; 517 } 518 519 var doNotSell = document.querySelector("[data-edcc-us-privacy='doNotSellOrShare']"); 520 var targetedAds = document.querySelector("[data-edcc-us-privacy='targetedAdvertisingOptOut']"); 521 privacy.doNotSellOrShare = doNotSell ? doNotSell.checked === true : previous.usPrivacy.doNotSellOrShare === true; 522 privacy.targetedAdvertisingOptOut = targetedAds ? targetedAds.checked === true : previous.usPrivacy.targetedAdvertisingOptOut === true; 523 return privacy; 524 } 525 526 function renderPrivacyChoicesLockedNotice() { 527 var notice = document.querySelector("[data-edcc-privacy-choices-gpc-notice]"); 528 if (!notice) { 529 return; 530 } 531 532 notice.hidden = !shouldApplyGpcOptOut(); 533 } 534 535 function currentPreferencesFromModal() { 536 var consent = defaultConsent(false); 537 var toggles = document.querySelectorAll("[data-edcc-category-toggle]"); 538 for (var i = 0; i < toggles.length; i += 1) { 539 var key = toggles[i].getAttribute("data-edcc-category-toggle"); 540 if (isConfiguredCategory(key) || key === "necessary") { 541 consent[key] = key === "necessary" ? true : !!toggles[i].checked; 542 } 543 } 544 return consent; 545 } 546 547 function normalizeTargetTab(tabName) { 548 tabName = String(tabName || "consent"); 549 if (tabName === "privacyChoices") { 550 tabName = "privacy-choices"; 551 } 552 553 return tabName === "privacy-choices" || tabName === "about" ? tabName : "consent"; 554 } 555 556 function activateTab(tabName) { 557 tabName = normalizeTargetTab(tabName); 558 if (tabName === "privacy-choices" && (!isPrivacyChoicesEnabled() || !modal || !modal.querySelector("[data-edcc-tab='privacy-choices']"))) { 559 tabName = "consent"; 560 } 561 562 selectTab(tabName, false); 563 } 564 565 function openPreferences(targetTab) { 566 refreshConfig(); 567 lastFocusedBeforeModal = document.activeElement; 568 var consent = applyUsPrivacyToConsent(parseConsent() || defaultConsent(false)); 569 syncToggles(consent); 570 writePrivacyChoicesToUi(consent); 571 renderGpcNotice(); 572 activateTab(targetTab || "consent"); 573 show(modal); 574 hide(banner); 575 focusFirstInModal(); 576 } 577 578 function openPrivacyChoices() { 579 openPreferences("privacy-choices"); 580 } 581 582 function googleConsentValue(value) { 583 return value === true ? "granted" : "denied"; 584 } 585 586 function getGoogleConsentUpdate(consent) { 587 consent = applyUsPrivacyToConsent(consent || {}); 588 var analyticsGranted = consent.analytics === true; 589 var marketingGranted = consent.marketing === true; 590 591 return { 592 analytics_storage: googleConsentValue(analyticsGranted), 593 ad_storage: googleConsentValue(marketingGranted), 594 ad_user_data: googleConsentValue(marketingGranted), 595 ad_personalization: googleConsentValue(marketingGranted), 596 functionality_storage: consent.functional ? "granted" : "denied", 597 personalization_storage: consent.functional ? "granted" : "denied", 598 security_storage: "granted" 599 }; 600 } 601 602 function updateGoogleConsent(consent) { 603 if (!config.googleConsentModeEnabled || typeof window.gtag !== "function") { 604 return; 605 } 606 607 var update = getGoogleConsentUpdate(consent); 608 window.gtag("consent", "update", update); 609 debugLog("Google Consent update", update); 610 } 611 612 function isSafePublicUrl(value) { 613 value = trim(value); 614 if (!value) { 615 return false;
616 } 617 618 var lower = value.toLowerCase(); 619 if (lower.indexOf("javascript:") === 0 || lower.indexOf("data:") === 0 || lower.indexOf("vbscript:") === 0 || lower.indexOf("//") === 0) { 620 return false; 621 } 622 623 return lower.indexOf("https://") === 0 || lower.indexOf("http://") === 0 || value.indexOf("/") === 0; 624 } 625 626 function blockedContentText(key, fallback) { 627 var textConfig = config.blockedContentText || {}; 628 return textConfig[key] || fallback || ""; 629 } 630 631 function blockedMessageForCategory(category) { 632 category = String(category || "").toLowerCase(); 633 if (category === "embedded") { 634 return blockedContentText("embeddedMessage", "This embedded content is blocked until you allow embedded content cookies."); 635 } 636 if (category === "analytics") { 637 return blockedContentText("analyticsMessage", "This content is blocked until you allow analytics cookies."); 638 } 639 if (category === "marketing") { 640 return blockedContentText("marketingMessage", "This content is blocked until you allow marketing cookies."); 641 } 642 if (category === "functional") { 643 return blockedContentText("functionalMessage", "This content is blocked until you allow functional cookies."); 644 } 645 646 return blockedContentText("defaultMessage", "This content is blocked until you allow the required cookies."); 647 } 648 649 function debugLog(message, detail) { 650 if (!config.googleConsentDebugEnabled || !window.console || !window.console.log) { 651 return; 652 } 653 654 if (typeof detail === "undefined") { 655 window.console.log("[EasyDNNCookieConsent] " + message); 656 } else { 657 window.console.log("[EasyDNNCookieConsent] " + message, detail); 658 } 659 } 660 661 function activateScripts(consent) { 662 var inertScripts = document.querySelectorAll("script[type='text/plain'][data-edcc-category]"); 663 for (var i = 0; i < inertScripts.length; i += 1) { 664 var inert = inertScripts[i]; 665 var scriptId = inert.getAttribute("data-edcc-script-id") || inert.getAttribute("data-edcc-src") || inert.getAttribute("data-src") || String(i); 666 var category = inert.getAttribute("data-edcc-category"); 667 if (activatedScripts[scriptId] || inert.getAttribute("data-edcc-activated") === "true" || inert.getAttribute("data-edcc-activated") === "1" || inert.getAttribute("data-edcc-skip-generic-activation") === "1" || !category || !isCategoryAllowed(consent, category)) { 668 continue; 669 } 670 671 var executable = document.createElement("script"); 672 executable.setAttribute("data-edcc-activated", "1"); 673 executable.setAttribute("data-edcc-script-id", scriptId); 674 var src = inert.getAttribute("data-edcc-src") || inert.getAttribute("data-src"); 675 if (src) { 676 if (!isSafePublicUrl(src)) { 677 continue; 678 } 679 executable.type = "text/javascript"; 680 executable.src = src; 681 setExternalScriptAttributes(executable, inert); 682 if (!isTruthyAttribute(inert.getAttribute("data-async"))) { 683 executable.async = false; 684 } 685 } else { 686 executable.type = "text/javascript"; 687 executable.text = inert.text || inert.textContent || inert.innerHTML || ""; 688 } 689 690 if (isAdSenseLoader(inert)) { 691 executable.onload = function () { 692 activateAdSenseSlots(consent); 693 }; 694 } 695 696 activatedScripts[scriptId] = true; 697 inert.setAttribute("data-edcc-activated", "true"); 698 inert.parentNode.insertBefore(executable, inert.nextSibling); 699 700 if (isAdSenseLoader(inert) && window.adsbygoogle) { 701 activateAdSenseSlots(consent); 702 } 703 } 704 705 if (consent && consent.marketing && window.adsbygoogle) { 706 activateAdSenseSlots(consent); 707 } 708 } 709 710 function setExternalScriptAttributes(executable, inert) { 711 var crossorigin = inert.getAttribute("crossorigin") || inert.getAttribute("data-crossorigin"); 712 var referrerPolicy = inert.getAttribute("referrerpolicy") || inert.getAttribute("data-referrerpolicy"); 713 var integrity = inert.getAttribute("integrity") || inert.getAttribute("data-integrity"); 714 var nonce = inert.getAttribute("nonce") || inert.getAttribute("data-nonce"); 715 if (crossorigin) { 716 executable.setAttribute("crossorigin", crossorigin); 717 } 718 if (referrerPolicy) { 719 executable.setAttribute("referrerpolicy", referrerPolicy); 720 } 721 if (integrity) { 722 executable.setAttribute("integrity", integrity); 723 } 724 if (nonce) { 725 executable.setAttribute("nonce", nonce); 726 } 727 if (inert.hasAttribute("defer") || isTruthyAttribute(inert.getAttribute("data-defer"))) { 728 executable.defer = true; 729 } 730 if (inert.hasAttribute("async") || isTruthyAttribute(inert.getAttribute("data-async"))) { 731 executable.async = true; 732 } 733 } 734 735 function processBlockedContent(consent) { 736 activateScripts(consent); 737 processBlockedEmbeds(consent); 738 } 739 740 function processBlockedEmbeds(consent) { 741 var placeholders = document.querySelectorAll(".edcc-blocked-embed[data-edcc-src][data-edcc-category]"); 742 for (var i = 0; i < placeholders.length; i += 1) { 743 processBlockedEmbedPlaceholder(placeholders[i], consent); 744 } 745 746 var iframes = document.querySelectorAll("iframe[data-edcc-src][data-edcc-category]"); 747 for (var f = 0; f < iframes.length; f += 1) { 748 processBlockedIframe(iframes[f], consent); 749 } 750 } 751 752 function processBlockedEmbedPlaceholder(element, consent) { 753 if (!element || element.getAttribute("data-edcc-activated") === "true") { 754 return; 755 } 756 757 var category = element.getAttribute("data-edcc-category"); 758 var src = element.getAttribute("data-edcc-src"); 759 if (!isSafePublicUrl(src)) { 760 renderBlockedEmbedMessage(element, blockedContentText("unsafeSource", "This content could not be loaded because the source is not allowed."), false); 761 return; 762 } 763 764 if (!isCategoryAllowed(consent, category)) { 765 renderBlockedEmbedMessage(element, blockedMessageForCategory(category), true); 766 return; 767 } 768 769 var iframe = document.createElement("iframe"); 770 iframe.src = src; 771 iframe.title = element.getAttribute("data-edcc-title") || blockedContentText("defaultTitle", "Embedded content"); 772 iframe.width = element.getAttribute("data-edcc-width") || "100%"; 773 iframe.height = element.getAttribute("data-edcc-height") || "315"; 774 iframe.loading = "lazy"; 775 iframe.frameBorder = "0"; 776 iframe.allowFullscreen = true; 777 iframe.setAttribute("allowfullscreen", "allowfullscreen"); 778 iframe.setAttribute("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"); 779 element.innerHTML = ""; 780 element.appendChild(iframe); 781 element.setAttribute("data-edcc-activated", "true"); 782 } 783 784 function processBlockedIframe(iframe, consent) { 785 if (!iframe || iframe.getAttribute("data-edcc-activated") === "true") { 786 return; 787 } 788 789 var category = iframe.getAttribute("data-edcc-category"); 790 var src = iframe.getAttribute("data-edcc-src"); 791 if (!isSafePublicUrl(src)) { 792 iframe.setAttribute("src", "about:blank"); 793 return; 794 } 795 796 if (!isCategoryAllowed(consent, category)) { 797 var currentSrc = iframe.getAttribute("src"); 798 if (!currentSrc || currentSrc === src) { 799 iframe.setAttribute("src", "about:blank"); 800 } 801 return; 802 } 803 804 iframe.setAttribute("src", src); 805 iframe.setAttribute("data-edcc-activated", "true"); 806 } 807 808 function renderBlockedEmbedMessage(element, message, showButton) { 809 if (element.getAttribute("data-edcc-placeholder-rendered") === "true") { 810 return; 811 } 812 813 var box = document.createElement("div"); 814 box.className = "edcc-blocked-embed__box"; 815 var paragraph = document.createElement("p"); 816 paragraph.className = "edcc-blocked-embed__message"; 817 paragraph.appendChild(document.createTextNode(message)); 818 box.appendChild(paragraph); 819 if (showButton) { 820 var button = document.createElement("button"); 821 button.type = "button"; 822 button.className = "edcc-button edcc-button--secondary"; 823 button.setAttribute("data-edcc-open-preferences", "1"); 824 button.appendChild(document.createTextNode(blockedContentText("managePreferences", "Manage preferences"))); 825 box.appendChild(button); 826 } 827 828 element.innerHTML = ""; 829 element.appendChild(box); 830 element.setAttribute("data-edcc-placeholder-rendered", "true"); 831 } 832 833 function isTruthyAttribute(value) {
834 value = String(value || "").toLowerCase(); 835 return value === "true" || value === "1" || value === "async"; 836 } 837 838 function isAdSenseLoader(inert) { 839 return inert 840 && (inert.getAttribute("data-edcc-service") === "google-adsense" 841 || inert.getAttribute("data-edcc-script-id") === "auto-adsense-loader"); 842 } 843 844 function activateAdSenseSlots(consent) { 845 if (!consent || !consent.marketing) { 846 return; 847 } 848 849 var slots = document.querySelectorAll("ins.adsbygoogle[data-edcc-adsense-slot='1']"); 850 var activatedAny = false; 851 for (var i = 0; i < slots.length; i += 1) { 852 var slot = slots[i]; 853 if (slot.getAttribute("data-edcc-adsense-activated") === "1") { 854 continue; 855 } 856 857 slot.setAttribute("data-edcc-adsense-activated", "1"); 858 activatedAny = true; 859 860 try { 861 window.adsbygoogle = window.adsbygoogle || []; 862 window.adsbygoogle.push({}); 863 } catch (ex) { 864 if (window.console && window.console.warn) { 865 window.console.warn("[EasyDNNCookieConsent] Could not activate AdSense slot.", ex); 866 } 867 } 868 } 869 870 if (activatedAny || slots.length > 0) { 871 hideAdSensePlaceholders(); 872 } 873 } 874 875 function hideAdSensePlaceholders() { 876 var placeholders = document.querySelectorAll("[data-edcc-adsense-placeholder='1']"); 877 for (var i = 0; i < placeholders.length; i += 1) { 878 placeholders[i].style.display = "none"; 879 } 880 } 881 882 function anonymousId() { 883 var key = "EasyDNNCookieConsentAnonymousId"; 884 try { 885 var existing = window.localStorage.getItem(key); 886 if (existing) { 887 return existing; 888 } 889 var created = "edcc-" + Math.random().toString(36).substring(2) + Date.now().toString(36); 890 window.localStorage.setItem(key, created); 891 return created; 892 } catch (ignore) { 893 return ""; 894 } 895 } 896 897 function logConsent(action, consent) { 898 if (!config.logUrl || !window.fetch) { 899 return; 900 } 901 902 try { 903 window.fetch(config.logUrl, { 904 method: "POST", 905 credentials: "same-origin", 906 headers: { "Content-Type": "application/json" }, 907 body: JSON.stringify({ 908 portalId: config.portalId, 909 action: action, 910 consentVersion: consent.version, 911 categories: consent, 912 anonymousId: anonymousId(), 913 pageUrl: window.location.href 914 }) 915 }).catch(function () {}); 916 } catch (ignore) {} 917 } 918 919 function requestServerCookieDeletion(consent, reason) { 920 if (!config.deleteCookiesUrl || !window.fetch || !consent) { 921 return; 922 } 923 924 try { 925 window.fetch(config.deleteCookiesUrl, { 926 method: "POST", 927 credentials: "same-origin", 928 headers: { "Content-Type": "application/json" }, 929 body: JSON.stringify({ 930 portalId: config.portalId, 931 moduleId: config.moduleId, 932 reason: reason || "save", 933 consentVersion: consent.version, 934 categories: consent 935 }) 936 }).catch(function () {}); 937 } catch (ignore) {} 938 } 939 940 function dispatchConsentChanged(consent) { 941 if (typeof window.CustomEvent === "function") { 942 document.dispatchEvent(new CustomEvent("EasyDNNCookieConsentChanged", { detail: consent })); 943 } 944 } 945 946 function notify(consent, action) { 947 consent = applyUsPrivacyToConsent(consent); 948 updateGoogleConsent(consent); 949 processBlockedContent(consent); 950 hide(banner); 951 hide(modal); 952 show(reopenButton); 953 954 for (var i = 0; i < callbacks.length; i += 1) { 955 try { 956 callbacks[i](consent); 957 } catch (ignore) {} 958 } 959 960 dispatchConsentChanged(consent); 961 if (action) { 962 logConsent(action, consent); 963 restoreFocus(); 964 } 965 } 966 967 function savePreferences(preferences, action) { 968 refreshConfig(); 969 var previous = parseConsent(); 970 var consent = defaultConsent(false); 971 preferences = preferences || {}; 972 eachCategory(function (category) { 973 var key = categoryKey(category); 974 if (!key) { 975 return; 976 } 977 consent[key] = categoryRequired(category) || !!preferences[key]; 978 }); 979 consent.usPrivacy = readPrivacyChoicesFromUi(previous); 980 applyUsPrivacyToConsent(consent); 981 writeConsent(consent); 982 applyCookieRules(consent, "save"); 983 requestServerCookieDeletion(consent, "save"); 984 notify(consent, action || "save_preferences"); 985 logGpcOptOutIfNeeded(previous, consent); 986 logUsPrivacyOptOutIfNeeded(previous, consent); 987 return consent; 988 } 989 990 function acceptAll() { 991 refreshConfig(); 992 var previous = parseConsent(); 993 var consent = defaultConsent(true); 994 copyUsPrivacy(previous, consent); 995 applyUsPrivacyToConsent(consent); 996 writeConsent(consent); 997 notify(consent, "accept_all"); 998 logGpcOptOutIfNeeded(previous, consent); 999 return consent; 1000 } 1001 1002 function hasOptionalConsent(consent) { 1003 var hasOptional = false;
1004 eachCategory(function (category) { 1005 var key = categoryKey(category); 1006 if (key && !categoryRequired(category) && consent && consent[key]) { 1007 hasOptional = true; 1008 } 1009 }); 1010 return hasOptional; 1011 } 1012 1013 function rejectAll() { 1014 refreshConfig(); 1015 var previous = parseConsent(); 1016 var consent = defaultConsent(false); 1017 copyUsPrivacy(previous, consent); 1018 applyUsPrivacyToConsent(consent); 1019 writeConsent(consent); 1020 var reason = hasOptionalConsent(previous) ? "withdraw" : "reject"; 1021 applyCookieRules(consent, reason); 1022 requestServerCookieDeletion(consent, reason); 1023 notify(consent, reason === "withdraw" ? "withdraw" : "reject_all"); 1024 logGpcOptOutIfNeeded(previous, consent); 1025 return consent; 1026 } 1027 1028 function logGpcOptOutIfNeeded(previous, consent) { 1029 if (shouldApplyGpcOptOut() && hasAppliedGpcState(consent) && !hasAppliedGpcState(previous)) { 1030 logConsent("gpc_opt_out", consent); 1031 } 1032 } 1033 1034 function logUsPrivacyOptOutIfNeeded(previous, consent) { 1035 if (!isPrivacyChoicesEnabled() || shouldApplyGpcOptOut()) { 1036 return; 1037 } 1038 1039 previous = ensureUsPrivacy(previous || {}); 1040 consent = ensureUsPrivacy(consent || {}); 1041 var currentOptOut = consent.usPrivacy.doNotSellOrShare === true || consent.usPrivacy.targetedAdvertisingOptOut === true; 1042 var changed = previous.usPrivacy.doNotSellOrShare !== consent.usPrivacy.doNotSellOrShare 1043 || previous.usPrivacy.targetedAdvertisingOptOut !== consent.usPrivacy.targetedAdvertisingOptOut; 1044 if (currentOptOut && changed) { 1045 logConsent("us_privacy_opt_out", consent); 1046 } 1047 } 1048 1049 function renderGpcNotice() { 1050 var notice = document.querySelector("[data-edcc-gpc-notice]"); 1051 if (!notice) { 1052 return; 1053 } 1054 1055 if (shouldApplyGpcOptOut()) { 1056 notice.hidden = false; 1057 } else { 1058 notice.hidden = true; 1059 } 1060 } 1061 1062 function bind() { 1063 refreshConfig(); 1064 if (config.googleConsentModeEnabled) { 1065 debugLog("Google Consent default registered"); 1066 } 1067 root = document.querySelector("[data-edcc-root]"); 1068 banner = document.querySelector("[data-edcc-banner]"); 1069 modal = document.querySelector("[data-edcc-modal]"); 1070 reopenButton = document.querySelector(".edcc-reopen"); 1071 1072 document.addEventListener("click", function (event) { 1073 if (event.target.closest("[data-edcc-open-privacy-choices]")) { 1074 event.preventDefault(); 1075 openPrivacyChoices(); 1076 return; 1077 } 1078 if (event.target.closest("[data-edcc-accept-all]")) { 1079 acceptAll(); 1080 } 1081 if (event.target.closest("[data-edcc-reject-all]")) { 1082 rejectAll(); 1083 } 1084 if (event.target.closest("[data-edcc-open-preferences]")) { 1085 openPreferences(); 1086 } 1087 var tab = event.target.closest("[data-edcc-tab]"); 1088 if (tab) { 1089 selectTab(tab.getAttribute("data-edcc-tab"), false); 1090 } 1091 if (event.target.closest("[data-edcc-save-preferences]")) { 1092 savePreferences(currentPreferencesFromModal(), "save_preferences"); 1093 } 1094 }); 1095 1096 document.addEventListener("keydown", function (event) { 1097 var tab = event.target.closest("[data-edcc-tab]"); 1098 if (tab && modal && modal.contains(tab)) { 1099 if (event.key === "ArrowRight") { 1100 event.preventDefault(); 1101 moveTab(tab, 1); 1102 } else if (event.key === "ArrowLeft") { 1103 event.preventDefault(); 1104 moveTab(tab, -1); 1105 } else if (event.key === "Home") { 1106 event.preventDefault(); 1107 moveTab(tab, "first"); 1108 } else if (event.key === "End") { 1109 event.preventDefault(); 1110 moveTab(tab, "last"); 1111 } 1112 } 1113 1114 trapModalFocus(event); 1115 1116 if (event.key === "Escape" && modal && !modal.hidden) { 1117 hide(modal); 1118 if (!parseConsent()) { 1119 show(banner); 1120 focusBannerAction(); 1121 } else { 1122 restoreFocus(); 1123 } 1124 } 1125 }); 1126 1127 var consent = parseConsent(); 1128 if (consent) { 1129 var previousGpcApplied = hasAppliedGpcState(consent); 1130 applyUsPrivacyToConsent(consent); 1131 if (shouldApplyGpcOptOut() && !previousGpcApplied && hasAppliedGpcState(consent)) { 1132 writeConsent(consent); 1133 logConsent("gpc_opt_out", consent); 1134 } 1135 applyCookieRules(consent, "load"); 1136 requestServerCookieDeletion(consent, "load"); 1137 notify(consent, null); 1138 } else { 1139 show(banner); 1140 hide(reopenButton); 1141 var defaultState = defaultConsent(false); 1142 if (shouldApplyGpcOptOut() && hasAppliedGpcState(defaultState)) { 1143 writeConsent(defaultState); 1144 logConsent("gpc_opt_out", defaultState); 1145 } 1146 syncToggles(defaultState); 1147 writePrivacyChoicesToUi(defaultState); 1148 processBlockedContent(defaultState); 1149 renderGpcNotice(); 1150 } 1151 } 1152 1153 window.EasyDNNCookieConsent = { 1154 openPreferences: openPreferences, 1155 openPrivacyChoices: openPrivacyChoices, 1156 getConsent: function () { 1157 refreshConfig(); 1158 var consent = parseConsent(); 1159 return consent ? applyUsPrivacyToConsent(consent) : null; 1160 }, 1161 hasConsent: function (key) { 1162 refreshConfig(); 1163 var consent = applyUsPrivacyToConsent(parseConsent()); 1164 return !!(key === "necessary" || (isConfiguredCategory(key) && consent && consent[key])); 1165 }, 1166 acceptAll: acceptAll, 1167 rejectAll: rejectAll, 1168 savePreferences: function (preferences) { 1169 return savePreferences(preferences, "save_preferences"); 1170 }, 1171 onConsentChanged: function (callback) { 1172 if (typeof callback === "function") { 1173 callbacks.push(callback); 1174 } 1175 } 1176 }; 1177 1178 if (document.readyState === "loading") { 1179 document.addEventListener("DOMContentLoaded", bind); 1180 } else { 1181 bind(); 1182 } 1183}(window, document));
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.