1(function () { 2 var SUPPORT_EMAIL = "[email protected]"; 3 var DEFAULT_SUBMIT_LABEL = "Chci nezávaznou nabÃdku"; 4 var MONETA_RECAPTCHA_ACTION = "moneta_contact"; 5 6 function updateMetadataUrls() { 7 var pageUrl = new URL("/moneta/", window.location.origin).href; 8 var imageUrl = new URL("/moneta/og-image.png", window.location.origin).href; 9 var canonical = document.querySelector('link[rel="canonical"]'); 10 var ogUrl = document.querySelector('meta[property="og:url"]'); 11 var ogImage = document.querySelector('meta[property="og:image"]'); 12 var twitterImage = document.querySelector('meta[name="twitter:image"]'); 13 var structuredData = document.getElementById("structured-data-moneta"); 14 15 if (canonical) canonical.setAttribute("href", pageUrl); 16 if (ogUrl) ogUrl.setAttribute("content", pageUrl); 17 if (ogImage) ogImage.setAttribute("content", imageUrl); 18 if (twitterImage) twitterImage.setAttribute("content", imageUrl); 19 20 if (!structuredData) return; 21 22 try { 23 var payload = JSON.parse(structuredData.textContent); 24 payload.url = pageUrl; 25 structuredData.textContent = JSON.stringify(payload); 26 } catch (error) { 27 console.warn("Structured data update failed.", error); 28 } 29 } 30 31 function setupPhoneFormatting() { 32 var phoneInput = document.getElementById("phone"); 33 if (!phoneInput) return; 34 35 phoneInput.addEventListener("input", function () { 36 var raw = this.value.replace(/[^0-9+]/g, ""); 37 38 if (raw.indexOf("+420") === 0) raw = raw.substring(4); 39 else if (raw.indexOf("420") === 0 && raw.length > 9) raw = raw.substring(3); 40 41 raw = raw.replace(/[^0-9]/g, ""); 42 if (raw.length > 9) raw = raw.substring(0, 9); 43 if (!raw) { 44 this.value = ""; 45 return; 46 } 47 48 var formatted = "+420 "; 49 for (var i = 0; i < raw.length; i += 1) { 50 if (i > 0 && i % 3 === 0) formatted += " "; 51 formatted += raw[i]; 52 } 53 54 this.value = formatted; 55 this.setSelectionRange(formatted.length, formatted.length); 56 }); 57 58 phoneInput.addEventListener("focus", function () { 59 if (!this.value) this.value = "+420 "; 60 }); 61 62 phoneInput.addEventListener("blur", function () { 63 if (this.value.trim() === "+420") this.value = ""; 64 }); 65 } 66 67 function hideFormError() { 68 var errorBox = document.getElementById("formError"); 69 if (!errorBox) return; 70 71 errorBox.classList.remove("show"); 72 errorBox.replaceChildren(); 73 } 74 75 function getGenericFormError() { 76 return ( 77 "FormuláŠse nepodaÅilo odeslat. Zkuste to prosÃm za chvÃli znovu. " + 78 "V pÅÃpadÄ problémů nás kontaktujte na emailové adrese " + 79 SUPPORT_EMAIL + 80 "." 81 ); 82 } 83 84 function createSupportEmailLink() { 85 var link = document.createElement("a"); 86 var subject = encodeURIComponent("Problém s odeslánÃm MONETA formuláÅe"); 87 var body = encodeURIComponent( 88 "Dobrý den,\n\nnedaÅà se mi odeslat MONETA formuláÅ. ProsÃm o pomoc.\n\nDÄkuji" 89 ); 90 91 link.href = "mailto:" + SUPPORT_EMAIL + "?subject=" + subject + "&body=" + body; 92 link.textContent = SUPPORT_EMAIL; 93 return link; 94 } 95 96 function showFormError(message) { 97 var errorBox = document.getElementById("formError"); 98 var errorMessage = message || getGenericFormError(); 99 var supportEmailIndex = errorMessage.indexOf(SUPPORT_EMAIL); 100 101 if (!errorBox) { 102 alert(errorMessage); 103 return; 104 } 105 106 errorBox.replaceChildren(); 107 108 if (supportEmailIndex === -1) { 109 errorBox.textContent = errorMessage; 110 } else { 111 errorBox.append( 112 document.createTextNode(errorMessage.slice(0, supportEmailIndex)), 113 createSupportEmailLink(), 114 document.createTextNode(errorMessage.slice(supportEmailIndex + SUPPORT_EMAIL.length)) 115 ); 116 } 117 118 errorBox.classList.add("show"); 119 errorBox.scrollIntoView({ behavior: "smooth", block: "center" }); 120 } 121 122 function setSubmitButtonLoading(button, isLoading) { 123 if (!button) return; 124 125 var label = button.querySelector(".btn-submit__label"); 126 button.disabled = isLoading; 127 button.classList.toggle("is-loading", isLoading); 128 129 if (label) { 130 label.textContent = isLoading ? "OdesÃlám..." : DEFAULT_SUBMIT_LABEL; 131 } 132 } 133 134 async function handleSubmit(event) { 135 event.preventDefault(); 136 137 var form = document.getElementById("contactForm"); 138 var btn = document.getElementById("submitBtn"); 139 140 hideFormError(); 141 setSubmitButtonLoading(btn, true); 142 143 try { 144 var recaptcha = window.VZRecaptcha 145 ? await window.VZRecaptcha.execute(MONETA_RECAPTCHA_ACTION) 146 : { action: MONETA_RECAPTCHA_ACTION, token: "" }; 147 var response = await fetch("/api/contact", { 148 method: "POST", 149 headers: { "Content-Type": "application/json" }, 150 body: JSON.stringify({ 151 source: "moneta", 152 recaptchaAction: recaptcha.action, 153 recaptchaToken: recaptcha.token, 154 name: document.getElementById("name").value, 155 email: document.getElementById("email").value, 156 phone: document.getElementById("phone").value, 157 ico: document.getElementById("ico").value.replace(/[^0-9]/g, ""), 158 marketingConsent: document.getElementById("marketingConsent").checked, 159 pageUrl: window.location.href, 160 referrer: document.referrer, 161 }), 162 }); 163 164 var result = await response.json().catch(function () { 165 return {}; 166 }); 167 168 if (!response.ok || !result.ok) { 169 throw new Error(result.error || getGenericFormError()); 170 } 171 172 var success = document.getElementById("formSuccess"); 173 174 if (form) { 175 form.style.display = "none"; 176 form.reset(); 177 } 178 179 if (success) success.classList.add("show"); 180 } catch (error) { 181 setSubmitButtonLoading(btn, false); 182 showFormError(error && error.message ? error.message : getGenericFormError()); 183 } 184 } 185 186 function setupContactForm() { 187 var form = document.getElementById("contactForm"); 188 if (!form) return; 189 190 if (window.VZRecaptcha) { 191 window.VZRecaptcha.attachDisclosure( 192 form.querySelector(".form-submit-action") || form, 193 "light" 194 ); 195 window.VZRecaptcha.init(); 196 } 197 198 form.addEventListener("submit", handleSubmit); 199 } 200 201 function setupHeroInfoTooltip() { 202 var trigger = document.querySelector(".hero-info"); 203 if (!trigger) return; 204 205 var mobileQuery = window.matchMedia("(max-width: 640px), (hover: none) and (pointer: coarse)"); 206 207 function closeTooltip() { 208 trigger.classList.remove("is-open"); 209 trigger.setAttribute("aria-expanded", "false"); 210 trigger.blur(); 211 } 212 213 trigger.addEventListener("click", function (event) { 214 if (!mobileQuery.matches) return; 215 216 event.preventDefault(); 217 var isOpen = trigger.classList.toggle("is-open"); 218 trigger.setAttribute("aria-expanded", isOpen ? "true" : "false"); 219 }); 220 221 document.addEventListener("pointerdown", function (event) { 222 if (!mobileQuery.matches || !trigger.classList.contains("is-open")) return; 223 if (trigger.contains(event.target)) return; 224 225 closeTooltip(); 226 }); 227 228 document.addEventListener("keydown", function (event) { 229 if (event.key === "Escape") closeTooltip(); 230 }); 231 232 if (typeof mobileQuery.addEventListener === "function") { 233 mobileQuery.addEventListener("change", closeTooltip); 234 } 235 } 236 237 updateMetadataUrls(); 238 239 document.addEventListener("DOMContentLoaded", function () { 240 setupPhoneFormatting(); 241 setupContactForm(); 242 setupHeroInfoTooltip(); 243 }); 244})();
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.