1/* 2 * Unsupported Browser Fallback 3 * Authored in pure ES3. DO NOT introduce ES2015+ syntax. 4 */ 5(function () { 6 var APPLICATION_DOMAIN_TO_ID = { 7 "spicychat.ai": "spicychat", 8 "pixelchat.ai": "pixelchat", 9 "secretmate.ai": "secretmate", 10 "roleplay.adulttime.com": "adulttime_application", 11 "roleplay.evilangel.com": "evil_angel", 12 "roleplay.asgmax.com": "asg_max", 13 }; 14 15 var APPLICATION_ID_TO_LOGO_FILE = { 16 spicychat: "spicychat.png", 17 pixelchat: "pixelchat.png", 18 secretmate: "secretmate.png", 19 adulttime_application: "adulttime.png", 20 evil_angel: "evilangel.png", 21 asg_max: "asgmax.png", 22 }; 23 24 var LEGACY_BROWSERS_FALLBACK_GA_ID = "G-HNDD06M469"; 25 var LOGO_BASE_PATH = "/Assets/logos/"; 26 var DEFAULT_APPLICATION_ID = "spicychat"; 27 28 function getApplicationId() { 29 var hostname = window.location.hostname; 30 for (var domain in APPLICATION_DOMAIN_TO_ID) { 31 if (APPLICATION_DOMAIN_TO_ID.hasOwnProperty(domain) && hostname.indexOf(domain) !== -1) { 32 return APPLICATION_DOMAIN_TO_ID[domain]; 33 } 34 } 35 return DEFAULT_APPLICATION_ID; 36 } 37 38 function getLogoUrl() { 39 var applicationId = getApplicationId(); 40 var logoFile = APPLICATION_ID_TO_LOGO_FILE[applicationId] || APPLICATION_ID_TO_LOGO_FILE[DEFAULT_APPLICATION_ID]; 41 return LOGO_BASE_PATH + logoFile; 42 } 43 44 function supportsRegexUnicodePropertyEscapes() { 45 try { 46 new RegExp("\\p{Letter}", "u"); 47 return true; 48 } catch (regexError) { 49 return false; 50 } 51 } 52 53 // For Safari <=13.1 54 function supportsMatchMediaAddEventListener() { 55 if (typeof window.matchMedia !== "function") return false; 56 try { 57 var mediaQuery = window.matchMedia("(min-width: 0px)"); 58 return mediaQuery && typeof mediaQuery.addEventListener === "function"; 59 } catch (matchMediaError) { 60 return false; 61 } 62 } 63 64 // For Chrome <=79, Opera <=66 â required by modernTargets "since 2021" bundle 65 function supportsOptionalChaining() { 66 try { 67 Function("return null?.x")(); 68 return true; 69 } catch (syntaxError) { 70 return false; 71 } 72 } 73 74 function isBrowserSupported() { 75 return ( 76 typeof Promise !== "undefined" && 77 typeof Promise.allSettled === "function" && 78 typeof Symbol !== "undefined" && 79 typeof Object.assign === "function" && 80 typeof window.fetch === "function" && 81 typeof window.Proxy !== "undefined" && 82 typeof globalThis !== "undefined" && 83 supportsRegexUnicodePropertyEscapes() && 84 supportsMatchMediaAddEventListener() && 85 supportsOptionalChaining() 86 ); 87 } 88 89 function injectFallbackGoogleAnalytics() { 90 var head = document.getElementsByTagName("head")[0]; 91 if (!head) return; 92 var gtagScript = document.createElement("script"); 93 gtagScript.async = true; 94 gtagScript.src = "https://www.googletagmanager.com/gtag/js?id=" + LEGACY_BROWSERS_FALLBACK_GA_ID; 95 head.appendChild(gtagScript); 96 window.dataLayer = window.dataLayer || []; 97 window.gtag = 98 window.gtag || 99 function () { 100 window.dataLayer.push(arguments); 101 }; 102 window.gtag("js", new Date()); 103 window.gtag("config", LEGACY_BROWSERS_FALLBACK_GA_ID); 104 } 105 106 function buildBannerHtml() { 107 var logoUrl = getLogoUrl(); 108 return ( 109 '<div style="height:100vh;background:#000;display:flex;align-items:center;justify-content:center;color:#fff;padding:16px;">' + 110 '<div style="background:#1a1a1a;border-radius:12px;padding:24px;max-width:400px;width:100%;font-family:Arial,sans-serif;">' + 111 '<img src="' + 112 logoUrl + 113 '" alt="" height="28" style="margin-bottom:18px;" onerror="this.style.display=\'none\'" />' + 114 '<h2 style="margin-bottom:18px;">Unable to load the app</h2>' + 115 '<p style="color:#9a9a9a;line-height:1.5;">Your current browser, device or app version is not supported. Please update the app or switch to a supported device/browser.</p>' + 116 "</div>" + 117 "</div>" 118 ); 119 } 120 121 function renderBannerWhenReady() { 122 function renderBanner() { 123 var rootElement = document.getElementById("root"); 124 if (rootElement) { 125 rootElement.innerHTML = buildBannerHtml(); 126 } else if (document.body) { 127 document.body.innerHTML = buildBannerHtml(); 128 } 129 } 130 if (document.readyState === "interactive" || document.readyState === "complete") { 131 renderBanner(); 132 return; 133 } 134 if (document.addEventListener) { 135 document.addEventListener("DOMContentLoaded", renderBanner); 136 } else { 137 document.attachEvent("onreadystatechange", function () { 138 if (document.readyState === "complete") renderBanner(); 139 }); 140 } 141 } 142 143 function triggerUnsupportedBrowserFallback() { 144 if (window.__UNSUPPORTED_BROWSER__) return; 145 window.__UNSUPPORTED_BROWSER__ = true; 146 injectFallbackGoogleAnalytics(); 147 renderBannerWhenReady(); 148 } 149 150 if (!isBrowserSupported()) { 151 triggerUnsupportedBrowserFallback(); 152 } 153})();
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.