{"id":"9KTZYwLBsu","url":"https://pastebin.ca/9KTZYwLBsu","raw_url":"https://raw.anybin.ca/9KTZYwLBsu","visibility":"public","access":"public","created_at":1787712354295,"expires_at":1795488354295,"fetch_limit":null,"fetches_used":0,"reads_remaining":null,"size_bytes":26306,"syntax_hint":null,"title":null,"filename":null,"change_note":null,"cipher":null,"cipher_meta":null,"parent_id":null,"root_id":"9KTZYwLBsu","version":1,"owner_id":null,"recipient_id":null,"body":"<!DOCTYPE html>\n<html lang=\"zh‑CN\">\n<head>\n<meta charset=\"UTF‑8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>🦆鹅鸭杀记录本</title>\n<style>\n*{box-sizing:border-box;margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,sans-serif}\nbody{\n    color:#4a3f2f;\n    padding:16px;\n    max-width:100%;\n    background:\n        radial-gradient(circle at 20% 20%, rgba(255,255,255,0.85) 0 8%, transparent 9%),\n        radial-gradient(circle at 80% 10%, rgba(255,255,255,0.75) 0 6%, transparent 7%),\n        linear-gradient(135deg,#fff7e8,#ffe4c4,#ffdab9);\n    background-attachment:fixed;\n    min-height:100vh;\n}\nbody::before{\n    content:\"\";\n    position:fixed;\n    inset:0;\n    background-image:url(\"https://picsum.photos/id/237/1920/1080\");\n    background-size:cover;\n    background-position:center;\n    opacity:0.18;\n    z-index:-1;\n}\nh2{margin-bottom:10px;color:#6b4226;font-size:22px}\nbutton{cursor:pointer;padding:8px 10px;border:none;border-radius:8px;font-size:15px}\n.btn-clear-all{background:#dc3545;color:#fff;margin-bottom:8px;width:100%}\n.btn-new-round{background:#208050;color:#fff;margin-bottom:12px;width:100%}\n.btn-fold{background:#304058;color:#fff;margin-bottom:12px;width:100%}\n.btn-copy-log{background:#4466bb;color:#fff;margin-bottom:8px;width:100%}\n\n.top-status-wrap{margin-bottom:14px;}\n.top-title{font-size:18px;font-weight:bold;margin:8px 0 6px;color:#5a3820}\n.drag-container{\n    display:grid;\n    grid-template-columns:repeat(auto-fill,minmax(130px,1fr));\n    grid-auto-rows:48px;\n    gap:8px;\n    min-height:80px;\n    padding:10px;\n    border-radius:10px;\n    background:rgba(255,255,255,0.65);\n    border:1px solid rgba(180,140,100,0.35);\n    margin-bottom:12px;\n}\n.drag-item{\n    padding:6px 8px;\n    border-radius:6px;\n    display:flex;\n    align-items:center;\n    font-size:14px;\n    cursor:move;\n    border:1px solid rgba(130,90,60,0.25);\n    user-select:none;\n    background:rgba(255,255,255,0.8);\n    position:relative;\n    transition:transform 0.15s;\n}\n.drag-item:hover{\n    transform:scale(1.03);\n}\n.drag-item.sus-low{border-color:#e6bc20;}\n.drag-item.sus-high{border-color:#d63030;}\n\n.drag-item .mark-tag{\n    position:absolute;\n    top:2px;\n    right:4px;\n    font-size:10px;\n    pointer-events:none;\n}\n.drag-item .love-tag{color:#ff88aa;}\n.drag-item .note-tag{color:#ffdd77;}\n\n.drag-item.camp-duck{background:rgba(180,60,60,0.85);color:#fff;border-color:#913c3c;}\n.drag-item.camp-neutral{background:rgba(160,90,180,0.85);color:#fff;border-color:#7c4ea8;}\n.drag-item.dead-item{opacity:0.75;}\n\n.stat-bar{\n    background:rgba(255,255,255,0.65);\n    border:1px solid rgba(180,140,100,0.35);\n    padding:12px;\n    border-radius:10px;\n    margin-bottom:8px;\n    font-size:15px;\n    line-height:1.7;\n    color:#4a3f2f;\n}\n.config-area{\n    background:rgba(255,255,255,0.65);\n    border:1px solid rgba(180,140,100,0.35);\n    padding:10px 12px;\n    border-radius:8px;\n    margin-bottom:12px;\n    font-size:13px;\n    color:#5a3820;\n}\n.blacklist-area{\n    background:rgba(255,255,255,0.65);\n    border:1px solid rgba(180,140,100,0.35);\n    padding:10px 12px;\n    border-radius:8px;\n    margin-bottom:12px;\n    font-size:13px;\n    color:#5a3820;\n}\n.death-log-area{\n    background:rgba(255,255,255,0.65);\n    border:1px solid rgba(180,140,100,0.35);\n    padding:10px 12px;\n    border-radius:8px;\n    margin-bottom:12px;\n    font-size:13px;\n    color:#5a3820;\n}\n.paste-area{padding:12px;border:1px dashed rgba(150,110,70,0.45);border-radius:10px;margin-bottom:12px;background:rgba(255,255,255,0.6);}\ntextarea{width:100%;background:#fff;color:#4a3f2f;border:1px solid rgba(130,90,60,0.25);border-radius:8px;padding:8px;font-size:15px}\n.input-bar{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}\ninput,select{padding:8px;background:#fff;color:#4a3f2f;border:1px solid rgba(130,90,60,0.25);border-radius:8px;font-size:15px;flex:1;min-width:90px}\n\n.col-wrap{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-bottom:12px;transition:all 0.3s;}\n.col-wrap.hidden{display:none;}\n@media (max-width:640px){\n    .col-wrap{grid-template-columns:1fr;}\n}\n.col-goose{border:1px solid #287038;border-radius:10px;padding:10px;background:rgba(27,44,32,0.08);}\n.col-duck{border:1px solid #882b2b;border-radius:10px;padding:10px;background:rgba(44,27,27,0.08);}\n.col-neutral{border:1px solid #603480;border-radius:10px;padding:10px;background:rgba(36,27,48,0.08);}\n.col-title{font-weight:bold;margin-bottom:8px;font-size:16px}\n.title-goose{color:#287038;}\n.title-duck{color:#882b2b;}\n.title-neutral{color:#603480;}\n\n.box-scroll{\n    max-height:320px;\n    overflow-y:auto;\n    -webkit-overflow-scrolling:touch;\n    overflow-x:hidden;\n}\n\n.player-item{padding:10px;border-radius:8px;margin:8px 0;border:1px solid rgba(130,90,60,0.25);background:rgba(255,255,255,0.7);}\n.player-item.dead{opacity:0.45;text-decoration:line-through;}\n.row-edit{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}\n.btn-del{background:#444;color:#ddd}\n.btn-save{background:#238636;color:#fff}\n.btn-kill{background:#992c2c;color:#fff}\n.btn-alive{background:#236386;color:#fff}\n.ai-panel{margin-top:12px;padding:12px;background:rgba(255,255,255,0.65);border-radius:10px;border:1px solid rgba(180,140,100,0.35);color:#4a3f2f;}\n.ai-panel h3{color:#6b4226;margin-bottom:8px;font-size:17px}\n#aiResult{\n    margin-top:6px;\n    line-height:1.7;\n    color:#4a3f2f;\n    font-size:14px;\n    white-space:pre-wrap;\n    word-wrap:break-word;\n    overflow-wrap:break-word;\n    max-height:320px;\n    overflow-y:auto;\n    overflow-x:hidden;\n}\n\n.modal-mask{\n    position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);display:none;align-items:center;justify-content:center;z-index:999;\n}\n.modal-box{\n    background:#fff;padding:16px;border-radius:10px;max-width:320px;width:90%;color:#4a3f2f;\n}\n#deathLogList{max-height:140px;overflow-y:auto;margin:6px 0;}\n.tip-copy{font-size:12px;color:#6b4226;margin:6px 0;}\n</style>\n</head>\n<body>\n<h2>🦆鹅鸭杀 玩家记录本</h2>\n<button class=\"btn-clear-all\" onclick=\"clearAll()\">🔄全部清空（全部归零）</button>\n<button class=\"btn-new-round\" onclick=\"newRound()\">🆕开启新对局（保留配置）</button>\n<button class=\"btn-fold\" onclick=\"toggleFold()\">📦折叠/展开下方阵营列表</button>\n<button class=\"btn-copy-log\" onclick=\"copyReplayLog()\">📋一键复制复盘文本</button>\n<div class=\"tip-copy\">复制成功后直接粘贴微信群复盘；手机浏览器权限不足会复制失败</div>\n\n<div class=\"config-area\">\n<div>⚙本局人数配置</div>\n<div style=\"display:flex;gap:8px;flex-wrap:wrap;margin-top:6px;\">\n<label>鸭子数量:<input type=\"number\" id=\"cfgDuck\" value=\"3\" min=\"0\" max=\"12\" style=\"width:60px\"/></label>\n<label>中立数量:<input type=\"number\" id=\"cfgNeu\" value=\"2\" min=\"0\" max=\"12\" style=\"width:60px\"/></label>\n</div>\n</div>\n\n<div class=\"blacklist-area\">\n<div>🚫本局不存在角色（勾选+自定义）</div>\n<div style=\"display:flex;flex-wrap:wrap;gap:8px;margin:4px 0 6px;\">\n<label><input type=\"checkbox\" value=\"猎鹰\" onchange=\"render()\">猎鹰</label>\n<label><input type=\"checkbox\" value=\"老鹰\" onchange=\"render()\">老鹰</label>\n<label><input type=\"checkbox\" value=\"鹈鹕\" onchange=\"render()\">鹈鹕</label>\n<label><input type=\"checkbox\" value=\"秃鹫\" onchange=\"render()\">秃鹫</label>\n<label><input type=\"checkbox\" value=\"鸽子\" onchange=\"render()\">鸽子</label>\n</div>\n<input id=\"banCustom\" placeholder=\"自定义禁用角色，逗号隔开\" style=\"width:100%\" onchange=\"render()\"/>\n</div>\n\n<div class=\"death-log-area\">\n<div>☠尸体记录</div>\n<div style=\"display:flex;gap:6px;flex-wrap:wrap;margin:4px 0;\">\n<select id=\"logDeadMan\">\n    <option value=\"\">选择死者</option>\n    <option value=\"未知\">未知</option>\n</select>\n<select id=\"logFinder\">\n    <option value=\"\">选择发现人</option>\n    <option value=\"未知\">未知</option>\n</select>\n<input id=\"logRound\" placeholder=\"回合，例：第2轮\">\n<button onclick=\"addDeathLog()\">添加记录</button>\n</div>\n<div id=\"deathLogList\"></div>\n</div>\n\n<div class=\"top-status-wrap\">\n    <div class=\"top-title\">🟢 现存人员（拖拽到死亡框直接置死亡）</div>\n    <div id=\"aliveBox\" class=\"drag-container\"></div>\n\n    <div class=\"top-title\">💀 已死亡人员（拖拽回存活框直接复活）</div>\n    <div id=\"deadBox\" class=\"drag-container\"></div>\n</div>\n\n<div class=\"stat-bar\" id=\"statBar\">\n总：0人｜🟢存活：0  💀死亡：0｜🦢好鹅：0 🦆坏鸭：0 🎭中立：0 ❓未标记：0\n</div>\n\n<div class=\"paste-area\">\n    <div>📷iPhone操作：相册打开截图 → 长按图片拷贝文字，粘贴到下方框，批量导入玩家（默认无阵营、存活）</div>\n    <textarea id=\"pasteText\" rows=\"4\" placeholder=\"粘贴识别出来的全部玩家名字，一行一个\"></textarea>\n    <button style=\"margin-top:8px;width:100%\" onclick=\"batchAdd()\">粘贴文本批量添加玩家</button>\n</div>\n\n<div class=\"input-bar\">\n    <input id=\"nameInput\" placeholder=\"玩家名字\">\n    <select id=\"campSelect\" onchange=\"onMainCampChange()\">\n        <option value=\"\">阵营标记</option>\n        <option value=\"鹅\">好鹅阵营</option>\n        <option value=\"鸭子\">坏鸭阵营</option>\n        <option value=\"中立\">中立阵营</option>\n    </select>\n    <select id=\"roleSelect\">\n        <option value=\"\">怀疑身份</option>\n    </select>\n    <select id=\"aliveSelect\">\n        <option value=\"alive\">活着</option>\n        <option value=\"dead\">死亡</option>\n    </select>\n    <button onclick=\"addPlayer()\">添加</button>\n</div>\n\n<div class=\"col-wrap\" id=\"colWrap\">\n    <div class=\"col-goose\">\n        <div class=\"col-title title-goose\">🦢 好鹅阵营 / 未标记</div>\n        <div id=\"boxGoose\" class=\"box-scroll\"></div>\n    </div>\n    <div class=\"col-duck\">\n        <div class=\"col-title title-duck\">🦆 坏鸭阵营</div>\n        <div id=\"boxDuck\" class=\"box-scroll\"></div>\n    </div>\n    <div class=\"col-neutral\">\n        <div class=\"col-title title-neutral\">🎭 中立阵营</div>\n        <div id=\"boxNeutral\" class=\"box-scroll\"></div>\n    </div>\n</div>\n\n<div class=\"ai-panel\">\n    <h3>📊简易AI分析</h3>\n    <button onclick=\"runAiAnalyse()\">执行分析</button>\n    <div id=\"aiResult\">点击执行分析，生成场上推理参考</div>\n</div>\n\n<div class=\"modal-mask\" id=\"noteModal\" onclick=\"closeNoteModal()\">\n    <div class=\"modal-box\" onclick=\"event.stopPropagation()\">\n        <div id=\"modalName\" style=\"font-weight:bold;margin-bottom:6px;\"></div>\n        <div id=\"modalNote\"></div>\n        <button onclick=\"closeNoteModal()\" style=\"width:100%;margin-top:10px;\">关闭</button>\n    </div>\n</div>\n\n<script>\nconst roleLib = {\n    \"鹅\":[\"侦探\",\"加拿大鹅\",\"士兵\",\"复仇者\",\"探测员\",\"星届行者\",\"模仿者\",\"正义使者\",\"清醒梦者\",\"生存主义者\",\"科学家\",\"网红\",\"肉汁\",\"观鸟者\",\"警长\",\"说客\",\"跟踪者\",\"通灵者\",\"预言家\",\"验尸官\",\"追踪者\",\"冒险家\",\"政治家\",\"恋人\",\"流浪儿童\",\"锁匠\"],\n    \"鸭子\":[\"专业杀手\",\"丧葬者\",\"传教士\",\"刺客\",\"剑客\",\"寄生者\",\"宿主\",\"小丑\",\"巫医\",\"忍者\",\"派对狂\",\"爆炸王\",\"走失小鸭\",\"超能力者\",\"身份窃贼\",\"连环杀手\",\"间谍\",\"隐形者\",\"静语者\",\"默剧演员\",\"变形者\",\"狙击手\",\"食鸟鸭\",\"术士\"],\n    \"中立\":[\"呆呆鸟\",\"决斗呆呆鸟\",\"喜鹊\",\"布谷鸟\",\"渡鸦\",\"猎鹰\",\"老鹰\",\"鸽子\",\"鹈鹕\",\"秃鹫\"]\n};\n\nlet list = [];\nlet dragSrcEl = null;\nlet foldState = false;\nlet deathLogs = [];\n\nfunction refreshDeathSelectOptions(){\n    const selDead = document.getElementById(\"logDeadMan\");\n    const selFinder = document.getElementById(\"logFinder\");\n    selDead.innerHTML = `<option value=\"\">选择死者</option><option value=\"未知\">未知</option>`;\n    selFinder.innerHTML = `<option value=\"\">选择发现人</option><option value=\"未知\">未知</option>`;\n    list.forEach(p=>{\n        selDead.innerHTML += `<option value=\"${p.name}\">${p.name}</option>`;\n        selFinder.innerHTML += `<option value=\"${p.name}\">${p.name}</option>`;\n    })\n}\n\nfunction toggleFold(){\n    foldState = !foldState;\n    const wrap = document.getElementById(\"colWrap\");\n    wrap.classList.toggle(\"hidden\",foldState);\n}\n\nfunction updateStat(){\n    const total = list.length;\n    const alive = list.filter(x=>x.status==='alive').length;\n    const dead = list.filter(x=>x.status==='dead').length;\n    const g = list.filter(x=>x.camp===\"鹅\").length;\n    const d = list.filter(x=>x.camp===\"鸭子\").length;\n    const n = list.filter(x=>x.camp===\"中立\").length;\n    const unknown = list.filter(x=>!x.camp).length;\n    document.getElementById('statBar').innerText =\n`总：${total}人｜🟢存活：${alive}  💀死亡：${dead}｜🦢好鹅：${g} 🦆坏鸭：${d} 🎭中立：${n} ❓未标记：0`;\n}\n\nfunction renderDeathLog(){\n    const box = document.getElementById(\"deathLogList\");\n    if(deathLogs.length===0){box.innerHTML=\"<div style='color:#888'>暂无尸体记录</div>\";return;}\n    box.innerHTML = deathLogs.map((item,idx)=>{\n        return `<div>${item.round}｜死者:${item.deadMan}｜发现:${item.finder} <button style=\"font-size:11px;padding:2px 4px\" onclick=\"delDeathLog(${idx})\">删除</button></div>`\n    }).join(\"\");\n}\nfunction addDeathLog(){\n    const dMan = document.getElementById(\"logDeadMan\").value.trim();\n    const finder = document.getElementById(\"logFinder\").value.trim();\n    const round = document.getElementById(\"logRound\").value.trim();\n    if(!dMan)return;\n    deathLogs.push({deadMan:dMan,finder:finder||\"未知\",round:round||\"未知回合\"});\n    document.getElementById(\"logRound\").value=\"\";\n    renderDeathLog();\n}\nfunction delDeathLog(idx){\n    deathLogs.splice(idx,1);\n    renderDeathLog();\n}\n\nlet modalOpenForIndex = null;\nfunction openNoteModal(idx){\n    modalOpenForIndex = idx;\n    const p = list[idx];\n    document.getElementById(\"modalName\").innerText = p.name;\n    document.getElementById(\"modalNote\").innerText = p.note ? \"备注：\"+p.note : \"暂无备注\";\n    document.getElementById(\"noteModal\").style.display=\"flex\";\n}\nfunction closeNoteModal(){\n    document.getElementById(\"noteModal\").style.display=\"none\";\n    modalOpenForIndex=null;\n}\n\nfunction renderTopPanel(){\n    const aliveBox = document.getElementById('aliveBox');\n    const deadBox = document.getElementById('deadBox');\n    aliveBox.innerHTML = '';\n    deadBox.innerHTML = '';\n\n    list.forEach((p,i)=>{\n        const div = document.createElement('div');\n        div.className = 'drag-item';\n        div.draggable = true;\n        div.dataset.index = i;\n        div.innerText = p.name + (p.role?\"【\"+p.role+\"】\":\"\");\n\n        if(p.suspect === \"low\") div.classList.add(\"sus-low\");\n        if(p.suspect === \"high\") div.classList.add(\"sus-high\");\n\n        if(p.note){\n            const noteSpan = document.createElement(\"span\");\n            noteSpan.className = \"mark-tag note-tag\";\n            noteSpan.innerText = \"📝\";\n            div.appendChild(noteSpan);\n        }\n        if(p.isLover){\n            const loveSpan = document.createElement(\"span\");\n            loveSpan.className = \"mark-tag love-tag\";\n            loveSpan.innerText = \"❤️\";\n            div.appendChild(loveSpan);\n        }\n        if(p.camp === \"鸭子\") div.classList.add(\"camp-duck\");\n        if(p.camp === \"中立\") div.classList.add(\"camp-neutral\");\n\n        if(p.status === 'dead'){\n            div.classList.add('dead-item');\n            deadBox.appendChild(div);\n        }else{\n            aliveBox.appendChild(div);\n        }\n\n        div.addEventListener('dragstart',handleDragStart);\n    })\n\n    aliveBox.addEventListener(\"dragover\",e=>e.preventDefault());\n    aliveBox.addEventListener(\"drop\",function(e){\n        e.preventDefault();\n        if(!dragSrcEl) return;\n        const idx = Number(dragSrcEl.dataset.index);\n        if(list[idx].status !== \"alive\"){\n            list[idx].status = \"alive\";\n            render();\n        }\n        dragSrcEl=null;\n    })\n\n    deadBox.addEventListener(\"dragover\",e=>e.preventDefault());\n    deadBox.addEventListener(\"drop\",function(e){\n        e.preventDefault();\n        if(!dragSrcEl) return;\n        const idx = Number(dragSrcEl.dataset.index);\n        if(list[idx].status !== \"dead\"){\n            list[idx].status = \"dead\";\n            render();\n        }\n        dragSrcEl=null;\n    })\n}\n\nfunction handleDragStart(e){\n    dragSrcEl = this;\n    e.dataTransfer.effectAllowed = 'move';\n}\n\nfunction fillRoleSelect(selDom,campVal,selectedVal){\n    selDom.innerHTML = `<option value=\"\">怀疑身份</option>`;\n    if(!campVal) return;\n    const arr = roleLib[campVal]||[];\n    arr.forEach(r=>{\n        selDom.innerHTML += `<option value=\"${r}\" ${r===selectedVal?'selected':''}>${r}</option>`;\n    })\n}\n\nfunction onMainCampChange(){\n    const c = document.getElementById('campSelect').value;\n    fillRoleSelect(document.getElementById('roleSelect'),c,\"\");\n}\n\nfunction quickKill(idx){\n    list[idx].status = \"dead\";\n    render();\n}\nfunction quickAlive(idx){\n    list[idx].status = \"alive\";\n    render();\n}\n\nfunction render(){\n    renderTopPanel();\n    renderDeathLog();\n    refreshDeathSelectOptions();\n    let htmlGoose='',htmlDuck='',htmlNeutral='';\n    list.forEach((p,i)=>{\n        const deadClass = p.status === 'dead' ? 'dead' : '';\n        let itemHtml = '<div class=\"player-item '+deadClass+'\">';\n        itemHtml += '<div>名字：'+p.name+'｜身份：'+(p.role||\"未知\")+'｜状态：'+(p.status==='dead'?'💀死亡':'🟢活着')+'</div>';\n        itemHtml += `<div>备注：<input value=\"${p.note||''}\" id=\"editNote${i}\" placeholder=\"简短备注\"></div>`;\n        itemHtml += `<div><label><input type=\"checkbox\" id=\"excludeDuck${i}\" ${p.excludeDuck?'checked':''}>排除鸭子嫌疑</label></div>`;\n        itemHtml += `<div><label><input type=\"checkbox\" id=\"isLover${i}\" ${p.isLover?'checked':''}>标记为恋人</label></div>`;\n        itemHtml += `<div>怀疑等级：\n        <select id=\"susSel${i}\">\n        <option value=\"none\" ${p.suspect===\"none\"||!p.suspect?\"selected\":\"\"}>无怀疑</option>\n        <option value=\"low\" ${p.suspect===\"low\"?\"selected\":\"\"}>轻度怀疑</option>\n        <option value=\"high\" ${p.suspect===\"high\"?\"selected\":\"\"}>高度怀疑</option>\n        </select>\n        </div>`;\n        itemHtml += '<div class=\"row-edit\">';\n        itemHtml += '<input value=\"'+p.name+'\" id=\"editName'+i+'\" placeholder=\"修改名字\">';\n        itemHtml += '<select id=\"editCamp'+i+'\" onchange=\"onEditCampChange('+i+')\">';\n        itemHtml += '<option value=\"\">阵营标记</option>';\n        itemHtml += '<option value=\"鹅\" '+(p.camp==='鹅'?'selected':'')+'>好鹅阵营</option>';\n        itemHtml += '<option value=\"鸭子\" '+(p.camp==='鸭子'?'selected':'')+'>坏鸭阵营</option>';\n        itemHtml += '<option value=\"中立\" '+(p.camp==='中立'?'selected':'')+'>中立阵营</option>';\n        itemHtml += '</select>';\n        itemHtml += '<select id=\"editRole'+i+'\"><option value=\"\">怀疑身份</option></select>';\n        itemHtml += '<select id=\"editStatus'+i+'\">';\n        itemHtml += '<option value=\"alive\" '+(p.status==='alive'?'selected':'')+'>活着</option>';\n        itemHtml += '<option value=\"dead\" '+(p.status==='dead'?'selected':'')+'>死亡</option>';\n        itemHtml += '</select>';\n        itemHtml += '<button class=\"btn-kill\" onclick=\"quickKill('+i+')\">💀置死亡</button>';\n        itemHtml += '<button class=\"btn-alive\" onclick=\"quickAlive('+i+')\">💚置存活</button>';\n        itemHtml += '<button class=\"btn-save\" onclick=\"saveEdit('+i+')\">保存修改</button>';\n        itemHtml += '<button class=\"btn-del\" onclick=\"remove('+i+')\">删除</button>';\n        itemHtml += '</div></div>';\n\n        if(p.camp === \"鸭子\"){\n            htmlDuck += itemHtml;\n        }else if(p.camp === \"中立\"){\n            htmlNeutral += itemHtml;\n        }else{\n            htmlGoose += itemHtml;\n        }\n    })\n    document.getElementById('boxGoose').innerHTML = htmlGoose;\n    document.getElementById('boxDuck').innerHTML = htmlDuck;\n    document.getElementById('boxNeutral').innerHTML = htmlNeutral;\n    list.forEach((p,i)=>{\n        const sel = document.getElementById('editRole'+i);\n        if(sel) fillRoleSelect(sel,p.camp,p.role);\n    })\n    updateStat();\n}\n\nfunction onEditCampChange(idx){\n    const campVal = document.getElementById('editCamp'+idx).value;\n    fillRoleSelect(document.getElementById('editRole'+idx), campVal, \"\");\n}\n\nfunction addPlayer(){\n    const name = document.getElementById('nameInput').value.trim();\n    const camp = document.getElementById('campSelect').value;\n    const role = document.getElementById('roleSelect').value;\n    const status = document.getElementById('aliveSelect').value;\n    if(!name)return;\n    list.push({name,camp,role,status,note:\"\",excludeDuck:false,isLover:false,suspect:\"none\"});\n    document.getElementById('nameInput').value='';\n    document.getElementById('campSelect').value=\"\";\n    document.getElementById('roleSelect').innerHTML=`<option value=\"\">怀疑身份</option>`;\n    render();\n}\n\nfunction saveEdit(idx){\n    const newName = document.getElementById('editName'+idx).value.trim();\n    const newCamp = document.getElementById('editCamp'+idx).value;\n    const newRole = document.getElementById('editRole'+idx).value;\n    const newStatus = document.getElementById('editStatus'+idx).value;\n    const newNote = document.getElementById('editNote'+idx).value.trim();\n    const excludeDuck = document.getElementById('excludeDuck'+idx).checked;\n    const isLover = document.getElementById('isLover'+idx).checked;\n    const suspect = document.getElementById(\"susSel\"+idx).value;\n    if(!newName) return;\n    list[idx].name = newName;\n    list[idx].camp = newCamp;\n    list[idx].role = newRole;\n    list[idx].status = newStatus;\n    list[idx].note = newNote;\n    list[idx].excludeDuck = excludeDuck;\n    list[idx].isLover = isLover;\n    list[idx].suspect = suspect;\n    render();\n}\n\nfunction remove(idx){\n    list.splice(idx,1);\n    render();\n}\n\nfunction batchAdd(){\n    const text = document.getElementById('pasteText').value;\n    const lines = text.split(/[\\n\\r]+/).map(s=>s.trim()).filter(s=>s.length>1&&s.length<22);\n    lines.forEach(name=>{\n        list.push({name:name,camp:\"\",role:\"\",status:\"alive\",note:\"\",excludeDuck:false,isLover:false,suspect:\"none\"})\n    })\n    document.getElementById('pasteText').value=\"\";\n    render();\n}\n\nfunction newRound(){\n    list = [];\n    deathLogs = [];\n    render();\n    document.getElementById('aiResult').innerText = \"点击执行分析，生成场上推理参考\";\n    document.getElementById('pasteText').value = \"\";\n}\nfunction clearAll(){\n    list = [];\n    deathLogs = [];\n    document.getElementById(\"cfgDuck\").value=3;\n    document.getElementById(\"cfgNeu\").value=2;\n    document.getElementById(\"banCustom\").value=\"\";\n    document.querySelectorAll(\".blacklist-area input\").forEach(cb=>cb.checked=false);\n    render();\n    document.getElementById('aiResult').innerText = \"点击执行分析，生成场上推理参考\";\n    document.getElementById('pasteText').value = \"\";\n}\n\nfunction runAiAnalyse(){\n    if(list.length===0){\n        document.getElementById(\"aiResult\").innerText = \"请先录入玩家信息！\";\n        return;\n    }\n    const theoDuck = Number(document.getElementById(\"cfgDuck\").value)||0;\n    const theoNeutral = Number(document.getElementById(\"cfgNeu\").value)||0;\n\n    let countGoose = list.filter(x=>x.camp===\"鹅\").length;\n    let countDuck = list.filter(x=>x.camp===\"鸭子\").length;\n    let countNeutral = list.filter(x=>x.camp===\"中立\").length;\n    let unKnow = list.filter(x=>!x.camp).length;\n    let aliveTotal = list.filter(x=>x.status==='alive').length;\n    let deadTotal = list.filter(x=>x.status==='dead').length;\n    const total = list.length;\n\n    const hideDuck = Math.max(0,theoDuck-countDuck);\n    const hideNeu = Math.max(0,theoNeutral-countNeutral);\n\n    const excludeList = list.filter(p=>p.excludeDuck).map(p=>p.name);\n    const loverList = list.filter(p=>p.isLover).map(p=>p.name);\n\n    const blkInputs = document.querySelectorAll(\".blacklist-area input:checked\");\n    const banCheckRoles = Array.from(blkInputs).map(el=>el.value);\n    const banCustomStr = document.getElementById(\"banCustom\").value.trim();\n    let banCustomArr = banCustomStr ? banCustomStr.split(\",\").map(s=>s.trim()).filter(s=>s) : [];\n    const banRoles = [...banCheckRoles,...banCustomArr];\n\n    let output = `【鹅鸭杀复盘记录】\n总录入玩家：${total}人\n存活：${aliveTotal}人｜已死亡：${deadTotal}人\n已标记好鹅：${countGoose}｜坏鸭：${countDuck}｜中立：${countNeutral}\n未判定阵营：${unKnow}人\n\n【潜藏身份估算（按你填写配置）】\n本局设置：坏鸭${theoDuck}，中立${theoNeutral}\n👉推测场上还藏坏鸭：${hideDuck}只\n👉推测场上还藏中立：${hideNeu}个\n\n${excludeList.length>0?\"✅已排除鸭子嫌疑：\"+excludeList.join(\"、\"):\"✅暂无排除鸭子嫌疑人员\"}\n${loverList.length>0?\"❤️标记恋人：\"+loverList.join(\"、\")+\"；恋人胜负跟随绑定对象\":\"❤️暂无标记恋人\"}\n${banRoles.length>0?\"🚫本局不存在角色：\"+banRoles.join(\"、\"):\"🚫未勾选禁用角色\"}\n\n☠尸体记录：\n${deathLogs.length>0 ? deathLogs.map(d=>`${d.round}｜死者${d.deadMan}｜发现人${d.finder}`).join(\"\\n\"):\"无尸体记录\"}\n\n玩家明细：\n${list.map(p=>`${p.status==='dead'?'💀':'🟢'}${p.name}｜阵营:${p.camp||\"未标记\"}｜怀疑身份:${p.role||\"无\"}｜怀疑等级:${p.suspect===\"low\"?\"轻度\":p.suspect===\"high\"?\"高度\":\"无\"}｜备注:${p.note||\"无\"}`).join(\"\\n\")}\n\n提示：\n1.潜藏数量基于你手动填写本局配置计算；\n2.恋人属于特殊双阵营角色，胜负跟随绑定对象；\n3.仅统计你手动填写的数据，仅供参考。`\n    document.getElementById(\"aiResult\").innerText = output;\n}\n\nasync function copyReplayLog(){\n    runAiAnalyse();\n    const text = document.getElementById(\"aiResult\").innerText;\n    try{\n        await navigator.clipboard.writeText(text);\n        alert(\"✅复盘文本已经复制！直接粘贴到聊天框\");\n    }catch(e){\n        alert(\"⚠️浏览器复制权限失败，请手动长按AI结果框复制文字\");\n    }\n}\n\nrender();\n</script>\n</body>\n</html>\n\n"}