commenting-visual-explainers/public/widget.js
2026-03-20 13:30:40 +09:00

3 lines
34 KiB
JavaScript

"use strict";(()=>{var k={must:{bg:"#ef4444",text:"#fff",light:"rgba(239,68,68,0.1)",border:"rgba(239,68,68,0.3)"},better:{bg:"#f59e0b",text:"#fff",light:"rgba(245,158,11,0.1)",border:"rgba(245,158,11,0.3)"},want:{bg:"#22c55e",text:"#fff",light:"rgba(34,197,94,0.1)",border:"rgba(34,197,94,0.3)"}};var _={must:"better",better:"want",want:"must"};var S="fb-username",M="fb-sidebar-width";function W(t){return t.replace(/^https?:\/\//,"").replace(/[^a-zA-Z0-9\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]/g,"_").substring(0,100)}function z(){return Date.now().toString(36)+Math.random().toString(36).substring(2,8)}function j(t){let e={"Content-Type":"application/json"};return t&&(e.Authorization="Bearer "+t),e}var q="",F="";function D(t,e){q=t,F=e}function y(t,e){let n=q+"/api/comments",r=j(F),s={method:t,headers:r};return t==="GET"?n+="?slug="+encodeURIComponent(e.slug):t==="DELETE"?n+="?id="+encodeURIComponent(e.id):s.body=JSON.stringify(e),fetch(n,s).then(i=>i.json())}var o={username:localStorage.getItem(S)||"",comments:[],filter:"unresolved",sidebarOpen:!1,selectedText:"",selectedQuoteContext:{beforeText:"",afterText:""},selectedRect:null,popupContent:"",editingId:null,editContent:"",editPriority:"want",replyingTo:null,replyText:"",editingName:!1,nameInput:"",popupPriority:"must",sidebarWidth:parseInt(localStorage.getItem(M)||"",10)||400},I=W(window.location.href);function U(){let t=document.createElement("style");t.id="fb-widget-styles",t.textContent=[':root{--fb-bg:#ffffff;--fb-fg:#0a0a0a;--fb-muted:#f5f5f5;--fb-muted-fg:#737373;--fb-border:#e5e5e5;--fb-primary:#171717;--fb-primary-fg:#fafafa;--fb-accent:#3b82f6;--fb-destructive:#ef4444;--fb-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Hiragino Sans",sans-serif}',"#fb-toggle{position:fixed;right:0;top:50%;transform:translateY(-50%);width:36px;background:var(--fb-bg);border:1px solid var(--fb-border);border-right:none;border-radius:8px 0 0 8px;cursor:pointer;z-index:99999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;font-family:var(--fb-font);transition:all .15s;box-shadow:-2px 0 8px rgba(0,0,0,0.06);padding:8px 0}","#fb-toggle:hover{background:var(--fb-muted);box-shadow:-2px 0 12px rgba(0,0,0,0.1)}","#fb-toggle .fb-toggle-icon{color:var(--fb-muted-fg);display:flex;align-items:center;justify-content:center;position:relative}","#fb-toggle .fb-toggle-label{font-size:10px;color:var(--fb-accent);font-weight:700;writing-mode:vertical-rl;letter-spacing:1px;line-height:1;white-space:nowrap}","#fb-toggle .fb-badge{position:absolute;top:-6px;left:-6px;background:var(--fb-destructive);color:#fff;font-size:9px;font-weight:700;min-width:16px;height:16px;border-radius:8px;display:flex;align-items:center;justify-content:center;padding:0 3px;line-height:1}","#fb-sidebar{position:fixed;top:0;height:100vh;background:rgba(245,245,245,0.5);border-left:1px solid var(--fb-border);z-index:99998;transition:right .3s ease;display:flex;flex-direction:column;font-family:var(--fb-font);font-size:14px;color:var(--fb-fg)}","#fb-sidebar *{box-sizing:border-box}",".fb-resize-handle{position:absolute;left:-3px;top:0;width:6px;height:100%;cursor:col-resize;z-index:1}",".fb-resize-handle:hover{background:rgba(59,130,246,0.15)}",".fb-resize-handle.active{background:rgba(59,130,246,0.3)}","body.fb-resizing{cursor:col-resize !important;-webkit-user-select:none !important;user-select:none !important}","body.fb-resizing *{cursor:col-resize !important}",".fb-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--fb-border)}",".fb-header-left{display:flex;align-items:center;gap:8px}",".fb-header-title{font-size:14px;font-weight:700;color:var(--fb-accent)}",".fb-header-count{background:var(--fb-muted);color:var(--fb-muted-fg);font-size:11px;padding:1px 7px;border-radius:10px}",".fb-header-actions{display:flex;align-items:center;gap:2px}",".fb-hdr-btn{background:none;border:none;cursor:pointer;padding:6px;border-radius:6px;color:var(--fb-muted-fg);transition:all .15s;display:inline-flex;align-items:center;gap:4px;font-family:var(--fb-font);font-size:12px}",".fb-hdr-btn:hover{background:var(--fb-muted);color:var(--fb-fg)}",".fb-user-row{display:flex;align-items:center;padding:8px 16px;border-bottom:1px solid var(--fb-border);font-size:13px;color:var(--fb-muted-fg);cursor:pointer;transition:color .15s;gap:6px}",".fb-user-row:hover{color:var(--fb-fg)}",".fb-filters{display:flex;border-bottom:1px solid var(--fb-border)}",".fb-filter{flex:1;padding:10px 0;text-align:center;font-size:13px;color:var(--fb-muted-fg);border:none;background:none;cursor:pointer;border-bottom:2px solid transparent;transition:all .15s;font-family:var(--fb-font)}",".fb-filter:hover{color:var(--fb-fg)}",".fb-filter.active{color:var(--fb-fg);border-bottom-color:var(--fb-accent)}",".fb-filter .cnt{font-size:11px;margin-left:4px;padding:1px 5px;border-radius:8px;background:var(--fb-muted);color:var(--fb-muted-fg)}",".fb-filter.active .cnt{background:rgba(59,130,246,0.1);color:var(--fb-accent)}",".fb-list{flex:1;overflow-y:auto;padding:8px}",".fb-empty{text-align:center;padding:60px 20px;color:var(--fb-muted-fg);font-size:13px}",".fb-empty svg{margin:0 auto 12px;display:block;color:var(--fb-border)}",".fb-card{background:var(--fb-bg);border:1px solid var(--fb-border);border-left:3px solid var(--fb-border);border-radius:12px;padding:14px;margin-bottom:6px;transition:box-shadow .3s,background .3s;cursor:pointer}",".fb-card:hover{box-shadow:0 1px 3px rgba(0,0,0,0.05)}",".fb-card.resolved{opacity:.5}",".fb-card-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}",".fb-card-head-left{display:flex;align-items:center;gap:6px}",".fb-avatar{width:22px;height:22px;border-radius:50%;background:var(--fb-primary);color:var(--fb-primary-fg);display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;flex-shrink:0}",".fb-author{font-size:13px;font-weight:700;color:var(--fb-fg)}",".fb-time{font-size:11px;color:var(--fb-muted-fg)}",".fb-resolved-mark{font-size:11px;color:#22c55e;margin-left:4px;display:inline-flex;align-items:center;gap:2px}",".fb-badge-p{font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;color:#fff;cursor:default;transition:all .15s}",".fb-badge-p.own{cursor:pointer}",".fb-badge-p.own:hover{transform:scale(1.1);box-shadow:0 0 0 2px rgba(0,0,0,0.08)}",".fb-quote{font-size:12px;color:var(--fb-muted-fg);padding:6px 10px;background:var(--fb-muted);border-left:2px solid var(--fb-primary);border-radius:0 4px 4px 0;margin-bottom:8px;font-style:italic;line-height:1.5;cursor:pointer;transition:background .15s}",".fb-quote:hover{background:var(--fb-border)}",".fb-body{font-size:13px;color:var(--fb-muted-fg);line-height:1.6;margin-bottom:6px;white-space:pre-wrap}",".fb-actions{display:flex;gap:2px;flex-wrap:wrap}",".fb-act{font-size:12px;color:#a3a3a3;background:none;border:none;padding:4px 8px;border-radius:4px;cursor:pointer;transition:all .15s;display:inline-flex;align-items:center;gap:3px;font-family:var(--fb-font)}",".fb-act:hover{color:var(--fb-fg)}",".fb-act.del:hover{color:var(--fb-destructive)}",".fb-act.res:hover{color:#22c55e}",".fb-replies{margin-top:8px;padding-top:8px;border-top:1px solid var(--fb-muted)}",".fb-reply-item{display:flex;gap:8px;padding:6px 0}",".fb-reply-item+.fb-reply-item{border-top:1px solid var(--fb-muted)}",".fb-reply-avatar{width:20px;height:20px;border-radius:50%;background:var(--fb-primary);color:var(--fb-primary-fg);display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:700;flex-shrink:0;margin-top:2px}",".fb-reply-meta{font-size:12px;color:var(--fb-muted-fg);margin-bottom:2px}",".fb-reply-meta strong{color:#525252;font-weight:700}",".fb-reply-text{font-size:13px;color:var(--fb-muted-fg);line-height:1.5}",".fb-reply-input{display:flex;gap:8px;margin-top:8px}",".fb-reply-input textarea{flex:1;padding:8px 10px;border:1px solid var(--fb-border);border-radius:6px;font-size:13px;font-family:var(--fb-font);resize:none;outline:none;min-height:36px;color:var(--fb-fg)}",".fb-reply-input textarea:focus{border-color:var(--fb-accent)}",".fb-reply-input button{padding:6px 14px;background:var(--fb-primary);color:var(--fb-primary-fg);border:none;border-radius:6px;font-size:12px;cursor:pointer;font-family:var(--fb-font);align-self:flex-end}",".fb-reply-input button:disabled{opacity:.4;cursor:default}",".fb-edit-area textarea{width:100%;padding:8px 10px;border:1px solid var(--fb-border);border-radius:6px;font-size:13px;font-family:var(--fb-font);resize:vertical;outline:none;min-height:50px;margin-bottom:6px;color:var(--fb-fg)}",".fb-edit-area textarea:focus{border-color:var(--fb-accent)}",".fb-edit-btns{display:flex;gap:6px}",".fb-edit-btns button{padding:4px 12px;border-radius:6px;font-size:12px;cursor:pointer;border:1px solid var(--fb-border);background:var(--fb-bg);color:var(--fb-muted-fg);font-family:var(--fb-font)}",".fb-edit-btns button.save{background:var(--fb-primary);color:var(--fb-primary-fg);border-color:var(--fb-primary)}",".fb-edit-pri{display:flex;gap:4px;margin-bottom:6px}",".fb-edit-pri button{padding:2px 10px;border-radius:4px;font-size:11px;font-weight:700;cursor:pointer;border:1px solid var(--fb-border);background:var(--fb-bg);color:var(--fb-muted-fg);font-family:var(--fb-font);transition:all .15s}",".fb-popup{position:fixed;z-index:100000;width:400px;background:var(--fb-bg);border:1px solid var(--fb-border);border-radius:12px;padding:16px;box-shadow:0 10px 25px rgba(0,0,0,0.1);font-family:var(--fb-font);display:none}",".fb-popup.show{display:block}",".fb-popup-head{margin-bottom:10px}",".fb-popup-head span{font-size:14px;font-weight:700;color:var(--fb-fg)}",".fb-popup-quote{font-size:13px;color:var(--fb-muted-fg);padding:8px 12px;background:var(--fb-muted);border-left:2px solid var(--fb-accent);border-radius:0 6px 6px 0;margin-bottom:10px;font-style:italic;line-height:1.5}",".fb-popup textarea{width:100%;min-height:70px;padding:10px 12px;border:1px solid var(--fb-border);border-radius:8px;font-size:14px;font-family:var(--fb-font);resize:vertical;outline:none;margin-bottom:10px;color:var(--fb-fg)}",".fb-popup textarea:focus{border-color:var(--fb-accent)}",".fb-popup textarea::placeholder{color:var(--fb-muted-fg)}",".fb-popup-pri{display:flex;gap:6px;margin-bottom:10px}",".fb-popup-pri button{flex:1;padding:7px 8px;border-radius:8px;font-size:13px;font-weight:600;cursor:pointer;border:2px solid transparent;transition:all .15s;font-family:var(--fb-font)}",".fb-popup-actions{display:flex;gap:8px;justify-content:flex-end}",".fb-popup-actions button{padding:8px 18px;border-radius:8px;font-size:13px;font-weight:600;cursor:pointer;transition:all .15s;font-family:var(--fb-font)}",".fb-popup-actions .cancel{background:none;border:1px solid var(--fb-border);color:var(--fb-muted-fg)}",".fb-popup-actions .cancel:hover{background:var(--fb-muted);color:var(--fb-fg)}",".fb-popup-actions .submit{border:none;color:#fff}",".fb-name-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.4);display:flex;align-items:center;justify-content:center;z-index:100001}",".fb-name-box{background:var(--fb-bg);border-radius:12px;padding:28px;width:360px;box-shadow:0 20px 40px rgba(0,0,0,0.15)}",".fb-name-box h2{font-size:18px;font-weight:700;margin:0 0 6px;color:var(--fb-fg)}",".fb-name-box p{font-size:14px;color:var(--fb-muted-fg);margin:0 0 16px}",".fb-name-box input{width:100%;padding:10px 14px;border:1px solid var(--fb-border);border-radius:8px;font-size:15px;outline:none;margin-bottom:12px;font-family:var(--fb-font);color:var(--fb-fg)}",".fb-name-box input:focus{border-color:var(--fb-accent)}",".fb-name-box input::placeholder{color:var(--fb-muted-fg)}",".fb-name-box button{width:100%;padding:10px;background:var(--fb-primary);color:var(--fb-primary-fg);border:none;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;font-family:var(--fb-font)}",".fb-name-box button:disabled{opacity:.4;cursor:default}",".fb-name-input{width:100%;padding:4px 8px;border:1px solid var(--fb-border);border-radius:4px;font-size:12px;outline:none;font-family:var(--fb-font);color:var(--fb-fg)}",".fb-name-input:focus{border-color:var(--fb-accent)}",".fb-highlight{padding:1px 0;cursor:pointer;transition:background .15s}",".fb-highlight-must{background:rgba(239,68,68,0.15);border-bottom:2px solid #ef4444}",".fb-highlight-must:hover{background:rgba(239,68,68,0.25)}",".fb-highlight-better{background:rgba(245,158,11,0.15);border-bottom:2px solid #f59e0b}",".fb-highlight-better:hover{background:rgba(245,158,11,0.25)}",".fb-highlight-want{background:rgba(34,197,94,0.15);border-bottom:2px solid #22c55e}",".fb-highlight-want:hover{background:rgba(34,197,94,0.25)}","@keyframes fb-pulse{0%,100%{opacity:1}50%{opacity:0.4}}",".fb-highlight.fb-pulse{animation:fb-pulse 1s ease-in-out infinite}",".fb-card.fb-focused{box-shadow:0 0 0 2px var(--fb-accent);background:rgba(59,130,246,0.04)}","#fb-sidebar svg,#fb-toggle svg,.fb-popup svg{pointer-events:none}"].join(`
`),document.head.appendChild(t)}function w(t,e,n){let r=document.createElement(t);return e&&Object.keys(e).forEach(s=>{let i=e[s];s==="className"?r.className=i:s==="innerHTML"?r.innerHTML=i:s.startsWith("on")&&typeof i=="function"?r.addEventListener(s.substring(2).toLowerCase(),i):r.setAttribute(s,String(i))}),n!=null&&(typeof n=="string"?r.textContent=n:Array.isArray(n)?n.forEach(s=>{s&&r.appendChild(s)}):r.appendChild(n)),r}function f(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}var lt={message:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"/></svg>',check:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>',rotateCcw:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>',pencil:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>',trash:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><path d="M10 11v6"/><path d="M14 11v6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>',user:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>',x:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>',panelRight:'<svg width="SIZE" height="SIZE" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="SW" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M15 3v18"/></svg>'};function b(t,e=14,n=2){return(lt[t]||"").replace(/SIZE/g,String(e)).replace(/SW/g,String(n))}function Y(t){let e=document.getElementById("fb-toggle");e||(e=w("button",{id:"fb-toggle",onClick:t}),document.body.appendChild(e));let n=o.comments.filter(s=>!s.parentId&&!s.resolved).length,r='<span class="fb-toggle-icon">'+b("panelRight",16);n>0&&(r+='<span class="fb-badge">'+n+"</span>"),r+="</span>",r+='<span class="fb-toggle-label">\u30B3\u30E1\u30F3\u30C8</span>',e.innerHTML=r,e.style.display=o.sidebarOpen?"none":""}function A(t){let e=Date.now()-t;return e<6e4?"\u305F\u3063\u305F\u4ECA":e<36e5?Math.floor(e/6e4)+"\u5206\u524D":e<864e5?Math.floor(e/36e5)+"\u6642\u9593\u524D":new Date(t).toLocaleDateString("ja-JP",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function Z(t){let e=t.author===o.username,n=k[t.priority]||k.want,r='<div class="fb-card'+(t.resolved?" resolved":"")+'" style="border-left-color:'+n.bg+'" data-id="'+t.id+'">';if(r+='<div class="fb-card-head"><div class="fb-card-head-left">',r+='<div class="fb-avatar">'+f(t.author.charAt(0))+"</div>",r+='<span class="fb-author">'+f(t.author)+"</span>",r+='<span class="fb-time">'+A(t.timestamp)+"</span>",t.resolved&&(r+='<span class="fb-resolved-mark">'+b("check",12)+" \u89E3\u6C7A\u6E08</span>"),r+="</div>",r+='<span class="fb-badge-p'+(e?" own":"")+'" style="background:'+n.bg+'" data-action="cycle" data-id="'+t.id+'">'+f(t.priority.charAt(0).toUpperCase()+t.priority.slice(1))+"</span>",r+="</div>",t.quote){let i=t.quote.length>100?t.quote.substring(0,100)+"...":t.quote;r+='<div class="fb-quote" style="border-left-color:'+n.bg+'" data-action="scroll-quote" data-id="'+t.id+'">'+f(i)+"</div>"}o.editingId===t.id?(r+='<div class="fb-edit-area">',r+='<div class="fb-edit-pri">',["must","better","want"].forEach(i=>{let d=o.editPriority===i,a=k[i];r+='<button data-action="set-edit-pri" data-pri="'+i+'" style="'+(d?"background:"+a.bg+";color:#fff;border-color:"+a.bg:"")+'">'+i.charAt(0).toUpperCase()+i.slice(1)+"</button>"}),r+="</div>",r+='<textarea data-action="edit-textarea">'+f(o.editContent)+"</textarea>",r+='<div class="fb-edit-btns"><button data-action="cancel-edit">\u30AD\u30E3\u30F3\u30BB\u30EB</button><button class="save" data-action="save-edit" data-id="'+t.id+'">\u4FDD\u5B58</button></div>',r+="</div>"):r+='<div class="fb-body">'+f(t.content)+"</div>",o.editingId!==t.id&&(r+='<div class="fb-actions">',r+='<button class="fb-act" data-action="reply" data-id="'+t.id+'">'+b("message",12)+"\u8FD4\u4FE1</button>",r+='<button class="fb-act res" data-action="resolve" data-id="'+t.id+'">'+(t.resolved?b("rotateCcw",12):b("check",12))+(t.resolved?"\u623B\u3059":"\u89E3\u6C7A")+"</button>",e&&(r+='<button class="fb-act" data-action="edit" data-id="'+t.id+'">'+b("pencil",12)+"\u7DE8\u96C6</button>"),e&&(r+='<button class="fb-act del" data-action="delete" data-id="'+t.id+'">'+b("trash",12)+"\u524A\u9664</button>"),r+="</div>");let s=o.comments.filter(i=>i.parentId===t.id).sort((i,d)=>i.timestamp-d.timestamp);return s.length>0&&(r+='<div class="fb-replies">',s.forEach(i=>{let d=i.author===o.username;r+='<div class="fb-reply-item"><div class="fb-reply-avatar">'+f(i.author.charAt(0))+'</div><div style="flex:1;min-width:0"><div class="fb-reply-meta"><strong>'+f(i.author)+"</strong> &middot; "+A(i.timestamp)+"</div>",o.editingId===i.id?r+='<div class="fb-edit-area"><textarea data-action="edit-textarea">'+f(o.editContent)+'</textarea><div class="fb-edit-btns"><button data-action="cancel-edit">\u30AD\u30E3\u30F3\u30BB\u30EB</button><button class="save" data-action="save-edit" data-id="'+i.id+'">\u4FDD\u5B58</button></div></div>':(r+='<div class="fb-reply-text">'+f(i.content)+"</div>",r+='<div class="fb-actions" style="margin-top:4px">',r+='<button class="fb-act" data-action="reply" data-id="'+t.id+'">'+b("message",12)+"\u8FD4\u4FE1</button>",d&&(r+='<button class="fb-act" data-action="edit" data-id="'+i.id+'">'+b("pencil",12)+"\u7DE8\u96C6</button>"),d&&(r+='<button class="fb-act del" data-action="delete-reply" data-id="'+i.id+'">'+b("trash",12)+"\u524A\u9664</button>"),r+="</div>"),r+="</div></div>"}),r+="</div>"),o.replyingTo===t.id&&(r+='<div class="fb-reply-input"><textarea placeholder="\u8FD4\u4FE1\u3092\u5165\u529B..." data-action="reply-textarea">'+f(o.replyText)+'</textarea><button data-action="submit-reply" data-id="'+t.id+'"'+(o.replyText.trim()?"":" disabled")+">\u9001\u4FE1</button></div>"),r+="</div>",r}function Q(){let t=document.getElementById("fb-sidebar");if(!t)return;let e=o.sidebarWidth;t.style.width=e+"px",t.style.right=o.sidebarOpen?"0px":-(e+20)+"px",document.body.style.marginRight=o.sidebarOpen?e+"px":""}function L(){o.sidebarOpen=!o.sidebarOpen;let t=document.getElementById("fb-toggle");t&&(t.style.display=o.sidebarOpen?"none":""),document.body.style.transition="margin-right 0.3s ease",Q()}function K(){return o.comments.filter(t=>!t.parentId)}function pt(){let t=K();return o.filter==="resolved"?t.filter(e=>e.resolved):o.filter==="all"?t:t.filter(e=>!e.resolved)}function V(t){let e=document.getElementById("fb-sidebar"),n=!e;n&&(e=w("div",{id:"fb-sidebar"}),document.body.appendChild(e),e.addEventListener("mouseover",a=>{let l=a.target.closest(".fb-card");if(!l)return;let p=document.querySelector('.fb-highlight[data-comment-id="'+l.dataset.id+'"]');p&&p.classList.add("fb-pulse")}),e.addEventListener("mouseout",a=>{let l=a.target.closest(".fb-card");if(!l||a.relatedTarget&&l.contains(a.relatedTarget))return;let p=document.querySelector('.fb-highlight[data-comment-id="'+l.dataset.id+'"]');p&&p.classList.remove("fb-pulse")})),Q();let r=K(),s={unresolved:r.filter(a=>!a.resolved).length,resolved:r.filter(a=>a.resolved).length,all:r.length},i='<div class="fb-resize-handle"></div>';i+='<div class="fb-header">',i+='<div class="fb-header-left"><span class="fb-header-title">\u30B3\u30E1\u30F3\u30C8</span><span class="fb-header-count">'+s.all+"</span></div>",i+='<div class="fb-header-actions">',i+='<button class="fb-hdr-btn" data-action="close" title="\u9589\u3058\u308B">'+b("x",18)+"</button>",i+="</div></div>",o.username&&(o.editingName?i+='<div class="fb-user-row"><input class="fb-name-input" value="'+f(o.nameInput)+'" data-action="name-input" autofocus></div>':i+='<div class="fb-user-row" data-action="edit-name">'+b("user",14)+f(o.username)+"</div>"),i+='<div class="fb-filters">',["unresolved","resolved","all"].forEach(a=>{let l=a==="unresolved"?"\u672A\u89E3\u6C7A":a==="resolved"?"\u89E3\u6C7A\u6E08":"\u3059\u3079\u3066";i+='<button class="fb-filter'+(o.filter===a?" active":"")+'" data-filter="'+a+'">'+l+'<span class="cnt">'+s[a]+"</span></button>"}),i+="</div>";let d=pt().sort((a,l)=>l.timestamp-a.timestamp);i+='<div class="fb-list">',d.length===0?i+='<div class="fb-empty">'+b("message",40)+'\u30B3\u30E1\u30F3\u30C8\u306F\u307E\u3060\u3042\u308A\u307E\u305B\u3093<br><span style="font-size:11px">\u30C6\u30AD\u30B9\u30C8\u3092\u9078\u629E\u3057\u3066\u30B3\u30E1\u30F3\u30C8\u3092\u8FFD\u52A0</span></div>':d.forEach(a=>{i+=Z(a)}),i+="</div>",e.innerHTML=i,n&&ft(e,t)}var g=null;function G(t){g=t}function ft(t,e){t.addEventListener("click",n=>{let r=n.target.closest("[data-action]");if(r){let d=r.dataset.action,a=r.dataset.id;if(d==="close")g?.toggleSidebar();else if(d==="edit-name")o.editingName=!0,o.nameInput=o.username,e();else if(d==="cycle"&&a)g?.cyclePriority(a);else if(d==="scroll-quote"&&a)g?.scrollToQuote(a);else if(d==="reply"&&a)o.replyingTo=o.replyingTo===a?null:a,o.replyText="",e();else if(d==="resolve"&&a)g?.resolveComment(a);else if(d==="edit"&&a){let l=o.comments.find(p=>p.id===a);l&&(o.editingId=a,o.editContent=l.content,o.editPriority=l.priority,e())}else d==="delete"&&a?g?.deleteComment(a):d==="delete-reply"&&a?g?.deleteReply(a):d==="cancel-edit"?(o.editingId=null,e()):d==="save-edit"&&a?g?.saveEdit(a):d==="submit-reply"&&a?g?.submitReply(a):d==="set-edit-pri"&&(o.editPriority=r.dataset.pri,e());return}let s=n.target.closest("[data-filter]");if(s){o.filter=s.dataset.filter,e();return}let i=n.target.closest(".fb-card");i&&i.dataset.id&&g?.scrollToQuote(i.dataset.id)}),t.addEventListener("mousedown",n=>{if(!n.target.closest(".fb-resize-handle"))return;n.preventDefault();let r=n.clientX,s=o.sidebarWidth,i=n.target.closest(".fb-resize-handle");document.body.classList.add("fb-resizing"),i.classList.add("active");function d(l){o.sidebarWidth=Math.min(800,Math.max(300,s+(r-l.clientX)));let p=document.getElementById("fb-sidebar");p&&(p.style.width=o.sidebarWidth+"px"),document.body.style.transition="none",document.body.style.marginRight=o.sidebarWidth+"px"}function a(){document.removeEventListener("mousemove",d),document.removeEventListener("mouseup",a),document.body.classList.remove("fb-resizing"),i.classList.remove("active"),document.body.style.transition="",localStorage.setItem(M,String(o.sidebarWidth))}document.addEventListener("mousemove",d),document.addEventListener("mouseup",a)}),t.addEventListener("input",n=>{let r=n.target;if(r.dataset.action==="name-input")o.nameInput=r.value;else if(r.dataset.action==="edit-textarea")o.editContent=r.value;else if(r.dataset.action==="reply-textarea"){o.replyText=r.value;let s=t.querySelector('[data-action="submit-reply"]');s&&(s.disabled=!o.replyText.trim())}}),t.addEventListener("keydown",n=>{let r=n.target;if(r.dataset.action==="name-input"&&(n.key==="Enter"?g?.finishNameEdit():n.key==="Escape"&&(o.editingName=!1,e())),r.dataset.action==="reply-textarea"&&(n.metaKey||n.ctrlKey)&&n.key==="Enter"){let s=t.querySelector('[data-action="submit-reply"]')?.dataset.id;s&&g?.submitReply(s)}}),t.addEventListener("blur",n=>{n.target.dataset?.action==="name-input"&&g?.finishNameEdit()},!0)}function J(t,e,n){let r=document.getElementById("fb-popup");if(!r&&(r=w("div",{id:"fb-popup",className:"fb-popup"}),document.body.appendChild(r),r.addEventListener("click",c=>{let h=c.target.closest("[data-action]");h&&(h.dataset.action==="cancel-popup"?e():h.dataset.action==="set-popup-pri"?(o.popupPriority=h.dataset.pri,t()):h.dataset.action==="submit-popup"&&n(o.popupPriority))}),r.addEventListener("input",c=>{c.target.dataset.action==="popup-textarea"&&(o.popupContent=c.target.value)}),r.addEventListener("keydown",c=>{c.target.dataset.action==="popup-textarea"&&(c.metaKey||c.ctrlKey)&&c.key==="Enter"&&n(o.popupPriority)})),!o.selectedRect){r.classList.remove("show");return}r.classList.add("show");let i=o.selectedText.length>120?o.selectedText.substring(0,120)+"...":o.selectedText,d=k[o.popupPriority],a='<div class="fb-popup-head"><span>\u30B3\u30E1\u30F3\u30C8\u3092\u8FFD\u52A0</span></div>';a+='<div class="fb-popup-quote">'+f(i)+"</div>",a+='<textarea placeholder="\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u5165\u529B..." data-action="popup-textarea">'+f(o.popupContent)+"</textarea>",a+='<div class="fb-popup-pri">',["must","better","want"].forEach(c=>{let h=k[c],dt=o.popupPriority===c?"background:"+h.light+";color:"+h.bg+";border-color:"+h.bg:"background:var(--fb-bg);color:var(--fb-muted-fg);border-color:var(--fb-border)";a+='<button style="'+dt+'" data-action="set-popup-pri" data-pri="'+c+'">'+c.charAt(0).toUpperCase()+c.slice(1)+"</button>"}),a+="</div>",a+='<div class="fb-popup-actions">',a+='<button class="cancel" data-action="cancel-popup">\u30AD\u30E3\u30F3\u30BB\u30EB</button>',a+='<button class="submit" style="background:'+d.bg+'" data-action="submit-popup">\u9001\u4FE1</button>',a+="</div>",r.innerHTML=a;let l=o.selectedRect,p=400,x=300,m=12,v=l.bottom+m;v+x>window.innerHeight&&(v=l.top-x-m),v<m&&(v=Math.max(m,(window.innerHeight-x)/2));let E=o.sidebarOpen?window.innerWidth-o.sidebarWidth:window.innerWidth,P=Math.max(m,Math.min(l.left,E-p-m));r.style.top=v+"px",r.style.left=P+"px"}function $(t){let e=document.getElementById("fb-name-overlay");if(o.username){e&&e.remove();return}if(e)return;let n=w("div",{id:"fb-name-overlay",className:"fb-name-overlay"});n.innerHTML='<div class="fb-name-box"><h2>\u3088\u3046\u3053\u305D</h2><p>\u30B3\u30E1\u30F3\u30C8\u306B\u8868\u793A\u3055\u308C\u308B\u540D\u524D\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002</p><input placeholder="\u4F8B: \u7530\u4E2D\u592A\u90CE" id="fb-name-field"><button id="fb-name-submit" disabled>\u59CB\u3081\u308B</button></div>',document.body.appendChild(n);let r=document.getElementById("fb-name-field"),s=document.getElementById("fb-name-submit");r.addEventListener("input",()=>{s.disabled=!r.value.trim()}),r.addEventListener("keydown",i=>{i.key==="Enter"&&r.value.trim()&&X(r.value.trim(),t)}),s.addEventListener("click",()=>{r.value.trim()&&X(r.value.trim(),t)}),setTimeout(()=>{r.focus()},100)}function X(t,e){o.username=t,localStorage.setItem(S,t);let n=document.getElementById("fb-name-overlay");n&&n.remove(),e()}var tt=null,et=null;function rt(t,e){tt=t,et=e}function u(){Y(L),V(u),J(u,tt,et),$(u)}function ct(){let t=[],e=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,{acceptNode(r){let s=r.parentElement;return!s||s.tagName==="SCRIPT"||s.tagName==="STYLE"||s.closest("#fb-sidebar,#fb-toggle,#fb-popup,.fb-highlight")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),n;for(;n=e.nextNode();)t.push(n);return t}function ot(t,e,n){let r=t.replace(/[\s\u00A0]+/g," ");if(e>=r.length)return null;let s=0,i=0,d=-1,a=-1;for(;s<t.length;){if(i===e&&d===-1&&(d=s),i===n){a=s;break}i<r.length&&t[s]===r[i]?(s++,i++):s++}return a===-1&&i>=n&&(a=s),d===-1||a===-1||d>=a?null:[d,a]}function H(t,e,n,r,s){let i=t.textContent,d=document.createTextNode(i.substring(0,e)),a=document.createElement("mark");a.className="fb-highlight fb-highlight-"+r.priority,a.dataset.commentId=r.id,a.textContent=i.substring(e,n),a.addEventListener("click",()=>{s(r.id)});let l=document.createTextNode(i.substring(n));t.parentNode.insertBefore(d,t),t.parentNode.insertBefore(a,t),t.parentNode.insertBefore(l,t),t.parentNode.removeChild(t)}function T(t){document.querySelectorAll(".fb-highlight").forEach(e=>{let n=document.createTextNode(e.textContent||"");e.parentNode.replaceChild(n,e)}),document.body.normalize(),o.comments.filter(e=>!e.parentId&&!e.resolved&&e.quote&&e.quote.length>=2).forEach(e=>{let n=e.quote.replace(/[\s\u00A0]+/g," ").trim(),r=ct(),s=!1;for(let i=0;i<r.length;i++){let d=r[i],a=d.textContent,l=a.indexOf(n);if(l!==-1){try{H(d,l,l+n.length,e,t),s=!0}catch{}break}let x=a.replace(/[\s\u00A0]+/g," ").indexOf(n);if(x===-1)continue;let m=ot(a,x,x+n.length);if(m){try{H(d,m[0],m[1],e,t),s=!0}catch{}break}}if(!s){let i="",d=[];for(let p=0;p<r.length;p++){let x=i.length;i+=r[p].textContent,d.push({node:r[p],start:x,end:i.length})}let l=i.replace(/[\s\u00A0]+/g," ").indexOf(n);if(l!==-1){let p=ot(i,l,l+n.length);if(p){let x=p[0],m=p[1];for(let v=d.length-1;v>=0;v--){let E=d[v];if(E.end<=x||E.start>=m)continue;let P=Math.max(0,x-E.start),c=Math.min(E.node.textContent.length,m-E.start);try{H(E.node,P,c,e,t)}catch{}}}}}})}var N={must:"rgba(239,68,68,0.4)",better:"rgba(245,158,11,0.4)",want:"rgba(34,197,94,0.4)"};function nt(t){let e=document.querySelector('.fb-highlight[data-comment-id="'+t+'"]');if(!e)return;e.scrollIntoView({behavior:"smooth",block:"center"});let n=o.comments.find(i=>i.id===t),r=n&&N[n.priority]||N.want,s=e.style.backgroundColor;e.style.backgroundColor=r,e.style.transition="background-color 0.3s",setTimeout(()=>{e.style.backgroundColor=s},1500)}function it(t,e){let n=!o.sidebarOpen;n&&e(),setTimeout(()=>{let r=document.querySelector('.fb-card[data-id="'+t+'"]');r&&(r.scrollIntoView({behavior:"smooth",block:"center"}),r.classList.add("fb-focused"),setTimeout(()=>{r.classList.remove("fb-focused")},1500))},n?350:0)}function bt(t){let e="",n="";try{let r=document.createRange();r.setStart(document.body,0),r.setEnd(t.startContainer,t.startOffset),e=r.toString().slice(-50).replace(/[\s\u00A0]+/g," ").trim();let s=document.createRange();s.setStart(t.endContainer,t.endOffset),s.setEnd(document.body,document.body.childNodes.length),n=s.toString().slice(0,50).replace(/[\s\u00A0]+/g," ").trim()}catch{}return{beforeText:e,afterText:n}}function at(t,e){document.addEventListener("mouseup",n=>{if(n.target.closest("#fb-sidebar,#fb-toggle,#fb-popup"))return;let r=window.getSelection(),s=r?.toString().trim();if(!s||!r||r.rangeCount===0||!o.username)return;let i=r.getRangeAt(0);o.selectedText=s.replace(/[\s\u00A0]+/g," ").substring(0,200),o.selectedRect=i.getBoundingClientRect(),o.selectedQuoteContext=bt(i),o.popupContent="",t()}),document.addEventListener("mousedown",n=>{n.target.closest("#fb-popup")||o.selectedRect&&e()})}var R=document.currentScript,ut=R?R.src.replace(/\/widget\.js.*$/,""):"",mt=R&&R.dataset.token||"";D(ut,mt);function B(){return y("GET",{slug:I}).then(t=>{Array.isArray(t)&&(o.comments=t),u(),T(C)}).catch(()=>{u(),T(C)})}function O(){o.selectedText="",o.selectedRect=null,o.popupContent="",o.popupPriority="must",u()}function gt(t){if(!o.username||!o.selectedText)return;let e={id:z(),author:o.username,type:"comment",quote:o.selectedText,quoteContext:o.selectedQuoteContext,content:o.popupContent.trim(),priority:t,parentId:null,pageUrl:window.location.href,projectSlug:I,timestamp:Date.now(),resolved:!1,resolvedBy:null,resolvedAt:null,updatedAt:null};o.comments.push(e),O(),T(C),y("POST",e).then(B)}function xt(t){let e=o.comments.find(r=>r.id===t);if(!e)return;let n=!e.resolved;e.resolved=n,e.resolvedBy=n?o.username:null,e.resolvedAt=n?Date.now():null,u(),T(C),y("PUT",{id:t,action:"resolve",resolved:n,resolvedBy:e.resolvedBy,resolvedAt:e.resolvedAt})}function vt(t){let e=o.comments.find(n=>n.id===t);!e||e.author!==o.username||(e.priority=_[e.priority]||"must",u(),T(C),y("PUT",{id:t,action:"cyclePriority",priority:e.priority}))}function ht(t){o.comments=o.comments.filter(e=>e.id!==t&&e.parentId!==t),u(),T(C),y("DELETE",{id:t})}function yt(t){o.comments=o.comments.filter(e=>e.id!==t),u(),y("DELETE",{id:t})}function Et(t){let e=o.comments.find(n=>n.id===t);e&&(e.content=o.editContent,e.priority=o.editPriority,o.editingId=null,u(),T(C),y("PUT",{id:t,action:"edit",content:e.content,priority:e.priority}))}function wt(t){if(!o.replyText.trim()||!o.username)return;let e={id:z(),author:o.username,type:"comment",quote:"",quoteContext:{beforeText:"",afterText:""},content:o.replyText.trim(),priority:"want",parentId:t,pageUrl:window.location.href,projectSlug:I,timestamp:Date.now(),resolved:!1,resolvedBy:null,resolvedAt:null,updatedAt:null};o.comments.push(e),o.replyingTo=null,o.replyText="",u(),y("POST",e)}function Tt(){if(o.nameInput.trim()&&o.nameInput.trim()!==o.username){let t=o.username;o.username=o.nameInput.trim(),localStorage.setItem(S,o.username),y("PUT",{id:"_rename",action:"rename",author:o.username,oldAuthor:t,projectSlug:I}).then(B)}o.editingName=!1,u()}function C(t){it(t,L)}rt(O,gt);G({toggleSidebar:L,cyclePriority:vt,scrollToQuote:nt,resolveComment:xt,deleteComment:ht,deleteReply:yt,saveEdit:Et,submitReply:wt,finishNameEdit:Tt});function st(){U(),u(),at(u,O),B()}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",st):st();})();