1(function () { 2 'use strict'; 3 4 var invalidPoster = '/images/poster-invalid-55xcc.jpg'; 5 var posterSelector = '.poster img,.thumb img,.video-card img,.vodlist_thumb,.vodlist_thumb img,.play_vlist_thumb img,.mgn-picture img,.video-img-box img,.img-box img,a[href*="/video"] img,a[href*="/play"] img,a[href*="vodplay"] img'; 6 7 function isPosterImage(image) { 8 return image instanceof HTMLImageElement && image.matches(posterSelector); 9 } 10 11 document.addEventListener('error', function (event) { 12 var image = event.target; 13 if (!isPosterImage(image) || image.dataset.invalidPosterApplied === '1') return; 14 image.dataset.invalidPosterApplied = '1'; 15 image.removeAttribute('srcset'); 16 image.removeAttribute('sizes'); 17 image.src = invalidPoster; 18 }, true); 19 20 var mobileMenuStyle = document.createElement('style'); 21 mobileMenuStyle.textContent = '@media(max-width:950px){.main-nav.open,.main-nav.show,.site-header.nav-open .main-nav,.navbar-collapse.show,.mobile-nav.open,.mobile-nav.show,.nav-menu.open,.nav-menu.show,.main-menu.open,.main-menu.show,.offcanvas.show,.category-menu.open,.category-menu.show{padding-bottom:300px!important;scroll-padding-bottom:300px!important}}'; 22 document.head.appendChild(mobileMenuStyle); 23 24 // Disable only on touch-only devices. Hybrid notebooks and desktop browsers 25 // do not always report `pointer: fine`, although they still emit mouse hover. 26 if (window.matchMedia('(hover: none) and (pointer: coarse)').matches) return; 27 28 var active = null; 29 var timer = 0; 30 var cardSelector = '[data-missav-preview],a.poster,a.thumb,a.vodlist_thumb,.atlas-card>a,.mgn-picture>a,.video-img>a,.position-relative>a,a[href]'; 31 32 function decodeProxyUrl(value) { 33 var decoded = String(value || ''); 34 for (var depth = 0; depth < 4; depth += 1) { 35 var match = decoded.match(/\/(?:base|resource)\/([A-Za-z0-9_=-]+)(?:\.cache|\/|$)/); 36 if (!match) break; 37 try { 38 var token = match[1].replace(/-/g, '+').replace(/_/g, '/'); 39 while (token.length % 4) token += '='; 40 var next = atob(token); 41 if (!next || next === decoded) break; 42 decoded = next; 43 } catch (_) { 44 break; 45 } 46 } 47 return decoded; 48 } 49 50 function resolvePreview(container) { 51 if (container.dataset.missavPreview) return container.dataset.missavPreview; 52 if (container.dataset.preview && /\.mp4(?:$|\?)/i.test(container.dataset.preview)) { 53 return container.dataset.preview; 54 } 55 var image = container.querySelector('img'); 56 if (!image) return ''; 57 if (/^https?:\/\//i.test(image.dataset.mediabook || '')) return image.dataset.mediabook; 58 var candidates = [image.currentSrc, image.src, image.dataset.original, image.dataset.wpsrc]; 59 for (var index = 0; index < candidates.length; index += 1) { 60 var decoded = decodeProxyUrl(candidates[index]); 61 var match = decoded.match(/https?:\/\/fourhoi\.com\/([^/?#]+)\//i); 62 if (!match) continue; 63 var slug = match[1]; 64 try { slug = decodeURIComponent(slug); } catch (_) {} 65 var preview = 'https://mp.dage263.one/?url=https://fourhoi.com/' + encodeURIComponent(slug) + '/preview.mp4'; 66 container.dataset.missavPreview = preview; 67 return preview; 68 } 69 return ''; 70 } 71 72 function stop(container) { 73 clearTimeout(timer); 74 timer = 0; 75 var video = container && container.querySelector(':scope > .missav-hover-preview'); 76 if (video) { 77 video.pause(); 78 video.removeAttribute('src'); 79 video.load(); 80 video.remove(); 81 } 82 if (active === container) active = null; 83 } 84 85 function start(container) { 86 var source = resolvePreview(container); 87 if (!source || container.querySelector(':scope > .missav-hover-preview')) return; 88 if (active && active !== container) stop(active); 89 active = container; 90 timer = window.setTimeout(function () { 91 if (active !== container || !container.isConnected) return; 92 var video = document.createElement('video'); 93 video.className = 'missav-hover-preview'; 94 video.muted = true; 95 video.loop = true;
96 video.playsInline = true; 97 video.preload = 'auto'; 98 video.src = source; 99 Object.assign(video.style, { 100 position: 'absolute', inset: '0', width: '100%', height: '100%', 101 objectFit: 'cover', zIndex: '3', pointerEvents: 'none', background: '#000' 102 }); 103 var position = getComputedStyle(container).position; 104 if (position === 'static') container.style.position = 'relative'; 105 container.style.overflow = 'hidden'; 106 container.appendChild(video); 107 video.addEventListener('error', function () { stop(container); }, { once: true }); 108 video.play().catch(function () { 109 // Some browsers resolve autoplay only after enough media data is available. 110 video.addEventListener('canplay', function () { 111 if (active === container) video.play().catch(function () {}); 112 }, { once: true }); 113 }); 114 }, 180); 115 } 116 117 document.addEventListener('mouseover', function (event) { 118 var container = event.target.closest(cardSelector); 119 if (!container || !container.querySelector('img') || (event.relatedTarget && container.contains(event.relatedTarget))) return; 120 start(container); 121 }, true); 122 123 document.addEventListener('mouseout', function (event) { 124 var container = event.target.closest(cardSelector); 125 if (!container || !container.querySelector('img') || (event.relatedTarget && container.contains(event.relatedTarget))) return; 126 stop(container); 127 }, true); 128 129 document.addEventListener('visibilitychange', function () { 130 if (document.hidden && active) stop(active); 131 }); 132})();
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.