1const StartSession = new Promise(function (resolve, reject) { 2 const token = Cookies.get("token"); 3 const tokenType = Cookies.get("token_type"); 4 const tokenExpiry = Cookies.get("token_expiry"); // Retrieve the stored expiry time 5 6 if (token && tokenType) { 7 const now = new Date().getTime(); // Current timestamp in milliseconds 8 const timeRemaining = tokenExpiry - now; // Calculate time remaining in milliseconds 9 10 if (timeRemaining > 24 * 60 * 60 * 1000) { 11 // If more than a day remains, no need to renew 12 resolve(1); 13 } else { 14 // If less than a day remains, renew the token 15 renewToken(resolve, reject); 16 } 17 } else { 18 // If token doesn't exist, call the function to renew 19 renewToken(resolve, reject); 20 } 21}); 22 23function renewToken(resolve, reject) { 24 const headers = window.Api.headers; 25 headers.Authorization = "Basic " + window.Api.key; 26 $.ajax({ 27 url: window.Api.url + "oauth2/token/client_credentials", 28 cache: false, 29 type: "POST", 30 dataType: "json", 31 headers: window.Api.headers, 32 async: true, 33 data: JSON.stringify({client_id: "stl3oyim7bop", client_secret: "95foglnewr6c"}), 34 beforeSend: function () {}, 35 success: function (data) { 36 if (data.success) { 37 const expiresInMs = data.data.expires_in * 1000; // Convert expires_in to milliseconds 38 const expiryTimestamp = new Date().getTime() + expiresInMs; // Current time + expires_in 39 const daysRemaining = expiresInMs / (24 * 60 * 60 * 1000); 40 41 // Save the token and expiry details 42 Cookies.set("token", data.data.access_token, {expires: daysRemaining}); // Set token with expiry in days 43 Cookies.set("token_type", data.data.token_type, {}); // Save token type 44 Cookies.set("token_expiry", expiryTimestamp); 45 } 46 resolve(1); 47 }, 48 error: function (xhr, ajaxOptions, thrownError) { 49 reject(0); 50 // console.error(thrownError + '\r\n' + xhr.statusText + '\r\n' + xhr.responseText); 51 console.error(thrownError, xhr.statusText, xhr.responseText); 52 // console.error(xhr.statusText); 53 // console.error(xhr.responseText); 54 }, 55 }); 56} 57 58// Accessability improvements 59document.addEventListener("DOMContentLoaded", () => { 60 61 const menus = document.querySelectorAll(".main-menu.main-menu-3"); 62 63 menus.forEach((el, index) => { 64 if (index > 0) { 65 el.remove(); 66 } 67 }); 68 const checkInterval = 500; 69 70 let doneAlt1 = false; 71 let doneAlt2 = false; 72 let doneMerge = false; 73 let doneReplaceButton = false; 74 75 const intervalId = setInterval(() => { 76 // 1) Set alt on first image 77 if (!doneAlt1) { 78 const img1 = document.querySelector('img[src="https://selo.confio.pt/sites/profile/5eb6e85e-45cc-4b0a-98da-99d856ab5502/widget/image-seal.svg"]'); 79 if (img1) { 80 img1.setAttribute("alt", "Selo Confio â Certificação de Confiança"); 81 doneAlt1 = true; 82 } 83 } 84 85 // 2) Set alt on second image 86 if (!doneAlt2) { 87 const img2 = document.querySelector('img[src="https://selo.confio.pt/sites/profile/5eb6e85e-45cc-4b0a-98da-99d856ab5502/widget/image-trust.png"]'); 88 if (img2) { 89 img2.setAttribute("alt", "Selo Confio â Certificação de Confiança"); 90 doneAlt2 = true; 91 } 92 } 93 94 // 3) Merge duplicate links/images 95 if (!doneMerge) { 96 const container = document.querySelector(".partners-logos"); 97 if (container) { 98 const links = Array.from(container.querySelectorAll("a")); 99 const groups = {}; 100 101 links.forEach((link) => { 102 const href = link.getAttribute("href"); 103 if (!groups[href]) groups[href] = []; 104 groups[href].push(link); 105 }); 106 107 for (const href in groups) { 108 const group = groups[href]; 109 if (group.length > 1) { 110 const firstLink = group[0]; 111 112 for (let i = 1; i < group.length; i++) { 113 const imgs = group[i].querySelectorAll("img");
114 imgs.forEach((img) => { 115 img.removeAttribute("alt"); 116 firstLink.appendChild(img); 117 }); 118 group[i].remove(); 119 } 120 121 firstLink.setAttribute("aria-label", "Selo Confio â Certificação de Confiança"); 122 firstLink.querySelectorAll("img").forEach((img) => img.setAttribute("alt", "")); 123 } 124 } 125 doneMerge = true; 126 } 127 } 128 129 // Stop interval if all done 130 if (doneAlt1 && doneAlt2 && doneMerge) { 131 clearInterval(intervalId); 132 } 133 }, checkInterval); 134 135 let cookiebotAttempts = 0; 136 const maxCookiebotAttempts = 5; 137 const cookiebotInterval = setInterval(() => { 138 cookiebotAttempts++; 139 140 // Fix skip link issue 141 const skipLink = document.getElementById("CybotCookiebotDialogPoweredbyCybot"); 142 const consentTextDiv = document.getElementById("CybotCookiebotDialogDetailBodyContentTextAbout"); 143 const linksWithTitle = document.querySelectorAll("a[title]"); 144 145 if (skipLink || consentTextDiv || linksWithTitle.length > 0) { 146 // 1) Fix skip link href and text 147 if (skipLink) { 148 if (skipLink.getAttribute("href") !== "#content") { 149 skipLink.setAttribute("href", "#content"); 150 } 151 // Always set aria-label to improve accessibility 152 skipLink.setAttribute("aria-label", "Skip to main content"); 153 // Do NOT set textContent since the link has an image 154 } 155 156 // 2) Remove redundant title attributes on links 157 linksWithTitle.forEach((link) => { 158 const title = link.getAttribute("title")?.trim(); 159 const text = link.textContent?.trim(); 160 if (title && text && title === text) { 161 link.removeAttribute("title"); 162 } 163 }); 164 165 // 3) Replace <br> sequences with paragraphs inside consent text div 166 if (consentTextDiv) { 167 const html = consentTextDiv.innerHTML; 168 const paragraphTexts = html.split(/(<br\s*\/?>\s*)+/i).filter(Boolean); 169 const filteredTexts = paragraphTexts.filter((t) => t.trim().length > 0); 170 const newHtml = filteredTexts.map((text) => `<p>${text.trim()}</p>`).join(""); 171 consentTextDiv.innerHTML = newHtml; 172 } 173 174 clearInterval(cookiebotInterval); // Done, clear interval 175 } else if (cookiebotAttempts >= maxCookiebotAttempts) { 176 clearInterval(cookiebotInterval); // Max attempts reached, clear interval anyway 177 } 178 }, checkInterval); 179});
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.