91爆料·吃瓜
https://abandon.yixuiyyj.cc/
分享者: laizhiyu (6509)发布时间: 7天前
AI制作,先登录界面选路线
{
"articleStyle": 1,
"cacheFirst": false,
"concurrentRate": "1\/300",
"coverDecodeJs": "\/\/ ==================== 订阅源「封面解密 Js」(coverDecodeJs) v2 ====================\n\/\/ pic.hdhwqx.cn 全站图片 = AES-128-CBC 加密字节(站点 image.0821.js 实锤)\n\/\/ KEY='f5d965df75336270' IV='97b60394abc2fbe1' PKCS7 → 解密后即 JPEG\/PNG\/WebP\/GIF\n\/\/ 绑定:java \/ source \/ src \/ result \/ book,要求返回 **ByteArray**。\n\/\/\n\/\/ ★★ v2 修复「大部分封面不显示」:v1 里对每张封面用 java.get(src) **重新发一次请求**,\n\/\/ Glide 并发加载 32 张时大量超时 ⇒ 只有少数成功。v2 直接使用 Glide 已给到的 result 字节,\n\/\/ 零额外网络请求。\n\/\/ ★ result 通常是 InputStream(OkHttpStreamFetcher 传 responseBody.byteStream()):\n\/\/ 用 java.base64DecodeToByteArray 造 Java byte[] 缓冲,read(buf) 循环读到 -1。\n\/\/ 若是 ByteArray(另一重载)则直接用。\n\/\/ ★ 解密用 java.createSymmetricCrypto 原生 API(LT 实测 359ms\/66KB;纯 JS AES 在 Rhino 60s 超时不可用)。\n\/\/ E 版若无此 API,try\/catch 返回原字节(不崩,只是不解密)。\n(function () {\n \/\/ ★ 关键提速:java.strToBytes(str, 'ISO-8859-1') 把 0-255 的 JS 字符串直接转 Java byte[]\n \/\/ (实测 7ms\/66KB,而纯 JS toB64 + base64DecodeToByteArray 要 876ms)。\n var CH = String.fromCharCode;\n try {\n var cipher = null, i, n, v, s, buf;\n if (result == null) return result;\n \/\/ ① result 是 ByteArray \/ byte[](有 length、可下标、无 read 方法)\n if (typeof result.length === 'number' && typeof result.read !== 'function') {\n cipher = result;\n } else if (typeof result.read === 'function') {\n \/\/ ② result 是 InputStream:read(byte[]) 循环,边读边拼 0-255 字符串\n s = '';\n try {\n buf = java.base64DecodeToByteArray(new Array(8193).join('A')); \/\/ 6144B Java byte[] 缓冲\n var guard = 0;\n while (guard < 2048) {\n guard++;\n n = result.read(buf);\n if (n <= 0) break;\n for (i = 0; i < n; i++) { v = buf[i]; s += CH(v < 0 ? v + 256 : v); }\n }\n } catch (e2) {}\n if (s.length) {\n try { cipher = java.strToBytes(s, 'ISO-8859-1'); }\n catch (e3) { try { cipher = java.strToBytes(s); } catch (e4) {} }\n }\n }\n if (!cipher || !cipher.length || cipher.length % 16) return result;\n if (typeof java.createSymmetricCrypto !== 'function') return result;\n var out = java.createSymmetricCrypto(\n 'AES\/CBC\/PKCS5Padding', 'f5d965df75336270', '97b60394abc2fbe1'\n ).decrypt(cipher);\n if (out && out.length) return out; \/\/ 已是 Java byte[]\n } catch (e) {}\n return result;\n})()",
"customOrder": 0,
"enableJs": true,
"enabled": true,
"enabledCookieJar": true,
"header": "{\"User-Agent\": \"Mozilla\/5.0 (Linux; Android 13; Pixel 7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/124.0.0.0 Mobile Safari\/537.36\", \"Referer\": \"https:\/\/abandon.yixuiyyj.cc\/\"}",
"injectJs": "(function() {\n \/\/ 播放器增强(原脚本 by 网友,经 91爆料订阅源多视频适配)\n \/\/ 功能:①自动识别横\/竖屏全屏切换 ②长按 3 倍速 ③拖动调进度 ④直播保护(duration 无效时不 seek)\n \/\/ 适配点:原版只绑 querySelector('video') 第一个;本源正文含 6 个视频 → 全部绑定。\n \/\/ injectJs 每次 onPageFinished 都会执行 → 加全局守卫,避免重复注入\/轮询叠加。\n if (window.__jyPlayerEnhanced) return;\n window.__jyPlayerEnhanced = true;\n\n var st = document.createElement('style');\n st.textContent = 'body.fs-ls{transform:rotate(90deg) translateY(-100%);transform-origin:top left;width:100vh!important;height:100vw!important;overflow:hidden!important;position:fixed!important;top:0!important;left:0!important}';\n document.head.appendChild(st);\n\n \/\/ 按「当前处于全屏的那个 video」判断横竖,而不是固定取第一个\n function currentFsVideo() {\n var f = document.fullscreenElement || document.webkitFullscreenElement;\n if (f && f.tagName === 'VIDEO') return f;\n if (f && f.querySelector) return f.querySelector('video');\n var vs = document.querySelectorAll('video');\n for (var i = 0; i < vs.length; i++) {\n if (vs[i] === document.fullscreenElement || vs[i] === document.webkitFullscreenElement) return vs[i];\n }\n return vs[0] || null;\n }\n function isLS() {\n var v = currentFsVideo();\n return (!v || !v.videoWidth) ? true : v.videoWidth >= v.videoHeight;\n }\n function fsHandler() {\n var full = document.fullscreenElement || document.webkitFullscreenElement;\n if (full && isLS()) {\n document.body.classList.add('fs-ls');\n if (screen.orientation && screen.orientation.lock)\n screen.orientation.lock('landscape').catch(function(){});\n } else {\n document.body.classList.remove('fs-ls');\n if (screen.orientation && screen.orientation.unlock)\n screen.orientation.unlock();\n }\n }\n document.addEventListener('fullscreenchange', fsHandler);\n document.addEventListener('webkitfullscreenchange', fsHandler);\n if (document.fullscreenElement || document.webkitFullscreenElement) fsHandler();\n\n \/\/ ============ 手势(逐视频绑定) ============\n function bind(v) {\n if (v.__gestureBound) return;\n v.__gestureBound = true;\n\n \/\/ ===== 可调参数(长按倍速在这里改) =====\n var LONG_PRESS_MS = 500; \/\/ 长按判定时长(毫秒)\n var FAST_RATE = 3.0; \/\/ 长按时的播放倍速\n var SWIPE_SENS = 1.0; \/\/ 滑动灵敏度:划满一屏 = 完整时长\n var SEEK_THROTTLE = 24; \/\/ seek 节流(毫秒)\n\n var sx = 0, st0 = 0, lp = null, ff = false, wasPaused = false, origRate = 1;\n var pendT = 0, seekTimer = null, seekPending = false, tipEl = null, speedTipEl = null;\n\n function fmt(t){var m=Math.floor(t\/60),s=Math.floor(t%60);return(m<10?'0':'')+m+':'+(s<10?'0':'')+s;}\n function showTip(t){\n if(!tipEl){tipEl=document.createElement('div');tipEl.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,.75);color:#fff;padding:10px 20px;border-radius:8px;font-size:16px;font-weight:bold;z-index:99999;pointer-events:none;';document.body.appendChild(tipEl);}\n tipEl.textContent = fmt(t)+' \/ '+fmt(v.duration||0);\n tipEl.style.display = 'block';\n }\n function hideTip(){ if(tipEl) tipEl.style.display='none'; }\n function showSpeedTip(){\n if(!speedTipEl){speedTipEl=document.createElement('div');speedTipEl.style.cssText='position:fixed;top:20px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.8);color:#fff;padding:8px 16px;border-radius:20px;font-size:14px;z-index:99999;pointer-events:none;';document.body.appendChild(speedTipEl);}\n speedTipEl.textContent = v.playbackRate + 'x 倍速中';\n speedTipEl.style.display = 'block';\n }\n function hideSpeedTip(){ if(speedTipEl) speedTipEl.style.display='none'; }\n\n function stopLong(){ if(lp){clearTimeout(lp);lp=null;} }\n function resetFF(){ if(ff){v.playbackRate=origRate;ff=false;hideSpeedTip();if(wasPaused)v.pause();} }\n function flushSeek(){ if(seekPending){seekPending=false;if(isFinite(pendT))v.currentTime=pendT;} clearTimeout(seekTimer); }\n\n v.addEventListener('touchstart', function(e){\n if(e.touches.length!==1) { stopLong(); return; }\n sx = e.touches[0].clientX;\n st0 = v.currentTime || 0;\n wasPaused = v.paused;\n origRate = v.playbackRate || 1;\n stopLong();\n lp = setTimeout(function(){\n lp = null;\n ff = true;\n v.playbackRate = FAST_RATE;\n if(wasPaused) { var p = v.play(); if(p && p.catch) p.catch(function(){}); }\n showSpeedTip();\n hideTip();\n }, LONG_PRESS_MS);\n }, {passive:true});\n\n v.addEventListener('touchmove', function(e){\n if(e.touches.length!==1) return;\n stopLong();\n var dx = e.touches[0].clientX - sx;\n if(Math.abs(dx) > 15){\n if(ff){v.playbackRate=origRate;ff=false;hideSpeedTip();}\n e.preventDefault();\n var dur = v.duration;\n if(!isFinite(dur) || dur <= 0) return; \/\/ ★ 直播保护:duration 无效不 seek\n var nt = st0 + (dx \/ (window.innerWidth * SWIPE_SENS)) * dur;\n if(nt<0) nt=0; if(nt>dur) nt=dur;\n pendT = nt;\n showTip(nt);\n if(!seekPending){\n seekPending = true;\n seekTimer = setTimeout(function(){ seekPending=false; if(isFinite(pendT)) v.currentTime=pendT; }, SEEK_THROTTLE);\n }\n }\n }, {passive:false});\n\n function endTouch(){\n stopLong();\n if(ff){ resetFF(); return; }\n flushSeek();\n hideTip();\n }\n v.addEventListener('touchend', endTouch);\n v.addEventListener('touchcancel', endTouch);\n }\n\n function tryBind(){\n try {\n var vs = document.querySelectorAll('video');\n for (var i = 0; i < vs.length; i++) bind(vs[i]);\n } catch (e) {}\n setTimeout(tryBind, 800); \/\/ 兼容 hls.js 后建\/动态插入的 video\n }\n tryBind();\n console.log('[注入] 播放器增强已启用(多视频适配版)');\n})();\n",
"lastUpdateTime": 1794038155951,
"loadWithBaseUrl": true,
"loginUi": "[{\"name\": \"jyPub\", \"type\": \"text\", \"viewName\": \"'发布页地址(默认jybl26)'\"}, {\"name\": \"🧭获取发布页线路\", \"type\": \"button\", \"action\": \"JY_fetchPub()\", \"viewName\": \"'🧭 一键从发布页获取网址路线'\"}, {\"name\": \"⏱测试延时\", \"type\": \"button\", \"action\": \"JY_testAll()\", \"viewName\": \"'⏱ 测试延时(ms写入各线路按钮)'\"}, {\"name\": \"🔍检查登录状态\", \"type\": \"button\", \"action\": \"JY_checkLogin()\", \"viewName\": \"'🔍 检查登录状态 \/ 线路可用性'\"}, {\"name\": \"━━━ 点击切换线路(延时见按钮名)━━━\", \"type\": \"button\", \"action\": \"\", \"viewName\": \"'━━━ 点击切换线路 ━━━'\"}, {\"name\": \"线路1\", \"type\": \"button\", \"action\": \"JY_switch(1)\", \"viewName\": \"JY_lineBtn(1)\"}, {\"name\": \"线路2\", \"type\": \"button\", \"action\": \"JY_switch(2)\", \"viewName\": \"JY_lineBtn(2)\"}, {\"name\": \"线路3\", \"type\": \"button\", \"action\": \"JY_switch(3)\", \"viewName\": \"JY_lineBtn(3)\"}, {\"name\": \"线路4\", \"type\": \"button\", \"action\": \"JY_switch(4)\", \"viewName\": \"JY_lineBtn(4)\"}, {\"name\": \"线路5\", \"type\": \"button\", \"action\": \"JY_switch(5)\", \"viewName\": \"JY_lineBtn(5)\"}, {\"name\": \"线路6\", \"type\": \"button\", \"action\": \"JY_switch(6)\", \"viewName\": \"JY_lineBtn(6)\"}]",
"loginUrl": "\/\/ ==================== 91爆料订阅源 · 线路管理面板(LT\/E 双版本兼容 V1 静态 loginUi) ====================\n\/\/ 用途:发布页(jybl26.com, Base64 编码) → 解析 zz_line 三条基础域 → 泛子域线路池\n\/\/ → 测速(java.connect 返回真 StrResponse, callTime() 取 ms) → 逐线路按钮切换\n\/\/ 全部函数挂在 loginUrl,SourceLoginDialog 拼接 \"$loginJS\\n$jsStr\" 后 loginUi\/action\/viewName 环境均可用。\n\/\/ 各阶段一律 Toast 反馈(java.longToast,E 版无 longToast 时降级 java.toast)。\n\nvar JY_MAX = 6; \/\/ 线路按钮位数(当前发布页 3 条,留余量)\nvar JY_DEFAULT = 'https:\/\/abandon.yixuiyyj.cc';\nvar JY_DEFAULT_PUB = 'https:\/\/jybl26.com';\nvar JY_UA = 'Mozilla\/5.0 (Linux; Android 13; Pixel 7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/124.0.0.0 Mobile Safari\/537.36';\n\/\/ 发布页 words 词表抽样(306 词,泛解析任意词均可用;每次获取随机挑一个,避免单前缀被针对)\nvar JY_WORDS = ['abandon', 'ability', 'able', 'above', 'abroad', 'access', 'account', 'action', 'active'];\n\nfunction JY_toast(t) {\n try { java.longToast(String(t)); } catch (e) { try { java.toast(String(t)); } catch (e2) {} }\n}\nfunction JY_gv(k, def) {\n var v = '';\n try { v = String(source.get(k)); } catch (e) { v = ''; }\n if (v === 'null' || v === 'undefined' || v === '') v = def || '';\n return v;\n}\nfunction JY_pub() {\n var p = JY_gv('jyPub', JY_DEFAULT_PUB).replace(\/\\\/+$\/, '');\n if (p.indexOf('http') !== 0) p = 'https:\/\/' + p;\n return p;\n}\nfunction JY_line() {\n var d = JY_gv('jyLine', JY_DEFAULT).replace(\/\\\/+$\/, '');\n if (d.indexOf('http') !== 0) d = JY_DEFAULT;\n return d;\n}\nfunction JY_hdr() { return JSON.stringify({ 'User-Agent': JY_UA }); }\nfunction JY_word() { return JY_WORDS[Math.floor(Math.random() * JY_WORDS.length)]; }\n\n\/\/ 把发布页 zz_line 的基础域还原成可访问线路\nfunction JY_build(bases) {\n var out = [], i, b, w = JY_word();\n for (i = 0; i < bases.length; i++) {\n b = String(bases[i]).trim().toLowerCase().replace(\/\\.$\/, '');\n if (!b || b.indexOf('..') > -1) continue;\n if (!\/^[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$\/.test(b)) continue;\n \/\/ 发布页逻辑:第 3 条(cloudfront)不加随机前缀;前两条是泛子域\n var u = (i === 2 || b.indexOf('cloudfront') > -1) ? ('https:\/\/' + b) : ('https:\/\/' + w + '.' + b);\n if (out.indexOf(u) < 0) out.push(u);\n }\n return out;\n}\n\n\/\/ 内置兜底(发布页抓不到时用,来自 261107 实测 zz_line)\n\/\/ ★ 固定词 'ability' 而非随机:JY_found() 每次调用必须返回同一组线路,\n\/\/ 否则 viewName 显示的域名与 JY_switch() 实际切换的域名会对不上(用户判为 bug)。\nfunction JY_fallbackFixed() {\n return ['https:\/\/abandon.yixuiyyj.cc', 'https:\/\/abandon.cvcmneja.cc',\n 'https:\/\/d3hw80p8c34pat.cloudfront.net'];\n}\nfunction JY_fallback() {\n \/\/ 仅在 jyFound 为空时被调用:生成固定兜底线路并持久化,\n \/\/ 保证后续 viewName \/ action \/ sortUrl 每次读到的都是同一组域名。\n var list = JY_fallbackFixed();\n JY_setFound(list);\n return list;\n}\n\nfunction JY_setFound(list) {\n source.put('jyFound', list.join(' '));\n var i;\n for (i = 0; i < JY_MAX; i++) source.put('jyDelay' + i, '');\n}\nfunction JY_found() {\n var s = JY_gv('jyFound', '');\n if (s === '') return JY_fallback();\n var a = s.split(\/\\s+\/), out = [], i;\n for (i = 0; i < a.length; i++) if (a[i].indexOf('http') === 0 && out.indexOf(a[i]) < 0) out.push(a[i]);\n return out.length ? out : JY_fallback();\n}\n\n\/\/ ---------- 🧭 一键从发布页获取网址路线 ----------\nfunction JY_fetchPub() {\n JY_toast('🧭 开始获取:正在打开发布页 ' + JY_pub());\n var raw = '', err = '';\n try {\n var r = java.connect(JY_pub() + '\/', JY_hdr(), 20000);\n raw = String(r.body());\n if (r.code && r.code() !== 200) err = 'HTTP ' + r.code();\n } catch (e) { err = String(e).substring(0, 80); }\n if (err === '' && (raw.length < 1000 || raw.indexOf('Exception') === 0)) err = '发布页内容异常';\n if (err !== '') {\n JY_toast('⚠ 发布页抓取失败(' + err + '),改用内置 3 条兜底线路');\n var fb = JY_fallback(); JY_setFound(fb);\n JY_toast('✅ 已载入内置线路 ' + fb.length + ' 条,请点「⏱测试延时」');\n JY_refresh(); return;\n }\n JY_toast('🔓 发布页已获取(' + raw.length + 'B),正在 Base64 解码…');\n var html = raw, dec = '';\n var m = \/Base64\\.decode\\(['\"]([A-Za-z0-9+\/=]+)['\"]\\)\/.exec(raw);\n if (m) {\n try { dec = String(java.base64Decode(m[1])); } catch (e) { dec = ''; }\n if (dec.length > 1000) html = dec;\n }\n var zz = \/zz_line\\s*=\\s*\"([^\"]+)\"\/.exec(html);\n var bases = [];\n if (zz) {\n var ls = zz[1].replace(\/\\\\n\/g, '\\n').replace(\/\\\\r\/g, '').split(\/\\r?\\n\/), i;\n for (i = 0; i < ls.length; i++) if (ls[i].trim()) bases.push(ls[i].trim());\n }\n if (!bases.length) {\n JY_toast('⚠ 未解析到 zz_line(发布页可能改版),改用内置 3 条兜底线路');\n var fb2 = JY_fallback(); JY_setFound(fb2);\n JY_toast('✅ 已载入内置线路 ' + fb2.length + ' 条');\n JY_refresh(); return;\n }\n JY_toast('🔍 解码成功,提取到 ' + bases.length + ' 条基础域:' + bases.join(' \/ '));\n var lines = JY_build(bases);\n JY_setFound(lines);\n JY_toast('✅ 共生成 ' + lines.length + ' 条线路,已写入各线路按钮;请点「⏱测试延时」测速');\n JY_refresh();\n}\n\n\/\/ ---------- ⏱ 测试延时(只回填 ms,不自动切换,避免误切) ----------\nfunction JY_testAll() {\n var list = JY_found();\n JY_toast('⏱ 开始测速:共 ' + list.length + ' 条线路,逐个请求 \/usr\/themes\/ping.gif…');\n var best = -1, bestMs = 999999, i, r, b, ms, tag;\n for (i = 0; i < list.length && i < JY_MAX; i++) {\n ms = -1; tag = '✗ 不可达';\n try {\n r = java.connect(list[i] + '\/usr\/themes\/ping.gif', JY_hdr(), 12000);\n b = String(r.body());\n if (b.indexOf('Exception') > -1 || b.indexOf('timeout') > -1 || (r.code && r.code() !== 200)) {\n tag = '✗ HTTP\/' + (r.code ? r.code() : '异常');\n } else if (b.length < 20) {\n tag = '✗ 内容异常';\n } else {\n ms = r.callTime ? Number(r.callTime()) : -1;\n if (ms < 0) ms = 0;\n tag = ms + 'ms';\n if (ms < bestMs) { bestMs = ms; best = i; }\n }\n } catch (e) { tag = '✗ ' + String(e).substring(0, 40); }\n source.put('jyDelay' + i, tag);\n JY_toast(' [' + (i + 1) + '\/' + list.length + '] ' + JY_host(list[i]) + ' → ' + tag);\n }\n if (best >= 0) {\n for (i = 0; i < list.length && i < JY_MAX; i++) {\n if (i === best) source.put('jyDelay' + i, '⚡' + bestMs + 'ms');\n }\n JY_toast('🏁 测速完成:最快 ' + JY_host(list[best]) + ' ' + bestMs + 'ms(点对应线路按钮即可切换)');\n } else {\n JY_toast('⚠ 测速完成:没有可用线路,请点「🧭获取发布页线路」刷新后重试');\n }\n JY_refresh();\n}\n\n\/\/ ---------- 🔍 检查登录状态 \/ 线路可用性(本站免登录,做连通性 + 登录墙检测) ----------\nfunction JY_checkLogin() {\n var d = JY_line();\n JY_toast('🔍 正在检查当前线路状态:' + JY_host(d));\n var b = '', code = 0;\n try {\n var r = java.connect(d + '\/', JY_hdr(), 15000);\n b = String(r.body()); code = r.code ? r.code() : 0;\n } catch (e) { JY_toast('❌ 检查失败:' + String(e).substring(0, 80)); return; }\n if (b.indexOf('Exception') > -1 || code !== 200 || b.length < 5000) {\n JY_toast('❌ 当前线路不可用(HTTP ' + code + ', ' + b.length + 'B),建议测速后切换线路'); return;\n }\n var needLogin = \/(请先登录|登录后查看|需要登录|会员专享|VIP专属)\/.test(b);\n var hasUser = \/(退出登录|wc-header-user-logged|side-toolbar-logout)\/.test(b);\n JY_toast('✅ 线路正常(' + b.length + 'B);' + (needLogin ? '⚠ 检测到登录墙(部分内容需登录)' : '本站内容免登录,可直接阅读全部图文') + (hasUser ? ';已检测到登录态' : ';当前为游客态'));\n}\n\n\/\/ ---------- ▶ 各线路切换(索引制,每站一个按钮) ----------\nfunction JY_switch(n) {\n var list = JY_found();\n var i = Number(n) - 1;\n if (i < 0 || i >= list.length) { JY_toast('⚠ 线路 ' + n + ' 尚未获取,请先点「🧭获取发布页线路」'); return; }\n var old = JY_line(), nw = list[i];\n JY_toast('🔄 正在切换:' + JY_host(old) + ' → ' + JY_host(nw));\n source.put('jyLine', nw);\n JY_toast('✅ 已切换到 ' + JY_host(nw) + ';请重新进入订阅\/发现页生效(如分类未刷新,用排序菜单「清理排序缓存」)');\n JY_refresh();\n}\n\n\/\/ ---------- 按钮动态文字:▶当前 \/ ⚡最快 \/ 域名 + 延时ms ----------\nfunction JY_host(u) {\n var m = \/^https?:\\\/\\\/([^\/]+)\/.exec(String(u));\n return m ? m[1] : String(u);\n}\nfunction JY_lineBtn(n) {\n var list = JY_found(), i = Number(n) - 1;\n if (i < 0 || i >= list.length) return \"'━━ 线路\" + n + \" 未获取 ━━'\";\n var cur = JY_line(), mark = (list[i].replace(\/\\\/+$\/, '') === cur.replace(\/\\\/+$\/, '')) ? '▶ ' : ' ';\n var dl = JY_gv('jyDelay' + i, '');\n if (dl !== '') mark += dl + ' ';\n return \"'\" + mark + JY_host(list[i]) + \"'\";\n}\nfunction JY_refresh() {\n try { java.reLoginView(); } catch (e) {\n try { java.reLoginView(false); } catch (e2) { JY_toast('(若按钮文字未刷新,请重新打开本面板)'); }\n }\n}\n\n\/\/ loginUrl 必须定义 login(),否则点击「登录」抛 Function login not implements\nfunction login(e) {\n if (e != undefined) { JY_toast(String(e)); return; }\n JY_toast('91爆料 · 线路管理面板(本站免登录)|先「🧭获取发布页线路」→「⏱测试延时」→ 点线路按钮切换');\n}\n",
"preload": false,
"ruleArticles": "article[itemtype=\"http:\/\/schema.org\/BlogPosting\"]",
"ruleContent": "@js:\n(function () {\n var NL = String.fromCharCode(10);\n var UA = 'Mozilla\/5.0 (Linux; Android 13; Pixel 7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/124.0.0.0 Mobile Safari\/537.36';\n var HDR = JSON.stringify({ 'User-Agent': UA });\n var pageUrl = String(baseUrl);\n \/\/ 线路自愈:文章链接可能落在旧线路域,正文请求改用当前选中线路重取同路径\n var cur = '';\n try { cur = String(source.get('jyLine')); } catch (e) { cur = ''; }\n if (cur === 'null' || cur === 'undefined' || cur === '' || cur.indexOf('http') !== 0) {\n cur = 'https:\/\/abandon.yixuiyyj.cc';\n }\n cur = cur.replace(\/\\\/+$\/, '');\n var path = \/^https?:\\\/\\\/[^\/]+(\\\/.*)$\/.exec(pageUrl);\n var fetchUrl = pageUrl;\n if (path && path[1]) fetchUrl = cur + path[1];\n\n var body = '';\n try {\n var r = java.connect(fetchUrl, HDR, 20000);\n body = String(r.body());\n } catch (e) { body = ''; }\n if (!body || body.length < 1000 || body.indexOf('Exception') === 0) {\n \/\/ 兜底:直接用文章原链接再取一次\n try {\n var r2 = java.connect(pageUrl, HDR, 20000);\n body = String(r2.body());\n } catch (e2) { body = ''; }\n }\n if (!body || body.length < 1000) {\n return '<div style=\"padding:16px;color:#c33\">正文加载失败:线路不可用或已失效,请到登录面板测速切换线路后重试。<\/div>';\n }\n\n \/\/ 定位正文容器(indexOf 边界扫描,避免正则把导航\/推荐区一起吞进去)\n var anchor = 'itemprop=\"articleBody\"';\n var st = body.indexOf(anchor);\n if (st < 0) {\n return '<div style=\"padding:16px;color:#c33\">正文容器未找到(站点可能改版),原页面:<a href=\"' + fetchUrl + '\">' + fetchUrl + '<\/a><\/div>';\n }\n var divStart = body.lastIndexOf('<div', st);\n var end = body.indexOf('<\/article>', st);\n if (end < 0) end = body.indexOf('id=\"body-bottom\"', st);\n if (end < 0) end = Math.min(body.length, st + 60000);\n var html = body.substring(divStart, end);\n\n \/\/ ① 懒加载图还原:把 z-image-loader-url 提为 src,保留 alt\/title\n html = html.replace(\/<img\\b([^>]*?)>\/gi, function (tag, attrs) {\n var m = \/z-image-loader-url\\s*=\\s*[\"']([^\"']+)[\"']\/i.exec(attrs);\n if (!m) return tag;\n var alt = \/alt\\s*=\\s*[\"']([^\"']*)[\"']\/i.exec(attrs);\n var title = \/title\\s*=\\s*[\"']([^\"']*)[\"']\/i.exec(attrs);\n var a = alt ? alt[1] : '';\n var t = title ? title[1] : a;\n return '<img data-jy-enc=\"' + m[1] + '\" alt=\"' + a + '\" title=\"' + t + '\" style=\"max-width:100%;height:auto;display:block;margin:8px auto;min-height:80px;background:#f0f0f0\">';\n });\n \/\/ ② 站点占位图(无 z-image-loader-url 的 zw.png)直接删\n html = html.replace(\/<img\\b[^>]*\\\/usr\\\/plugins\\\/tbxw\\\/zw\\.png[^>]*>\/gi, '');\n\n \/\/ ③ 剔除广告\/导航\/推荐\/播放器\/分享块\n \/\/ 实测(261107)关键结构:Typecho 主题把「猜你喜欢 \/ 热门推荐」插在正文**中段**(不是尾部),\n \/\/ 之后还有正文继续 ⇒ 绝不能「命中即从该处截断」(会丢掉后半篇文章)。\n \/\/ 定式 = ① div 配平删除法(从 <div class=...> 起数 <div \/ <\/div> 直到配平,整块删除,正文后半段保留)\n \/\/ ② 简单标记对删除(blockquote \/ style \/ script \/ 顶部广告位 \/ dplayer 容器)\n var jyReDiv = \/<div\\b|<\\\/div>\/gi;\n function JY_removeBalancedDiv(txt, startMark) {\n var guard = 0;\n while (guard < 12) {\n guard++;\n var s = txt.indexOf(startMark);\n if (s < 0) break;\n jyReDiv.lastIndex = s;\n var m, depth = 0, end = -1;\n while ((m = jyReDiv.exec(txt)) !== null) {\n if (m[0].toLowerCase() === '<\/div>') {\n depth--;\n if (depth === 0) { end = m.index + 6; break; }\n } else {\n depth++;\n }\n }\n if (end < 0) { txt = txt.substring(0, s) + txt.substring(s + startMark.length); break; }\n txt = txt.substring(0, s) + txt.substring(end);\n }\n return txt;\n }\n \/\/ ★★ 视频块:服务端用 java.ajaxAll 两轮并行取全部直链(彻底去掉 postAwait\/JS桥依赖)\n \/\/ 背景:页内 postAwait 依赖 preloadJs 注入 JS_INJECTION,链路易碎 → 用户报「视频获取失败」。\n \/\/ ajaxAll 实测 6 张票并行 ≈2.6s(串行 6 次 ≈21s),返回 Response 对象,.body 属性即正文字符串。\n \/\/ POST 通过 URL 选项 ,{\"method\":\"POST\"} 走 AnalyzeUrl(已实测 ticket 接口接受)。\n var JY_CID_M = \/\\\/archives\\\/(\\d+)\\\/\/.exec(fetchUrl);\n var jyCid = JY_CID_M ? JY_CID_M[1] : '0';\n var jyVideos = [];\n var jyCfgRe = \/data-config='([^']+)'\/g, jyCm;\n while ((jyCm = jyCfgRe.exec(body.substring(st, end))) !== null) {\n var cfgTxt = jyCm[1].replace(\/\\\\\\\/\/g, '\/');\n var idx = 0, poster = '';\n var im2 = \/[?&]idx=(\\d+)\/.exec(cfgTxt); if (im2) idx = Number(im2[1]);\n var pm2 = \/\"poster\"\\s*:\\s*\"([^\"]+)\"\/.exec(cfgTxt); if (pm2) poster = pm2[1];\n jyVideos.push({ idx: idx, poster: poster, src: '' });\n }\n \/\/ 第一轮:并行取全部一次性票\n var jyOpt = ',{\"method\":\"POST\"}';\n var jyTicketUrls = [], ji;\n for (ji = 0; ji < jyVideos.length; ji++) {\n jyTicketUrls.push(cur + '\/action\/player\/ticket?cid=' + jyCid + '&idx=' + jyVideos[ji].idx\n + '&_=' + Date.now().toString(36) + Math.random().toString(36).slice(2, 8) + ji + jyOpt);\n }\n var jyTickets = [];\n try {\n var jyTr = java.ajaxAll(jyTicketUrls, true);\n if (jyTr && jyTr.length !== undefined) {\n for (ji = 0; ji < jyTr.length; ji++) {\n var tk = '';\n try {\n var jb = jyTr[ji].body;\n var jbs = (typeof jb === 'function') ? String(jb.call(jyTr[ji])) : String(jb);\n tk = JSON.parse(jbs).data.ticket;\n } catch (e) {}\n jyTickets.push(tk);\n }\n }\n } catch (e) {}\n \/\/ 第二轮:并行换直链(每张票独立,表单 ticket + env={} + _ver=v0)\n var jyPlayUrls = [], jyBodies = [];\n for (ji = 0; ji < jyVideos.length; ji++) {\n if (!jyTickets[ji]) continue;\n var pBody = 'ticket=' + encodeURIComponent(jyTickets[ji]) + '&env=%7B%7D&_ver=v0';\n \/\/ ajax 的 POST body 走 URL 选项 {\"method\":\"POST\",\"body\":\"...\"}(AnalyzeUrl 支持)\n var popt = ',{\"method\":\"POST\",\"body\":' + JSON.stringify(pBody) + '}';\n jyPlayUrls.push(cur + '\/action\/player\/get_play_url?cid=' + jyCid + '&idx=' + jyVideos[ji].idx + popt);\n jyBodies.push(ji);\n }\n try {\n var jyPr = java.ajaxAll(jyPlayUrls, true);\n if (jyPr && jyPr.length !== undefined) {\n for (ji = 0; ji < jyPr.length; ji++) {\n try {\n var pb = jyPr[ji].body;\n var pbs = (typeof pb === 'function') ? String(pb.call(jyPr[ji])) : String(pb);\n var pj = JSON.parse(pbs);\n if (pj.status !== 0) continue;\n var pd = pj.data, pu = '';\n if (typeof pd === 'string' && pd.indexOf('http') === 0) pu = pd;\n else if (pd && pd.primary) pu = pd.primary;\n if (pu && jyBodies[ji] !== undefined) jyVideos[jyBodies[ji]].src = pu;\n } catch (e) {}\n }\n }\n } catch (e) {}\n \/\/ 把 <div class=\"vodplayer-container\">...<\/div><\/p> 替换为视频卡片(按出现顺序对应 jyVideos)\n var jyVidIdx = 0;\n html = html.replace(\/<div class=\"vodplayer-container\"[\\s\\S]*?<\\\/div>\\s*<\\\/div>\\s*<\\\/p>\/g, function (m0) {\n var n = jyVideos[jyVidIdx++];\n if (!n) return '';\n var pic = n.poster ? ' data-jy-poster=\"' + n.poster + '\"' : '';\n return '<div class=\"jy-vwrap\" style=\"position:relative\">'\n + '<video class=\"jy-v\" playsinline preload=\"none\"' + pic\n + ' style=\"width:100%;max-height:60vh;background:#000;display:block;border-radius:6px\"><\/video>'\n + '<button class=\"jy-playbtn\" type=\"button\" style=\"position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);'\n + 'background:rgba(0,0,0,.6);color:#fff;border:2px solid #fff;border-radius:40px;padding:12px 26px;'\n + 'font-size:16px;cursor:pointer;z-index:5\">▶ 点击播放<\/button>'\n + '<div class=\"jy-tip\" style=\"display:none;color:#0a58ca;font-size:13px;padding:6px 2px\">'\n + '视频 ' + (n.idx + 1) + ' · 直链有时效,失效请退出重进本文刷新<\/div>'\n + '<\/div>';\n });\n html = JY_removeBalancedDiv(html, '<div class=\"guess-like-post\"');\n html = JY_removeBalancedDiv(html, '<div class=\"hot-recommend-post\"');\n html = JY_removeBalancedDiv(html, '<div class=\"a2a_kit');\n html = JY_removeBalancedDiv(html, '<div class=\"flash\"');\n html = JY_removeBalancedDiv(html, '<div id=\"top-slot-btn\"');\n html = JY_removeBalancedDiv(html, '<div id=\"top-slot-img\"');\n \/\/ 简单标记对(无嵌套)\n var cuts = [['<blockquote>', '<\/blockquote>'], ['<style>', '<\/style>'], ['<script', '<\/script>']];\n var ci, from, to;\n for (ci = 0; ci < cuts.length; ci++) {\n var safe = 0;\n while (safe < 40) {\n safe++;\n from = html.indexOf(cuts[ci][0]);\n if (from < 0) break;\n to = html.indexOf(cuts[ci][1], from + cuts[ci][0].length);\n if (to < 0) { html = html.substring(0, from) + html.substring(from + cuts[ci][0].length); break; }\n html = html.substring(0, from) + html.substring(to + cuts[ci][1].length);\n }\n }\n \/\/ ④ 残留内联样式\/事件\/空壳\/分享尾巴清理\n html = html.replace(\/\\sonclick\\s*=\\s*[\"'][^\"']*[\"']\/gi, '');\n html = html.replace(\/\\sdata-config\\s*=\\s*'[^']*'\/gi, '');\n html = html.replace(\/\\sdata-video_[a-z_]+\\s*=\\s*\"[^\"]*\"\/gi, '');\n html = html.replace(\/<div class=\"bling\"[\\s\\S]*?<\\\/div>\/gi, '');\n html = html.replace(\/<!--[\\s\\S]*?-->\/g, '');\n html = html.replace(\/<p>\\s*<\\\/p>\/gi, '');\n html = html.replace(\/<aside\\b[^>]*>[\\s\\S]*?<\\\/aside>\/gi, '');\n \/\/ 收尾:若末尾残留未闭合的容器 div,截到最后一个 <\/p> 或 <\/h2> 之后\n var lastP = html.lastIndexOf('<\/p>'), lastH = html.lastIndexOf('<\/h2>');\n var cut = Math.max(lastP, lastH);\n if (cut > 0 && html.indexOf('<div class=\"bling\"') < 0) {\n \/\/ 只在尾部确属站点残留时截断(保持正文完整)\n var tail = html.substring(cut);\n if (\/^\\s*(?:<\\\/div>\\s*|<div\\b[^>]*>\\s*)*$\/i.test(tail)) html = html.substring(0, cut + 4);\n }\n\n \/\/ 标题 + 来源行 + 正文 + 视频播放器\n var tm = \/<title>([^<]*)<\\\/title>\/.exec(body);\n var tt = tm ? tm[1].replace(\/\\s*-\\s*91爆料\\s*$\/, '') : '';\n \/\/ 页内播放器脚本:只替换视频数据(JSON.stringify 保证转义安全)\n var jyPageJs = \"\/\/ 页内播放器 JS(直链已由 ruleContent 服务端 ajaxAll 并行取好,写进 JY_VIDEOS[i].src)\\n\/\/ ★ 用户要求:**只有用户点击才播放**,绝不全部一起自动播。\\n\/\/ 做法:video 初始无 src、无 controls、preload=none,上面盖一个「▶ 点击播放」按钮;\\n\/\/ 点按钮 → jyAttach(hls) + startLoad + play(),并暂停其它视频。\\nvar JY_VIDEOS = __JY_VIDEOS__;\\nvar JY_HLSES = [], JY_ATTACHED = [];\\nfunction jyTip(el, t) {\\n try { var n = el.parentNode.querySelector('.jy-tip'); if (n) { n.textContent = t; n.style.display = 'block'; } } catch (e) {}\\n}\\nfunction jyPauseOthers(except) {\\n try {\\n var vs = document.querySelectorAll('video.jy-v');\\n for (var i = 0; i < vs.length; i++) if (vs[i] !== except && !vs[i].paused) vs[i].pause();\\n } catch (e) {}\\n}\\nfunction jyAttach(v, src, i) {\\n if (!src || JY_ATTACHED[i]) return;\\n JY_ATTACHED[i] = true;\\n if (window.Hls && Hls.isSupported() && src.indexOf('.m3u8') > -1) {\\n try {\\n var h = new Hls({ enableSoftwareAES: true, maxBufferLength: 30, maxMaxBufferLength: 60, autoStartLoad: false });\\n h.loadSource(src); h.attachMedia(v);\\n h.on(Hls.Events.ERROR, function (e, d) {\\n if (!d.fatal) return;\\n if (d.type === Hls.ErrorTypes.NETWORK_ERROR) jyTip(v, '直链过期或网络失败,退出重进本文刷新');\\n else if (d.type === Hls.ErrorTypes.MEDIA_ERROR) { try { h.recoverMediaError(); } catch (x) {} }\\n else jyTip(v, '播放出错,退出重进本文刷新');\\n });\\n JY_HLSES[i] = h;\\n return;\\n } catch (e) {}\\n }\\n v.src = src;\\n}\\nfunction jyPlayOnClick(v, i) {\\n try {\\n var n = JY_VIDEOS[i];\\n if (!n || !n.src) { jyTip(v, '该视频直链获取失败,退出重进本文可刷新'); return; }\\n jyPauseOthers(v); \/\/ 同一时刻只播一个\\n jyAttach(v, n.src, i);\\n if (JY_HLSES[i]) { try { JY_HLSES[i].startLoad(); } catch (e) {} }\\n v.controls = true; \/\/ 播放后才给原生控件\\n var p = v.play();\\n if (p && p.catch) p.catch(function () {});\\n var btn = v.parentNode.querySelector('.jy-playbtn');\\n if (btn) btn.style.display = 'none';\\n } catch (e) {}\\n}\\nfunction jyBoot() {\\n try {\\n var vids = document.querySelectorAll('video.jy-v');\\n for (var i = 0; i < vids.length; i++) {\\n (function (v, i) {\\n try {\\n var btn = v.parentNode.querySelector('.jy-playbtn');\\n if (btn) btn.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); jyPlayOnClick(v, i); });\\n \/\/ 点视频区域(poster 区)也等同点按钮\\n v.addEventListener('click', function (e) { e.preventDefault(); jyPlayOnClick(v, i); });\\n } catch (e) {}\\n })(vids[i], i);\\n }\\n } catch (e) {}\\n}\\n\/\/ hls.js 用 async 加载,但绑定点击不依赖它(用户点击时若还没就绪,jyAttach 会走原生兜底;\\n\/\/ 8 秒后补一次,保证点击晚于脚本加载的场景能用 hls)\\nfunction jyEnsureHls() {\\n jyBoot();\\n var h = document.getElementById('jy-hls');\\n if (h && !window.Hls) {\\n h.addEventListener('error', function () {\\n var s = document.createElement('script');\\n s.src = 'https:\/\/s4.zstatic.net\/ajax\/libs\/hls.js\/1.6.13\/hls.min.js';\\n (document.head || document.body).appendChild(s);\\n });\\n }\\n}\\nif (document.readyState === 'complete' || document.readyState === 'interactive') {\\n setTimeout(jyEnsureHls, 0);\\n} else {\\n document.addEventListener('DOMContentLoaded', function () { setTimeout(jyEnsureHls, 0); });\\n}\\n\".replace('__JY_VIDEOS__', JSON.stringify(jyVideos));\n var out = '<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">'\n + '<style>body{margin:0;padding:12px 14px;background:#fff;color:#222;font-size:16px;line-height:1.85;word-wrap:break-word}'\n + 'img{max-width:100%!important;height:auto!important}h1{font-size:20px;line-height:1.5;margin:6px 0 14px}'\n + 'h2{font-size:18px;margin:18px 0 8px}p{margin:10px 0}a{color:#0a58ca;word-break:break-all}'\n + '.jy-src{color:#888;font-size:12px;border-bottom:1px solid #eee;padding-bottom:8px;margin-bottom:14px}'\n + '.jy-vwrap{margin:14px 0;background:#000;border-radius:6px;overflow:hidden}'\n + 'blockquote{margin:8px 0;padding:8px 12px;background:#f7f7f7;border-left:3px solid #ddd}<\/style>'\n + '<script id=\"jy-hls\" async src=\"' + cur + '\/usr\/plugins\/ArtPlayer\/assets\/hls.min.js?v=1.6.7\"><\\\/script>'\n + '<\/head><body>'\n + (tt ? '<h1>' + tt + '<\/h1>' : '')\n + '<div class=\"jy-src\">91爆料 · 当前线路 ' + cur + ' · 含 ' + jyVideos.length + ' 段视频(点击视频下方文字可刷新直链)<\/div>'\n + html\n + '<script>' + \"\/\/ 正文图片页内解密(pic.hdhwqx.cn AES-128-CBC)\\n\/\/ 优先 Web Crypto crypto.subtle(原生毫秒级),不可用时回退纯 JS AES。\\n\/\/ 不依赖 preloadJs \/ JS 桥:本脚本直接内联在 ruleContent 输出的 HTML 里(由 script 标签包裹)。\\n\/\/ 图片域 ACAO:* 已实测,fetch 可跨域;baseUrl 为 https → 安全上下文,subtle 可用。\\n(function () {\\n var KEY = 'f5d965df75336270', IV = '97b60394abc2fbe1';\\n function sb(x){var a=new Uint8Array(x.length);for(var i=0;i<x.length;i++)a[i]=x.charCodeAt(i)&255;return a}\\n var KB = sb(KEY), IVB = sb(IV);\\n function mime(u8){\\n if(u8.length>=3&&u8[0]===0x47&&u8[1]===0x49&&u8[2]===0x46)return 'image\/gif';\\n if(u8.length>=2&&u8[0]===0xff&&u8[1]===0xd8)return 'image\/jpeg';\\n if(u8.length>=4&&u8[0]===0x89&&u8[1]===0x50)return 'image\/png';\\n if(u8.length>=12&&u8[8]===0x57&&u8[9]===0x45&&u8[10]===0x42&&u8[11]===0x50)return 'image\/webp';\\n return 'image\/jpeg';\\n }\\n function setImg(img, u8){\\n try{\\n var blob=new Blob([u8],{type:mime(u8)});\\n var u=URL.createObjectURL(blob);\\n img.src=u; img.removeAttribute('data-jy-enc');\\n }catch(e){}\\n }\\n \/\/ ---- 纯 JS AES 兜底(Web Crypto 不可用时)----\\n var SBOX=[0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];\\n var INV=new Uint8Array(256),RCON=[1,2,4,8,16,32,64,128,27,54],q;for(q=0;q<256;q++)INV[SBOX[q]]=q;\\n function xt(a){return ((a<<1)^((a&128)?27:0))&255}\\n function mul(a,b){var r=0;while(b){if(b&1)r^=a;a=xt(a);b>>=1}return r}\\n function expK(k){var w=[],i,j,t,r;for(i=0;i<16;i++)w.push(k[i]);for(i=16;i<176;i+=4){t=[w[i-4],w[i-3],w[i-2],w[i-1]];if(i%16===0){var z=t[0];t[0]=SBOX[t[1]]^RCON[i\/16-1];t[1]=SBOX[t[2]];t[2]=SBOX[t[3]];t[3]=SBOX[z]}for(j=0;j<4;j++)w.push((w[i+j-16]^t[j])&255)}var R=[];for(r=0;r<=10;r++){var s=[];for(i=0;i<16;i++)s.push(w[r*16+i]);R.push(s)}return R}\\n function ark(s,k){for(var i=0;i<16;i++)s[i]^=k[i]}\\n function isr(s){var t=s.slice(0);s[1]=t[13];s[5]=t[1];s[9]=t[5];s[13]=t[9];s[2]=t[10];s[6]=t[14];s[10]=t[2];s[14]=t[6];s[3]=t[7];s[7]=t[11];s[11]=t[15];s[15]=t[3]}\\n function isb(s){for(var i=0;i<16;i++)s[i]=INV[s[i]]}\\n function imc(s){for(var c=0;c<4;c++){var i=c*4,a0=s[i],a1=s[i+1],a2=s[i+2],a3=s[i+3];s[i]=mul(a0,14)^mul(a1,11)^mul(a2,13)^mul(a3,9);s[i+1]=mul(a0,9)^mul(a1,14)^mul(a2,11)^mul(a3,13);s[i+2]=mul(a0,13)^mul(a1,9)^mul(a2,14)^mul(a3,11);s[i+3]=mul(a0,11)^mul(a1,13)^mul(a2,9)^mul(a3,14)}}\\n function decB(b,R){var s=b.slice(0),r;ark(s,R[10]);for(r=9;r>=0;r--){isr(s);isb(s);ark(s,R[r]);if(r>0)imc(s)}return s}\\n function jsDec(u8){var n=u8.length,i,j;if(!n||n%16)return null;var R=expK(Array.prototype.slice.call(KB)),out=new Uint8Array(n),prev=Array.prototype.slice.call(IVB);\\n for(i=0;i<n;i+=16){var blk=Array.prototype.slice.call(u8.subarray(i,i+16)),d=decB(blk,R);\\n for(j=0;j<16;j++)out[i+j]=d[j]^prev[j];prev=blk}\\n var pad=out[n-1];if(pad<1||pad>16)return null;\\n for(i=n-pad;i<n;i++)if(out[i]!==pad)return null;\\n return out.subarray(0,n-pad)}\\n\\n function decryptOne(img){\\n var u=img.getAttribute('data-jy-enc');\\n if(!u)return;\\n fetch(u,{mode:'cors'}).then(function(r){return r.arrayBuffer()}).then(function(buf){\\n var enc=new Uint8Array(buf);\\n if(enc.length%16)throw new Error('len');\\n if(window.crypto&&window.crypto.subtle&&window.crypto.subtle.importKey){\\n return window.crypto.subtle.importKey('raw',KB,{name:'AES-CBC'},false,['decrypt'])\\n .then(function(k){return window.crypto.subtle.decrypt({name:'AES-CBC',iv:IVB},k,buf)})\\n .then(function(d){return new Uint8Array(d)});\\n }\\n return jsDec(enc);\\n }).then(function(u8){if(u8&&u8.length)setImg(img,u8)}).catch(function(){});\\n }\\n function boot(){\\n var imgs=document.querySelectorAll('img[data-jy-enc]');\\n for(var i=0;i<imgs.length;i++)decryptOne(imgs[i]);\\n \/\/ video 的 poster 也是加密图:借用临时 img 解密后把 blob URL 赋给 video.poster\\n var vs=document.querySelectorAll('video[data-jy-poster]');\\n for(var k=0;k<vs.length;k++){\\n (function(v){\\n var tmp=new Image();\\n tmp.setAttribute('data-jy-enc',v.getAttribute('data-jy-poster'));\\n decryptOne(tmp);\\n \/\/ decryptOne 是异步,轮询等 tmp.src 变成 blob:\\n var n=0,t=setInterval(function(){\\n n++;\\n if(tmp.src&&tmp.src.indexOf('blob:')===0){v.poster=tmp.src;clearInterval(t)}\\n else if(n>100)clearInterval(t);\\n },100);\\n })(vs[k]);\\n }\\n }\\n if(document.readyState==='complete'||document.readyState==='interactive')setTimeout(boot,0);\\n else document.addEventListener('DOMContentLoaded',function(){setTimeout(boot,0)});\\n})();\" + '<\\\/script>'\n + '<script>' + jyPageJs + '<\\\/script>'\n + '<\/body><\/html>';\n return out;\n})()",
"ruleImage": "@js:(function(){try{var e=result.select('img[z-image-loader-url]');var u=e.size()>0?String(e.get(0).attr('z-image-loader-url')):'';if(!u){var i=result.select('img[src]');if(i.size()>0)u=String(i.get(0).attr('src'))}if(!u)return '';var k=u.indexOf(':\/\/');if(k<0)return u;var head=u.substring(0,k+3);var rest=u.substring(k+3);while(rest.indexOf('\/\/')===0)rest=rest.substring(1);while(rest.indexOf('\/\/')>-1)rest=rest.split('\/\/').join('\/');return head+rest}catch(e){return ''}})()",
"ruleLink": "@js:(function(){try{var e=result.select('a[href]');if(e.size()>0){return e.get(0).attr('href')}return ''}catch(e){return ''}})()",
"ruleNextPage": "PAGE",
"rulePubDate": "@js:(function(){try{var e=result.select('[itemprop=datePublished]');if(e.size()>0){var c=e.get(0).attr('content');if(c)return c;return e.get(0).text()}return ''}catch(e){return ''}})()",
"ruleTitle": "@js:(function(){try{var e=result.select('.post-card-title');if(e.size()>0){return e.get(0).ownText()}return ''}catch(e){return ''}})()",
"searchUrl": "{{(function(){var d='';try{d=String(source.get('jyLine'))}catch(e){d=''}if(d==='null'||d==='undefined'||d===''||d.indexOf('http')!==0){d='https:\/\/abandon.yixuiyyj.cc'}d=d.replace(\/\\\/+$\/,'');var p=(page&&page>1)?page:1;return d+'\/search\/'+encodeURIComponent(key)+'\/'+p+'\/'})()}}",
"shouldOverrideUrlLoading": "if (\/^https?:\\\/\\\/\/.test(url)) {\n var ok = \/(yixuiyyj\\.cc|cvcmneja\\.cc|cloudfront\\.net|pic\\.hdhwqx\\.cn|op\\.udhhzr\\.cn|oolrvd\\.cn|udhhzr\\.cn|s4\\.zstatic\\.net|jybl2[0-9]\\.com|91bl[a-z0-9]*\\.com|abandon\\.)\/.test(url);\n if (!ok) { java.toast('已拦截外部跳转:' + url); true; } else { false; }\n} else { false; }",
"showWebLog": false,
"singleUrl": false,
"sortUrl": "@js:\n(function () {\n var d = '';\n try { d = String(source.get('jyLine')); } catch (e) { d = ''; }\n if (d === 'null' || d === 'undefined' || d === '' || d.indexOf('http') !== 0) {\n d = 'https:\/\/abandon.yixuiyyj.cc';\n }\n d = d.replace(\/\\\/+$\/, '');\n var C = [\n ['📰 最新', ''],\n ['🍉 今日吃瓜', 'jrcg1'], ['🏆 每日大赛', 'mrds'], ['🤖 AI短剧', 'aiduanju'],\n ['🎀 萝莉jk', 'lljk'], ['🌐 网黄资源', 'ylgx'], ['🔥 热门大瓜', 'rgjx'],\n ['🌊 海角伦理', 'llzq'], ['💥 反差爆料', 'fcsj'], ['📺 st站直播回放', 'stzzb'],\n ['🏫 校园爆料', 'xyrg'], ['📷 探花偷拍', 'lpzq'], ['🎬 AV动漫', 'gcqs'],\n ['🔍 全网疯求', 'qwfq'], ['⭐ 明星爆料', 'whbg'], ['🎭 奇闻异事', 'qwys'],\n ['🎨 AI成人漫剧', 'aimj'], ['🌐 体育直播', 'tycg']\n ];\n var out = [], i, name, seg, line;\n for (i = 0; i < C.length; i++) {\n name = C[i][0]; seg = C[i][1];\n if (seg === '') {\n line = name + '::' + d + '\/page\/{{page}}\/';\n } else {\n line = name + '::' + d + '\/category\/' + seg + '\/{{page}}\/';\n }\n out.push(line);\n }\n return out.join('\\n');\n})()",
"sourceComment": "发布页 https:\/\/jybl26.com(Base64编码,zz_line 3条泛子域线路);内容站 Typecho Mirages,17分类,路径式分页;免登录。正文含图文+多视频:两步票据协议取 AES-128 HLS 直链,hls.js 播放,页内 postAwait 自愈(直链短时效+正文缓存)。登录面板可获取发布页线路\/测速\/切换\/检查登录状态。兼容 LegadoTeam 与 legado-E。",
"sourceGroup": "R18,AI",
"sourceIcon": "https:\/\/jybl26.com\/favicon.ico?v=1",
"sourceName": "91爆料·吃瓜",
"sourceUrl": "https:\/\/abandon.yixuiyyj.cc\/",
"style": "img{max-width:100%!important;height:auto!important;display:block;margin:8px auto;}video{max-width:100%!important;background:#000}body{padding:0 12px;word-wrap:break-word;}",
"type": 0,
"variableComment": "jyLine=当前线路(默认 https:\/\/abandon.yixuiyyj.cc);jyPub=发布页地址;jyFound=已获取线路列表;jyDelay0..5=各线路测速结果"
}