(function () { 'use strict'; var FLAG = 'lampa_p365x_plugin_started_v2'; if (window[FLAG]) return; window[FLAG] = true; var CFG = { baseUrl: 'https://m.porno365x.space', // Если прямой доступ блокируется CORS, укажи прокси URL: // например: 'https://your-domain.tld/lampa/p365x?url=' proxyPrefix: '', requestTimeoutMs: 15000 }; var STATE = { items: [], page: 1, loading: false, mounted: false }; function qs(sel, root) { return (root || document).querySelector(sel); } function ce(tag, cls, txt) { var n = document.createElement(tag); if (cls) n.className = cls; if (typeof txt !== 'undefined' && txt !== null) n.textContent = txt; return n; } function log(msg) { try { console.log('[p365x] ' + msg); } catch (e) {} } function safeUrl(url) { if (!CFG.proxyPrefix) return url; return CFG.proxyPrefix + encodeURIComponent(url); } function requestText(url) { return new Promise(function (resolve, reject) { try { var xhr = new XMLHttpRequest(); xhr.open('GET', safeUrl(url), true); xhr.timeout = CFG.requestTimeoutMs; xhr.onreadystatechange = function () { if (xhr.readyState !== 4) return; if (xhr.status >= 200 && xhr.status < 300) resolve(xhr.responseText || ''); else reject(new Error('HTTP ' + xhr.status)); }; xhr.ontimeout = function () { reject(new Error('TIMEOUT')); }; xhr.onerror = function () { reject(new Error('NETWORK')); }; xhr.send(); } catch (e) { reject(e); } }); } function extractCards(html) { var out = []; var re = /
  • ([^<]+)<\/p>[\s\S]*?([^<]*)<\/span>/g; var m; while ((m = re.exec(html))) { out.push({ id: m[1], url: m[2].indexOf('http') === 0 ? m[2] : (CFG.baseUrl + m[2]), poster: m[3], title: (m[4] || '').trim(), duration: (m[5] || '').trim() }); } return out; } function extractMp4(movieHtml) { var all = []; var re = /file\s*:\s*"([^"]+\.mp4[^"]*)"/g; var m; while ((m = re.exec(movieHtml))) all.push(m[1]); if (!all.length) { var v = movieHtml.match(/]+src="([^"]+\.mp4[^"]*)"/i); if (v) all.push(v[1]); } all.sort(function (a, b) { function q(x) { var mm = x.match(/_(\d{3,4})p\.mp4/i); return mm ? Number(mm[1]) : 0; } return q(b) - q(a); }); return all[0] || ''; } function setStatus(text) { var s = qs('#p365x-status'); if (s) s.textContent = text || ''; } function makeCss() { if (qs('#p365x-style')) return; var css = ce('style'); css.id = 'p365x-style'; css.textContent = '' + '#p365x-fab{position:fixed;right:24px;bottom:24px;z-index:99999;background:#e91e63;color:#fff;border:none;border-radius:999px;padding:10px 14px;font-weight:700;}' + '#p365x-root{position:fixed;inset:0;z-index:99998;background:#111;color:#fff;display:none;}' + '#p365x-head{padding:12px 16px;display:flex;gap:10px;align-items:center;border-bottom:1px solid #333;}' + '#p365x-list{padding:10px;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px;overflow:auto;height:calc(100% - 64px);}' + '.p365x-card{background:#1b1b1b;border:1px solid #333;border-radius:8px;overflow:hidden;cursor:pointer;}' + '.p365x-card img{width:100%;height:130px;object-fit:cover;display:block;}' + '.p365x-meta{padding:8px;font-size:13px;}' + '#p365x-player{position:fixed;inset:0;z-index:100000;background:#000;display:none;}' + '#p365x-player video{width:100%;height:100%;}' + '#p365x-close-player{position:absolute;top:10px;right:10px;z-index:2;}'; document.head.appendChild(css); } function renderItems() { var list = qs('#p365x-list'); if (!list) return; list.innerHTML = ''; STATE.items.forEach(function (item) { var c = ce('div', 'p365x-card'); c.innerHTML = '
    ' + item.title + '
    ' + item.duration + '
    '; c.onclick = function () { setStatus('Загрузка видео...'); requestText(item.url) .then(function (html) { var src = extractMp4(html); if (!src) throw new Error('Поток не найден'); var player = qs('#p365x-player'); var video = qs('#p365x-video'); video.src = src; player.style.display = 'block'; setStatus(''); }) .catch(function (e) { setStatus('Ошибка: ' + (e && e.message ? e.message : e)); }); }; list.appendChild(c); }); } function loadNextPage() { if (STATE.loading) return; STATE.loading = true; var url = STATE.page > 1 ? (CFG.baseUrl + '/page/' + STATE.page + '/') : (CFG.baseUrl + '/'); setStatus('Загрузка страницы ' + STATE.page + '...'); requestText(url) .then(function (html) { var items = extractCards(html); STATE.items = STATE.items.concat(items); STATE.page += 1; renderItems(); setStatus('Найдено: ' + STATE.items.length); }) .catch(function (e) { setStatus('Не удалось загрузить. CORS/блокировка: ' + (e && e.message ? e.message : e)); }) .finally(function () { STATE.loading = false; }); } function openPanel() { var root = qs('#p365x-root'); if (!root) return; root.style.display = 'block'; if (!STATE.items.length) loadNextPage(); } function mountUi() { if (STATE.mounted || qs('#p365x-root')) return; STATE.mounted = true; makeCss(); var fab = ce('button'); fab.id = 'p365x-fab'; fab.textContent = 'P365'; fab.onclick = openPanel; var root = ce('div'); root.id = 'p365x-root'; root.innerHTML = '
    '; var player = ce('div'); player.id = 'p365x-player'; player.innerHTML = ''; document.body.appendChild(fab); document.body.appendChild(root); document.body.appendChild(player); qs('#p365x-close').onclick = function () { root.style.display = 'none'; }; qs('#p365x-more').onclick = loadNextPage; qs('#p365x-close-player').onclick = function () { player.style.display = 'none'; var v = qs('#p365x-video'); v.pause(); v.removeAttribute('src'); v.load(); }; addLampaMenuButton(); log('UI mounted'); } function addLampaMenuButton() { try { if (!window.Lampa || !Lampa.SettingsApi || !Lampa.SettingsApi.addParam) return; Lampa.SettingsApi.addParam({ component: 'interface', param: { name: 'p365x_open_btn', type: 'button' }, field: { name: 'P365X каталог', description: 'Открыть каталог P365X' }, onChange: function () { openPanel(); } }); log('Settings button registered'); } catch (e) { log('Settings button error: ' + (e && e.message ? e.message : e)); } } function start() { try { mountUi(); } catch (e) { log('Start error: ' + (e && e.message ? e.message : e)); } } if (window.appready) { start(); } else if (window.Lampa && Lampa.Listener && Lampa.Listener.follow) { Lampa.Listener.follow('app', function (e) { if (e && e.type === 'ready') start(); }); } else { window.addEventListener('load', start); } })();