1/* MIR THAILAND common.js â audited and fixed 2026-09-14 */ 2(function () { 3 "use strict"; 4 5 function defaultRussianUrl(value) { 6 try { 7 var url = new URL(value, window.location.href); 8 var language = (url.searchParams.get("lang") || "").toLowerCase(); 9 10 if (url.origin !== window.location.origin || language !== "ru") { 11 return null; 12 } 13 14 url.searchParams.delete("lang"); 15 return url; 16 } catch (error) { 17 return null; 18 } 19 } 20 21 function normalizedUrlValue(originalValue, url) { 22 if (/^[a-z][a-z0-9+.-]*:/i.test(originalValue) || originalValue.indexOf("//") === 0) { 23 return url.origin + url.pathname + url.search + url.hash; 24 } 25 26 return url.pathname + url.search + url.hash; 27 } 28 29 function normalizeCurrentDefaultLanguageUrl() { 30 if (window.__mirDefaultLanguageRedirecting) { 31 return true; 32 } 33 34 var url = defaultRussianUrl(window.location.href); 35 36 if (!url) { 37 return false; 38 } 39 40 document.documentElement.setAttribute("lang", "ru"); 41 42 try { 43 window.localStorage.setItem("mirLang", "ru"); 44 } catch (error) { 45 void error; 46 } 47 48 var cleanLocation = url.pathname + url.search + url.hash; 49 var currentLocation = window.location.pathname + window.location.search + window.location.hash; 50 51 if (cleanLocation !== currentLocation) { 52 window.__mirDefaultLanguageRedirecting = true; 53 window.location.replace(cleanLocation); 54 return true; 55 } 56 57 return false; 58 } 59 60 function normalizeDefaultLanguageUrls(root) { 61 var selector = 'a[href], link[rel="canonical"][href], link[rel="alternate"][href], meta[property="og:url"][content]'; 62 var elements = []; 63 64 if (root && root.nodeType !== 1 && root.nodeType !== 9) { 65 return; 66 } 67 68 if (root && root.nodeType === 1 && root.matches && root.matches(selector)) { 69 elements.push(root); 70 } 71 72 var scope = root || document; 73 scope.querySelectorAll(selector).forEach(function (element) { 74 elements.push(element); 75 }); 76 77 elements.forEach(function (element) { 78 var attribute = element.tagName === "META" ? "content" : "href"; 79 var originalValue = element.getAttribute(attribute) || ""; 80 var url = defaultRussianUrl(originalValue); 81 82 if (!url) { 83 return; 84 } 85 86 var cleanValue = normalizedUrlValue(originalValue, url); 87 if (cleanValue !== originalValue) { 88 element.setAttribute(attribute, cleanValue); 89 } 90 }); 91 } 92 93 function improveCookieAccessibility() { 94 var cookieClose = document.getElementById("cookiePolicyHide"); 95 96 if (cookieClose && !cookieClose.getAttribute("aria-label")) { 97 cookieClose.setAttribute("aria-label", "ÐакÑÑÑÑ Ñведомление о cookies"); 98 } 99 } 100 101 function pageImageLabel(image) { 102 var galleryImage = document.querySelector('.mt-gallery-item img[alt]:not([alt=""])'); 103 var heading = document.querySelector("h1, .mt-article-title"); 104 105 if (image.classList.contains("mt-plan-image")) { 106 var planTitle = document.getElementById("mt-plan-title"); 107 if (planTitle && planTitle.textContent.trim()) { 108 return planTitle.textContent.trim(); 109 } 110 } 111 112 if (galleryImage) { 113 return galleryImage.getAttribute("alt").trim(); 114 } 115 116 if (heading && heading.textContent.trim()) { 117 return heading.textContent.trim(); 118 } 119 120 return "MIR THAILAND"; 121 } 122 123 function improveSingleImage(image) { 124 if (!image || image.tagName !== "IMG") { 125 return; 126 } 127 128 var src = image.getAttribute("src") || ""; 129 130 if (image.matches("img.captcha-question") || /^\/secure\//i.test(src)) { 131 if (!image.getAttribute("alt")) { 132 image.setAttribute("alt", "Security code CAPTCHA"); 133 } 134 return; 135 } 136 137 if (/\/\.s\/img\/wd\/7\/sample\.gif(?:$|[?#])/i.test(src)) { 138 image.setAttribute("alt", ""); 139 image.setAttribute("aria-hidden", "true"); 140 image.setAttribute("role", "presentation"); 141 return; 142 } 143 144 if (image.matches(".leaflet-tile")) { 145 image.setAttribute("alt", ""); 146 image.setAttribute("aria-hidden", "true"); 147 image.setAttribute("role", "presentation"); 148 return; 149 } 150 151 if ( 152 image.matches(".mt-lightbox-image, .mt-plan-image") && 153 !image.getAttribute("alt") 154 ) { 155 image.setAttribute("alt", pageImageLabel(image)); 156 return; 157 } 158 159 if (!image.hasAttribute("alt") && image.getAttribute("title")) { 160 image.setAttribute("alt", image.getAttribute("title").trim()); 161 } 162 } 163 164 function improveImageAccessibility(root) { 165 if (root && root.nodeType !== 1 && root.nodeType !== 9) { 166 return; 167 } 168 169 var scope = root || document; 170 171 if (root && root.nodeType === 1) { 172 improveSingleImage(root); 173 } 174 175 if (!scope.querySelectorAll) { 176 return; 177 } 178 179 scope.querySelectorAll("img").forEach(improveSingleImage); 180 } 181 182 // 2026-10-01: all news categories and articles use Mariam's WhatsApp. 183 function isNewsPage() { 184 return !!document.querySelector('.mt-article-title, .mt-news-main'); 185 } 186 187 function normalizeNewsContacts(root) { 188 if (!isNewsPage() || !root || (root.nodeType !== 1 && root.nodeType !== 9)) return; 189 var links = []; 190 if (root.matches && root.matches('a[href]')) links.push(root); 191 root.querySelectorAll('a[href]').forEach(function (a) { links.push(a); }); 192 links.forEach(function (a) { 193 if (a.matches('.js-share-whatsapp, [data-share], [data-mir-share]')) return; 194 var url;
195 try { url = new URL(a.getAttribute('href'), location.href); } catch (e) { return; } 196 var host = url.hostname.toLowerCase(); 197 var isShort = host === 'wa.me' && /^\/(?:\d+|undefined|null)\/?$/.test(url.pathname); 198 var isSend = /^(?:api|web|www)\.whatsapp\.com$/.test(host) && url.pathname === '/send' && url.searchParams.has('phone'); 199 if (!isShort && !isSend) return; 200 if (isShort) url.pathname = '/37495040785'; 201 else url.searchParams.set('phone', '37495040785'); 202 if (a.href !== url.href) a.href = url.href; 203 if (a.getAttribute('data-wa-number') !== '37495040785') a.setAttribute('data-wa-number', '37495040785'); 204 var walker = document.createTreeWalker(a, NodeFilter.SHOW_TEXT); 205 var node; 206 while ((node = walker.nextNode())) { 207 var text = node.nodeValue.replace(/\+?66[\s()-]*64[\s()-]*062[\s()-]*00[\s()-]*56|\+?66[\s()-]*83[\s()-]*528[\s()-]*47[\s()-]*09/g, '+374 95 040 785'); 208 if (text !== node.nodeValue) node.nodeValue = text; 209 } 210 ['aria-label', 'title'].forEach(function (attr) { 211 var value = a.getAttribute(attr); 212 if (!value) return; 213 var updated = value.replace(/\+?66[\s()-]*64[\s()-]*062[\s()-]*00[\s()-]*56|\+?66[\s()-]*83[\s()-]*528[\s()-]*47[\s()-]*09/g, '+374 95 040 785'); 214 if (updated !== value) a.setAttribute(attr, updated); 215 }); 216 }); 217 // Keep one direct WhatsApp contact in each footer; channel links are untouched. 218 document.querySelectorAll('footer, .mt-footer').forEach(function (footer) { 219 var found = false; 220 footer.querySelectorAll('a[href="https://wa.me/37495040785"]').forEach(function (a) { 221 a.hidden = found; 222 if (!found && a.textContent !== 'WhatsApp: +374 95 040 785') a.textContent = 'WhatsApp: +374 95 040 785'; 223 found = true; 224 }); 225 }); 226 } 227 228 function normalizeNewsContactSchema() { 229 if (!isNewsPage()) return; 230 document.querySelectorAll('script[type="application/ld+json"]').forEach(function (script) { 231 var data;
232 try { data = JSON.parse(script.textContent); } catch (e) { return; } 233 function visit(value) { 234 if (!value || typeof value !== 'object') return; 235 if (value['@type'] === 'ContactPoint' && /^https:\/\/wa\.me\/\d+/.test(value.url || '')) { 236 value.url = 'https://wa.me/37495040785'; 237 value.telephone = '+37495040785'; 238 value.contactType = 'customer service'; 239 } 240 Object.keys(value).forEach(function (key) { visit(value[key]); }); 241 if (Array.isArray(value.contactPoint)) { 242 value.contactPoint = value.contactPoint.filter(function (point, index, all) { 243 return all.findIndex(function (other) { return JSON.stringify(other) === JSON.stringify(point); }) === index; 244 }); 245 } 246 } 247 visit(data); 248 var updated = JSON.stringify(data); 249 if (updated !== script.textContent) script.textContent = updated; 250 }); 251 } 252 253 function watchSystemImages() { 254 if (!window.MutationObserver || !document.documentElement || window.__mirMarkupObserver) { 255 return; 256 } 257 258 var observer = new MutationObserver(function (mutations) { 259 mutations.forEach(function (mutation) { 260 if (mutation.type === "attributes") { 261 improveImageAccessibility(mutation.target); 262 normalizeDefaultLanguageUrls(mutation.target); 263 normalizeNewsContacts(mutation.target); 264 return; 265 } 266 267 mutation.addedNodes.forEach(function (node) { 268 improveImageAccessibility(node); 269 normalizeDefaultLanguageUrls(node); 270 normalizeNewsContacts(node); 271 }); 272 }); 273 }); 274 275 observer.observe(document.documentElement, { 276 childList: true, 277 subtree: true, 278 attributes: true, 279 attributeFilter: ["href", "src", "content"] 280 }); 281 282 window.__mirMarkupObserver = observer; 283 } 284 285 function localizeCookieNotice() { 286 var message = document.querySelector("#cookiePolicy .bottom-info-block-content"); 287 var agree = document.getElementById("cookiePolicyAgree"); 288 289 if (!message || !agree) { 290 return; 291 } 292 293 var language = (document.documentElement.lang || "ru").toLowerCase().split("-")[0]; 294 var copy = { 295 ru: { 296 before: "ÐÑ Ð¸ÑполÑзÑем cookies, ÑÑÐ¾Ð±Ñ ÑÐ°Ð¹Ñ ÑабоÑал коÑÑекÑно. ÐÑÐ¾Ð´Ð¾Ð»Ð¶Ð°Ñ Ð¿Ð¾Ð»ÑзоваÑÑÑÑ ÑайÑом, Ð²Ñ ÑоглаÑаеÑеÑÑ Ñ ", 297 link: "полиÑикой cookies", 298 after: ".", 299 agree: "ÐÑинÑÑÑ" 300 }, 301 en: { 302 before: "We use cookies so the website works correctly. By continuing to use the website, you agree to the ", 303 link: "Cookie Policy", 304 after: ".", 305 agree: "Accept" 306 }, 307 th: { 308 before: "à¹à¸£à¸²à¹à¸à¹à¸à¸¸à¸à¸à¸µà¹à¹à¸à¸·à¹à¸à¹à¸«à¹à¹à¸§à¹à¸à¹à¸à¸à¹à¸à¸³à¸à¸²à¸à¹à¸à¹à¸à¸¢à¹à¸²à¸à¸à¸¹à¸à¸à¹à¸à¸ à¸à¸²à¸£à¹à¸à¹à¸à¸²à¸à¹à¸§à¹à¸à¹à¸à¸à¹à¸à¹à¸à¸«à¸¡à¸²à¸¢à¸à¸¶à¸à¸à¸¸à¸à¸¢à¸à¸¡à¸£à¸±à¸ ", 309 link: "à¸à¹à¸¢à¸à¸²à¸¢à¸à¸¸à¸à¸à¸µà¹", 310 after: "", 311 agree: "ยà¸à¸¡à¸£à¸±à¸" 312 } 313 }; 314 var selected = copy[language] || copy.ru; 315 var policyLink = message.querySelector("a") || document.createElement("a"); 316 317 policyLink.href = "/index/cookiepolicy"; 318 policyLink.target = "_blank"; 319 policyLink.rel = "noopener noreferrer"; 320 policyLink.textContent = selected.link; 321 message.textContent = selected.before; 322 message.appendChild(policyLink); 323 message.appendChild(document.createTextNode(selected.after)); 324 agree.textContent = selected.agree; 325 } 326 327 function removeInactivePlanViewer() { 328 var planViewer = document.getElementById("mt-plan-viewer"); 329 330 if (!planViewer) { 331 return; 332 } 333 334 var planElements = document.querySelectorAll( 335 ".mir-palm__plan, .js-plan-album" 336 ); 337 338 var hasExternalPlanContent = Array.prototype.some.call( 339 planElements, 340 function (element) { 341 return !planViewer.contains(element); 342 } 343 ); 344 345 if (!hasExternalPlanContent) { 346 planViewer.remove(); 347 } 348} 349 350 function watchLanguageControls() { 351 if (window.__mirLanguageControlsBound) { 352 return; 353 } 354 355 window.__mirLanguageControlsBound = true; 356 document.addEventListener("click", function (event) { 357 var control = event.target && event.target.closest 358 ? event.target.closest("[data-lang]") 359 : null; 360 361 if (!control) { 362 return; 363 } 364 365 window.setTimeout(function () { 366 normalizeCurrentDefaultLanguageUrl(); 367 normalizeDefaultLanguageUrls(document); 368 localizeCookieNotice(); 369 }, 75); 370 }); 371 } 372 373 function applySafetyFixes() { 374 normalizeCurrentDefaultLanguageUrl(); 375 normalizeDefaultLanguageUrls(document); 376 normalizeNewsContacts(document); 377 normalizeNewsContactSchema(); 378 improveCookieAccessibility(); 379 improveImageAccessibility(document); 380 watchSystemImages(); 381 watchLanguageControls(); 382 localizeCookieNotice(); 383 removeInactivePlanViewer(); 384 } 385 386 normalizeCurrentDefaultLanguageUrl(); 387 normalizeDefaultLanguageUrls(document); 388 389 if (document.readyState === "loading") { 390 document.addEventListener("DOMContentLoaded", applySafetyFixes); 391 } else { 392 applySafetyFixes(); 393 } 394 395 window.setTimeout(applySafetyFixes, 800); 396 window.setTimeout(applySafetyFixes, 2500); 397})(); 398 399/* MIR THAILAND â GA4 analytics, audited 2026-09-14 v4 */ 400(function () { 401 "use strict"; 402 403 if (window.__mirAnalyticsBound) return; 404 window.__mirAnalyticsBound = true; 405 406 var MEASUREMENT_ID = "G-8EWLDNMSKB"; 407 408 /* 409 * Analytics labels only â never send phone numbers or email addresses to GA4. 410 * Thai property contacts: +66 64 062 0056 = Edgar, +66 83 528 4709 = Ilya. 411 * Service WhatsApp: +374 95 040 785. 412 */ 413 var CONTACT_LABELS = { 414 "66640620056": "edgar_whatsapp", 415 "66835284709": "ilya_whatsapp", 416 "37495040785": "services_whatsapp" 417 }; 418 419 function initGoogleAnalytics() { 420 window.dataLayer = window.dataLayer || []; 421 window.gtag = window.gtag || function () { 422 window.dataLayer.push(arguments); 423 }; 424 425 if (!window.__mirGa4Configured) { 426 window.__mirGa4Configured = true; 427 window.gtag("js", new Date()); 428 window.gtag("config", MEASUREMENT_ID); 429 } 430 431 if (!document.querySelector('script[src*="googletagmanager.com/gtag/js?i
431d=' + MEASUREMENT_ID + '"]')) { 432 var script = document.createElement("script"); 433 script.async = true; 434 script.src = "https://www.googletagmanager.com/gtag/js?id=" + encodeURIComponent(MEASUREMENT_ID); 435 (document.head || document.documentElement).appendChild(script); 436 } 437 } 438 439 function sendEvent(name, params) { 440 if (typeof window.gtag !== "function") return; 441 window.gtag("event", name, params || {}); 442 } 443 444 function pagePath() { 445 return window.location.pathname + window.location.search; 446 } 447 448 function pageLanguage() { 449 return (document.documentElement.getAttribute("lang") || "ru").toLowerCase().split("-")[0]; 450 } 451 452 function safeUrl(value) { 453 try { 454 return new URL(value, window.location.href); 455 } catch (error) { 456 return null; 457 } 458 } 459 460 function hostMatches(hostname, domain) { 461 var host = (hostname || "").toLowerCase(); 462 return host === domain || host.endsWith("." + domain); 463 } 464 465 function digitsOnly(value) { 466 return String(value || "").replace(/\D/g, ""); 467 } 468 469 function whatsappNumber(target, url) { 470 var dataNumber = target && target.getAttribute 471 ? digitsOnly(target.getAttribute("data-wa-number")) 472 : ""; 473 474 if (dataNumber) return dataNumber; 475 if (!url) return ""; 476 477 var host = (url.hostname || "").toLowerCase(); 478 var pathParts; 479 var phone; 480 481 if (hostMatches(host, "wa.me")) { 482 pathParts = url.pathname.split("/").filter(Boolean); 483 return digitsOnly(pathParts[0] || ""); 484 } 485 486 if (hostMatches(host, "whatsapp.com")) { 487 phone = url.searchParams.get("phone") || ""; 488 return digitsOnly(phone); 489 } 490 491 return ""; 492 } 493 494 function phoneNumber(target) { 495 if (!target || !target.getAttribute) return ""; 496 return digitsOnly(target.getAttribute("href") || ""); 497 } 498 499 function contactTargetLabel(channel, target, url) { 500 var number; 501 var path = url ? (url.pathname || "").toLowerCase() : ""; 502 503 if (channel === "whatsapp" || channel === "phone") { 504 number = channel === "whatsapp" ? whatsappNumber(target, url) : phoneNumber(target); 505 return CONTACT_LABELS[number] || "other_contact"; 506 } 507 508 if (channel === "email") return "business_email"; 509 510 if (channel === "telegram") { 511 if (path.indexOf("/+") === 0) return "telegram_mirthailand"; 512 return "telegram_other"; 513 } 514 515 if (channel === "facebook") return "facebook_mirthailand"; 516 if (channel === "instagram") return "instagram_mirthailand"; 517 if (channel === "max") return "max_mirthailand"; 518 if (channel === "whatsapp_channel") return "whatsapp_channel_mirthailand"; 519 520 return "other"; 521 } 522 523 function cleanEnquiryId(value) {
524 var candidate = String(value || "").trim().toUpperCase(); 525 if (!candidate) return ""; 526 if (!/^[A-Z0-9_-]{3,100}$/.test(candidate)) return ""; 527 return candidate; 528 } 529 530 function idFromText(value) { 531 var text = String(value || "").toUpperCase(); 532 var match = text.match(/\b(?:SALE|RENT|VILLA|CONDO|PROPERTY|MANAGEMENT|VISA|LEGAL|CONSTRUCTION|SERVICES|MIR)-[A-Z0-9_-]+\b/); 533 return match ? cleanEnquiryId(match[0]) : ""; 534 } 535 536 function enquiryId(target, url) { 537 var value = ""; 538 var holder; 539 var message; 540 var meta; 541 var pageHolders; 542 var index; 543 544 if (target && target.getAttribute) { 545 value = cleanEnquiryId( 546 target.getAttribute("data-enquiry-id") || 547 target.getAttribute("data-property-id") || 548 target.getAttribute("data-reference") || 549 "" 550 ); 551 if (value) return value; 552 553 if (target.closest) { 554 holder = target.closest("[data-enquiry-id], [data-property-id], [data-reference]"); 555 if (holder) { 556 value = cleanEnquiryId( 557 holder.getAttribute("data-enquiry-id") || 558 holder.getAttribute("data-property-id") || 559 holder.getAttribute("data-reference") || 560 "" 561 ); 562 if (value) return value; 563 } 564 } 565 } 566 567 if (url && url.searchParams) { 568 message = url.searchParams.get("text") || ""; 569 value = idFromText(message); 570 if (value) return value; 571 } 572 573 meta = document.querySelector('meta[name="mir:enquiry-id"], meta[name="property-id"]'); 574 if (meta) { 575 value = cleanEnquiryId(meta.getAttribute("content")); 576 if (value) return value; 577 } 578 579 /* 580 * Only explicitly page-level identifiers are safe fallbacks. Never take the 581 * first card identifier from a catalogue or the homepage: that would attach 582 * unrelated form and social clicks to the first property shown on the page. 583 */ 584 pageHolders = [ 585 document.documentElement, 586 document.body, 587 document.querySelector("main") 588 ]; 589 590 for (index = 0; index < pageHolders.length; index += 1) { 591 holder = pageHolders[index]; 592 if (!holder || !holder.getAttribute) continue; 593 594 value = cleanEnquiryId( 595 holder.getAttribute("data-enquiry-id") || 596 holder.getAttribute("data-property-id") || 597 holder.getAttribute("data-reference") || 598 "" 599 ); 600 if (value) return value; 601 } 602 603 return ""; 604 } 605 606 function contactRole(channel, targetLabel, enquiry, target) { 607 var explicit = target && target.getAttribute 608 ? String(target.getAttribute("data-contact-role") || "").toLowerCase() 609 : ""; 610 var path = window.location.pathname.toLowerCase(); 611 var allowed = ["sale", "rent", "property", "services", "general"]; 612 613 if (allowed.indexOf(explicit) !== -1) return explicit; 614 if (targetLabel === "services_whatsapp") return "services"; 615 616 if (/^RENT[-_]/.test(enquiry)) return "rent"; 617 if (/^SALE[-_]/.test(enquiry)) return "sale"; 618 if (/^(?:VISA|LEGAL|CONSTRUCTION|MANAGEMENT|SERVICES)[-_]/.test(enquiry)) return "services"; 619 620 if (path.indexOf("for-rent") !== -1 || /(?:^|\/)rent(?:-|\/|$)/.test(path)) return "rent"; 621 if (path.indexOf("for-sale") !== -1 || /(?:^|\/)sale(?:-|\/|$)/.test(path)) return "sale"; 622 623 if (targetLabel === "edgar_whatsapp" || targetLabel === "ilya_whatsapp") return "property"; 624 if (channel === "email") return "general"; 625 626 return "general"; 627 } 628 629 function formContactRole(context, enquiry, target) { 630 var value = String(context || "").toLowerCase(); 631 632 if ( 633 /пÑодаÑÑ|ÑдаÑÑ Ð¾Ð±ÑекÑ|ÑазмеÑÑиÑÑ Ð¾Ð±ÑекÑ|sell|list(?:ing)? property|submit property|à¸à¸²à¸¢à¸«à¸£à¸·à¸à¸à¸¥à¹à¸à¸¢à¹à¸à¹à¸²/.test(value) 634 ) { 635 return "property"; 636 } 637 638 if (/аÑенд|\brent\b|à¹à¸à¹à¸²/.test(value)) return "rent"; 639 if (/кÑпиÑÑ|покÑп|\bbuy\b|purchase|\bsale\b|à¸à¸·à¹à¸/.test(value)) return "sale"; 640 641 if ( 642 /обÑлÑж|ÑпÑавлен|ÑемонÑ|ÑÑÑоиÑ|виз|ÑÑид|бизнеÑ|service|management|maintenance|construction|renovation|visa|legal|business|à¸à¸£à¸´à¸à¸²à¸£|à¸à¸¹à¹à¸¥|à¸à¹à¸à¸ªà¸£à¹à¸²à¸|วีà¸à¹à¸²|à¸à¸à¸«à¸¡à¸²à¸¢|à¸à¸¸à¸£à¸à¸´à¸/.test(value) 643 ) { 644 return "services"; 645 } 646 647 return contactRole("form", "", enquiry, target); 648 } 649
650 function contactEventParams(channel, target, url) { 651 var targetLabel = contactTargetLabel(channel, target, url); 652 var enquiry = enquiryId(target, url); 653 var params = { 654 page_path: pagePath(), 655 page_language: pageLanguage(), 656 contact_channel: channel, 657 contact_target: targetLabel, 658 contact_role: contactRole(channel, targetLabel, enquiry, target), 659 transport_type: "beacon" 660 }; 661 662 if (enquiry) { 663 params.enquiry_id = enquiry; 664 if (/^(?:SALE|RENT|VILLA|CONDO)[-_]/.test(enquiry)) { 665 params.property_id = enquiry; 666 } 667 } 668 669 return params; 670 } 671 672 function formAnalyticsContext(target) { 673 var enquiry = enquiryId(target, null); 674 var context = target && target.getAttribute 675 ? String(target.getAttribute("data-context") || "general_enquiry").trim() 676 : "general_enquiry"; 677 var params = { 678 page_path: pagePath(), 679 page_language: pageLanguage(), 680 form_context: context || "general_enquiry", 681 form_name: "MIR THAILAND enquiry", 682 contact_role: formContactRole(context, enquiry, target), 683 transport_type: "beacon" 684 }; 685 686 if (enquiry) { 687 params.enquiry_id = enquiry; 688 if (/^(?:SALE|RENT|VILLA|CONDO)[-_]/.test(enquiry)) { 689 params.property_id = enquiry; 690 } 691 } 692 693 return params; 694 } 695 696 function rememberedFormContext() { 697 var saved = window.__mirPendingFormAnalytics; 698 var params = { 699 page_path: pagePath(), 700 page_language: pageLanguage(), 701 form_name: "MIR THAILAND enquiry", 702 transport_type: "beacon" 703 }; 704 705 if (!saved || typeof saved !== "object") return params; 706 707 ["form_context", "contact_role", "enquiry_id", "property_id"].forEach(function (key) { 708 if (saved[key]) params[key] = saved[key]; 709 }); 710 711 return params; 712 } 713 714 function fileNameFromUrl(href) { 715 try { 716 var url = new URL(href, window.location.href); 717 return decodeURIComponent(url.pathname.split("/").pop() || "document.pdf"); 718 } catch (error) { 719 return "document.pdf"; 720 } 721 } 722 723 function trackClicks(event) { 724 var target = event.target && event.target.closest ? event.target.closest("a,button") : null; 725 if (!target) return; 726 727 if ( 728 target.matches(".open-form, .js-open-form, .mobile-request") || 729 target.getAttribute("aria-controls") === "requestModal" || 730 target.getAttribute("aria-controls") === "mt-request-modal" 731 ) { 732 var openFormParams = formAnalyticsContext(target); 733 window.__mirPendingFormAnalytics = openFormParams; 734 sendEvent("open_form", openFormParams); 735 } 736 737 if (target.tagName !== "A") return; 738 739 var rawHref = target.getAttribute("href") || target.href || ""; 740 var hrefLower = rawHref.toLowerCase(); 741 var url = safeUrl(rawHref); 742 var host = url ? (url.hostname || "").toLowerCase() : ""; 743 var path = url ? (url.pathname || "").toLowerCase() : ""; 744 745 var isWhatsAppChannel = hostMatches(host, "whatsapp.com") && path.indexOf("/channel/") === 0; 746 var isWhatsAppDirect = 747 hostMatches(host, "wa.me") || 748 (hostMatches(host, "whatsapp.com") && !isWhatsAppChannel && (path.indexOf("/send") === 0 || url.searchParams.has("phone"))) || 749 (!!target.getAttribute("data-wa-number") && !isWhatsAppChannel); 750 var isTelegram = hostMatches(host, "t.me") || hostMatches(host, "telegram.me"); 751 var isFacebook = hostMatches(host, "facebook.com") || hostMatches(host, "fb.com"); 752 var isInstagram = hostMatches(host, "instagram.com"); 753 var isMax = hostMatches(host, "max.ru"); 754 var isShareLink = target.matches( 755 ".js-share-whatsapp, .js-share-telegram, [data-share], [data-mir-share]" 756 ); 757 758 if (isShareLink && (isWhatsAppDirect || isTelegram)) { 759 sendEvent("share", { 760 method: isWhatsAppDirect ? "whatsapp" : "telegram", 761 content_type: "page", 762 page_path: pagePath(), 763 page_language: pageLanguage(), 764 transport_type: "beacon" 765 }); 766 return; 767 } 768 769 if (isWhatsAppChannel) { 770 sendEvent("click_whatsapp_channel", contactEventParams("whatsapp_channel", target, url)); 771 return; 772 } 773 774 if (isWhatsAppDirect) {
775 sendEvent("click_whatsapp", contactEventParams("whatsapp", target, url)); 776 return; 777 } 778 779 if (isTelegram) { 780 sendEvent("click_telegram", contactEventParams("telegram", target, url)); 781 return; 782 } 783 784 if (isFacebook) { 785 sendEvent("click_facebook", contactEventParams("facebook", target, url)); 786 return; 787 } 788 789 if (isInstagram) { 790 sendEvent("click_instagram", contactEventParams("instagram", target, url)); 791 return; 792 } 793 794 if (isMax) { 795 sendEvent("click_max", contactEventParams("max", target, url)); 796 return; 797 } 798 799 if (hrefLower.indexOf("tel:") === 0) { 800 sendEvent("click_phone", contactEventParams("phone", target, url)); 801 return; 802 } 803 804 if (hrefLower.indexOf("mailto:") === 0) { 805 sendEvent("click_email", contactEventParams("email", target, url)); 806 return; 807 } 808 809 if (/\.pdf(?:$|[?#])/i.test(rawHref)) { 810 sendEvent("download_pdf", { 811 page_path: pagePath(), 812 page_language: pageLanguage(), 813 transport_type: "beacon", 814 file_name: fileNameFromUrl(rawHref) 815 }); 816 } 817 } 818 819 function findFormWrapper(form) { 820 if (!form || !form.closest) return null; 821 return form.closest(".ucoz-mail-form, .mt-form-box, .mt-mail-form"); 822 } 823 824 function trackFormSubmit(event) { 825 var form = event.target; 826 if (!form || form.tagName !== "FORM") return; 827 828 var wrapper = findFormWrapper(form); 829 if (!wrapper) return; 830 831 wrapper.removeAttribute("data-mir-form-success"); 832 wrapper.setAttribute("data-mir-form-pending", "1"); 833 sendEvent("form_submit_attempt", rememberedFormContext()); 834 } 835 836 function isSuccessText(text) { 837 var value = (text || "").toLowerCase().replace(/\s+/g, " "); 838 return [ 839 "ÑÑпеÑно оÑпÑав", 840 "ÑообÑение оÑпÑавлено", 841 "заÑвка оÑпÑавлена", 842 "ÑпаÑибо за обÑаÑение", 843 "successfully sent", 844 "message has been sent", 845 "message sent", 846 "thank you for your message", 847 "สà¹à¸à¸à¹à¸à¸à¸§à¸²à¸¡à¸ªà¸³à¹à¸£à¹à¸", 848 "สà¹à¸à¹à¸£à¸µà¸¢à¸à¸£à¹à¸à¸¢" 849 ].some(function (phrase) { 850 return value.indexOf(phrase) !== -1; 851 }); 852 } 853 854 function watchSuccessfulForms() { 855 if (!window.MutationObserver || !document.body || window.__mirFormSuccessObserver) return; 856 857 var observer = new MutationObserver(function (mutations) { 858 mutations.forEach(function (mutation) { 859 var node = mutation.target && mutation.target.nodeType === 1 860 ? mutation.target 861 : mutation.target && mutation.target.parentElement; 862 if (!node || !node.closest) return; 863 864 var wrapper = node.closest(".ucoz-mail-form, .mt-form-box, .mt-mail-form"); 865 var successSource = wrapper; 866 if (!wrapper) { 867 var candidates = []; 868 var ownPopup = node.closest('.myWinCont'); 869 if (ownPopup) candidates.push(ownPopup); 870 Array.prototype.forEach.call(mutation.addedNodes || [], function (added) { 871 if (added.nodeType !== 1) return; 872 if (added.matches('.myWinCont')) candidates.push(added); 873 Array.prototype.push.apply(candidates, added.querySelectorAll('.myWinCont')); 874 }); 875 successSource = candidates.find(function (popup) { return isSuccessText(popup.textContent); }); 876 if (successSource) wrapper = document.querySelector('[data-mir-form-pending="1"]'); 877 } 878 if (!wrapper || wrapper.getAttribute("data-mir-form-pending") !== "1") return; 879 if (wrapper.getAttribute("data-mir-form-success") === "1") return; 880 881 if (successSource && isSuccessText(successSource.textContent)) { 882 wrapper.setAttribute("data-mir-form-success", "1"); 883 wrapper.removeAttribute("data-mir-form-pending"); 884 var successParams = rememberedFormContext(); 885 sendEvent("form_submit_success", successParams); 886 887 var leadParams = {}; 888 Object.keys(successParams).forEach(function (key) { 889 leadParams[key] = successParams[key]; 890 }); 891 leadParams.lead_source = "website_form"; 892 leadParams.lead_status = "confirmed_submission"; 893 sendEvent("generate_lead", leadParams); 894 895 window.__mirPendingFormAnalytics = null; 896 } 897 }); 898 }); 899 900 observer.observe(document.body, { 901 childList: true, 902 subtree: true, 903 characterData: true 904 }); 905 window.__mirFormSuccessObserver = observer; 906 } 907 908 initGoogleAnalytics(); 909 910 if (document.readyState === "loading") { 911 document.addEventListener("DOMContentLoaded", function () { 912 watchSuccessfulForms(); 913 }); 914 } else { 915 watchSuccessfulForms(); 916 } 917 918 document.addEventListener("click", trackClicks, true); 919 document.addEventListener("submit", trackFormSubmit, true); 920})(); 921 922/* Enquiry context and dialog keyboard support â 2026-09-23. */ 923(function(){'use strict';var lastTrigger=null;var prefix='';function applyContext(button){var modal=document.getElementById('mt-request-modal');if(!modal)return;if(!modal.classList.contains('is-open')){modal.classList.add('is-open');document.body.classList.remove('menu-open');document.body.style.overflow='hidden';var menu=document.querySelector('.mt-menu-button');var panel=document.querySelector('.mt-mobile-menu');if(menu)menu.setAttribute('aria-expanded','false');if(panel)panel.setAttribute('aria-hidden','true');}var form=modal.querySelector('form');if(!form)return;var message=form.querySelector('[name="f2"]');if(message&&message.tagName==='INPUT'&&message.type==='text'){var multiline=
923document.createElement('textarea');Array.prototype.forEach.call(message.attributes,function(attr){if(attr.name!=='type'&&attr.name!=='value')multiline.setAttribute(attr.name,attr.value);});multiline.value=message.value;multiline.rows=4;multiline.style.width='100%';multiline.style.minHeight='96px';multiline.style.setProperty('color','#17312c','important');multiline.style.setProperty('background','#ffffff','important');multiline.style.setProperty('border','1px solid #d4ddd8','important');message.replaceWith(multiline);message=multiline;}var select=form.querySelector('select[name="f3"]');var context=button.getAttribute('data-context')||document.title;var card=button.closest('.mt-news-card');var link=card&&card.querySelector('.mt-news-card-title a');var page=link?link.href:location.href;var role=button.getAttribute('data-contact-role')||'general';if(message){var userText=message.value;if(prefix&&userText.indexOf(prefix)===0)userText=userText.slice(prefix.length);prefix=context+' | '+page+' â ';message.value=prefix+userText;}if(select){var serviceContext=context+' '+(button.getAttribute('data-enquiry-id')||'');var choices={sale:'ÐÑпиÑÑ Ð½ÐµÐ´Ð²Ð¸Ð¶Ð¸Ð¼Ð¾ÑÑÑ',rent:'ÐÑендоваÑÑ Ð½ÐµÐ´Ð²Ð¸Ð¶Ð¸Ð¼Ð¾ÑÑÑ',services:/ÑÑ Ñ|yacht/i.test(serviceContext)?'ÐÑÑгое':/виз|visa/i.test(serviceContext)?'ÐизÑ':/бизнеÑ|пÑав|legal/i.test(serviceContext)?'ÐÐ¸Ð·Ð½ÐµÑ Ð¸ пÑаво':/ÑÑÑоиÑ|ÑемонÑ|construction/i.test(serviceContext)?'Ð ÐµÐ¼Ð¾Ð½Ñ Ð¸ ÑÑÑоиÑелÑÑÑво':'ÐбÑлÑживание'};var choice=choices[role];if(choice)Array.prototype.some.call(select.options,function(option){if(option.value===choice){select.value=choice;return true;}return false;});}lastTrigger=button;var input=form.querySelector('input:not([type="hidden"]):not([type="checkbox"]):not([type="submit"]),textarea');if(input)input.focus();}document.addEventListener('click',function(event){var button=event.target.closest&&event.target.closest('.js-open-form');if(button)applyContext(button);if(event.target.closest&&event.target.closest('.mt-modal-close')&&lastTrigger)lastTrigger.focus();});document.addEventListener('keydown',function(event){var modal=document.getElementById('mt-request-modal');if(!modal||!modal.classList.contains('is-open'))return;if(event.key==='Tab'){var nodes=Array.prototype.filter.call(modal.querySelectorAll('a[href],button,input,select,textarea,[tabindex="0"]'),function(e){return !e.disabled&&e.type!=='hidden'&&e.getClientRects().length;});if(!nodes.length)return;var first=nodes[0],last=nodes[nodes.length-1];if(event.shiftKey&&document.activeElement===first){event.preventDefault();last.focus();}else if(!event.shiftKey&&document.activeElement===last){event.preventDefault();first.focus();}}},true);document.addEventListener('keydown',function(event){if(event.key==='Escape'&&lastTrigger)lastTrigger.focus();});})(); 924 925/* Full multilingual editorial content and category labels. */ 926(function(){'use strict';function init(){var lang=(location.search.match(/[?&]lang=(ru|en|th)(?:&|$)/i)||[])[1]||'ru';var labels={'/thailand-property-management':{ru:'ÐбÑлÑживание недвижимоÑÑи',en:'Property management',th:'à¸à¸£à¸´à¸à¸²à¸£à¸à¸¹à¹à¸¥à¸à¸ªà¸±à¸à¸«à¸²à¸£à¸´à¸¡à¸à¸£à¸±à¸à¸¢à¹'},'/phuket-construction-renovation':{ru:'Ð ÐµÐ¼Ð¾Ð½Ñ Ð¸ ÑÑÑоиÑелÑÑÑво',en:'Renovation and construction',th:'รีà¹à¸à¹à¸§à¸à¹à¸¥à¸°à¸à¹à¸à¸ªà¸£à¹à¸²à¸'},'/thailand-visas-relocation':{ru:'ÐÐ¸Ð·Ñ Ð¸ пеÑеезд',en:'Visas and relocation',th:'วีà¸à¹à¸²à¹à¸¥à¸°à¸à¸²à¸£à¸¢à¹à¸²à¸¢à¸à¸´à¹à¸à¸à¸²à¸'},'/thailand-business-legal-services':{ru:'ÐÐ¸Ð·Ð½ÐµÑ Ð¸ пÑаво',en:'Business and legal',th:'à¸à¸¸à¸£à¸à¸´à¸à¹à¸¥à¸°à¸à¸à¸«à¸¡à¸²à¸¢'},'/phuket-thailand-news':{ru:'ÐовоÑÑи Таиланда и ÐÑ ÑкеÑа',en:'Phuket and Thailand news',th:'à¸à¹à¸²à¸§à¸ ูà¹à¸à¹à¸à¹à¸¥à¸°à¸à¸£à¸°à¹à¸à¸¨à¹à¸à¸¢'}};document.querySelectorAll('.mt-category-label a,.mt-news-card-category').forEach(function(a){var label=labels[new URL(a.href,location.origin).pathname.replace(/\/$/,'')];if(label)a.textContent=label[lang];});var ui={ru:{services:'ÑÑлÑги',name:'ÐмÑ',phone:'ТелеÑон / WhatsApp / Telegram',service:'УÑлÑга',message:'СообÑение',consent:'СоглаÑие',code:'Ðод Ñ ÐºÐ°ÑÑинки'},en:{services:'services',name:'Name',phone:'Phone / WhatsApp / Telegram',service:'Service',message:'Message',consent:'Consent',code:'Security code'},th:{services:'à¸à¸£à¸´à¸à¸²à¸£',name:'à¸à¸·à¹à¸',phone:'à¹à¸à¸£à¸¨à¸±à¸à¸à¹ / WhatsApp / Telegram',service:'à¸à¸£à¸´à¸à¸²à¸£',message:'à¸à¹à¸à¸à¸§à¸²à¸¡',consent:'à¸à¸§à¸²à¸¡à¸¢à¸´à¸à¸¢à¸à¸¡',code:'รหัสยืà¸à¸¢à¸±à¸'}}[lang];document.querySelectorAll('footer a[href="https://wa.me/37495040785"],.mt-footer a[href="https://wa.me/37495040785"]').forEach(function(a){a.textContent='WhatsApp: +374 95 040 785 · '+ui.services;});document.querySelectorAll('#mt-request-modal tr').forEach(function(row){var cell=row.querySelector('td');if(!cell)return;var text=cell.textContent;var key=/ÐмÑ|Name|à¸à¸·à¹à¸/.test(text)?'name':/ТелеÑон|Phone|à¹à¸à¸£à¸¨à¸±à¸à¸à¹/.test(text)?'phone':/УÑлÑга|Service|à¸à¸£à¸´à¸à¸²à¸£/.test(text)?'service':/СообÑение|Message|à¸à¹à¸à¸à¸§à¸²à¸¡/.test(text)?'message':/СоглаÑие|Consent|à¸à¸§à¸²à¸¡à¸¢à¸´à¸à¸¢à¸à¸¡/.test(text)?'consent':/Security code|Ðод Ñ ÐºÐ°ÑÑинки|รหัสยืà¸à¸¢à¸±à¸/.test(text)?'code':null;if(key)cell.textContent=ui[key]+(text.indexOf('*')>=0?' *:':':');});document.querySelectorAll('#mt-request-modal a[href^="/index/policy"]').forEach(function(a){a.href='/index/policy'+(lang==='ru'?'':'?lang='+lang);});var blocks=document.querySelectorAll('.mt-multilang-article .mt-editorial-language');if(!blocks.length)return;var selected;blocks.forEach(function(b){b.hidden=b.lang!==lang;if(!b.hidden)selected=b;});if(!selected)return;var title=(selected.getAttribute('data-title')||'').trim(),description=(selected.getAttribute('data-description')||'').trim();var h1=document.querySelector('h1');var fallbackTitle=(h1&&h1.textContent?h1.textContent.trim():'')||(document.title||'').replace(/\s*\|\s*MIR THAILAND\s*$/i,'').trim();
926var descriptionMetaExisting=document.querySelector('meta[name="description"]');var fallbackDescription=descriptionMetaExisting?(descriptionMetaExisting.getAttribute('content')||'').trim():'';if(!title)title=fallbackTitle;if(!description)description=fallbackDescription;if(h1&&title)h1.textContent=title;if(title)document.title=title+' | MIR THAILAND';document.querySelectorAll('.js-share-whatsapp').forEach(function(a){a.href='https://wa.me/?text='+encodeURIComponent(title+' '+location.href);});document.querySelectorAll('.js-share-telegram').forEach(function(a){a.href='https://t.me/share/url?url='+encodeURIComponent(location.href)+'&text='+encodeURIComponent(title);});document.querySelectorAll('meta[name="description"],meta[property="og:description"],meta[name="twitter:description"]').forEach(function(e){e.content=description;});document.querySelectorAll('meta[property="og:title"],meta[name="twitter:title"]').forEach(function(e){e.content=title;});document.querySelectorAll('.js-open-form').forEach(function(e){e.setAttribute('data-context',title);var role=e.getAttribute('data-contact-role');if(role!=='sale'&&role!=='rent'){var article=selected.closest('.mt-multilang-article');e.setAttribute('data-contact-role',article.getAttribute('data-contact-role')||'services');}});document.querySelectorAll('[data-contact-role="services"][href*="wa.me/"]').forEach(function(a){a.href='https://wa.me/37495040785?text='+encodeURIComponent(title+'\n'+location.href);});document.querySelectorAll('script[type="application/ld+json"]').forEach(function(s){try{var data=JSON.parse(s.textContent);var graph=data['@graph']||[data];graph.forEach(function(x){if(['WebPage','Article','NewsArticle'].includes(x['@type'])){x.name=title;if(x.headline)x.headline=title;x.description=description;x.inLanguage=lang;}});s.textContent=JSON.stringify(data);}catch(e){}});}if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init);else init();})();
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.