0 && streamLink === '') { streamLink = vids[0].link; enhancedStreamLink = vids[0].link; streamLabel = vids[0].label; prepareFastStart(); }" x-data="{
stream: '0',
isSharpened: false,
streamLink: 'https://peachify.top/embed/tv/121534/1/30',
streamLabel: 'Peachify | VF/VO',
enhancedStreamLink: 'https://peachify.top/embed/tv/121534/1/30',
smartlinkClicks: 0,
omegaMobileStarting: false,
omegaMobilePlayReady: false,
omegaMobilePlaying: false,
_omegaFallbackTimer: null,
baseRequiredClicks: 2,
bonusRequiredClicks: 0,
smartlinkContentKey: 'content:339831',
isFastfluxPremium: false,
isOmegaPremium: false,
isPeachifyPremium: false,
isFastfluxStream() {
// Aligné sur config/players.php (labels + liens FastFlux)
const label = (this.streamLabel || '').toLowerCase();
const link = ((this.enhancedStreamLink || this.streamLink || '') + '').toLowerCase();
if (label.includes('omega') || label.includes('purstream') || label.includes('pulse') || label.includes('youtube')) return false;
if (link.includes('purstream') || link.includes('hls-proxy.php?purstream_relay') || link.includes('finepulfe') || link.includes('embed-stream/')) return false;
const labelHit = ['fastflux','noctaflix','citron','source 1','source1'].some(k => label.includes(k));
const linkHit = ['citron-edge','embedo','blinkflux','swiftflow','falzey','cheksum','fastflux','drinkoflix','streamtrack','r2.dev','noctaflix'].some(k => link.includes(k));
// Liens /embed/{id} FastFlux stockés sans mot-clé dans l URL
const embedHit = link.includes('/embed/') && !label.includes('omega');
return labelHit || linkHit || embedHit;
},
isOmegaStream() {
const label = (this.streamLabel || '').toLowerCase();
const link = ((this.enhancedStreamLink || this.streamLink || '') + '').toLowerCase();
return label.includes('omega') || label.includes('purstream') || label.includes('pulse')
|| link.includes('purstream') || link.includes('hls-proxy.php?purstream_relay') || link.includes('finepulfe');
},
isGatedStream() {
// FastFlux et Omega : smartlinks à chaque sélection.
return this.isFastfluxStream() || this.isOmegaStream();
},
isMobileDevice() {
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent || '')
|| (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
},
get smartlinkOverlayLimit() {
return this.requiredClicks;
},
otherSourcesUnlocked: false,
loadOtherSourcesUnlock() {
try {
this.otherSourcesUnlocked = sessionStorage.getItem('zenix_other_src_unlock:' + this.smartlinkContentKey) === '1';
} catch (e) {
this.otherSourcesUnlocked = false;
}
},
markOtherSourcesUnlock() {
this.otherSourcesUnlocked = true;
try { sessionStorage.setItem('zenix_other_src_unlock:' + this.smartlinkContentKey, '1'); } catch (e) {}
},
onSmartlinksCompleted() {
if (!this.isGatedStream()) this.markOtherSourcesUnlock();
// Mobile + Omega : lancer dans l iframe (lecteur complet) pendant
// le geste du dernier smartlink ; overlay discret seulement si échec.
if (this.isMobileDevice() && this.isOmegaStream()) {
this.startOmegaMobilePlayback();
return;
}
this.triggerPlay();
},
applySmartlinkGate() {
if (this.baseRequiredClicks === 0) return;
if (this.isGatedStream()) {
this.smartlinkClicks = 0;
return;
}
this.loadOtherSourcesUnlock();
if (this.otherSourcesUnlocked) {
this.smartlinkClicks = this.requiredClicks;
this.$nextTick(() => this.triggerPlay());
} else {
this.smartlinkClicks = 0;
}
},
get requiredClicks() {
// Premium global → aucun smartlink
if (this.baseRequiredClicks === 0) return 0;
const label = (this.streamLabel || '').toLowerCase();
// Premium par lecteur → pas de smartlink sur ce lecteur
if (this.isFastfluxStream() && this.isFastfluxPremium) return 0;
if ((label.includes('omega') || label.includes('purstream')) && this.isOmegaPremium) return 0;
if (label.includes('peachify') && this.isPeachifyPremium) return 0;
// Non-premium : smartlinks sur TOUS les lecteurs (Omega inclus)
// Captcha CF reste séparé via needsCfCaptcha (FastFlux only)
return this.baseRequiredClicks + this.bonusRequiredClicks;
},
turnstileRendered: false,
turnstileLoadFailed: false,
turnstileWidgetId: null,
iframeLoaded: false,
cfVerified: false,
turnstileOk: false,
turnstileToken: '',
get needsCfCaptcha() {
// Cloudflare Turnstile : UNIQUEMENT FastFlux, non-premium, à chaque fois
if (false) return false;
if (this.isFastfluxPremium) return false;
if (!this.isFastfluxStream()) return false;
return !this.cfVerified;
},
fastStartPrepared: false,
fastStartWarmUrl: '',
init() {
this.$watch('streamLink', () => { this.iframeLoaded = false; });
this.$watch('$wire.videos', videos => {
if (videos && videos.length > 0 && !this.streamLink) {
this.streamLink = videos[0].link;
this.enhancedStreamLink = videos[0].link;
this.streamLabel = videos[0].label;
this.prepareFastStart();
}
});
// Ensure warm-up runs on initial load even if $wire.videos is already populated
// ($watch only fires on changes, not initial value)
if (this.$wire.videos && this.$wire.videos.length > 0 && !this.streamLink) {
this.streamLink = this.$wire.videos[0].link;
this.enhancedStreamLink = this.$wire.videos[0].link;
this.streamLabel = this.$wire.videos[0].label;
this.prepareFastStart();
}
this.setupBonusSmartlink();
this.loadOtherSourcesUnlock();
this.$nextTick(() => {
this.applySmartlinkGate();
this.syncCfCaptchaForStream();
this.prepareFastStart();
});
const self = this;
this._onPlaybackStarted = function (e) {
if (e.data !== 'zenix_playback_started') return;
self.omegaMobileStarting = false;
self.omegaMobilePlayReady = false;
self.omegaMobilePlaying = true;
if (self._omegaFallbackTimer) clearTimeout(self._omegaFallbackTimer);
};
window.addEventListener('message', this._onPlaybackStarted);
this._onVisibilityResume = function () {
if (document.visibilityState !== 'visible') return;
if (!self.isMobileDevice() || !self.isOmegaStream()) return;
if (self.smartlinkClicks < self.requiredClicks) return;
if (self.omegaMobilePlaying) return;
self.triggerPlay();
};
document.addEventListener('visibilitychange', this._onVisibilityResume);
},
syncCfCaptchaForStream() {
if (false || this.isFastfluxPremium || !this.isFastfluxStream()) {
this.cfVerified = true;
this.turnstileRendered = true;
try { $wire.watching('premium_or_local_bypass'); } catch (e) {}
return;
}
// FastFlux non-premium : forcer le captcha Cloudflare à chaque fois
this.cfVerified = false;
this.turnstileOk = false;
this.turnstileToken = '';
this.turnstileRendered = false;
this.turnstileLoadFailed = false;
this.renderTurnstile();
},
passCfCaptcha(token) {
this.cfVerified = true;
this.turnstileRendered = true;
try { $wire.watching(token || 'manual_verify'); } catch (e) {}
},
buildWarmUrl(link) {
try {
let u = new URL(link, window.location.origin);
let raw = '';
if (u.pathname.indexOf('/embed-stream/') === 0) {
raw = atob(u.pathname.split('/embed-stream/')[1].split('/')[0]);
} else if (u.pathname.indexOf('/api/hls-proxy.php') === 0) {
raw = u.href;
}
if (raw.indexOf('/api/hls-proxy.php') === -1) return '';
let hls = new URL(raw, window.location.origin);
hls.searchParams.set('warm', '1');
return hls.toString();
} catch (e) {
return '';
}
},
prepareFastStart() {
if (this.fastStartPrepared) return;
this.fastStartPrepared = true;
// HLS is started by the embed only after the user presses play.
// Pre-warming here doubled upstream segment requests before playback.
},
selectStream(index, link, label) {
this.stream = String(index);
this.streamLink = link || '';
this.enhancedStreamLink = link || '';
this.streamLabel = label || '';
// Autres sources : 1 unlock pour tout le groupe.
// FastFlux / Omega : smartlinks à chaque fois.
this.iframeLoaded = false;
this.fastStartPrepared = false;
this.resetOmegaMobilePlay();
this.applySmartlinkGate();
this.syncCfCaptchaForStream();
this.prepareFastStart();
},
resetOmegaMobilePlay() {
this.omegaMobileStarting = false;
this.omegaMobilePlayReady = false;
this.omegaMobilePlaying = false;
if (this._omegaFallbackTimer) clearTimeout(this._omegaFallbackTimer);
const iframe = document.getElementById('video-iframe');
if (iframe) iframe.style.visibility = 'visible';
},
startOmegaMobilePlayback() {
if (this.omegaMobilePlaying) return;
const iframe = document.getElementById('video-iframe');
if (iframe) iframe.style.visibility = 'visible';
this.omegaMobilePlaying = false;
this.omegaMobilePlayReady = false;
this.omegaMobileStarting = true;
this.triggerPlay();
const self = this;
if (this._omegaFallbackTimer) clearTimeout(this._omegaFallbackTimer);
this._omegaFallbackTimer = setTimeout(function () {
if (!self.omegaMobilePlaying) {
self.omegaMobileStarting = false;
self.omegaMobilePlayReady = true;
}
}, 2800);
},
playOmegaMobile() {
if (this._omegaPlayLock) return;
this._omegaPlayLock = true;
this.omegaMobilePlayReady = false;
this.omegaMobileStarting = true;
this.triggerPlay();
const self = this;
setTimeout(function () { self._omegaPlayLock = false; }, 1200);
if (this._omegaFallbackTimer) clearTimeout(this._omegaFallbackTimer);
this._omegaFallbackTimer = setTimeout(function () {
if (!self.omegaMobilePlaying) {
self.omegaMobileStarting = false;
self.omegaMobilePlayReady = true;
}
}, 2800);
},
triggerPlay() {
const iframe = document.getElementById('video-iframe');
if (!iframe || !iframe.contentWindow) return;
const kick = () => {
try {
if (typeof iframe.contentWindow.zenixStartPlayback === 'function') {
iframe.contentWindow.zenixStartPlayback();
return true;
}
} catch (e) {}
try {
const video = iframe.contentDocument && iframe.contentDocument.getElementById('player');
if (video && typeof video.play === 'function') {
const p = video.play();
if (p && typeof p.catch === 'function') p.catch(function () {});
return true;
}
} catch (e) {}
return false;
};
if (kick()) return;
let attempts = 0;
const tryPlay = () => {
attempts++;
if (kick()) return;
if (attempts < 15) setTimeout(tryPlay, 300);
};
tryPlay();
},
setupBonusSmartlink() {
if (this.baseRequiredClicks === 0) return;
// Toujours activer le clic bonus pour imposer 3 clics permanents
this.bonusRequiredClicks = 1;
},
recordSmartlinkClick() {
try {
let raw = localStorage.getItem('zenix_smartlink_timestamps');
let data = raw ? JSON.parse(raw) : {};
data[this.smartlinkContentKey] = Date.now();
localStorage.setItem('zenix_smartlink_timestamps', JSON.stringify(data));
} catch(e) {}
},
renderTurnstile() {
if (this.cfVerified) return;
let attempts = 0;
const self = this;
const tryRender = () => {
attempts++;
if (self.cfVerified || !self.needsCfCaptcha) return;
if (typeof turnstile === 'undefined') {
if (attempts < 40) setTimeout(tryRender, 250);
else console.warn('[Turnstile] script not loaded yet (adblock?)');
return;
}
const container = document.getElementById('zenix-ts-bg');
if (!container) {
if (attempts < 40) setTimeout(tryRender, 250);
return;
}
try {
if (self.turnstileWidgetId !== null) {
try { turnstile.remove(self.turnstileWidgetId); } catch (e) {}
self.turnstileWidgetId = null;
}
container.innerHTML = '';
self.turnstileWidgetId = turnstile.render(container, {
sitekey: '0x4AAAAAADAM-kpqntxYPQx1',
callback: (token) => {
self.turnstileToken = token || 'ok';
self.turnstileOk = true;
// Garder le vrai widget CF visible ; Continuer passe aux smartlinks
},
'error-callback': (code) => {
console.warn('[Turnstile] error', code);
// Ne PAS skip auto : on laisse le captcha visible + bouton secours
self.turnstileLoadFailed = true;
},
'expired-callback': () => {
self.cfVerified = false;
self.turnstileRendered = false;
self.renderTurnstile();
},
theme: 'light',
size: 'normal',
appearance: 'always',
execution: 'render'
});
self.turnstileRendered = true;
} catch (e) {
console.warn('[Turnstile] render exception', e);
self.turnstileLoadFailed = true;
}
};
// Attendre que l overlay soit visible avant render
requestAnimationFrame(() => setTimeout(tryRender, 50));
},
clickSmartlink() {
// Le VPS choisit A ou B et enregistre chaque redirection.
const smartlinkRedirect = 'https://zenix.best/go/smartlink' + '?source=watch';
const fastfluxLink = 'https://interlinecustomroofingllc.com/4/65f2f91c0da689b260d90a4d85fc3247';
let isFastFlux = this.isFastfluxStream();
let currentLabel = (this.streamLabel || '').toLowerCase();
let targetUrl = '';
if (this.smartlinkClicks >= 2 && isFastFlux) {
targetUrl = fastfluxLink;
} else {
targetUrl = smartlinkRedirect;
}
// PROTECTION ANTI ABOUT:BLANK ET SAFARI POPUP BLOCKER
if (!targetUrl || targetUrl.trim() === '' || targetUrl.includes('about:blank')) {
this.smartlinkClicks++;
if (this.smartlinkClicks >= this.requiredClicks) {
this.onSmartlinksCompleted();
}
return;
}
try {
let win = window.open(targetUrl, '_blank');
if (!win || win.closed || typeof win.closed === 'undefined') {
let a = document.createElement('a');
a.href = targetUrl;
a.target = '_blank';
a.rel = 'noopener noreferrer';
document.body.appendChild(a);
a.click();
a.remove();
}
} catch(e) {}
this.smartlinkClicks++;
if (this.smartlinkClicks >= this.requiredClicks) {
this.onSmartlinksCompleted();
}
},
toggleHD(enabled) {
this.isSharpened = !!enabled;
}
}">
FREE PREMIUM · 3H
Tired of ads?
Unlock the Premium experience on all players, for free.
Free streaming. Ads are external and are not managed by Zenix. Close them, then return to Zenix without clicking anywhere else.
Cast
Episode list
Aller à l'épisode