1(function () { 2 // Default configuration 3 const DefaultProductConfig = { 4 windows: { 5 icon: resolvePath("images/head/white_win_normal.png"), 6 downloadLink: "#", 7 buyLink: "#", 8 discount: 0 9 }, 10 mac: { 11 icon: resolvePath("images/head/white_mac_normal.png"), 12 downloadLink: "#", 13 buyLink: "#", 14 discount: 0 15 }, 16 android: { 17 icon: resolvePath("images/head/white_android_normal.png"), 18 downloadLink: "#", 19 buyLink: "#", 20 discount: 0 21 }, 22 ios: { 23 icon: resolvePath("images/head/white_ios_normal.png"), 24 downloadLink: "#", 25 buyLink: "#", 26 discount: 0 27 } 28 }; 29 const I18N = { 30 en: { 31 free_download: 'Free Download', 32 buy_now: 'Buy Now' 33 }, 34 pt: { 35 free_download: 'Baixar Grátis', 36 buy_now: 'Comprar' 37 }, 38 de: { 39 free_download: 'Kostenlos Laden', 40 buy_now: 'Kaufen' 41 }, 42 fr: { 43 free_download: 'Télécharger', 44 buy_now: 'Acheter' 45 }, 46 jp: { 47 free_download: 'ç¡æãã¦ã³ãã¼ã', 48 buy_now: 'ä»ããè³¼å ¥' 49 }, 50 es: { 51 free_download: 'Descarga Gratuita', 52 buy_now: 'Comprar ahora' 53 }, 54 it: { 55 free_download: 'Download gratuito', 56 buy_now: 'Acquista ora' 57 } 58 }; 59 60 function resolvePath(path) { 61 const currentJsUrl = document.currentScript.src; 62 const currentJsDir = currentJsUrl.substring(0, currentJsUrl.lastIndexOf('/') + 1); 63 const isLocal = location.hostname === "localhost" || 64 location.hostname === "127.0.0.1" || 65 location.protocol === "file:"; 66 return isLocal ? currentJsDir + "../" + path : "/" + path; 67 } 68 69 // Merge page configuration with default configuration 70 function getMergedConfig() { 71 const pageConfig = window.ProductConfig || {}; 72 const merged = {}; 73 Object.keys(DefaultProductConfig).forEach(platform => { 74 merged[platform] = Object.assign( 75 {}, 76 DefaultProductConfig[platform], 77 pageConfig[platform] || {} 78 ); 79 }); 80 return merged; 81 } 82 83 // Auto detect platform from user agent 84 function detectPlatform() { 85 const defaultPlatform = document.body.dataset.defaultPlatform; 86 const ua = navigator.userAgent.toLowerCase(); 87 const platform = navigator.platform.toLowerCase(); 88 if (defaultPlatform === 'android') { //only android,ios 89 const isIOS = /iphone|ipod|ipad/i.test(ua) 90 || (platform === "macintel" && navigator.maxTouchPoints > 1); 91 if (isIOS) return "ios"; 92 return "android"; 93 } else if (defaultPlatform === 'windows') { //only windows,mac 94 if (/mac os/i.test(ua) && !/iphone|ipad|ipod/i.test(ua)) return "mac"; 95 return "windows"; 96 } else if (defaultPlatform === 'mac') { //only mac 97 return "mac"; 98 } else { 99 if (/android/i.test(ua)) return "android"; 100 if (/iphone|ipad|ipod/i.test(ua)) return "ios"; 101 if (/mac/i.test(ua)) return "mac"; 102 if (/win/i.test(ua)) return "windows"; 103 return "windows"; 104 } 105 } 106 107 // Set download and buy buttons for the page 108 function setPlatform(platform, config) { 109 const data = config[platform]; 110 111 if (!data) return console.warn("Unknown platform:", platform); 112 113 switchImages(platform); 114 115 switchUrl(platform); 116 117 switchText(platform); 118 119 replaceDiscount(platform); 120 121 hidePlatformObject(platform); 122 // Highlight the current platform icon 123 document.querySelectorAll(".platform-icons .code-img").forEach((img) => { 124 img.classList.toggle("active", img.dataset.platform === platform); 125 }); 126 127 const lang = (location.pathname.split('/')[1] || '').toLowerCase(); 128 const supportLangs = ['pt', 'de', 'fr', 'es', 'it', 'jp']; 129 const langPrefix = supportLangs.includes(lang) ? `/${lang}` : ''; 130 131 //top-menu-button,Common-top-menu 132 document.querySelectorAll(".menu_buttons").forEach(buttons => { 133 const btnDownload = buttons.querySelector(".BtnDownCode"); 134 const btnBuy = buttons.querySelector(".BtnDownBuy"); 135 if (!btnDownload || !btnBuy) return; 136 btnDownload.href = data.downloadLink; 137 if (data.buyLink) { 138 btnBuy.href = langPrefix + data.buyLink; 139 btnBuy.style.display = ''; 140 buttons.style.gridTemplateColumns = ''; 141 buttons.style.justifyItems = ''; 142 } else { 143 btnBuy.style.display = 'none'; 144 buttons.style.gridTemplateColumns = '1fr'; 145 buttons.style.justifyItems = 'end'; 146 } 147 }); 148 149 const pageConfig = window.ProductConfig || {}; 150 document.querySelectorAll('.replace-product-name').forEach(el => { 151 el.textContent = pageConfig.product_name; 152 }); 153 document.querySelectorAll('.replace-product-icon').forEach(img => {
154 img.src = pageConfig.product_icon; 155 }); 156 document.querySelectorAll('.product-main-url').forEach(url => { 157 url.href = langPrefix + pageConfig.mainurl; 158 }); 159 } 160 161 function setButtonLang(lang) { 162 const dict = I18N[lang] || I18N.en; 163 document.querySelectorAll('[data-i18n]').forEach(el => { 164 const key = el.dataset.i18n; 165 if (dict[key]) { 166 el.textContent = dict[key]; 167 } 168 }); 169 } 170 171 function switchImages(platform) { 172 document.querySelectorAll('.replace-images').forEach(img => { 173 let newSrc; 174 if (platform === 'mac') newSrc = img.dataset.mac; 175 else if (platform === 'ios') newSrc = img.dataset.ios; 176 else if (platform === 'android') newSrc = img.dataset.android; 177 else newSrc = img.dataset.win; 178 if (newSrc) { 179 if (img.classList.contains('lazyload')) { 180 img.dataset.src = newSrc; 181 img.classList.remove('lazyloaded'); 182 img.classList.add('lazyload'); 183 } else { 184 img.src = newSrc; 185 } 186 } 187 }); 188 } 189 190 //replace win&mac url 191 function switchUrl(platform) { 192 document.querySelectorAll('.replace-url').forEach(url => { 193 if (platform === 'mac') { 194 url.href = url.dataset.mac; 195 } else if (platform === 'ios') { 196 url.href = url.dataset.ios || url.dataset.win; 197 } else if (platform === 'android') { 198 url.href = url.dataset.android || url.dataset.win; 199 } else { // default windows 200 url.href = url.dataset.win; 201 } 202 }); 203 } 204 205 function hidePlatformObject(platform) { 206 document.querySelectorAll('.platform-hide-object').forEach(el => { 207 if (el.dataset.platform === platform) { 208 el.classList.remove('hide-code'); 209 } else { 210 el.classList.add('hide-code'); 211 } 212 }); 213 } 214 215 function switchText(platform) { 216 document.querySelectorAll('.replace-text').forEach(p => { 217 if (platform === 'mac') { 218 p.textContent = p.dataset.mac; 219 } else if (platform === 'ios') { 220 p.textContent = p.dataset.ios; 221 } else if (platform === 'android') { 222 p.textContent = p.dataset.android; 223 } else { // default windows 224 p.textContent = p.dataset.win; 225 } 226 }); 227 228 document.querySelectorAll('.star-rating-fill').forEach(star => { 229 let width; 230 if (platform === 'mac') { 231 width = star.dataset.mac; 232 } else if (platform === 'ios') { 233 width = star.dataset.ios; 234 } else if (platform === 'android') { 235 width = star.dataset.android; 236 } else { 237 width = star.dataset.win; 238 } 239 if (width) { 240 star.style.width = width; 241 } 242 }); 243 } 244 245 function replaceDiscount(platform) { 246 const pageConfig = window.ProductConfig || {}; 247 const productConfig = pageConfig[platform] || {}; 248 const isJP = location.pathname.startsWith('/jp/'); 249 const discount = isJP 250 ? Number(productConfig.discount_jp ?? productConfig.discount) || 0 251 : Number(productConfig.discount) || 0; 252 253 document.querySelectorAll(".BtnDownBuy-title").forEach(span => { 254 const original = span.dataset.original || span.textContent.trim(); 255 const titleTemplate = span.dataset.title || original; 256 if (discount > 0) { 257 span.textContent = titleTemplate.replace(/\d+/, discount); 258 } else { 259 span.textContent = original; 260 } 261 }); 262 263 document.querySelectorAll(".sale-img").forEach(img => { 264 if (discount === 0) { 265 img.style.display = "none"; 266 } else { 267 img.style.display = ""; 268 img.src = "/images/common/Discount-" + discount + ".png"; 269 } 270 }); 271 } 272 273 function initPlatformSwitcher(config, defaultPlatform) { 274 const imgs = document.querySelectorAll(".platform-icons .code-img"); 275 276 // unified handler using event.currentTarget 277 function handleSelect(e) { 278 // Stop default behaviour that may synthesize another click on some devices 279 if (e.type === 'pointerup' || e.type === 'touchend') { 280 // only preventDefault when it's a touch/pointer event to avoid blocking normal click in non-touch contexts 281 e.preventDefault(); 282 } 283 const el = e.currentTarget; // always the element the listener was attached to 284 const platform = el.dataset.platform; 285 const cfg = getMergedConfig(); 286 setPlatform(platform, cfg); 287 } 288
289 imgs.forEach(img => { 290 // pointer events are the most consistent across mouse/touch/stylus 291 img.addEventListener('pointerup', handleSelect, {passive: false}); 292 // fallback for older iOS/Android that might not support pointer events reliably 293 img.addEventListener('click', handleSelect); 294 // optional: also listen to touchend to be extra-safe on some Android webviews 295 img.addEventListener('touchend', handleSelect, {passive: false}); 296 }); 297 298 const platform = defaultPlatform; 299 300 setPlatform(platform, config); 301 } 302 303 window.toggleCommonTopMenu = function (clickId) { 304 console.log(clickId); 305 let platform = 'windows'; 306 if (clickId === 2) { 307 platform = 'mac'; 308 } 309 const cfg = getMergedConfig(); 310 setPlatform(platform, cfg); 311 }; 312 313 function showCommonTopMenu() { 314 const menu = document.querySelector('.Floating-menu'); 315 if (!menu) return; 316 317 if (document.documentElement.scrollTop > 500) { 318 menu.classList.add('floating-menu-show'); 319 } else { 320 menu.classList.remove('floating-menu-show'); 321 } 322 } 323 324 // Execute on DOMContentLoaded 325 document.addEventListener("DOMContentLoaded", () => { 326 const config = getMergedConfig(); 327 if (!config) { 328 console.warn("No ProductConfig found in window scope"); 329 return; 330 } 331 const urlParams = new URLSearchParams(window.location.search); 332 let urlPlatform = urlParams.get("platform"); 333 const defaultPlatform = urlPlatform || detectPlatform();// document.body.dataset.defaultPlatform; 334 335 initPlatformSwitcher(config, defaultPlatform); 336 337 const lang = location.pathname.split('/')[1]; 338 339 setButtonLang(lang); 340 }); 341 342 document.addEventListener('scroll', showCommonTopMenu, true); 343 344 // Expose manual call 345 window.setPlatform = function (platform) { 346 const config = getMergedConfig(); 347 setPlatform(platform, config); 348 }; 349})();
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.