javascript:(async()=>{
/* === 重複起動防止 === */
if(window.__prRunning){ console.log('[PR] already running'); return } window.__prRunning=true;
/* === 基本変数・共通ユーティリティ === */
const D=document, B=D.body, CE=e=>D.createElement(e), ST=setTimeout, JP=JSON.parse, T8=new TextDecoder, T16=new TextDecoder('utf-16le'), done=new Set;
/* === CSS注入 === */
if(!D.getElementById('pr-style')){ const S=CE('style'); S.id='pr-style'; S.textContent=` #pr-ovly{ position:fixed; inset:0; background:#0008; z-index:999999; display:flex; align-items:center; justify-content:center; font-family:sans-serif } #pr-mdl{ background:#111; color:#eee; width:90%; max-width:800px; max-height:90vh; overflow:auto; border-radius:16px; padding:20px } .pr-b{ margin:0 0 12px; background:#1a1a1a; border-radius:10px; overflow:hidden } .pr-h{ display:flex; align-items:center; padding:10px 14px; background:#222; cursor:pointer } .pr-h b{ flex:1 } .pr-t{ padding:14px; white-space:pre-wrap; word-break:break-word; font:12px monospace } .pr-c{ margin-left:8px; background:none; border:1px solid #888; color:#fff; border-radius:4px; padding:2px 8px; cursor:pointer } .info-btn{ margin-left:6px; font:11px monospace; padding:2px 7px; border-radius:4px; border:1px solid #aaa; background:#fff; cursor:pointer } .pr-none{ color:#888; text-align:center; padding:24px; font-size:14px }
/* === sidebar === */
#pr-side{ position:fixed; left:0; top:0; width:170px; height:100vh; background:#111d; backdrop-filter:blur(6px); z-index:999998; transition:left .2s; overflow:hidden; font-size:0; box-shadow:0 0 20px #0008 } #pr-side.hide{ left:-146px } #pr-side-handle{ position:absolute; right:0; top:10px; width:24px; height:56px; background:#222; color:#fff; display:flex; align-items:center; justify-content:center; cursor:pointer; border-radius:8px 0 0 8px; font:14px sans-serif; user-select:none } #pr-side-handle:hover{ background:#333 } #pr-side-list{ height:100%; overflow-y:auto; padding:6px 28px 6px 6px; box-sizing:border-box } .pr-side-thumb{ position:relative; width:100%; margin:0 0 8px; border-radius:8px; overflow:hidden; cursor:pointer; border:2px solid #333; transition:.15s; background:#000 } .pr-side-thumb:hover{ border-color:#7af; transform:scale(1.03) } .pr-side-thumb img{ display:block; width:100%; height:auto } .pr-side-num{ position:absolute; right:4px; bottom:4px; background:#000c; color:#fff; font:11px monospace; padding:2px 4px; border-radius:4px } `; D.head.appendChild(S); }
/* === sidebar create === */
const SIDE=CE('div');
/* 初期状態を閉じる */
SIDE.id='pr-side'; SIDE.className='hide'; SIDE.innerHTML=`
▶
`; B.appendChild(SIDE); const SIDE_LIST=D.getElementById('pr-side-list');
/* === sidebar toggle === */
D.getElementById('pr-side-handle').onclick=e=>{ SIDE.classList.toggle('hide'); e.target.textContent= SIDE.classList.contains('hide') ?'▶' :'◀'; };
/* === decoder strategy === */
const dec={ u8:v=>T8.decode(v), u16:v=>T16.decode(v) };
/* === parser registry === */
const parsers={ nai:r=>{ try{ const j=JP(r); return{ p:j.prompt||'', n:j.uc||'', e:JSON.stringify(j,null,2), c:j.v4_prompt?.caption?.char_captions ?.map(v=>v.char_caption?.trim()) ?.filter(Boolean) } }catch{} }, a1111:r=>{ const nm=r.match(/\nNegative prompt:\s*/i), sm=r.match(/\n(Steps|Sampler|CFG|Seed|Size|Model)/i); let p='', n='', e=''; if(nm){ p=r.slice(0,nm.index).trim(); const a=r.slice(nm.index+nm[0].length); if(sm){ const i=a.search(/\n(Steps|Sampler|CFG|Seed|Size|Model)/i); if(i>=0){ n=a.slice(0,i).trim(); e=a.slice(i).trim(); }else n=a.trim(); }else n=a.trim(); }else if(sm){ const i=r.search(/\n(Steps|Sampler|CFG|Seed|Size|Model)/i); p=r.slice(0,i).trim(); e=r.slice(i).trim(); }else p=r.trim(); return{p,n,e} }, comfy:r=>{ try{ const j=JP(r), ps=[], ns=[]; (Object.values(j.nodes||j)).forEach(n=>{ if(n?.class_type=='CLIPTextEncode'){ const t=n.inputs?.text||''; ((n._meta?.title||'') .toLowerCase() .includes('neg') ?ns :ps).push(t) } }); return{ p:ps.join('\n'), n:ns.join('\n'), e:'ComfyUI Workflow' } }catch{} } };
/* === provider detect === */
const detect=r=>{ if(!r)return''; try{ const j=JP(r); if(j.prompt||j.uc)return'nai'; if(j.nodes)return'comfy'; }catch{} if(/Negative prompt:/i.test(r)) return'a1111'; return''; };
/* === PNG metadata reader === */
const rPNG=async b=>{ const v=new DataView(b), c={}; let o=8; while(ob.byteLength)break; const l=v.getUint32(o); o+=4; const t=String.fromCharCode( v.getUint8(o), v.getUint8(o+1), v.getUint8(o+2), v.getUint8(o+3) ); o+=4; if(o+l>b.byteLength||t=='IDAT')break; const d=new Uint8Array(b,o,l); o+=l+4; if(t=='tEXt'||t=='iTXt'||t=='zTXt'){ const s=d.indexOf(0); if(s!=-1){ const k=T8.decode(d.slice(0,s)); let val=''; try{ if(t=='zTXt'){ const ds=new DecompressionStream('deflate'); const rb=new Response( new Blob([d.slice(s+2)]) .stream() .pipeThrough(ds) ); val=dec.u8( new Uint8Array(await rb.arrayBuffer()) ); }else{ val=dec.u8( d.slice( t=='iTXt' ?d.lastIndexOf(0)+1 :s+1 ) ); } c[k]=val; }catch{} } } if(t=='IEND')break; } return c; };
/* === Exif metadata reader === */
const rExif=b=>{ const u=new Uint8Array(b), lim=Math.min(u.length-1,65536); for(let i=0;iparsers[detect(r)]?.(r);
/* === UI block generator === */
const blk=(l,t,c)=>{ const b=CE('div'); b.className='pr-b'; b.innerHTML=` ${l} ${c?'+':'-'}
`; const tx=b.querySelector('.pr-t'), tg=b.querySelector('span'); tx.textContent=t; c&&(tx.style.display='none'); b.querySelector('.pr-h').onclick=e=>{ if(e.target.className=='pr-c')return; const h=tx.style.display=='none'; tx.style.display=h?'block':'none'; tg.textContent=h?'-':'+'; }; b.querySelector('.pr-c').onclick=e=>{ e.stopPropagation(); navigator.clipboard.writeText(t); e.target.textContent='DONE'; ST(()=>e.target.textContent='COPY',1200); }; return b; };
/* === modal === */
const pop=(r,noMeta)=>{ const o=CE('div'), m=CE('div'); o.id='pr-ovly'; m.id='pr-mdl'; if(noMeta){ const d=CE('div'); d.className='pr-none'; d.textContent='⚠️ メタデータが見つかりませんでした'; m.appendChild(d); }else{ r.c?.forEach((v,i)=> m.appendChild(blk('CHAR '+(i+1),v)) ); r.p&&m.appendChild(blk('PROMPT',r.p)); r.n&&m.appendChild(blk('NEGATIVE',r.n)); r.e&&m.appendChild(blk('INFO',r.e,1)); } o.onclick=()=>o.remove(); m.onclick=e=>e.stopPropagation(); B.appendChild(o).appendChild(m); };
/* === ordered sidebar thumb add === */
const sideDone=new Set; const sideItems=[]; const addSideThumb=(img,target,resNo)=>{ if(!img?.src||sideDone.has(img.src))return; sideDone.add(img.src); const pos=[...D.querySelectorAll('table,div.thre')] .indexOf(target); const item=CE('div'); item.className='pr-side-thumb'; item.innerHTML=`
No.${resNo||'?'}
`; item.onclick=()=>{ target.scrollIntoView({ behavior:'smooth', block:'center' }); target.animate([ { boxShadow:'0 0 0 3px #7af' }, { boxShadow:'0 0 0 0px transparent' } ],{ duration:1200 }); }; sideItems.push({ pos, el:item }); sideItems.sort((a,b)=> a.pos-b.pos ); SIDE_LIST.textContent=''; for(const v of sideItems) SIDE_LIST.appendChild(v.el); };
/* === HEAD確認 → GET Range === */
const IMG_CT=/^image\/(png|jpeg|webp)/i; const chk=async u=>{ try{ const h=await fetch(u,{method:'HEAD'}); if(!h.ok&&h.status!==206)return null; const ct=h.headers.get('content-type')||''; if(!IMG_CT.test(ct)) return null; }catch{} try{ const g=await fetch(u,{ headers:{Range:'bytes=0-65535'} }); if(!g.ok&&g.status!==206&&g.status!==200) return null; const b=await g.arrayBuffer(); const c=await rPNG(b); const raw= c.parameters|| c.Comment|| Object.values(c)[0]|| rExif(b); const r=parse(raw); if(r?.p||r?.n||r?.e) return r; return false; }catch{ return null; } };
/* === request queue === */
const q=[], lim=6; let act=0; const run=_=>{ if(act>=lim||!q.length)return; act++; q.shift()() .finally(_=>(act--,run())); }; const enq=f=>{ q.push(f); run(); };
/* === direct image page detect === */
const re=/\.(png|jpe?g|webp)$/i; const isD= re.test(location.href)|| D.contentType?.startsWith('image/')|| (B?.children.length==1&& B.firstElementChild?.tagName=='IMG'); if(isD){ const r=await chk(location.href); if(r)pop(r); else pop(null,true); return; }
/* === image link scanner === */
const scn=_=>{ for(const t of D.links){ if(!done.has(t.href)&&re.test(t.href)){ done.add(t.href); enq(async()=>{ const r=await chk(t.href); if(r){ const b=CE('button'); b.className='info-btn'; b.textContent='Info'; b.onclick=e=>{ e.preventDefault(); e.stopPropagation(); pop(r); }; t.after(b); const box=t.closest('table,div.thre'); const im=box?.querySelector('img'); const no=box?.querySelector('.cno') ?.textContent ?.replace('No.',''); if(im){ addSideThumb( im, box, no ); } } }); } } };
/* === 初回実行 === */
scn();
/* === 動的監視 === */
new MutationObserver(scn) .observe(B,{ childList:true, subtree:true }); })();