{"id":2675,"date":"2025-12-13T18:53:30","date_gmt":"2025-12-13T10:53:30","guid":{"rendered":"https:\/\/conga.tw\/memo\/?page_id=2675"},"modified":"2026-06-05T22:11:13","modified_gmt":"2026-06-05T14:11:13","slug":"%e2%97%89-%e8%bf%bd%e5%8a%87%e9%80%b2%e5%ba%a6%e8%bf%bd%e8%b9%a4%e6%9d%bf-watchlist-tracker-ver-2-2","status":"publish","type":"page","link":"https:\/\/conga.tw\/memo\/?page_id=2675","title":{"rendered":"\u25c9 \u52d5\u6f2b\u5287\u9032\u5ea6\u8ffd\u8e64\u677f"},"content":{"rendered":"\n<meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u52d5\u6f2b\u5287\u9032\u5ea6\u8ffd\u8e64\u677f Ver 2.2<\/title>\n\n\n\n<div class=\"watchlist-board\">\n    <h2 align=\"center\">\ud83d\udcfa \u52d5\u6f2b\u5287\u9032\u5ea6\u8ffd\u8e64\u677f<\/h2>\n\n    <!-- \u8a0a\u606f\u63d0\u793a\u5340 -->\n    <div id=\"message-box\" class=\"message-box hidden\"><\/div>\n\n    <!-- \u8868\u683c\u986f\u793a\u5340 (\u4e0a\u534a\u90e8) -->\n    <!-- \u52a0\u5165  style=\"cursor: default; user-select: none; -webkit-user-select: none;\" \u6539\u8b8a\u6a19\u984c\u5217\u9f20\u6a19\u884c\u70ba -->\n    <div class=\"table-container\">\n        <table class=\"watch-table\">\n            <thead>\n                <tr>\n                    <th class=\"col-fav sortable\" data-sort-key=\"isFavorite\" title=\"\u6211\u7684\u6700\u611b\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\ud83d\udc8c<font color=\"#00ff00\">\u2b61<\/font><\/th>\n                    <th class=\"col-title\" title=\"\u5287\u96c6\u540d\u7a31\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u5287\u540d<\/th>\n                    <th class=\"col-total\" title=\"\u5287\u96c6\u5168\u90e8\u96c6\u6578\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u7e3d\u96c6\u6578<\/th>\n                    <th class=\"col-season\" title=\"\u7576\u524d\u89c0\u770b\u5b63\u6b21\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u5b63<\/th>\n                    <th class=\"col-episode\" title=\"\u7576\u524d\u5df2\u89c0\u770b\u96c6\u6578\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u96c6<\/th>\n                    <th class=\"col-last-watch sortable\" data-sort-key=\"lastWatchedDate\" title=\"\u6700\u5f8c\u89c0\u770b\u65e5\u671f\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u6700\u5f8c\u89c0\u770b<font color=\"#00ff00\">\u2b83<\/font><\/th>\n                    <th class=\"col-latest\" title=\"\u5df2\u66f4\u65b0\u96c6\u6578\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u5df2\u66f4\u65b0<\/th>\n                    <!-- \u4fee\u6b63\u9ede 1: \u589e\u52a0\u6392\u5e8f\u80fd\u529b -->\n                    <th class=\"col-cycle sortable\" data-sort-key=\"updateCycle\" title=\"\u66f4\u65b0\u9031\u671f\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u66f4\u65b0\u9031\u671f<font color=\"#00ff00\">\u2b83<\/font><\/th>\n                    <!-- \u4fee\u6b63\u9ede 1: \u589e\u52a0\u6392\u5e8f\u80fd\u529b -->\n                    <th class=\"col-status sortable\" data-sort-key=\"status\" title=\"\u5287\u96c6\u66f4\u65b0\u72c0\u614b\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u5287\u60c5\u767c\u5c55<font color=\"#00ff00\">\u2b83<\/font><\/th>\n                    <th class=\"col-notes\" title=\"\u5099\u8a3b\u6b04\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u88dc\u5145\u8cc7\u8a0a<\/th>\n                    <th class=\"col-del\"><font color=\"#ff8866\" title=\"\u522a\u9664\u6574\u5217\u8cc7\u6599\" style=\"cursor: default; user-select: none; -webkit-user-select: none;\">\u274c<\/font><\/th>\n                <\/tr>\n            <\/thead>\n            <tbody id=\"watchlist-body\">\n                <!-- \u8cc7\u6599\u5c07\u7531 JavaScript \u6e32\u67d3 -->\n            <\/tbody>\n        <\/table>\n    <\/div>\n\n<hr style=\"border: none; border-top: 0.9px solid; background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet); width: 100%; margin: auto;\">\n\n    <!-- \u7279\u6b8a\u529f\u80fd\u5217\uff1a\u641c\u5c0b\u3001\u532f\u51fa\u3001\u532f\u5165 -->\n    <div class=\"special-tools-bar\">\n        <input id=\"search-input\" title=\"\u641c\u5c0b\u6b04\u4f4d \u81f3\u5c11 1 \u500b\u5b57\u5143\" placeholder=\"\u8f38\u5165\u6b32\u641c\u5c0b\u5287\u540d\u95dc\u9375\u5b57...\">\n        <button id=\"search-btn\" title=\"\u641c\u5c0b\u5287\u540d\">\ud83d\udd0e \u641c\u5c0b<\/button>\n        <button id=\"clear-search-btn\" title=\"\u6e05\u9664\u641c\u5c0b\u6b04\u4f4d\">\ud83e\uddf9 \u6e05\u9664<\/button>\n        <input type=\"file\" id=\"import-file\" accept=\".json\" style=\"display:none;\">\n        <button id=\"export-btn\" title=\"\u532f\u51fa\u8cc7\u6599\">\ud83d\udce4 \u532f\u51fa<\/button>\n        <button id=\"import-btn\" title=\"\u532f\u5165\u8cc7\u6599\">\ud83d\udce5 \u532f\u5165<\/button>\n    <\/div>\n<hr style=\"border: none; border-top: 0.9px solid; background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet); width: 100%; margin: auto;\">\n    <!-- \u8cc7\u8a0a\u8f38\u5165\u5217 (\u4e0b\u534a\u90e8) -->\n    <div class=\"add-form\">\n        <!-- \u5287\u540d\u8207\u52a0\u5165\u6700\u611b\u540c\u4e00\u5217 -->\n        <div class=\"input-group-row title-fav-row\">\n            <input id=\"title-input\" placeholder=\"\u8f38\u5165\u5287\u540d... (\u5fc5\u586b\u6b04\u4f4d)\" class=\"col-title-input input-field\" title=\"\u8f38\u5165\u5287\u96c6\u540d\u7a31 (\u5fc5\u586b\u6b04\u4f4d)\">\n            <div class=\"input-field fav-field\" title=\"\u52fe\u9078\u6838\u53d6\u65b9\u584a\u2611\ufe0e\u52a0\u5165\u6700\u611b\">\n    <label for=\"fav-input\" class=\"fav-label\">\n        \ud83d\udc8c \u52a0\u5165\u6211\u7684\u6700\u611b\n        <input type=\"checkbox\" id=\"fav-input\">\n    <\/label>\n<\/div>\n\n        <\/div>\n\n        <!-- \u6578\u503c\u8207\u65e5\u671f\u6b04\u4f4d -->\n        <div class=\"input-group-row numeric-date-row\">\n            <input id=\"total-input\" type=\"number\" inputmode=\"numeric\" title=\"\u5287\u96c6\u5168\u90e8\u96c6\u6578\" placeholder=\"\u8f38\u5165\u7e3d\u96c6\u6578\" min=\"0\" class=\"input-field\">\n            <input id=\"season-input\" type=\"number\" inputmode=\"numeric\" title=\"\u76ee\u524d\u6b63\u5728\u89c0\u770b\u7684\u5b63\u6b21\" placeholder=\"\u8f38\u5165\u7576\u524d\u5b63\u6b21\" min=\"0\" class=\"input-field\">\n            <input id=\"episode-input\" type=\"number\" inputmode=\"numeric\" title=\"\u76ee\u524d\u5df2\u7d93\u770b\u5b8c\u7684\u96c6\u6578\" placeholder=\"\u8f38\u5165\u5df2\u89c0\u770b\u96c6\u6578\" min=\"0\" class=\"input-field\">\n            <input id=\"latest-episode-input\" type=\"number\" inputmode=\"numeric\" title=\"\u73fe\u5728\u5df2\u5b8c\u6210\u66f4\u65b0\u7684\u96c6\u6578\" placeholder=\"\u8f38\u5165\u5df2\u66f4\u65b0\u96c6\u6578\" min=\"0\" class=\"input-field\">\n            <!-- \u4fee\u6b63\u9ede\uff1a\u6700\u5f8c\u89c0\u770b\u65e5\u671f\u6b04\u4f4d\u52a0\u5165\u63d0\u793a\u8a5e -->\n            <input id=\"last-watch-input\" type=\"date\" title=\"\u9078\u64c7\u6700\u5f8c\u89c0\u770b\u65e5\u671f\uff0c\u672c\u6b04\u6700\u53f3\u5074-\u53ef\u986f\u793a\u65e5\u671f\u9078\u64c7\u5668\" class=\"col-date-input input-field\">\n        <\/div>\n\n        <!-- \u72c0\u614b\u8207\u5099\u8a3b -->\n        <div class=\"input-group-row status-notes-row\">\n           <select id=\"status-select\" class=\"input-field\" title=\"\u4e0b\u62c9\u5f0f\u6e05\u55ae-\u9078\u64c7\u66f4\u65b0\u72c0\u614b\">\n                <option value=\"\" selected=\"\" disabled=\"\">[\u4e0b\u62c9] \u9078\u64c7\u5287\u60c5\u767c\u5c55-\u66f4\u65b0\u9032\u5ea6<\/option>\n                <option value=\"\u66f4\u65b0\u4e2d\">\u5287\u60c5\u767c\u5c55\uff1a\u66f4\u65b0\u4e2d<\/option>\n                <option value=\"\u5df2\u5b8c\u7d50\">\u5287\u60c5\u767c\u5c55\uff1a\u5df2\u5b8c\u7d50<\/option>\n                <option value=\"\u5df2\u505c\u66f4\">\u5287\u60c5\u767c\u5c55\uff1a\u5df2\u505c\u66f4<\/option>\n            <\/select>\n            <input id=\"notes-input\" title=\"\u7d66\u81ea\u5df1\u8a3b\u8a18\u7684\u5167\u5bb9 \u5efa\u8b70\u81f3\u591a10-12\u5b57\u5143..\" placeholder=\"\u8f38\u5165\u88dc\u5145\u8cc7\u8a0a...(\u4f8b: \u65b0\u5287\u60c5\u6545\u4e8b\u65bc2026\u6625\u4e0a\u6620)\" class=\"col-notes-input input-field\">\n        <\/div>\n\n        <!-- \u66f4\u65b0\u9031\u671f \u8207 \u65b0\u589e\u6309\u9215 \u540c\u5217 -->\n        <div class=\"input-group-row cycle-add-row\">\n            <div class=\"cycle-group\">\n                <div class=\"cycle-header\"><font color=\"#b0e0e6\"><b>\ud83d\udcc5 \u66f4\u65b0\u9031\u671f:<\/b><\/font><\/div>\n                <div id=\"cycle-options\" class=\"cycle-options\">\n                    <label><input type=\"checkbox\" name=\"update-cycle\" value=\"\u65e5\">\u661f\u671f\u65e5<\/label>\n                    <label><input type=\"checkbox\" name=\"update-cycle\" value=\"\u4e00\">\u661f\u671f\u4e00<\/label>\n                    <label><input type=\"checkbox\" name=\"update-cycle\" value=\"\u4e8c\">\u661f\u671f\u4e8c<\/label>\n                    <label><input type=\"checkbox\" name=\"update-cycle\" value=\"\u4e09\">\u661f\u671f\u4e09<\/label>\n                    <label><input type=\"checkbox\" name=\"update-cycle\" value=\"\u56db\">\u661f\u671f\u56db<\/label>\n                    <label><input type=\"checkbox\" name=\"update-cycle\" value=\"\u4e94\">\u661f\u671f\u4e94<\/label>\n                    <label><input type=\"checkbox\" name=\"update-cycle\" value=\"\u516d\">\u661f\u671f\u516d<\/label>\n                <\/div>\n            <\/div>\n            <button id=\"add-item\" class=\"action-btn add-btn\" title=\"\u65b0\u589e\u4e00\u7b46\u8cc7\u6599\">\ud83d\uddc2\ufe0f \u65b0\u589e\u8cc7\u6599<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n \n<style>\n\/* =========================================================\n    CSS \u6a23\u5f0f\uff1a\u7e7c\u627f Ver 3.5 \u7684\u4f48\u5c40\n    ========================================================= *\/\n\n:root {\n    --bg-color: #0d0d0d;\n    --border-color-subtle: rgba(36, 36, 36, 0.6); \/* \u503c0.0\u5b8c\u5168\u900f\u660e 1.0\u5b8c\u5168\u4e0d\u900f\u660e *\/\n    --table-border-color: #1a1a1a; \/* \u5287\u96c6\u986f\u793a\u5217\u8868-\u6c34\u5e73\u6846\u7dda\u984f\u8272 - \u9810\u8a2d1a1a1a *\/\n    --text-color: #ccddff; \/* \u5287\u96c6\u986f\u793a\u6587\u5b57\u984f\u8272 - \u9810\u8a2d #ace *\/\n    --highlight-color: #00ffff; \/* \u4e3b\u8981\u6a19\u984c\u5217 \u6587\u5b57\u984f\u8272 *\/\n    --input-bg: #3f3f3f; \/* \u5168\u90e8\u8f38\u5165\u6b04\u4f4d-\u5132\u5b58\u683c\u5e95\u8272 *\/\n    --primary-text-color: #ffffff;\n    --btn-primary: #007bff; \/* \u641c\u5c0b-\u6309\u9215\u80cc\u666f\u8272 007bff *\/\n    --btn-success: #77af00; \/* \u532f\u51fa-\u6309\u9215\u80cc\u666f\u8272 5cb85c *\/\n    --btn-warning: #ff8800; \/* \u532f\u5165-\u6309\u9215\u80cc\u666f\u8272 f0ad4e *\/\n    --btn-info: #fd60fe;  \/* \u6e05\u9664-\u6309\u9215\u80cc\u666f\u8272 5bc0de *\/\n    --btn-action: #ff0000; \/* 007bff *\/\n    --delete-red: #ff4d4d;\n    --main-border-color: #ff8866;\n    --main-header-height: 60px; \/* \u65b0\u589e\u4e00\u500b\u9ad8\u5ea6\u8b8a\u6578 *\/\n}\n\n.watchlist-board {\n    width: 100%;\n    max-width: 900px;\n    margin: 12px auto;\n    font-family: \"Segoe UI\", \"\u5fae\u8edf\u6b63\u9ed1\u9ad4\", sans-serif;\n    color: var(--text-color);\n    box-sizing: border-box;\n    overflow-x: hidden;\n    \/* \u4e3b\u5bb9\u5668\u908a\u6846\u6a58\u7d05 *\/\n    border: 2px solid var(--main-border-color);\n    border-radius: 12px;\n    padding: 6px;\n    background: var(--bg-color);\n}\n\n.message-box {\n    \/* \u78ba\u4fdd\u6d88\u606f\u6846\u6a23\u5f0f\u5b58\u5728 *\/\n    padding: 10px;\n    margin-bottom: 10px;\n    border-radius: 6px;\n    text-align: center;\n    background-color: #333; \/* \u9810\u8a2d#333\u80cc\u666f\u8272 *\/\n    color: var(--text-color); \/* \u9810\u8a2d\u6587\u5b57\u984f\u8272 *\/\n    font-weight: bold;\n}\n.message-box.error {\n    \/* *** \u9019\u662f\u60a8\u9700\u8981\u65b0\u589e\u7684\u5167\u5bb9\uff1a\u5c07\u932f\u8aa4\u8a0a\u606f\u6587\u5b57\u8a2d\u70ba\u7d05\u8272 *** *\/\n    font-size: 1.5em;\n    color: #ff0000; \/* \u9bae\u7d05\u8272 *\/\n    background-color: #002c00; \/* \u6697\u7da0\u8272\u80cc\u666f\uff0c\u8f03\u67d4\u548c *\/\n}\n\n.message-box.hidden { display: none !important; }\n\n\/* \u7279\u6b8a\u529f\u80fd\u5217 (Search, Export, Import) \u4f48\u5c40 - \u5f37\u5236\u55ae\u5217 *\/\n.special-tools-bar {\n    display: flex;\n    gap: 8px; \/* \u641c\u5c0b\u6b04\u4f4d\u548c4\u500b\u6309\u9215\u7684\u9593\u9694\u5bec\u5ea6 - 6 *\/\n    margin-top: 10px;  \/*\u641c\u5c0b\u6b04\u4f4d\u4e0a\u6846\u7dda\u8207\u4e0a\u65b9\u7684\u7a7a\u767d\u8ddd\u96e2 *\/\n    margin-bottom: 10px; \/*\u641c\u5c0b\u6b04\u4f4d\u4e0a\u6846\u7dda\u8207\u4e0b\u65b9\u7684\u7a7a\u767d\u8ddd\u96e2 *\/\n    margin-left: 9.5px; \/*\u641c\u5c0b\u6b04\u4f4d\u4e0a\u6846\u7dda\u8207\u5de6\u908a\u754c\u7684\u7a7a\u767d\u8ddd\u96e2 *\/\n    margin-right: 10px; \/*\u641c\u5c0b\u6b04\u4f4d\u5168\u5217\u4e0a\u6846\u7dda\u8207\u53f3\u908a\u754c\u7684\u7a7a\u767d\u8ddd\u96e2 *\/\n    align-items: center;\n    flex-wrap: nowrap;\n    overflow-x: auto;\n    padding-bottom: 1px;\n    padding-top: 1px; \/* \u89e3\u6c7a\u641c\u5c0b\u8f38\u5165\u4e0a\u6846\u7dda\u88ab\u5403\u7dda\u554f\u984c *\/\n    padding-left: 1px; \/* \u89e3\u6c7a\u641c\u5c0b\u8f38\u5165\u5de6\u6846\u7dda\u88ab\u5403\u7dda\u554f\u984c *\/\n}\n.special-tools-bar input {\n    flex-grow: 1;\n    min-width: 80px;\n    flex-shrink: 1;\n}\n.special-tools-bar button, .action-btn {\n    width: 70px;\n    padding: 8px 6px;\n    border-radius: 6px;\n    border: none;\n    cursor: pointer;\n    background: var(--btn-action);\n    color: #ffffff; \/* \u641c\u5c0b \u6e05\u9664 \u532f\u5165 \u532f\u51fa \u6309\u9215\u6587\u5b57\u984f\u8272 *\/\n    font-weight: bold;\n    font-size: 0.95em;\n    flex-shrink: 0;\n    height: 40px;\n    box-sizing: border-box;\n    white-space: nowrap;\n}\n#search-btn { background: var(--btn-primary); width: 80px; }\n#clear-search-btn { background: var(--btn-info); }\n#export-btn { background: var(--btn-success); }\n#import-btn { background: var(--btn-warning); }\n\n\/* \u4e0b\u534a\u90e8\uff1a\u8f38\u5165\u5340 *\/\n.add-form {display: flex; flex-direction: column; gap: 10px; padding: 10px; border-radius: 8px; background: #151515; } \/* \u8f38\u5165\u5340\u7684\u5927\u6846\u67b6\u5167\u80cc\u666fbg 151515 *\/\n.input-group-row { display: grid; gap: 10px; align-items: center; }\n\n\/* \u5287\u540d\u8207\u52a0\u5165\u6700\u611b\u4f48\u5c40 *\/\n.title-fav-row {\n    grid-template-columns: 1fr auto;\n    gap: 10px;\n    align-items: center;\n}\n.fav-label {\n    white-space: nowrap;\n    display: flex;\n    align-items: center;\n    cursor: pointer;\n}\n.fav-label input[type=\"checkbox\"] {\n    margin-right: 5px;\n    width: 18px;\n    height: 18px;\n}\n\n.numeric-date-row { grid-template-columns: repeat(5, 1fr); }\n.status-notes-row { grid-template-columns: 1fr 2fr; }\n.cycle-add-row { display: flex; justify-content: space-between; align-items: center; }\n.cycle-group { display: flex; align-items: center; flex-grow: 1; flex-wrap: wrap; gap: 5px 10px; }\n#add-item { width: 120px; flex-shrink: 0; font-size: 1.0em; background: #ffe066; color: #151515; }\n\n\/* \u5e95\u4e0b\u90194\u884c\u63a7\u5236\u5168\u90e8\u8f38\u5165\u6b04\u4f4d\u7684\u8a2d\u5b9a\u5916\u6846\u7dda\u984f\u8272\u548c\u63d0\u793a\u6587\u5b57\u5927\u5c0f *\/\n.add-form .input-field, .special-tools-bar input {\n    padding: 8px 10px; height: 40px; border-radius: 6px; border: 1px solid #666;\n    background: var(--input-bg); font-size: 1.0em; width: 100%; box-sizing: border-box;\n    appearance: none; color: var(--primary-text-color);\n}\ninput[type=\"date\"] { color: var(--primary-text-color) !important; }\n\/* \u8b93 date input \u5728 Chrome\/Edge \u4e2d\u80fd\u66f4\u597d\u5730\u986f\u793a placeholder \u6587\u5b57\u984f\u8272 *\/\ninput[type=\"date\"]::before {\n    content: attr(placeholder);\n    color: #fff; \/* Placeholder \u984f\u8272 *\/\n    pointer-events: none;\n    display: block;\n    line-height: 40px;\n    height: 40px;\n}\n\ninput[type=\"date\"]:focus::before,\ninput[type=\"date\"]:valid::before {\n    content: \"\";\n    display: none;\n}\n\/* \u8b93 Firefox \u4e5f\u80fd\u986f\u793a *\/\ninput[type=\"date\"]:not([value]):before {\n    content: attr(placeholder);\n    color: #888;\n}\n\n\/* \u8868\u683c\u986f\u793a\u5340 (\u6b04\u5bec\u8207\u7dda\u689d) *\/\n.watch-table {\n    width: 100%;\n    border-collapse: collapse;\n    border: none; \/* \u53d6\u6d88\u4e0a\u8868\u683c\u5167\u6846\u7dda *\/\n    table-layout: fixed;\n    font-size: 0.9em;\n    border-bottom: none;\n}\n\n.watch-table th,\n.watch-table td {\n    padding: 5px 3px;\n    text-align: center;\n    border: none; \/* \u53d6\u6d88\u4e0a\u8868\u683c\u5916\u6846\u7dda *\/\n    border-bottom: 1.5px solid var(--table-border-color);\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n.watch-table thead th {\n    background: #1a1a1a;\n    color: var(--highlight-color);\n    font-weight: normal;\n}\n.watch-table tr:hover { background: #666; }\n\n\/* \u522a\u9664\u6309\u9215\u6a23\u5f0f *\/\n.delete-btn {\n    background-color: var(--delete-red); \/* \u7d05\u5e95 *\/\n    color: white; \/* \u767d\u5b57 *\/\n    border: none;\n    padding: 4px 4px;\n    border-radius: 4px;\n    cursor: pointer;\n    font-weight: bold;\n    font-size: 0.95em;\n}\n.delete-btn:hover {\n    background-color: #cc0000;\n}\n\n\/* \u684c\u9762\u7248\u6b04\u5bec\u5b9a\u7fa9 *\/\n.col-fav { width: 3em; } \t\/* \u6211\u7684\u6700\u611b\u5bec\u5ea6 3em *\/\n.col-title { width: 10em; } \t\/* \u5287\u540d\u5bec\u5ea6 10em *\/\n.col-total { width: 4em; } \t\/* \u7e3d\u96c6\u6578\u5bec\u5ea6 4em *\/\n.col-season { width: 3em; } \t\/* \u5b63\u5bec\u5ea6 3em *\/\n.col-episode { width: 4em; } \t\/* \u96c6\u5bec\u5ea6 4em *\/\n.col-last-watch { width: 8em; }\t\/* \u6700\u5f8c\u89c0\u770b\u5bec\u5ea6 8em *\/\n.col-latest { width: 4em; }\t\/* \u5df2\u66f4\u65b0\u96c6\u6578\u5bec\u5ea6 4em *\/\n.col-cycle { width: 7em; }\t\/* \u66f4\u65b0\u9031\u671f\u5bec\u5ea6 7em *\/\n.col-status { width: 6em; }\t\/* \u5287\u60c5\u767c\u5c55\u5bec\u5ea6 6em *\/\n.col-del { width: 3em; }\t\/* \u88dc\u5145\u8cc7\u8a0a\u5bec\u5ea6 3em *\/\n.col-notes { width: auto; }\t\/* \u522a\u9664\u5bec\u5ea6 auto *\/\n\n\/*==============================*\/\n\/* \u6240\u6709\u8f38\u5165\u6b04\u4f4d placeholder \u984f\u8272 *\/\ninput::placeholder,\ntextarea::placeholder,\nselect::placeholder {\n    color: #ffffff !important;   \/* \u2190 \u6539\u6210\u4f60\u60f3\u8981\u7684\u984f\u8272 *\/\n}\n\n\/* \u4f60\u7684 input-field \u4e5f\u9069\u7528 *\/\n.input-field::placeholder {\n    color: #ffffff !important;\n}\n\n\/* \u5287\u60c5\u767c\u5c55 select \u672c\u9ad4 *\/\n#status-select {\n    background-color: #383838;  \/* \u5287\u60c5\u767c\u5c55-\u9032\u5ea6\u6b04\u4f4d-\u80cc\u666f\u5e95\u8272 \/*\n    color: #b0b0b0; \/* \u5287\u60c5\u767c\u5c55\u5b57\u9ad4\u984f\u8272 *\/\n}\n\n\/* \u4e0b\u62c9\u9078\u55ae\u9078\u9805\uff08option\uff09 *\/\n#status-select option {\n    background-color: #0d0d0d !important;\n    color: #fff !important;\n}\n\n\/* \u6240\u6709\u8f38\u5165\u6b04\u4f4d\u7684 placeholder \u984f\u8272 *\/\ninput::placeholder {\n    color: #efefef !important;   \/* \u2190 \u6539\u6210\u4f60\u60f3\u8981\u7684\u984f\u8272 *\/\n}\n\n\/* ===============================\n   \u52a0\u5165\u6211\u7684\u6700\u611b\uff1a\u5132\u5b58\u683c\u5316\n   =============================== *\/\n.fav-field {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: 0 10px;\n}\n\n.fav-label {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    cursor: pointer;\n    font-weight: bold;\n    color: #b0e0e6;\n}\n\n.fav-label input[type=\"checkbox\"] {\n    width: 18px;\n    height: 18px;\n    cursor: pointer;\n}\n\n\/* ===================================\n   \u97ff\u61c9\u5f0f\u8abf\u6574\uff08\u624b\u6a5f\u76f4\u5f0f\u87a2\u5e55\uff09\n   \u7b56\u7565\uff1a\u7dad\u6301\u684c\u6a5f\u8868\u683c\u7248\u9762\uff0c\u555f\u7528\u6c34\u5e73\u6372\u52d5\n   =================================== *\/\n@media screen and (max-width: 600px) {\n\n    \/* ===============================\n       1. \u8868\u683c\u5bb9\u5668\uff1a\u555f\u7528\u6c34\u5e73\u6372\u52d5\n       =============================== *\/\n    .table-container {\n        overflow-x: auto;\n        overflow-y: hidden;\n        -webkit-overflow-scrolling: touch; \/* iOS \u6163\u6027\u6ed1\u52d5 *\/\n        width: 100%;\n    }\n\n    \/* ===============================\n     2. \u8868\u683c\u672c\u9ad4\uff1a\u4fdd\u6301\u684c\u6a5f\u6b04\u5bec\n       =============================== *\/\n    .watch-table {\n        min-width: 900px;      \/* \u95dc\u9375\uff1a\u4e0d\u8b93\u6b04\u4f4d\u88ab\u64e0\u58d3 *\/\n        table-layout: fixed;   \/* \u8207\u684c\u6a5f\u4e00\u81f4 *\/\n    }\n\n    \/* ===============================\n      3. \u907f\u514d body \u51fa\u73fe\u6a6b\u5411\u6372\u8ef8\n       =============================== *\/\n    body {\n        overflow-x: hidden;\n    }\n\n    \/* ===============================\n       4. \u8868\u982d\u8207\u6b04\u4f4d\uff1a\u7dad\u6301\u55ae\u884c\u986f\u793a\n       =============================== *\/\n    .watch-table th,\n    .watch-table td {\n        white-space: nowrap;      \/* \u4e0d\u5f37\u5236\u63db\u884c *\/\n        text-overflow: ellipsis;\n        overflow: hidden;\n    }\n\n    \/* ===============================\n       5. \u641c\u5c0b \/ \u5de5\u5177\u5217\uff1a\u624b\u6a5f\u7248\u91cd\u65b0\u6392\u5217\n       \u5de5\u5177\u5217\uff1a\u907f\u514d\u641c\u5c0b\u6309\u9215\u534a\u5bec\n       =============================== *\/\n    .special-tools-bar {\n        display: grid;\n        grid-template-columns: 1fr 1fr 1fr 1fr 1fr; \/* \u641c\u5c0b\u6b04\u4f4d + 4\u500b\u6309\u9215 \u540c\u5217*\/\n        gap: 4px;\n    }\n\n    \/* \u641c\u5c0b\u6b04\uff1a\u7368\u4f54\u4e00\u5217 *\/\n    .special-tools-bar input {\n        grid-column: 1fr 1fr;\n        width: 100%;\n    }\n\n    \/* \u56db\u9846\u6309\u9215\uff1a\u7b49\u5bec\u3001\u586b\u6eff *\/\n    .special-tools-bar button {\n        width: 100%;\n    }\n\n    \/* ===============================\n      6. \u8f38\u5165\u5340\uff1a\u907f\u514d\u904e\u5ea6\u58d3\u7e2e\n         \u7e3d\u96c6\u6578 \/ \u5b63 \/ \u96c6 \/ \u5df2\u66f4\u65b0 \u2192 \u5169\u6b04\n       =============================== *\/\n    .numeric-date-row {\n        grid-template-columns: 1fr 1fr;\n        gap: 8px;\n    }\n\n    \/* \u6700\u5f8c\u89c0\u770b + \u5287\u60c5\u767c\u5c55 \u2192 \u540c\u4e00\u5217 *\/\n   .status-notes-row {\n       display: grid;\n       grid-template-columns: 1fr 1fr; \n       gap: 8px;\n    }\n\n    \/* \u88dc\u5145\u8cc7\u8a0a\uff1a\u7368\u4f54\u4e00\u5217 *\/\n    #notes-input {\n        grid-column: auto; \/*1fr span 2 *\/\n    }\n\n    .cycle-add-row {\n        flex-direction: column;\n        align-items: stretch;\n        gap: 8px;\n    }\n\n    #add-item {\n        width: 100%;\n    } \n\n    \/* ===============================\n       7. UX \u63d0\u793a\uff1a\u544a\u77e5\u53ef\u5de6\u53f3\u6ed1\u52d5\n       =============================== *\/\n    .table-container::after {\n        content: \"\u2194\ufe0f \u5de6\u53f3\u6ed1\u52d5\u67e5\u770b\u5b8c\u6574\u5287\u96c6\u8cc7\u8a0a\";\n        display: block;\n        text-align: center;\n        font-size: 0.85em;\n        color: #aaa;\n        padding: 6px 0 2px;\n        user-select: none;\n    }\n}\n\n<\/style>\n\n<script>\n\/\/ ====== ==========================\n\/\/ \u7a0b\u5f0f\u78bc\u8aaa\u660e: Watchlist Tracker Ver 2.2 - JavaScript \u6838\u5fc3\u908f\u8f2f\n\/\/ \u529f\u80fd\uff1a\u8cc7\u6599\u5132\u5b58\/\u8f09\u5165 (localStorage), \u6392\u5e8f, \u641c\u5c0b, \u7de8\u8f2f, \u522a\u9664, \u532f\u5165\/\u532f\u51fa\u3002\n\/\/ \u7279\u8272\uff1a\u65b0\u589e\u300c\u66f4\u65b0\u300d\u8207\u300c\u5287\u60c5\u767c\u5c55\u300d\u6392\u5e8f\u53ca\u9ede\u64ca\u7de8\u8f2f\u529f\u80fd\u3002\n\/\/ =============================================\n\n  \/\/ --- \u5168\u57df\u8b8a\u6578\u8207\u521d\u59cb\u5316 ---\nlet watchlist = JSON.parse(localStorage.getItem(\"watchlist\")) || [\n    { title: \"Ex.\u9032\u64ca\u7684\u5de8\u4eba \u6700\u7d42\u5b63\", total: \"28\", season: \"4\", episode: \"16\", isFavorite: true, lastWatchedDate: \"2024-06-01\", latestEpisode: \"28\", updateCycle: [\"\u516d\"], status: \"\u5df2\u5b8c\u7d50\", notes: \"\u7b49\u5f85\u5287\u5834\u7248\" },\n    { title: \"Ex.\u9b3c\u6ec5\u4e4b\u5203 \u67f1\u8a13\u7df4\u7bc7\", total: \"8\", season: \"4\", episode: \"5\", isFavorite: false, lastWatchedDate: \"2024-05-25\", latestEpisode: \"7\", updateCycle: [\"\u65e5\"], status: \"\u66f4\u65b0\u4e2d\", notes: \"\" },\n    { title: \"Ex.\u5492\u8853\u8ff4\u6230 (\u7b2c\u4e8c\u5b63)\", total: \"23\", season: \"2\", episode: \"23\", isFavorite: true, lastWatchedDate: \"2023-12-28\", latestEpisode: \"23\", updateCycle: [], status: \"\u5df2\u5b8c\u7d50\", notes: \"\u65b0\u5b63\u9810\u8a08 2025 \u5e74\u63a8\u51fa\" }\n];\nlet currentSort = { key: 'isFavorite', direction: 'desc' };\nlet isSearching = false;\n\nconst FIELD_LABELS = {\n    isFavorite: \"\u6700\u611b\",\n    title: \"\u5287\u540d\",\n    total: \"\u7e3d\u96c6\u6578\",\n    season: \"\u7576\u524d\u89c0\u770b\u300c\u5b63\u300d\u6b21\",\n    episode: \"\u300c\u5df2\u89c0\u770b\u300d\u96c6\u6578\",\n    lastWatchedDate: \"\u300c\u6700\u5f8c\u89c0\u770b\u300d\u65e5\u671f (\u683c\u5f0f: yyyy-MM-dd)\",\n    latestEpisode: \"\u300c\u5df2\u66f4\u65b0\u300d\u96c6\u6578\",\n    updateCycle: \"\u66f4\u65b0\u9031\u671f\",\n    status: \"\u5287\u60c5\u66f4\u65b0\u72c0\u6cc1\",\n    notes: \"\u88dc\u5145\u8cc7\u8a0a\"\n};\n\nconst VALID_CYCLE_VALUES = [\"\u65e5\",\"\u4e00\", \"\u4e8c\", \"\u4e09\", \"\u56db\", \"\u4e94\", \"\u516d\"];\nconst VALID_STATUS_VALUES = [\"\u66f4\u65b0\u4e2d\", \"\u5df2\u5b8c\u7d50\", \"\u5df2\u505c\u66f4\"];\n\nfunction saveList() {\n    localStorage.setItem(\"watchlist\", JSON.stringify(watchlist));\n}\n\nfunction showMessage(message, isError = false) {\n    const box = document.getElementById(\"message-box\");\n    box.textContent = message;\n    box.classList.remove(\"hidden\", \"error\");\n    if (isError) {\n        box.classList.add(\"error\");\n    }\n    setTimeout(() => {\n        box.classList.add(\"hidden\");\n    }, 3000);\n}\n\nfunction cleanNumeric(value) {\n    const num = parseInt(value, 10);\n    return isNaN(num) || num < 0 ? \"\" : num.toString();\n}\n\nfunction validateImportData(importedData) {\n    if (!Array.isArray(importedData)) {\n        showMessage(\"\u532f\u5165\u5931\u6557\uff1a\u8cc7\u6599\u683c\u5f0f\u4e0d\u662f\u6709\u6548\u7684\u9663\u5217\u3002\", true);\n        return false;\n    }\n    const requiredKeys = [\"title\", \"total\", \"season\", \"episode\", \"isFavorite\", \"lastWatchedDate\", \"latestEpisode\", \"updateCycle\", \"status\", \"notes\"];\n    for (const item of importedData) {\n        if (typeof item !== 'object' || item === null) {\n            showMessage(\"\u532f\u5165\u5931\u6557\uff1a\u9663\u5217\u4e2d\u5305\u542b\u975e\u7269\u4ef6\u9805\u76ee\u3002\", true);\n            return false;\n        }\n        for (const key of requiredKeys) {\n            if (!(key in item)) {\n                showMessage(`\u532f\u5165\u5931\u6557\uff1a\u7f3a\u5c11\u5fc5\u8981\u6b04\u4f4d ${key}\u3002`, true);\n                return false;\n            }\n        }\n        if (typeof item.title !== 'string' || typeof item.isFavorite !== 'boolean' || !VALID_STATUS_VALUES.includes(item.status)) {\n             showMessage(\"\u532f\u5165\u5931\u6557\uff1a\u90e8\u5206\u6b04\u4f4d\u578b\u5225\u4e0d\u6b63\u78ba\u3002\", true);\n             return false;\n        }\n        if (!Array.isArray(item.updateCycle) || item.updateCycle.some(val => !VALID_CYCLE_VALUES.includes(val))) {\n            showMessage(\"\u532f\u5165\u5931\u6557\uff1a\u66f4\u65b0\u9031\u671f\u683c\u5f0f\u7121\u6548\u3002\", true);\n            return false;\n        }\n    }\n    return true;\n}\n\n\/\/ \u661f\u671f\u5c0d\u61c9\u6578\u5b57\uff1a\u65e5=0\u3001\u4e00=1\u3001\u4e8c=2 ... \u516d=6\nconst WEEKDAY_ORDER = { \"\u65e5\":0, \"\u4e00\":1, \"\u4e8c\":2, \"\u4e09\":3, \"\u56db\":4, \"\u4e94\":5, \"\u516d\":6 };\n\nfunction sortList(list) {\n    const { key, direction } = currentSort;\n    const isAsc = direction === 'asc';\n\n    list.sort((a, b) => {\n        if (key === 'isFavorite') {\n            return b.isFavorite - a.isFavorite;\n        }\n        let valA = a[key];\n        let valB = b[key];\n\nif (key === 'updateCycle') {\n    \/\/ \u5c07\u591a\u500b\u661f\u671f\u7684\u9663\u5217\uff0c\u8f49\u70ba\u300c\u4f9d\u661f\u671f\u6392\u5e8f\u5f8c\u7684\u6700\u5c0f\u503c\u300d\n    const minA = Math.min(...valA.map(d => WEEKDAY_ORDER[d] ?? 99));\n    const minB = Math.min(...valB.map(d => WEEKDAY_ORDER[d] ?? 99));\n\n    return isAsc ? (minA - minB) : (minB - minA);\n}\n\n        \/\/ \u8655\u7406\u65e5\u671f\u6392\u5e8f\n        if (key === 'lastWatchedDate') {\n            const dateA = valA ? new Date(valA).getTime() : 0;\n            const dateB = valB ? new Date(valB).getTime() : 0;\n            if (dateA === 0 && dateB === 0) return 0;\n            if (dateA === 0) return isAsc ? -1 : 1;\n            if (dateB === 0) return isAsc ? 1 : -1;\n            return isAsc ? dateA - dateB : dateB - dateA;\n        }\n\n        \/\/ \u8655\u7406\u6578\u503c\u6392\u5e8f\n        if (typeof valA === 'string' && \/^\\d+$\/.test(valA)) {\n            valA = parseInt(valA, 10) || 0;\n            valB = parseInt(valB, 10) || 0;\n        }\n\n        if (valA < valB) return isAsc ? -1 : 1;\n        if (valA > valB) return isAsc ? 1 : -1;\n        return 0;\n    });\n    return list;\n}\n\nfunction renderTable(list = watchlist) {\n    const body = document.getElementById(\"watchlist-body\");\n    body.innerHTML = \"\";\n\n    let displayList = isSearching ? list : watchlist;\n    displayList = sortList([...displayList]);\n\n    displayList.forEach((item, index) => {\n        const row = document.createElement(\"tr\");\n\n        const data = [\n            { key: 'isFavorite', value: item.isFavorite ? '\u2764\ufe0f' : '\ud83e\udd0d', class: 'col-fav', editable: false },\n            { key: 'title', value: item.title, class: 'col-title', editable: true },\n            { key: 'total', value: item.total, class: 'col-total', editable: true },\n            { key: 'season', value: item.season, class: 'col-season', editable: true },\n            { key: 'episode', value: item.episode, class: 'col-episode', editable: true },\n            { key: 'lastWatchedDate', value: item.lastWatchedDate, class: 'col-last-watch', editable: true, type: 'date' },\n            { key: 'latestEpisode', value: item.latestEpisode, class: 'col-latest', editable: true },\n            \/\/ --- \u4fee\u6b63\u9ede 3: \u8a2d\u70ba\u53ef\u7de8\u8f2f ---\n            { key: 'updateCycle', value: item.updateCycle.join(', '), class: 'col-cycle', editable: true },\n            { key: 'status', value: item.status, class: 'col-status', editable: true },\n            \/\/ --------------------------\n            { key: 'notes', value: item.notes, class: 'col-notes', editable: true },\n        ];\n\n        data.forEach(field => {\n            const cell = document.createElement(\"td\");\n            cell.textContent = field.value;\n            cell.classList.add(field.class);\n            cell.setAttribute('data-label', FIELD_LABELS[field.key] + '\uff1a');\n\n            \/\/ \u7de8\u8f2f\u529f\u80fd\n            if (field.editable) {\n                cell.classList.add(\"editable\");\n                cell.addEventListener(\"click\", () => {\n\n                    \/\/ --- \u4fee\u6b63\u9ede 4: \u8655\u7406 'status' (\u5287\u60c5\u767c\u5c55) \u6b04\u4f4d ---\n                    if (field.key === 'status') {\n                        const currentStatus = item.status;\n                        const validOptions = VALID_STATUS_VALUES.join('\u3001'); \/\/ \u4f8b\u5982: \"\u66f4\u65b0\u4e2d\u3001\u5df2\u5b8c\u7d50\u3001\u5df2\u505c\u66f4\"\n                        let newValue = prompt(`\u4fee\u6539 ${FIELD_LABELS[field.key]} (${currentStatus}). \u8acb\u8f38\u5165\u4ee5\u4e0b\u9078\u9805\u4e4b\u4e00\uff1a\\n${validOptions}`, currentStatus);\n\n                        if (newValue !== null) {\n                            newValue = newValue.trim();\n                            if (!VALID_STATUS_VALUES.includes(newValue)) {\n                                showMessage(`\u8f38\u5165\u503c\u7121\u6548\u3002\u8acb\u9078\u64c7\uff1a${validOptions}`, true);\n                                return;\n                            }\n                            const originalIndex = watchlist.findIndex(w => w.title === item.title && w.total === item.total);\n                            if (originalIndex !== -1) {\n                                watchlist[originalIndex][field.key] = newValue;\n                                saveList();\n                                renderTable();\n                            }\n                        }\n                        return; \/\/ \u72c0\u614b\u6b04\u4f4d\u8655\u7406\u5b8c\u7562\n                    }\n                    \/\/ ---------------------------------------------\n\n                    \/\/ --- \u4fee\u6b63\u9ede 4: \u8655\u7406 'updateCycle' (\u66f4\u65b0\u9031\u671f) \u6b04\u4f4d ---\n                    if (field.key === 'updateCycle') {\n                        const currentCycle = item.updateCycle.join(', ');\n                        const validDays = VALID_CYCLE_VALUES.join('\u3001');\n                        let input = prompt(`\u4fee\u6539 ${FIELD_LABELS[field.key]} (${currentCycle}). \u8acb\u8f38\u5165\u4ee5\u9017\u865f\u5206\u9694\u7684\u661f\u671f (\u4f8b\u5982: \u4e00,\u4e09,\u65e5)\uff0c\u907f\u514d\u9020\u6210\u300c\u6392\u5e8f\u300d\u932f\u8aa4\uff1a`, currentCycle);\n\n                        if (input !== null) {\n                            \/\/ \u62c6\u5206\u8f38\u5165\uff0c\u53bb\u9664\u7a7a\u683c\uff0c\u4e26\u904e\u6ffe\u7a7a\u5b57\u4e32\n                            const newCycles = input.split(',').map(d => d.trim()).filter(d => d);\n                            const invalidDays = newCycles.filter(d => !VALID_CYCLE_VALUES.includes(d));\n\n                            if (invalidDays.length > 0) {\n                                showMessage(`\u8f38\u5165\u503c\u7121\u6548\uff0c\u7121\u6548\u7684\u661f\u671f\uff1a${invalidDays.join('\u3001')}\u3002\u8acb\u4f7f\u7528\uff1a${validDays}`, true);\n                                return;\n                            }\n\n                            const originalIndex = watchlist.findIndex(w => w.title === item.title && w.total === item.total);\n                            if (originalIndex !== -1) {\n                                watchlist[originalIndex].updateCycle = newCycles;\n                                saveList();\n                                renderTable();\n                            }\n                        }\n                        return; \/\/ \u9031\u671f\u6b04\u4f4d\u8655\u7406\u5b8c\u7562\n                    }\n                    \/\/ ----------------------------------------------------\n\n                    let promptMessage = `\u4fee\u6539 ${FIELD_LABELS[field.key]} (${field.value}):`;\n                    let newValue = prompt(promptMessage, item[field.key]);\n\n                    if (newValue !== null) {\n                        if (['total', 'season', 'episode', 'latestEpisode'].includes(field.key)) {\n                            newValue = cleanNumeric(newValue);\n                            if (newValue === \"\") {\n                                showMessage(`${FIELD_LABELS[field.key]} \u8f38\u5165\u5fc5\u9808\u70ba\u975e\u8ca0\u6578\u503c\u3002`, true);\n                                return;\n                            }\n                        }\n\n                        const originalIndex = watchlist.findIndex(w => w.title === item.title && w.total === item.total);\n\n                        if (originalIndex !== -1) {\n                            watchlist[originalIndex][field.key] = newValue;\n                            saveList();\n                            renderTable();\n                        }\n                    }\n                });\n            }\n\n            \/\/ \u611b\u5fc3\u5207\u63db\u529f\u80fd\u52a0\u5165\u78ba\u8a8d\u5c0d\u8a71\u6846\n            if (field.key === 'isFavorite') {\n                 cell.classList.add(\"editable\");\n                 cell.addEventListener(\"click\", () => {\n                     const originalIndex = watchlist.findIndex(w => w.title === item.title && w.total === item.total);\n\n                     if (originalIndex !== -1) {\n                          const currentFavStatus = watchlist[originalIndex].isFavorite;\n                          const action = currentFavStatus ? \"\u5f9e\u300c\u6211\u7684\u6700\u611b\u300d\u4e2d\u79fb\u9664\" : \"\u52a0\u5165\u300c\u6211\u7684\u6700\u611b\u300d\";\n\n                          if (confirm(`\u78ba\u5b9a\u8981\u5c07\u300c${item.title}\u300d${action}\u55ce\uff1f`)) {\n                              watchlist[originalIndex].isFavorite = !currentFavStatus;\n                              saveList();\n                              renderTable();\n                              showMessage(`\u300c${item.title}\u300d\u5df2${action}\u3002`);\n                          }\n                     }\n                 });\n            }\n\n            row.appendChild(cell);\n        });\n\n        \/\/ \u522a\u9664\u6309\u9215\n        const delCell = document.createElement(\"td\");\n        delCell.classList.add(\"col-del\");\n        const btn = document.createElement(\"button\");\n        btn.classList.add(\"delete-btn\"); \/\/ \u4f7f\u7528\u7d05\u5e95\u767d\u5b57\u6a23\u5f0f\n        btn.textContent = \"\u522a\";\n\n        const originalIndex = watchlist.findIndex(w => w.title === item.title && w.total === item.total);\n\n        btn.onclick = () => {\n            if (confirm(`\u78ba\u5b9a\u8981\u522a\u9664\u5287\u540d\u70ba\u300c${item.title}\u300d\u7684\u8cc7\u6599\u55ce\uff1f`)) {\n                if (originalIndex !== -1) {\n                     watchlist.splice(originalIndex, 1);\n                     saveList();\n                     renderTable();\n                     showMessage(`\u8cc7\u6599\u300c${item.title}\u300d\u5df2\u522a\u9664\u3002`);\n                }\n            }\n        };\n\n        delCell.appendChild(btn);\n        row.appendChild(delCell);\n\n        body.appendChild(row);\n    });\n}\n\n\/\/ --- \u4e8b\u4ef6\u8655\u7406\u51fd\u6578 (\u5176\u9918\u908f\u8f2f\u4fdd\u6301\u4e0d\u8b8a) ---\ndocument.getElementById(\"add-item\").addEventListener(\"click\", () => {\n    const titleInput = document.getElementById(\"title-input\");\n    const totalInput = document.getElementById(\"total-input\");\n    const seasonInput = document.getElementById(\"season-input\");\n    const episodeInput = document.getElementById(\"episode-input\");\n    const favInput = document.getElementById(\"fav-input\");\n    const lastWatchInput = document.getElementById(\"last-watch-input\");\n    const latestEpisodeInput = document.getElementById(\"latest-episode-input\");\n    const statusSelect = document.getElementById(\"status-select\");\n    const notesInput = document.getElementById(\"notes-input\");\n    const cycleCheckboxes = document.querySelectorAll('input[name=\"update-cycle\"]:checked');\n\n    if (!titleInput.value) {\n        showMessage(\"\u8acb\u81f3\u5c11\u586b\u5beb\u300c\u5287\u540d\u300d!\", true);\n        return;\n    }\n\n    const cycleValues = Array.from(cycleCheckboxes).map(cb => cb.value);\n\n    const newItem = {\n        title: titleInput.value.trim(),\n        total: cleanNumeric(totalInput.value),\n        season: cleanNumeric(seasonInput.value),\n        episode: cleanNumeric(episodeInput.value),\n        isFavorite: favInput.checked,\n        lastWatchedDate: lastWatchInput.value,\n        latestEpisode: cleanNumeric(latestEpisodeInput.value),\n        updateCycle: cycleValues,\n        status: statusSelect.value,\n        notes: notesInput.value.trim()\n    };\n\n    if (confirm(`\u78ba\u5b9a\u8981\u65b0\u589e\u5287\u540d\u70ba\u300c${newItem.title}\u300d\u7684\u8cc7\u6599\u55ce\uff1f`)) {\n        watchlist.push(newItem);\n        saveList();\n        renderTable();\n        showMessage(`\u8cc7\u6599\u300c${newItem.title}\u300d\u5df2\u65b0\u589e\u3002`);\n\n        \/\/ \u81ea\u52d5\u6e05\u7a7a\u8f38\u5165\u6b04\u4f4d\n        titleInput.value = \"\";\n        totalInput.value = \"\";\n        seasonInput.value = \"\";\n        episodeInput.value = \"\";\n        favInput.checked = false;\n        lastWatchInput.value = \"\";\n        latestEpisodeInput.value = \"\";\n        notesInput.value = \"\";\n        statusSelect.value = \"\u66f4\u65b0\u4e2d\";\n        cycleCheckboxes.forEach(cb => cb.checked = false);\n    }\n});\n\ndocument.querySelectorAll('.sortable').forEach(th => {\n    th.addEventListener('click', function() {\n        const key = this.dataset.sortKey;\n\n        if (currentSort.key === key) {\n            currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc';\n        } else {\n            currentSort.key = key;\n            currentSort.direction = key === 'isFavorite' ? 'desc' : 'asc';\n        }\n        renderTable();\n    });\n});\n\ndocument.getElementById(\"search-btn\").addEventListener(\"click\", () => {\n    const query = document.getElementById(\"search-input\").value.trim().toLowerCase();\n\n    if (query === \"\") {\n        if (isSearching) {\n            isSearching = false;\n            renderTable();\n            showMessage(\"\u5df2\u6e05\u9664\u641c\u5c0b\u7d50\u679c\u3002\");\n        } else {\n            showMessage(\"\u8acb\u8f38\u5165\u300c\u5287\u540d\u95dc\u9375\u5b57\u300d!\", true );\n        }\n        return;\n    }\n\n    const filteredList = watchlist.filter(item => item.title.toLowerCase().includes(query));\n\n    if (filteredList.length === 0) {\n        showMessage(`\u627e\u4e0d\u5230\u5305\u542b\u300c${query}\u300d\u7684\u8cc7\u6599\u3002`, true);\n        isSearching = true;\n        renderTable([]);\n    } else {\n        isSearching = true;\n        renderTable(filteredList);\n        showMessage(`\u5df2\u627e\u5230 ${filteredList.length} \u7b46\u8cc7\u6599\u3002`);\n    }\n});\n\ndocument.getElementById(\"clear-search-btn\").addEventListener(\"click\", () => {\n    document.getElementById(\"search-input\").value = \"\";\n    if (isSearching) {\n        isSearching = false;\n        renderTable();\n        showMessage(\"\u5df2\u6e05\u9664\u641c\u5c0b\u6b04\u4f4d\u3002\");\n    }\n});\n\ndocument.getElementById(\"export-btn\").addEventListener(\"click\", () => {\n    const dataStr = JSON.stringify(watchlist, null, 2);\n    const blob = new Blob([dataStr], { type: \"application\/json\" });\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement(\"a\");\n    a.href = url;\n    a.download = \"watchlist_export_\" + new Date().toISOString().slice(0, 10) + \".json\";\n    document.body.appendChild(a);\n    a.click();\n    document.body.removeChild(a);\n    URL.revokeObjectURL(url);\n    showMessage(\"\u8cc7\u6599\u5df2\u532f\u51fa\u70ba JSON \u6a94\u6848\u3002\");\n});\n\ndocument.getElementById(\"import-btn\").addEventListener(\"click\", () => {\n    document.getElementById(\"import-file\").click();\n});\n\ndocument.getElementById(\"import-file\").addEventListener(\"change\", (event) => {\n    const file = event.target.files[0];\n    if (!file) return;\n\n    if (file.type !== \"application\/json\") {\n        showMessage(\"\u50c5\u652f\u63f4 JSON \u6a94\u6848\u532f\u5165\u3002\", true);\n        return;\n    }\n\n    const reader = new FileReader();\n    reader.onload = (e) => {\n        try {\n            const importedData = JSON.parse(e.target.result);\n\n            if (!validateImportData(importedData)) {\n                return;\n            }\n\n            if (confirm(`\u78ba\u5b9a\u8981\u532f\u5165 ${importedData.length} \u7b46\u8cc7\u6599\u4e26\u8986\u84cb\u73fe\u6709\u8cc7\u6599\u55ce\uff1f`)) {\n                watchlist = importedData;\n                saveList();\n                renderTable();\n                showMessage(`\u6210\u529f\u532f\u5165 ${importedData.length} \u7b46\u8cc7\u6599\u3002`);\n            }\n\n        } catch (error) {\n            console.error(\"\u532f\u5165\u932f\u8aa4:\", error);\n            showMessage(\"\u532f\u5165\u6a94\u6848\u5167\u5bb9\u683c\u5f0f\u932f\u8aa4\u6216\u640d\u58de\u3002\", true);\n        } finally {\n            event.target.value = '';\n        }\n    };\n    reader.readAsText(file);\n});\n\n\/\/ --- \u8f09\u5165\u6642\u986f\u793a ---\nwindow.addEventListener(\"load\", renderTable);\n<\/script>\n\n\n\n<!DOCTYPE html>\n<html lang=\"zh-TW\">\n   <head>\n   <meta charset=\"UTF-8\">\n   <title>\u7248\u672c\u66f4\u65b0\u7d00\u9304<\/title>\n<style>\n   .accordion-item {\n      border: none;\n      border-radius: 15px;\n      margin-bottom: 6px;\n      margin-left: 10px;\n      width: 100%;\n      max-width: 900px;\n      }\n\n\/* \u6a19\u984c\u6a23\u5f0f *\/\n   .accordion-summary {\n      background-color: #0d0d0d;\n      padding: 3px 15px;\n      cursor: pointer; \/* \u9f20\u6a19\u8b8a\u70ba\u624b\u578b *\/\n      font-weight: normal;\n      color: #989898; \/* \u6a19\u984c\u5b57\u984f\u8272 *\/\n      user-select: none; \/* \u9632\u6b62\u9078\u53d6\u6a19\u984c\u6587\u5b57 *\/\n      list-style: none; \/* \u79fb\u9664\u9810\u8a2d\u7684\u6a19\u8a18 *\/\n      }\n\n\/* \u5167\u5bb9\u6a23\u5f0f *\/\n   .accordion-content {\n      padding: 15px;\n      border-top: 1px solid #1a1a1a;\n      background-color: #363636;\n      color: #cacaca; \/* \u5167\u5bb9\u6587\u5b57\u984f\u8272 *\/ \n\n\/* \u8abf\u6574\u5217\u8868\u6a23\u5f0f *\/\n      margin: 0;\n      padding-left: 10px;\n\n\/* \u65b0\u589e\u9019\u5169\u884c\u4f86\u8a2d\u7f6e\u5713\u89d2 *\/\n      border-top-left-radius: 8px; \/* \u5de6\u4e0b\u89d2\u5713\u89d2 *\/\n      border-top-right-radius: 8px; \/* \u53f3\u4e0b\u89d2\u5713\u89d2 *\/\n      border-bottom-left-radius: 8px; \/* \u5de6\u4e0b\u89d2\u5713\u89d2 *\/\n      border-bottom-right-radius: 8px; \/* \u53f3\u4e0b\u89d2\u5713\u89d2 *\/\n      }\n\n\/* \u96b1\u85cf\u9810\u8a2d\u7684\u4e09\u89d2\u5f62\u5716\u793a (\u53ef\u9078\uff0c\u8b93\u6a23\u5f0f\u66f4\u7c21\u6f54) *\/\n   .accordion-summary::-webkit-details-marker {\n      display: none;\n      }\n\n\/* \u7528\u4e00\u500b\u7b26\u865f\u4ee3\u66ff\u9810\u8a2d\u7684\u7bad\u982d *\/\n   .accordion-summary::before {\n      content: '\u25b6 '; \n      display: inline-block;\n      margin-right: 5px;\n      transform: rotate(90deg);\n      transition: transform 0.2s;\n      }\n\n      \/* \u7576 details \u6253\u958b\u6642\uff0c\u65cb\u8f49\u7bad\u982d *\/\n   .accordion-item[open] .accordion-summary::before {\n      transform: rotate(270deg);\n      }\n<\/style>\n<\/head>\n\n<body>\n\n   <details class=\"accordion-item\">\n   <summary class=\"accordion-summary\">\u7248\u672c\u66f4\u65b0\u8cc7\u8a0a<\/summary>\n   <div class=\"accordion-content\">\n      <ul>\n         <li>Ver 1.0 @2025.11.14:: \u521d\u59cb\u7248\u672c\uff1b\u9069\u7528\u65bc\u624b\u6a5f\u76f4\u5411\u87a2\u5e55\u700f\u89bd\u3002\u63d0\u4f9b\u57fa\u672c\u529f\u80fd\uff0c\u53ef\u81ea\u884c\u589e\/\u522a\/\u4fee\u6539\u8ffd\u5287\u7684\u7d30\u76ee\u3002<\/li>\n         <li>Ver 1.1 @2025.11.15:: \u522a\u9664\u5287\u96c6\u6642\u589e\u52a0\u5f48\u51fa\u78ba\u8a8d\u8996\u7a97\uff0c\u4ee5\u907f\u514d\u8aa4\u522a\u3002<\/li>\n         <li>Ver 2.0 @2025.12.11:: \u9032\u968e\u7248\u672c\uff1b\u9069\u7528\u65bc\u6a6b\u5411\u87a2\u5e55\u700f\u89bd\u3002\u91cd\u65b0\u8abf\u6574\u7248\u9762\uff0c\u65b0\u589e\u5404\u985e\u8cc7\u8a0a\u6b04\u4f4d\u3001\u6700\u611b\u3001\u6392\u5e8f\u2026 \u529f\u80fd\u512a\u5316\u3002<\/li>\n         <li>Ver 2.1 @2025.12.13:: \u65b0\u589e\u6700\u65b0\u66f4\u65b0\u3001\u5287\u60c5\u767c\u5c55\u6392\u5e8f\u529f\u80fd\uff0c\u4fee\u6b63\u6b04\u4f4d\u63d0\u793a\u5167\u5bb9\u3002<\/li>\n         <li>Ver 2.2 @2025.12.14:: \u4f7f\u7528\u6a6b\u5411\u5377\u8ef8\uff0c\u89e3\u6c7a\u76f4\u5411\u87a2\u5e55-\u5287\u96c6\u6b04\u4f4d\u6ea2\u51fa\u8996\u7a97\u7121\u6cd5\u986f\u793a\u7684\u932f\u8aa4\u3002<\/li>\n      <\/ul>\n   <\/div>\n   <\/details>\n\n   <details class=\"accordion-item\">\n   <summary class=\"accordion-summary\">\u4f7f\u7528\u8aaa\u660e\u8207\u6ce8\u610f\u4e8b\u9805<\/summary>\n   <div class=\"accordion-content\">\n      <ul>\n         <li>\u6392\u5e8f:: \u51e1\u6709\u7da0\u8272\u96d9\u5411\u7bad\u982d(<font color=\"00ff00\"><b>\u2b83<\/b><\/font>)\u4e4b\u6b04\u4f4d\uff0c\u53ef\u9032\u884c\u5347(\/\u964d)\u51aa\u6392\u5e8f\u3002<\/li>\n         <li>\u6211\u7684\u6700\u611b:: \ud83d\udc8c\u7b26\u865f\u986f\u793a\uff1b\u9ede\u64ca\u53ef\u5c07\u6700\u611b\u9805\u76ee\u7f6e\u9802\u3002<\/li>\n         <li>\u66f4\u65b0:: \u5287\u96c6\u66f4\u65b0\u9031\u671f (\u53ef\u8907\u9078):: \u63d0\u4f9b\u6838\u53d6\u65b9\u584a\u2611\u52fe\u9078\u3002<\/li>\n         <li>\u5287\u60c5\u767c\u5c55:: \u4e0b\u62c9\u9078\u55ae:: (1) \u66f4\u65b0\u4e2d\u3001(2) \u5df2\u5b8c\u7d50\u3001(3) \u5df2\u505c\u66f4\u3002<\/li>\n         <li>\u88dc\u5145\u8cc7\u8a0a:: \u53ef\u81ea\u884c\u8f38\u5165\u8a3b\u8a18\u4e8b\u9805\uff0c\u7e41\u9ad4\u4e2d\u6587\u5b57\u81f3\u591a10-12\u5b57\u5143\u3002<\/li>\n         <li>\u4fee\u6539\u8cc7\u6599:: \u4fee\u6b63\u53ef\u6392\u5e8f\u6b04\u4f4d\u8cc7\u6599\uff0c\u8acb\u4f9d\u9810\u8a2d\u683c\u5f0f\u8f38\u5165\u3002<\/li>\n         <li>\u6309\u9215\u985e::\n         <ul>\n            <li>\u641c\u5c0b\u6309\u9215:: \u8f38\u5165\u6b32\u641c\u5c0b\u5287\u540d\u95dc\u9375\u5b57\u3002<\/li>\n            <li>\u6e05\u9664\u6309\u9215:: \u6e05\u9664\u641c\u5c0b\u8f38\u5165\u6b04\u4f4d\u3002<\/li>\n            <li>\u532f\u51fa\u6309\u9215:: \u5c07\u5df2\u5b58\u5287\u96c6\u8cc7\u6599\u4e0b\u8f09\u81f3\u7576\u524d\u88dd\u7f6e\u6216\u96f2\u7aef\u3002<\/li>\n            <li>\u532f\u5165\u6309\u9215:: \u5c07\u5df2\u532f\u51fa\u4e4b\u5287\u96c6\u8cc7\u6599\u6a94\u6848\u532f\u5165\u65b0\u88dd\u7f6e\u3002<\/li>\n         <\/ul>\n         <\/li>\n         <li><font color=\"#ffac12\">\u522a\u9664\u700f\u89bd\u5668<font color=\"#ffffff\">\u300c<\/font>Cookie<font color=\"#ffffff\">\u3001<\/font>\u7db2\u7ad9\u8cc7\u6599<font color=\"#ffffff\">\u300d<\/font><\/font>:: \u5c07\u540c\u6b65\u522a\u9664\u5df2\u8f38\u5165\u4e4b\u5287\u96c6\u8cc7\u6599\u3002<\/li>\n         <li>\u6700\u5f8c\u89c0\u770b:: \u65e5\u671f\u9078\u64c7\u5668 <font color=\"#ffac12\">iOS \u88dd\u7f6e<\/font>\u7121\u6cd5\u6b63\u5e38\u986f\u793a\uff0c\u4f46\u4ecd\u53ef\u4f5c\u7528\u3002<\/li>\n      <\/ul>\n   <\/div>\n   <\/details>\n\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>\u52d5\u6f2b\u5287\u9032\u5ea6\u8ffd\u8e64\u677f Ver 2.2 \ud83d\udcfa \u52d5\u6f2b\u5287\u9032\u5ea6\u8ffd\u8e64\u677f \ud83d\udc8c\u2b61 \u5287\u540d \u7e3d\u96c6\u6578 \u5b63 \u96c6 \u6700\u5f8c\u89c0\u770b\u2b83 \u5df2\u66f4\u65b0 \u66f4\u65b0\u9031 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2675","page","type-page","status-publish","hentry"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=\/wp\/v2\/pages\/2675","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2675"}],"version-history":[{"count":126,"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=\/wp\/v2\/pages\/2675\/revisions"}],"predecessor-version":[{"id":3421,"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=\/wp\/v2\/pages\/2675\/revisions\/3421"}],"wp:attachment":[{"href":"https:\/\/conga.tw\/memo\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2675"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}