@waterwx/dsh-novel-forge 1.1.7 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -75,6 +75,14 @@ window.__ModuleLoader__.load({
75
75
  chapterApprove: "/api/dsh-novel-forge/chapter/approve",
76
76
  /** 敏感词检查:全书已写章节或指定文本。 */
77
77
  sensitiveCheck: "/api/dsh-novel-forge/sensitive-check",
78
+ /** 开书想法 → AI 补全大纲:输入一句话想法,生成 2-3 个可选大纲方案。 */
79
+ outlineSuggest: "/api/dsh-novel-forge/outline/suggest",
80
+ /** 拆书分析:对已写章节做结构/人物/文风/卖点四维体检(两阶段:源笔记→分节分析)。 */
81
+ breakdown: "/api/dsh-novel-forge/breakdown",
82
+ /** 漫剧分镜生成:章节 → 角色锚点 + 分镜表(可适配豆包/Seedance/SD)。 */
83
+ storyboard: "/api/dsh-novel-forge/storyboard",
84
+ /** 漫剧分集计划:读一卷 → 按故事弧线分集(高潮拆集/过渡并章)。 */
85
+ storyboardPlan: "/api/dsh-novel-forge/storyboard/plan",
78
86
  config: "/api/dsh-novel-forge/config",
79
87
  openFolder: "/api/dsh-novel-forge/open-folder"
80
88
  };
@@ -125,6 +133,39 @@ window.__ModuleLoader__.load({
125
133
  async saveOutline(text) {
126
134
  return postJson(NOVEL_API.saveOutline, { text });
127
135
  }
136
+ /** 开书想法 → AI 大纲:生成 count 个方案(换批时传 exclude 避开已暂留方向)。 */
137
+ async outlineSuggest(idea, count, exclude) {
138
+ return postJson(NOVEL_API.outlineSuggest, {
139
+ idea,
140
+ count,
141
+ exclude
142
+ });
143
+ }
144
+ /** 拆书分析:对已写章节做结构/人物/文风/卖点体检。 */
145
+ async breakdown(scope, preset, budgetTokens) {
146
+ return postJson(NOVEL_API.breakdown, {
147
+ scope,
148
+ preset,
149
+ budgetTokens
150
+ });
151
+ }
152
+ /** 漫剧分镜生成:章节 → 角色锚点 + 分镜表。 */
153
+ async storyboard(chapterNo, genre, platform, tool) {
154
+ return postJson(NOVEL_API.storyboard, {
155
+ chapterNo,
156
+ genre,
157
+ platform,
158
+ tool
159
+ });
160
+ }
161
+ /** 漫剧分集计划:读一卷 → 按故事弧线分集。 */
162
+ async storyboardPlan(volumeNo, platform, maxEpisodes) {
163
+ return postJson(NOVEL_API.storyboardPlan, {
164
+ volumeNo,
165
+ platform,
166
+ maxEpisodes
167
+ });
168
+ }
128
169
  async plan(outline, chapterCount, volume) {
129
170
  return postJson(NOVEL_API.plan, {
130
171
  outline,
@@ -153,11 +194,12 @@ window.__ModuleLoader__.load({
153
194
  async chapter(no) {
154
195
  return readJson(await fetch(`${NOVEL_API.chapter}?no=${no}`));
155
196
  }
156
- /** 审查手动编辑的正文(不落盘)。 */
157
- async chapterCheck(no, text) {
197
+ /** 审查手动编辑的正文(不落盘)。previousReport 传入时走「验证模式」(核对原意见解决 + 只挑新增 high)。 */
198
+ async chapterCheck(no, text, previousReport) {
158
199
  return postJson(NOVEL_API.chapterCheck, {
159
200
  chapterNo: no,
160
- text
201
+ text,
202
+ previousReport
161
203
  });
162
204
  }
163
205
  /** 保存手动编辑的正文(自动备份 .bak;带报告则沿用落盘,否则保存后自动审稿)。 */
@@ -347,9 +389,13 @@ window.__ModuleLoader__.load({
347
389
  async polish(chapterNo, onFrame) {
348
390
  await this.streamJob(NOVEL_API.polish, { chapterNo }, onFrame);
349
391
  }
350
- /** 采纳待确认草稿(润色/重写产物),覆盖正文文件。 */
351
- async draftApply(chapterNo) {
352
- return postJson(NOVEL_API.draftApply, { chapterNo });
392
+ /** 采纳待确认草稿(润色/重写产物),覆盖正文文件。返回采纳后的新正文(markdown)。
393
+ * 可携带审查报告(沿用结论定状态:通过 approved)。 */
394
+ async draftApply(chapterNo, report) {
395
+ return postJson(NOVEL_API.draftApply, {
396
+ chapterNo,
397
+ report
398
+ });
353
399
  }
354
400
  /** 放弃待确认草稿,保留原稿。 */
355
401
  async draftDiscard(chapterNo) {
@@ -556,6 +602,8 @@ window.__ModuleLoader__.load({
556
602
  "settings.autoReview": "生成后自动审稿",
557
603
  "settings.autoAuthorReview": "生成后自动作者复盘",
558
604
  "settings.autoAuthorReviewHint": "复盘钩子兑现/结尾钩子/剧情线推进/连续性/节奏趋势,每章约 2000 token",
605
+ "settings.autoReviewAfterRevise": "修订后自动审查",
606
+ "settings.autoReviewAfterReviseHint": "按意见修订/润色产出草稿后自动附带一次 AI 审查,直接显示新稿评分与剩余问题(每章约 2-3k token,可关)",
559
607
  "settings.save": "保存设置",
560
608
  "settings.saved": "设置已保存",
561
609
  "settings.openFolder": "打开输出文件夹",
@@ -696,6 +744,8 @@ window.__ModuleLoader__.load({
696
744
  "settings.autoReview": "Auto-review after writing",
697
745
  "settings.autoAuthorReview": "Auto author review after writing",
698
746
  "settings.autoAuthorReviewHint": "Reviews hook payoff / ending hook / plotline progress / continuity / pacing trend (~2000 tokens per chapter)",
747
+ "settings.autoReviewAfterRevise": "Auto review after revise",
748
+ "settings.autoReviewAfterReviseHint": "Automatically runs one AI review on the produced draft after revise/polish, showing the new score and remaining issues (~2-3k tokens, can be disabled)",
699
749
  "settings.save": "Save settings",
700
750
  "settings.saved": "Settings saved",
701
751
  "settings.openFolder": "Open output folder",
@@ -816,7 +866,7 @@ window.__ModuleLoader__.load({
816
866
  }
817
867
  //#endregion
818
868
  //#region \0dsh-css:C:\Users\Ryan\Desktop\111\novel-forge\src\client\panel\panel.module.css.mjs
819
- const css = ".CUIYUW_entry{width:100%;color:var(--dsw-alias-label-primary,#1f1f23);cursor:pointer;text-align:left;background:0 0;border:none;border-radius:6px;align-items:center;gap:8px;padding:8px 12px;font-size:13px;transition:background .15s;display:flex}body[data-ds-dark-theme] .CUIYUW_entry{color:var(--dsw-alias-label-primary,#ececf1)}.CUIYUW_entry:hover{background:var(--dsw-alias-interactive-bg-hover,#7f7f7f1f)}.CUIYUW_entry[data-active]{background:var(--dsw-alias-interactive-bg-active,#7f7f7f33)}.CUIYUW_entryIcon{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.CUIYUW_entryLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-pane=conversation]{position:relative}.CUIYUW_view{z-index:60;color-scheme:light;--nf-font:-apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"SF Pro Text\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--nf-font-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff80 0%, #ffffff38 45%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffffa6;--nf-glass-inset:#ffffff8c;--nf-glass-orb-a:#00b85c24;--nf-glass-orb-b:#78a0ff1a;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\");background:var(--nf-bg);backdrop-filter:blur(32px)saturate(180%);color:var(--nf-text);font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Segoe UI,Roboto,Helvetica Neue,sans-serif;display:none;position:absolute;inset:0;overflow:auto}body[data-ds-dark-theme] .CUIYUW_view{color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #70747a6b 0%, #60646a6b 26%, #52555a6b 52%, #44474c6b 78%, #383a3f6b 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff42 0%, #ffffff1a 45%, #fff0 78%);--nf-glass-sheen:#ffffff42;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff12;--nf-glass-orb-a:#00ca5233;--nf-glass-orb-b:#bec8d712;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\")}html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .CUIYUW_view{display:block}.CUIYUW_panel[data-nf-theme=classic]{--nf-accent:#007aff;--nf-accent-hover:#0071e3;--nf-accent-soft:#007aff1f;--nf-accent-fg:#fff;--nf-info:#5856d6;--nf-glass-face:var(--nf-bg-raise);--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:var(--nf-border);--nf-glass-inset:var(--nf-bg-inset);--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=classic]{--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-info:#bf5af2;--nf-glass-face:var(--nf-bg-raise);--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:var(--nf-border);--nf-glass-inset:var(--nf-bg-inset);--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph]{--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input,body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input:focus,body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #a3b1c680, inset -2px -2px 6px #ffffffd9, 0 0 0 3px var(--nf-accent-soft)}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input,body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input:focus,body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #00000080, inset -2px -2px 6px #60687638, 0 0 0 3px var(--nf-accent-soft)}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #a3b1c68c,-5px -5px 10px #ffffffe6}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #a3b1c699,-7px -7px 14px #fffffff2}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_buttonPrimary{background:linear-gradient(#00c563,#00a952);box-shadow:5px 5px 10px #a3b1c699,-5px -5px 10px #ffffffd9}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #0000008c,-7px -7px 14px #60687642}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_buttonPrimary{background:linear-gradient(#3ddc86,#27b96a);box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}.CUIYUW_panel{flex-direction:column;min-width:0;height:100%;font-size:14px;line-height:1.6;display:flex;position:relative;overflow:hidden}.CUIYUW_panel:before{content:\"\";z-index:0;pointer-events:none;background:radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%), radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%), radial-gradient(120% 95% at 50% 42%, transparent 55%, #0202031a 100%);position:absolute;inset:0}.CUIYUW_panelHeader{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);z-index:5;border-radius:18px;flex-shrink:0;justify-content:space-between;align-items:center;margin:10px 12px 0;padding:10px 16px;display:flex;position:sticky;top:10px}.CUIYUW_panelTitle{letter-spacing:.2px;align-items:center;gap:8px;margin:0;font-size:16px;font-weight:700;display:flex}.CUIYUW_panelTitle:before{content:\"\";background:linear-gradient(180deg, var(--nf-accent), var(--nf-info));border-radius:2px;width:4px;height:16px}.CUIYUW_iconButton{cursor:pointer;color:var(--nf-text-2);background:0 0;border:none;border-radius:8px;padding:4px 9px;font-size:16px;transition:background .15s,color .15s}.CUIYUW_iconButton:hover{background:var(--nf-hover);color:var(--nf-text)}.CUIYUW_tabBar{border-bottom:1px solid var(--nf-border);background:var(--nf-bg-raise);z-index:4;flex-shrink:0;gap:2px;padding:8px 14px 0;display:flex;position:sticky;top:45px}.CUIYUW_tab{cursor:pointer;color:var(--nf-text-2);background:0 0;border:none;border-radius:8px 8px 0 0;padding:7px 13px;font-size:13.5px;font-weight:500;transition:color .15s,background .15s;position:relative}.CUIYUW_tab:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_tab[data-active]{color:var(--nf-accent);font-weight:600}.CUIYUW_tab[data-active]:after{content:\"\";background:var(--nf-accent);border-radius:2px 2px 0 0;height:2.5px;position:absolute;bottom:-1px;left:10px;right:10px}.CUIYUW_panelContent{z-index:1;flex-direction:column;flex:1;gap:14px;padding:16px 18px 20px;display:flex;position:relative;overflow:auto}.CUIYUW_panelBody{z-index:1;flex:1;min-height:0;display:flex;position:relative}.CUIYUW_panelNav{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);width:142px;box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);border-radius:16px;flex-direction:column;flex:none;align-self:flex-start;gap:4px;margin:10px 0 10px 12px;padding:10px 8px;transition:width .18s;display:flex;overflow-y:auto}.CUIYUW_panelNavCollapsed{width:52px;padding:10px 6px}.CUIYUW_navGroup{flex-direction:column;gap:4px;display:flex}.CUIYUW_navGroupLabel{letter-spacing:.6px;text-transform:uppercase;color:var(--nf-text-3);user-select:none;padding:8px 10px 3px;font-size:10.5px;font-weight:600}.CUIYUW_navGroupSep{background:var(--nf-border);height:1px;margin:6px 8px 4px}.CUIYUW_navSpacer{flex:1;min-height:8px}.CUIYUW_navAbout{border-top:1px solid var(--nf-border);flex-direction:column;flex:none;gap:4px;margin-top:4px;padding:8px 6px 4px;display:flex}.CUIYUW_navAboutRow{cursor:pointer;color:var(--nf-text-3);text-align:left;white-space:nowrap;background:0 0;border:none;border-radius:8px;justify-content:space-between;align-items:center;gap:4px;padding:4px 6px;font-size:11px;transition:color .15s,background .15s;display:flex}.CUIYUW_navAboutRow:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_navAboutUpdate{background:var(--nf-accent-soft);color:var(--nf-accent);cursor:pointer;text-align:left;white-space:nowrap;border:none;border-radius:8px;padding:4px 6px;font-size:10.5px;font-weight:600}.CUIYUW_navAboutUpdate:hover{color:var(--nf-accent-hover)}.CUIYUW_panelNavCollapsed .CUIYUW_navAbout{align-items:center;padding:6px 2px 2px}.CUIYUW_panelNavCollapsed .CUIYUW_navAboutRow{justify-content:center;width:100%;padding:4px 0}.CUIYUW_navTabBadge{background:var(--nf-accent);color:#fff;text-align:center;border-radius:999px;flex:none;min-width:18px;height:18px;margin-left:auto;padding:0 5px;font-size:10.5px;font-weight:700;line-height:18px;display:inline-block}.CUIYUW_panelNavCollapsed .CUIYUW_navTabBadge{min-width:14px;height:14px;padding:0 3px;font-size:9px;line-height:14px;position:absolute;top:2px;right:2px}.CUIYUW_navTabBadgeDanger{background:var(--nf-error)}.CUIYUW_navTabBadgeWarn{background:var(--nf-warn)}.CUIYUW_navTabBadgeDone{background:var(--nf-success)}.CUIYUW_navTab{cursor:pointer;width:100%;color:var(--nf-text-2-alpha,var(--nf-text-2));text-align:left;white-space:nowrap;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:8px 10px;font-size:13px;font-weight:500;transition:color .15s,background .15s;display:flex;position:relative}.CUIYUW_panelNavCollapsed .CUIYUW_navTab{justify-content:center;padding:8px 0}.CUIYUW_navTab:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_navTab[data-active]{color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.CUIYUW_navTab[data-active]:before{content:\"\";background:var(--nf-accent);border-radius:999px;width:3px;position:absolute;top:20%;bottom:20%;left:-8px}.CUIYUW_panelNavCollapsed .CUIYUW_navTab[data-active]:before{left:-6px}.CUIYUW_navTabIcon{flex:none;font-size:15px;line-height:1}.CUIYUW_navTabLabel{text-overflow:ellipsis;overflow:hidden}.CUIYUW_panelSubtitle{color:var(--nf-text-2);white-space:nowrap;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:0 4px 2px;font-size:12px;display:flex}.CUIYUW_headerProgress{color:var(--nf-text-2);white-space:nowrap;align-items:center;gap:6px;margin-left:0;font-size:12px;font-weight:400;display:inline-flex}.CUIYUW_headerProgress b{color:var(--nf-accent);font-weight:700}.CUIYUW_headerProgressDot{background:var(--nf-border-strong,var(--nf-text-3));border-radius:50%;width:3px;height:3px;display:inline-block}.CUIYUW_card{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);border-radius:22px;flex-direction:column;gap:10px;padding:16px 18px;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.CUIYUW_card:before{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.CUIYUW_card:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.CUIYUW_card:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.CUIYUW_card>*{z-index:1;position:relative}.CUIYUW_cardTitle{color:var(--nf-text);align-items:center;gap:8px;margin:0;font-size:14px;font-weight:650;display:flex}.CUIYUW_button{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);cursor:pointer;white-space:nowrap;border-radius:12px;padding:6px 14px;font-size:13px;font-weight:500;transition:background .15s,border-color .15s,transform .1s,box-shadow .15s}.CUIYUW_button:hover:not([disabled]){background:var(--nf-hover);border-color:var(--nf-border-strong)}.CUIYUW_button:active:not([disabled]){transform:scale(.96)}.CUIYUW_button[disabled]{opacity:.45;cursor:not-allowed}.CUIYUW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #fff), var(--nf-accent));color:var(--nf-accent-fg);box-shadow:0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent);border-color:#0000}.CUIYUW_buttonPrimary:hover:not([disabled]){background:linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000));border-color:#0000}.CUIYUW_buttonDanger{border-color:var(--nf-error);color:var(--nf-error)}.CUIYUW_buttonDanger:hover:not([disabled]){background:#ff3b301a}.CUIYUW_buttonSmall{border-radius:9px;padding:3px 10px;font-size:12px}.CUIYUW_field{flex-direction:column;gap:5px;display:flex}.CUIYUW_fieldLabel{color:var(--nf-text-2);font-size:12px;font-weight:500}.CUIYUW_input{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);box-sizing:border-box;border-radius:12px;width:100%;padding:7px 11px;font-size:13px;transition:border-color .15s,box-shadow .15s}.CUIYUW_input:focus,.CUIYUW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft);outline:none}.CUIYUW_input::placeholder,.CUIYUW_textarea::placeholder{color:var(--nf-text-3)}.CUIYUW_textarea{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);box-sizing:border-box;resize:vertical;border-radius:12px;width:100%;min-height:200px;padding:9px 11px;font-family:inherit;font-size:13px;line-height:1.7;transition:border-color .15s,box-shadow .15s}.CUIYUW_row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.CUIYUW_spaceBetween{justify-content:space-between}.CUIYUW_chapterList{flex-direction:column;gap:8px;display:flex}.CUIYUW_volumeGroup{flex-direction:column;gap:6px;display:flex}.CUIYUW_volumeGroupHeader{background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;user-select:none;border-radius:10px;align-items:center;gap:8px;padding:6px 10px;font-size:13px;transition:border-color .15s;display:flex}.CUIYUW_volumeGroupHeader:hover{border-color:var(--nf-accent)}.CUIYUW_volumeGroupToggle{color:var(--nf-text-2);flex:none;font-size:11px}.CUIYUW_chapter{border:1px solid var(--nf-border);background:var(--nf-bg);border-radius:10px;align-items:center;gap:10px;padding:9px 12px;transition:border-color .15s,box-shadow .15s,transform .1s;display:flex}.CUIYUW_chapter:hover{border-color:var(--nf-border-strong);box-shadow:var(--nf-shadow)}.CUIYUW_chapterNum{background:var(--nf-bg-inset);border:1px solid var(--nf-border);min-width:28px;height:28px;color:var(--nf-text-2);border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;padding:0 8px;font-size:12px;font-weight:700;display:inline-flex}.CUIYUW_chapterMain{flex:1;min-width:0}.CUIYUW_chapterTitle{color:var(--nf-text);align-items:center;gap:8px;font-size:13px;font-weight:600;display:flex}.CUIYUW_chapterBeats{color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.CUIYUW_chapterActions{opacity:.85;flex-shrink:0;gap:4px;transition:opacity .15s;display:flex}.CUIYUW_chapter:hover .CUIYUW_chapterActions{opacity:1}.CUIYUW_badge{white-space:nowrap;letter-spacing:.2px;border:1px solid;border-radius:999px;padding:2px 9px;font-size:11px;font-weight:600}.CUIYUW_badgePending{color:var(--nf-info);border-color:var(--nf-info);background:color-mix(in srgb, var(--nf-info) 10%, transparent)}.CUIYUW_badgeGenerating{color:var(--nf-accent);border-color:var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 12%, transparent);animation:1.2s ease-in-out infinite CUIYUW_pulse}.CUIYUW_badgeWritten{color:var(--nf-warn);border-color:var(--nf-warn);background:color-mix(in srgb, var(--nf-warn) 10%, transparent)}.CUIYUW_badgeRejected{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.CUIYUW_badgeDone{color:var(--nf-success);border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 10%, transparent)}.CUIYUW_badgeError{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.CUIYUW_reviewBox{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-size:12.5px;display:flex}.CUIYUW_chapterPreview{white-space:pre-wrap;word-break:break-all;max-height:320px;color:var(--nf-text);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:10px;margin:0;padding:10px 12px;font-family:inherit;font-size:12.5px;line-height:1.8;overflow:auto}.CUIYUW_chatScroll{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:12px;flex-direction:column;flex:1;gap:10px;min-height:240px;max-height:480px;padding:14px;display:flex;overflow-y:auto}.CUIYUW_chatBubbleUser{background:linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));max-width:90%;color:var(--nf-accent-fg);border-radius:14px 14px 4px;align-self:flex-end;padding:9px 14px;font-size:13px;box-shadow:0 2px 6px #4d6bfe33}.CUIYUW_chatBubbleAssistant{background:var(--nf-bg-raise);max-width:92%;color:var(--nf-text);border:1px solid var(--nf-border);box-shadow:var(--nf-shadow);border-radius:14px 14px 14px 4px;align-self:flex-start;padding:9px 14px;font-size:13px}.CUIYUW_chatRole{color:var(--nf-text-3);margin-bottom:3px;font-size:11px;font-weight:600}.CUIYUW_toolLive{background:var(--nf-bg-inset);border:1px dashed var(--nf-border-strong);white-space:pre-wrap;word-break:break-all;color:var(--nf-text-2);border-radius:8px;max-height:180px;margin-top:6px;padding:8px 10px;font-size:12px;line-height:1.7;overflow-y:auto}.CUIYUW_assistantStatus{color:var(--nf-text-2);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:999px;flex:none;align-items:center;gap:6px;margin-top:6px;padding:6px 12px;font-size:12px;display:flex}.CUIYUW_assistantStatusBusy{color:var(--nf-accent);border-color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.CUIYUW_toolSteps{flex-direction:column;gap:4px;margin-top:6px;display:flex}.CUIYUW_toolStep{background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:8px;align-items:center;gap:8px;padding:5px 10px;font-size:12px;display:flex}.CUIYUW_toolStepActive{border-color:var(--nf-accent);background:var(--nf-accent-soft)}.CUIYUW_toolStepError{border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.CUIYUW_toolStepIcon{flex:none;font-size:13px}.CUIYUW_toolStepName{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:600;overflow:hidden}.CUIYUW_toolStepStatus{color:var(--nf-text-2);flex:none;font-size:11px}.CUIYUW_toolStepActive .CUIYUW_toolStepStatus{color:var(--nf-accent)}.CUIYUW_toolStepError .CUIYUW_toolStepStatus{color:var(--nf-error)}.CUIYUW_toolStepDetail{width:100%;color:var(--nf-error);word-break:break-all;font-size:11px}.CUIYUW_progress{border:1px solid var(--nf-border);white-space:pre-wrap;word-break:break-all;min-height:60px;max-height:220px;color:var(--nf-text-2);font-size:12px;font-family:var(--nf-font-mono);background:var(--nf-bg-inset);border-radius:10px;padding:10px 14px;line-height:1.8;overflow:auto}.CUIYUW_progressLine{color:var(--nf-text-2);opacity:.9}.CUIYUW_progressLineLive{color:var(--nf-accent);align-items:center;gap:8px;font-weight:600;display:flex}.CUIYUW_progressBar{background:var(--nf-border);border-radius:999px;flex:none;width:110px;height:6px;display:inline-block;overflow:hidden}.CUIYUW_progressBarFill{background:var(--nf-accent);border-radius:3px;height:100%;transition:width .3s;display:block}.CUIYUW_busyRow{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;display:flex}.CUIYUW_liveText{font-variant-numeric:tabular-nums;color:var(--nf-text-2);font-size:12px}.CUIYUW_bigProgressBar{background:var(--nf-border);border-radius:999px;height:8px;margin-top:10px;overflow:hidden}.CUIYUW_bigProgressBarFill{background:linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2,var(--nf-accent)));border-radius:999px;height:100%;transition:width .3s;display:block}.CUIYUW_diffLegend{flex-wrap:wrap;align-items:center;gap:14px;margin:6px 0 8px;font-size:12px;display:flex}.CUIYUW_legendOld{color:var(--nf-error);font-weight:700}.CUIYUW_legendNew{color:var(--nf-success);font-weight:700}.CUIYUW_onlyChanges{color:var(--nf-text-2);cursor:pointer;align-items:center;gap:4px;margin-left:auto;display:inline-flex}.CUIYUW_diffList{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:8px;flex-direction:column;flex:1;gap:8px;min-height:0;padding:10px 12px;font-size:13px;line-height:1.7;display:flex;overflow-y:auto}.CUIYUW_diffSame{border:1px dashed var(--nf-border);color:var(--nf-text-2);opacity:.85;border-radius:6px;padding:6px 10px}.CUIYUW_diffSame summary{cursor:pointer;user-select:none;font-size:12px}.CUIYUW_diffSameBody{white-space:pre-wrap;margin-top:6px}.CUIYUW_diffChange{border:1px solid var(--nf-border);border-radius:8px;grid-template-columns:1fr 1fr;display:grid;overflow:hidden}.CUIYUW_diffColumn{flex-direction:column;gap:6px;min-width:0;padding:8px 10px;display:flex}.CUIYUW_diffColumn:first-child{border-right:1px solid var(--nf-border)}.CUIYUW_diffTagOld,.CUIYUW_diffTagNew{letter-spacing:.5px;border-radius:4px;flex:none;align-self:flex-start;padding:1px 7px;font-size:11px;font-weight:700}.CUIYUW_diffTagOld{color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-error) 45%, transparent)}.CUIYUW_diffTagNew{color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-success) 45%, transparent)}.CUIYUW_diffOld{color:var(--nf-error);white-space:pre-wrap;text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 55%, transparent)}.CUIYUW_diffNew{color:var(--nf-success);white-space:pre-wrap;font-weight:500}.CUIYUW_diffDel{border:1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);background:color-mix(in srgb, var(--nf-error) 7%, transparent);border-radius:6px;flex-direction:column;gap:4px;padding:6px 10px;display:flex}.CUIYUW_diffAdd{border:1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);background:color-mix(in srgb, var(--nf-success) 7%, transparent);border-radius:6px;flex-direction:column;gap:4px;padding:6px 10px;display:flex}.CUIYUW_diffText{white-space:pre-wrap}.CUIYUW_diffDel .CUIYUW_diffText{color:var(--nf-error);text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 50%, transparent)}.CUIYUW_diffAdd .CUIYUW_diffText{color:var(--nf-success)}.CUIYUW_wsPage{flex-direction:column;flex:1;gap:10px;min-height:0;display:flex}.CUIYUW_wsPageHeader{flex-wrap:wrap;flex:none;align-items:center;gap:8px;display:flex}.CUIYUW_wsColumns{flex:1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;min-height:0;display:grid}.CUIYUW_wsColumn{flex-direction:column;gap:8px;min-width:0;min-height:0;display:flex}.CUIYUW_wsEditor{resize:vertical;min-height:0;font-family:var(--nf-font);white-space:pre-wrap;flex:1;font-size:13px;line-height:1.75}.CUIYUW_wsSelected{border:1px solid var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 8%, transparent);border-radius:6px;max-height:120px;padding:6px 10px;overflow:auto}.CUIYUW_wsSelectedText{color:var(--nf-text-2);white-space:pre-wrap;margin-top:4px;font-size:12px}.CUIYUW_wsPreview{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:8px;flex-direction:column;gap:8px;padding:8px 10px;display:flex}.CUIYUW_wsPreviewText{white-space:pre-wrap;min-height:0;color:var(--nf-text);flex:1;margin:0;font-size:13px;line-height:1.7;overflow:auto}.CUIYUW_assetGrid{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;display:grid}.CUIYUW_assetStat{border:1px solid var(--nf-glass-border);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;flex-direction:column;gap:4px;padding:10px 12px;display:flex}.CUIYUW_assetStatLabel{color:var(--nf-text-2);opacity:.9;font-size:11px}.CUIYUW_assetStatValue{color:var(--nf-text);font-size:15px;font-weight:700;line-height:1.2}.CUIYUW_assetStatDetail{color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.CUIYUW_dashHero{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);border-radius:22px;flex-direction:column;gap:14px;padding:18px 20px;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.CUIYUW_dashHero:before{content:\"\";border-radius:inherit;pointer-events:none;background:radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%), var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.CUIYUW_dashHero:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.CUIYUW_dashHero:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.CUIYUW_dashHero>*{z-index:1;position:relative}.CUIYUW_dashHeroEyebrow{color:var(--nf-accent);align-items:center;gap:6px;font-size:13px;font-weight:600;display:inline-flex}.CUIYUW_dashHeroSparkle{font-size:14px}.CUIYUW_dashHeroTitle{flex-direction:column;gap:2px;display:flex}.CUIYUW_dashHeroBook{letter-spacing:-.3px;margin:0;font-size:24px;font-weight:700;line-height:1.25}.CUIYUW_dashHeroAction{border:1px solid var(--nf-glass-border);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;align-items:center;gap:12px;padding:10px 14px;display:flex}.CUIYUW_dashHeroArrow{background:var(--nf-accent);color:#fff;border-radius:50%;flex:none;justify-content:center;align-items:center;width:28px;height:28px;font-size:14px;display:inline-flex}.CUIYUW_dashHeroActionBody{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.CUIYUW_dashHeroActionTitle{font-size:14px;font-weight:600}.CUIYUW_dashJourney{flex-direction:column;gap:6px;display:flex}.CUIYUW_dashJourneyBar{background:var(--nf-border);border-radius:999px;height:6px;overflow:hidden}.CUIYUW_dashJourneyFill{background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));border-radius:999px;height:100%;transition:width .4s;display:block}.CUIYUW_dashJourneyStages{grid-template-columns:repeat(6,minmax(0,1fr));gap:4px;display:grid}.CUIYUW_dashStage{color:var(--nf-text-3);text-align:center;white-space:nowrap;flex-direction:column;align-items:center;gap:3px;font-size:11px;display:flex}.CUIYUW_dashStageDot{border:1px solid var(--nf-border-strong,var(--nf-text-3));background:var(--nf-bg-base);border-radius:50%;justify-content:center;align-items:center;width:18px;height:18px;font-size:10px;display:inline-flex}.CUIYUW_dashStageDone{color:var(--nf-text-2)}.CUIYUW_dashStageDone .CUIYUW_dashStageDot{background:var(--nf-success);border-color:var(--nf-success);color:#fff}.CUIYUW_dashStageCurrent{color:var(--nf-accent);font-weight:600}.CUIYUW_dashStageCurrent .CUIYUW_dashStageDot{border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent)}.CUIYUW_dashFacts{border-top:1px solid var(--nf-border);grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding-top:12px;display:grid}.CUIYUW_dashFact{flex-direction:column;gap:2px;min-width:0;display:flex}.CUIYUW_dashFact b{white-space:nowrap;text-overflow:ellipsis;font-size:13px;overflow:hidden}.CUIYUW_dashGrid{grid-template-columns:minmax(0,3fr) minmax(0,2fr);align-items:start;gap:14px;display:grid}.CUIYUW_todoItem{border:1px solid var(--nf-border);border-radius:8px;align-items:center;gap:10px;padding:8px 12px;font-size:12.5px;display:flex}.CUIYUW_todoDanger{border-color:color-mix(in srgb, var(--nf-error) 40%, transparent);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.CUIYUW_todoWarning{border-color:color-mix(in srgb, var(--nf-warn) 40%, transparent);background:color-mix(in srgb, var(--nf-warn) 8%, transparent)}.CUIYUW_todoInfo{border-color:color-mix(in srgb, var(--nf-info) 40%, transparent);background:color-mix(in srgb, var(--nf-info) 7%, transparent)}.CUIYUW_todoText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.CUIYUW_outlineReadonly{border:1px solid var(--nf-border);background:var(--nf-bg-inset);white-space:pre-wrap;user-select:text;border-radius:12px;max-height:480px;margin:0;padding:12px 14px;font-size:12.5px;line-height:1.8;overflow:auto}.CUIYUW_bookCreateOutline{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.CUIYUW_assistantFloat{z-index:80;border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);border-radius:16px;flex-direction:column;min-width:320px;min-height:220px;display:flex;position:absolute;overflow:hidden}.CUIYUW_assistantFloatHeader{cursor:grab;user-select:none;border-bottom:1px solid var(--nf-border);background:var(--nf-bg-inset);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px 8px 14px;font-size:13px;font-weight:600;display:flex}.CUIYUW_assistantFloatHeader:active{cursor:grabbing}.CUIYUW_assistantFloatBody{flex:1;min-height:0;padding:10px;display:flex;overflow:hidden}.CUIYUW_assistantFloatBody>*{flex:1;min-width:0}.CUIYUW_assistantResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;width:20px;height:20px;position:absolute;bottom:0;right:0}.CUIYUW_coverPreview{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:12px;flex:none;justify-content:center;align-items:center;width:150px;height:200px;display:flex;overflow:hidden}.CUIYUW_coverPreview img{object-fit:contain;width:100%;height:100%;display:block}.CUIYUW_coverPlaceholder{color:var(--nf-text-3);font-size:12px}.CUIYUW_shelfView{flex-direction:column;flex:1;gap:16px;min-height:0;padding:18px;display:flex;overflow:auto}.CUIYUW_shelfHeader{flex-direction:column;gap:2px;display:flex}.CUIYUW_shelfGrid{grid-template-columns:repeat(auto-fill,minmax(190px,1fr));align-content:start;gap:14px;display:grid}.CUIYUW_bookCard{border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow);cursor:pointer;border-radius:16px;flex-direction:column;gap:8px;padding:12px;transition:border-color .15s,transform .1s,box-shadow .15s;display:flex}.CUIYUW_bookCard:hover{border-color:var(--nf-accent);box-shadow:var(--nf-shadow-lg);transform:translateY(-2px)}.CUIYUW_bookCardActive{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.CUIYUW_bookCardCover{aspect-ratio:3/4;background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:12px;flex:none;justify-content:center;align-items:center;display:flex;overflow:hidden}.CUIYUW_bookCardCover img{object-fit:contain;width:100%;height:100%;display:block}.CUIYUW_bookCardCoverFallback{background:radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%), linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));flex-direction:column;justify-content:center;align-items:center;gap:6px;width:100%;height:100%;display:flex}.CUIYUW_bookCardCoverTitle{color:var(--nf-accent);letter-spacing:2px;font-size:22px;font-weight:800}.CUIYUW_bookCardBody{flex-direction:column;gap:5px;min-width:0;display:flex}.CUIYUW_bookCardTitleRow{justify-content:space-between;align-items:center;gap:6px;display:flex}.CUIYUW_bookCardName{text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;font-weight:700;overflow:hidden}.CUIYUW_bookCardBlurb{-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;display:-webkit-box;overflow:hidden}.CUIYUW_bookCardProgressBar{background:var(--nf-border);border-radius:999px;height:5px;overflow:hidden}.CUIYUW_bookCardProgressFill{background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));border-radius:999px;height:100%;transition:width .3s;display:block}.CUIYUW_bookAddCard{text-align:center;color:var(--nf-text-2);border-style:dashed;justify-content:center;align-items:center;gap:8px;min-height:260px}.CUIYUW_bookAddCard:hover{color:var(--nf-accent)}.CUIYUW_bookAddIcon{color:var(--nf-accent);font-size:34px;line-height:1}.CUIYUW_bookCreateCard{border-color:var(--nf-accent);min-height:260px}.CUIYUW_createBookView{flex-direction:column;flex:1;gap:14px;min-height:0;padding:14px 18px 24px;display:flex;overflow:auto}.CUIYUW_createBookTop{align-items:center;display:flex}.CUIYUW_createBookCard{border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);width:min(520px,100%);box-shadow:var(--nf-shadow-lg);border-radius:20px;flex-direction:column;align-self:center;gap:12px;padding:26px 28px;display:flex}.CUIYUW_createBookIcon{font-size:34px;line-height:1}.CUIYUW_createBookTitle{letter-spacing:-.3px;margin:0;font-size:22px;font-weight:800}.CUIYUW_progressLineDone{color:var(--nf-success);font-weight:600}.CUIYUW_progressLineError{color:var(--nf-error);font-weight:600}.CUIYUW_meta{color:var(--nf-text-2);opacity:.9;font-size:12px}.CUIYUW_genreDesc{-webkit-line-clamp:2;-webkit-box-orient:vertical;max-width:560px;display:-webkit-box;overflow:hidden}.CUIYUW_fileList{color:var(--nf-text-2);opacity:.9;word-break:break-all;flex-direction:column;gap:3px;font-size:12px;display:flex}.CUIYUW_panelContent::-webkit-scrollbar,.CUIYUW_chatScroll::-webkit-scrollbar,.CUIYUW_chapterPreview::-webkit-scrollbar,.CUIYUW_progress::-webkit-scrollbar,.CUIYUW_toolLive::-webkit-scrollbar{width:8px;height:8px}.CUIYUW_panelContent::-webkit-scrollbar-thumb,.CUIYUW_chatScroll::-webkit-scrollbar-thumb,.CUIYUW_chapterPreview::-webkit-scrollbar-thumb,.CUIYUW_progress::-webkit-scrollbar-thumb,.CUIYUW_toolLive::-webkit-scrollbar-thumb{background:var(--nf-border-strong);border-radius:4px}.CUIYUW_panelContent::-webkit-scrollbar-thumb:hover,.CUIYUW_chatScroll::-webkit-scrollbar-thumb:hover,.CUIYUW_chapterPreview::-webkit-scrollbar-thumb:hover,.CUIYUW_progress::-webkit-scrollbar-thumb:hover,.CUIYUW_toolLive::-webkit-scrollbar-thumb:hover{background:var(--nf-text-3)}.CUIYUW_workflowList{flex-direction:column;gap:0;display:flex}.CUIYUW_workflowRow{align-items:flex-start;gap:12px;padding:8px 4px;display:flex;position:relative}.CUIYUW_workflowRow:before{content:\"\";background:var(--nf-border);width:2px;position:absolute;top:34px;bottom:-8px;left:13px}.CUIYUW_workflowRow:last-child:before{display:none}.CUIYUW_workflowDot{border:2px solid var(--nf-border-strong);background:var(--nf-bg-raise);width:28px;height:28px;color:var(--nf-text-2);z-index:1;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:12px;font-weight:700;display:inline-flex}.CUIYUW_workflowDotDone{border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));color:var(--nf-success)}.CUIYUW_workflowDotActive{border-color:var(--nf-accent);background:var(--nf-accent);color:var(--nf-accent-fg);box-shadow:0 0 0 4px var(--nf-accent-soft)}.CUIYUW_workflowBody{flex-direction:column;flex:1;gap:4px;min-width:0;padding-top:2px;display:flex}.CUIYUW_workflowLabel{color:var(--nf-text);font-size:13px;font-weight:600}.CUIYUW_workflowHint{color:var(--nf-text-2);font-size:12px}@keyframes CUIYUW_pulse{0%,to{opacity:1}50%{opacity:.45}}@keyframes CUIYUW_fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.CUIYUW_card{animation:.2s CUIYUW_fadeIn}.CUIYUW_bookshelf{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);z-index:1;border-radius:16px;flex-wrap:wrap;flex-shrink:0;align-items:center;gap:10px;margin:10px 12px 0;padding:8px 14px;display:flex;position:relative}.CUIYUW_bookshelfLabel{color:var(--nf-text-3);letter-spacing:1px;flex-shrink:0;font-size:12px;font-weight:700}.CUIYUW_bookshelfList{flex-wrap:wrap;flex:1;align-items:center;gap:6px;min-width:0;display:flex}.CUIYUW_bookChip{border:1px solid var(--nf-border);background:var(--nf-bg-inset);cursor:pointer;border-radius:999px;align-items:center;gap:6px;max-width:220px;padding:4px 8px 4px 10px;font-size:12px;transition:border-color .15s,background .15s;display:flex}.CUIYUW_bookChip:hover{border-color:var(--nf-border-strong)}.CUIYUW_bookChipActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.CUIYUW_bookChipName{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.CUIYUW_bookChipMeta{opacity:.7;white-space:nowrap;font-size:11px}.CUIYUW_bookChipRemove{color:var(--nf-text-3);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:0 2px;font-size:13px;line-height:1}.CUIYUW_bookChipRemove:hover{color:var(--nf-error)}.CUIYUW_bookAdd{border:1px dashed var(--nf-border-strong);color:var(--nf-text-2);cursor:pointer;background:0 0;border-radius:999px;padding:4px 12px;font-size:12px;transition:border-color .15s,color .15s}.CUIYUW_bookAdd:hover{border-color:var(--nf-accent);color:var(--nf-accent)}.CUIYUW_bookCreateForm{align-items:center;gap:6px;display:flex}.CUIYUW_dropzone{border:2px dashed var(--nf-border-strong);text-align:center;color:var(--nf-text-2);cursor:pointer;border-radius:10px;flex-direction:column;align-items:center;gap:6px;padding:18px 14px;font-size:13px;transition:border-color .15s,background .15s;display:flex}.CUIYUW_dropzone:hover,.CUIYUW_dropzoneActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.CUIYUW_dropzoneIcon{font-size:22px;line-height:1}";
869
+ const css = ".CUIYUW_entry{width:100%;color:var(--dsw-alias-label-primary,#1f1f23);cursor:pointer;text-align:left;background:0 0;border:none;border-radius:6px;align-items:center;gap:8px;padding:8px 12px;font-size:13px;transition:background .15s;display:flex}body[data-ds-dark-theme] .CUIYUW_entry{color:var(--dsw-alias-label-primary,#ececf1)}.CUIYUW_entry:hover{background:var(--dsw-alias-interactive-bg-hover,#7f7f7f1f)}.CUIYUW_entry[data-active]{background:var(--dsw-alias-interactive-bg-active,#7f7f7f33)}.CUIYUW_entryIcon{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.CUIYUW_entryLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-pane=conversation]{position:relative}.CUIYUW_view{z-index:60;color-scheme:light;--nf-font:-apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"SF Pro Text\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--nf-font-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff80 0%, #ffffff38 45%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffffa6;--nf-glass-inset:#ffffff8c;--nf-glass-orb-a:#00b85c24;--nf-glass-orb-b:#78a0ff1a;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\");background:var(--nf-bg);backdrop-filter:blur(32px)saturate(180%);color:var(--nf-text);font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Segoe UI,Roboto,Helvetica Neue,sans-serif;display:none;position:absolute;inset:0;overflow:auto}body[data-ds-dark-theme] .CUIYUW_view{color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #70747a6b 0%, #60646a6b 26%, #52555a6b 52%, #44474c6b 78%, #383a3f6b 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff42 0%, #ffffff1a 45%, #fff0 78%);--nf-glass-sheen:#ffffff42;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff12;--nf-glass-orb-a:#00ca5233;--nf-glass-orb-b:#bec8d712;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\")}html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .CUIYUW_view{display:block}.CUIYUW_panel[data-nf-theme=classic]{--nf-accent:#007aff;--nf-accent-hover:#0071e3;--nf-accent-soft:#007aff1f;--nf-accent-fg:#fff;--nf-info:#5856d6;--nf-glass-face:var(--nf-bg-raise);--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:var(--nf-border);--nf-glass-inset:var(--nf-bg-inset);--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=classic]{--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-info:#bf5af2;--nf-glass-face:var(--nf-bg-raise);--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:var(--nf-border);--nf-glass-inset:var(--nf-bg-inset);--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph]{--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input,body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input:focus,body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #a3b1c680, inset -2px -2px 6px #ffffffd9, 0 0 0 3px var(--nf-accent-soft)}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input,body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input:focus,body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #00000080, inset -2px -2px 6px #60687638, 0 0 0 3px var(--nf-accent-soft)}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #a3b1c68c,-5px -5px 10px #ffffffe6}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #a3b1c699,-7px -7px 14px #fffffff2}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_buttonPrimary{background:linear-gradient(#00c563,#00a952);box-shadow:5px 5px 10px #a3b1c699,-5px -5px 10px #ffffffd9}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #0000008c,-7px -7px 14px #60687642}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_buttonPrimary{background:linear-gradient(#3ddc86,#27b96a);box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}.CUIYUW_panel{flex-direction:column;min-width:0;height:100%;font-size:14px;line-height:1.6;display:flex;position:relative;overflow:hidden}.CUIYUW_panel:before{content:\"\";z-index:0;pointer-events:none;background:radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%), radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%), radial-gradient(120% 95% at 50% 42%, transparent 55%, #0202031a 100%);position:absolute;inset:0}.CUIYUW_panelHeader{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);border-radius:18px;flex-shrink:0;justify-content:space-between;align-items:center;margin:10px 12px 0;padding:10px 16px;display:flex}.CUIYUW_panelTitle{letter-spacing:.2px;align-items:center;gap:8px;margin:0;font-size:16px;font-weight:700;display:flex}.CUIYUW_panelTitle:before{content:\"\";background:linear-gradient(180deg, var(--nf-accent), var(--nf-info));border-radius:2px;width:4px;height:16px}.CUIYUW_iconButton{cursor:pointer;color:var(--nf-text-2);background:0 0;border:none;border-radius:8px;padding:4px 9px;font-size:16px;transition:background .15s,color .15s}.CUIYUW_iconButton:hover{background:var(--nf-hover);color:var(--nf-text)}.CUIYUW_tabBar{border-bottom:1px solid var(--nf-border);background:var(--nf-bg-raise);z-index:4;flex-shrink:0;gap:2px;padding:8px 14px 0;display:flex;position:sticky;top:45px}.CUIYUW_tab{cursor:pointer;color:var(--nf-text-2);background:0 0;border:none;border-radius:8px 8px 0 0;padding:7px 13px;font-size:13.5px;font-weight:500;transition:color .15s,background .15s;position:relative}.CUIYUW_tab:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_tab[data-active]{color:var(--nf-accent);font-weight:600}.CUIYUW_tab[data-active]:after{content:\"\";background:var(--nf-accent);border-radius:2px 2px 0 0;height:2.5px;position:absolute;bottom:-1px;left:10px;right:10px}.CUIYUW_panelContent{z-index:1;flex-direction:column;flex:1;gap:14px;padding:16px 18px 20px;display:flex;position:relative;overflow:auto}.CUIYUW_panelBody{z-index:1;flex:1;min-height:0;display:flex;position:relative}.CUIYUW_panelNav{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);width:142px;box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);border-radius:16px;flex-direction:column;flex:none;align-self:flex-start;gap:4px;margin:10px 0 10px 12px;padding:10px 8px;transition:width .18s;display:flex;overflow-y:auto}.CUIYUW_panelNavCollapsed{width:52px;padding:10px 6px}.CUIYUW_navGroup{flex-direction:column;gap:4px;display:flex}.CUIYUW_navGroupLabel{letter-spacing:.6px;text-transform:uppercase;color:var(--nf-text-3);user-select:none;padding:8px 10px 3px;font-size:10.5px;font-weight:600}.CUIYUW_navGroupSep{background:var(--nf-border);height:1px;margin:6px 8px 4px}.CUIYUW_navSpacer{flex:1;min-height:8px}.CUIYUW_navAbout{border-top:1px solid var(--nf-border);flex-direction:column;flex:none;gap:4px;margin-top:4px;padding:8px 6px 4px;display:flex}.CUIYUW_navAboutRow{cursor:pointer;color:var(--nf-text-3);text-align:left;white-space:nowrap;background:0 0;border:none;border-radius:8px;justify-content:space-between;align-items:center;gap:4px;padding:4px 6px;font-size:11px;transition:color .15s,background .15s;display:flex}.CUIYUW_navAboutRow:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_navAboutUpdate{background:var(--nf-accent-soft);color:var(--nf-accent);cursor:pointer;text-align:left;white-space:nowrap;border:none;border-radius:8px;padding:4px 6px;font-size:10.5px;font-weight:600}.CUIYUW_navAboutUpdate:hover{color:var(--nf-accent-hover)}.CUIYUW_panelNavCollapsed .CUIYUW_navAbout{align-items:center;padding:6px 2px 2px}.CUIYUW_panelNavCollapsed .CUIYUW_navAboutRow{justify-content:center;width:100%;padding:4px 0}.CUIYUW_navTabBadge{background:var(--nf-accent);color:#fff;text-align:center;border-radius:999px;flex:none;min-width:18px;height:18px;margin-left:auto;padding:0 5px;font-size:10.5px;font-weight:700;line-height:18px;display:inline-block}.CUIYUW_panelNavCollapsed .CUIYUW_navTabBadge{min-width:14px;height:14px;padding:0 3px;font-size:9px;line-height:14px;position:absolute;top:2px;right:2px}.CUIYUW_navTabBadgeDanger{background:var(--nf-error)}.CUIYUW_navTabBadgeWarn{background:var(--nf-warn)}.CUIYUW_navTabBadgeDone{background:var(--nf-success)}.CUIYUW_navTabBadgeLive{background:var(--nf-success);animation:1.2s ease-in-out infinite CUIYUW_navBadgePulse}@keyframes CUIYUW_navBadgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}.CUIYUW_navTab{cursor:pointer;width:100%;color:var(--nf-text-2-alpha,var(--nf-text-2));text-align:left;white-space:nowrap;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:8px 10px;font-size:13px;font-weight:500;transition:color .15s,background .15s;display:flex;position:relative}.CUIYUW_panelNavCollapsed .CUIYUW_navTab{justify-content:center;padding:8px 0}.CUIYUW_navTab:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_navTab[data-active]{color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.CUIYUW_navTab[data-active]:before{content:\"\";background:var(--nf-accent);border-radius:999px;width:3px;position:absolute;top:20%;bottom:20%;left:-8px}.CUIYUW_panelNavCollapsed .CUIYUW_navTab[data-active]:before{left:-6px}.CUIYUW_navTabIcon{flex:none;font-size:15px;line-height:1}.CUIYUW_navTabLabel{text-overflow:ellipsis;overflow:hidden}.CUIYUW_panelSubtitle{color:var(--nf-text-2);white-space:nowrap;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:0 4px 2px;font-size:12px;display:flex}.CUIYUW_headerProgress{color:var(--nf-text-2);white-space:nowrap;align-items:center;gap:6px;margin-left:0;font-size:12px;font-weight:400;display:inline-flex}.CUIYUW_headerProgress b{color:var(--nf-accent);font-weight:700}.CUIYUW_headerProgressDot{background:var(--nf-border-strong,var(--nf-text-3));border-radius:50%;width:3px;height:3px;display:inline-block}.CUIYUW_card{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);border-radius:22px;flex-direction:column;gap:10px;padding:16px 18px;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.CUIYUW_card:before{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.CUIYUW_card:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.CUIYUW_card:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.CUIYUW_card>*{z-index:1;position:relative}.CUIYUW_cardTitle{color:var(--nf-text);align-items:center;gap:8px;margin:0;font-size:14px;font-weight:650;display:flex}.CUIYUW_button{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);cursor:pointer;white-space:nowrap;border-radius:12px;padding:6px 14px;font-size:13px;font-weight:500;transition:background .15s,border-color .15s,transform .1s,box-shadow .15s}.CUIYUW_button:hover:not([disabled]){background:var(--nf-hover);border-color:var(--nf-border-strong)}.CUIYUW_button:active:not([disabled]){transform:scale(.96)}.CUIYUW_button[disabled]{opacity:.45;cursor:not-allowed}.CUIYUW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #fff), var(--nf-accent));color:var(--nf-accent-fg);box-shadow:0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent);border-color:#0000}.CUIYUW_buttonPrimary:hover:not([disabled]){background:linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000));border-color:#0000}.CUIYUW_buttonDanger{border-color:var(--nf-error);color:var(--nf-error)}.CUIYUW_buttonDanger:hover:not([disabled]){background:#ff3b301a}.CUIYUW_buttonSmall{border-radius:9px;padding:3px 10px;font-size:12px}.CUIYUW_field{flex-direction:column;gap:5px;display:flex}.CUIYUW_fieldLabel{color:var(--nf-text-2);font-size:12px;font-weight:500}.CUIYUW_input{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);box-sizing:border-box;border-radius:12px;width:100%;padding:7px 11px;font-size:13px;transition:border-color .15s,box-shadow .15s}.CUIYUW_input:focus,.CUIYUW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft);outline:none}.CUIYUW_input::placeholder,.CUIYUW_textarea::placeholder{color:var(--nf-text-3)}.CUIYUW_textarea{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);box-sizing:border-box;resize:vertical;border-radius:12px;width:100%;min-height:200px;padding:9px 11px;font-family:inherit;font-size:13px;line-height:1.7;transition:border-color .15s,box-shadow .15s}.CUIYUW_row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.CUIYUW_spaceBetween{justify-content:space-between}.CUIYUW_chapterList{flex-direction:column;gap:8px;display:flex}.CUIYUW_volumeGroup{flex-direction:column;gap:6px;display:flex}.CUIYUW_volumeGroupHeader{background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;user-select:none;border-radius:10px;align-items:center;gap:8px;padding:6px 10px;font-size:13px;transition:border-color .15s;display:flex}.CUIYUW_volumeGroupHeader:hover{border-color:var(--nf-accent)}.CUIYUW_volumeGroupToggle{color:var(--nf-text-2);flex:none;font-size:11px}.CUIYUW_chapter{border:1px solid var(--nf-border);background:var(--nf-bg);border-radius:10px;align-items:center;gap:10px;padding:9px 12px;transition:border-color .15s,box-shadow .15s,transform .1s;display:flex}.CUIYUW_chapter:hover{border-color:var(--nf-border-strong);box-shadow:var(--nf-shadow)}.CUIYUW_chapterFocus{animation:.9s ease-in-out 3 CUIYUW_chapterFocusPulse;border-color:var(--nf-accent)!important;box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 35%, transparent)!important}@keyframes CUIYUW_chapterFocusPulse{0%,to{background:var(--nf-bg)}50%{background:color-mix(in srgb, var(--nf-accent) 18%, var(--nf-bg))}}.CUIYUW_chapterNum{background:var(--nf-bg-inset);border:1px solid var(--nf-border);min-width:28px;height:28px;color:var(--nf-text-2);border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;padding:0 8px;font-size:12px;font-weight:700;display:inline-flex}.CUIYUW_chapterMain{flex:1;min-width:0}.CUIYUW_chapterTitle{color:var(--nf-text);align-items:center;gap:8px;font-size:13px;font-weight:600;display:flex}.CUIYUW_chapterBeats{color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.CUIYUW_chapterActions{opacity:.85;flex-shrink:0;gap:4px;transition:opacity .15s;display:flex}.CUIYUW_chapter:hover .CUIYUW_chapterActions{opacity:1}.CUIYUW_badge{white-space:nowrap;letter-spacing:.2px;border:1px solid;border-radius:999px;padding:2px 9px;font-size:11px;font-weight:600}.CUIYUW_badgePending{color:var(--nf-info);border-color:var(--nf-info);background:color-mix(in srgb, var(--nf-info) 10%, transparent)}.CUIYUW_badgeGenerating{color:var(--nf-accent);border-color:var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 12%, transparent);animation:1.2s ease-in-out infinite CUIYUW_pulse}.CUIYUW_badgeWritten{color:var(--nf-warn);border-color:var(--nf-warn);background:color-mix(in srgb, var(--nf-warn) 10%, transparent)}.CUIYUW_badgeRejected{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.CUIYUW_badgeDone{color:var(--nf-success);border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 10%, transparent)}.CUIYUW_badgeError{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.CUIYUW_reviewBox{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-size:12.5px;display:flex}.CUIYUW_chapterPreview{white-space:pre-wrap;word-break:break-all;max-height:320px;color:var(--nf-text);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:10px;margin:0;padding:10px 12px;font-family:inherit;font-size:12.5px;line-height:1.8;overflow:auto}.CUIYUW_chatScroll{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:12px;flex-direction:column;flex:1;gap:10px;min-height:240px;max-height:480px;padding:14px;display:flex;overflow-y:auto}.CUIYUW_chatBubbleUser{background:linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));max-width:90%;color:var(--nf-accent-fg);border-radius:14px 14px 4px;align-self:flex-end;padding:9px 14px;font-size:13px;box-shadow:0 2px 6px #4d6bfe33}.CUIYUW_chatBubbleAssistant{background:var(--nf-bg-raise);max-width:92%;color:var(--nf-text);border:1px solid var(--nf-border);box-shadow:var(--nf-shadow);border-radius:14px 14px 14px 4px;align-self:flex-start;padding:9px 14px;font-size:13px}.CUIYUW_chatRole{color:var(--nf-text-3);margin-bottom:3px;font-size:11px;font-weight:600}.CUIYUW_toolLive{background:var(--nf-bg-inset);border:1px dashed var(--nf-border-strong);white-space:pre-wrap;word-break:break-all;color:var(--nf-text-2);border-radius:8px;max-height:180px;margin-top:6px;padding:8px 10px;font-size:12px;line-height:1.7;overflow-y:auto}.CUIYUW_assistantStatus{color:var(--nf-text-2);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:999px;flex:none;align-items:center;gap:6px;margin-top:6px;padding:6px 12px;font-size:12px;display:flex}.CUIYUW_assistantStatusBusy{color:var(--nf-accent);border-color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.CUIYUW_toolSteps{flex-direction:column;gap:4px;margin-top:6px;display:flex}.CUIYUW_toolStep{background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:8px;align-items:center;gap:8px;padding:5px 10px;font-size:12px;display:flex}.CUIYUW_toolStepActive{border-color:var(--nf-accent);background:var(--nf-accent-soft)}.CUIYUW_toolStepError{border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.CUIYUW_toolStepIcon{flex:none;font-size:13px}.CUIYUW_toolStepName{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:600;overflow:hidden}.CUIYUW_toolStepStatus{color:var(--nf-text-2);flex:none;font-size:11px}.CUIYUW_toolStepActive .CUIYUW_toolStepStatus{color:var(--nf-accent)}.CUIYUW_toolStepError .CUIYUW_toolStepStatus{color:var(--nf-error)}.CUIYUW_toolStepDetail{width:100%;color:var(--nf-error);word-break:break-all;font-size:11px}.CUIYUW_progress{border:1px solid var(--nf-border);white-space:pre-wrap;word-break:break-all;min-height:60px;max-height:220px;color:var(--nf-text-2);font-size:12px;font-family:var(--nf-font-mono);background:var(--nf-bg-inset);border-radius:10px;padding:10px 14px;line-height:1.8;overflow:auto}.CUIYUW_progressLine{color:var(--nf-text-2);opacity:.9}.CUIYUW_progressLineLive{color:var(--nf-accent);align-items:center;gap:8px;font-weight:600;display:flex}.CUIYUW_progressBar{background:var(--nf-border);border-radius:999px;flex:none;width:110px;height:6px;display:inline-block;overflow:hidden}.CUIYUW_progressBarFill{background:var(--nf-accent);border-radius:3px;height:100%;transition:width .3s;display:block}.CUIYUW_busyRow{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;display:flex}.CUIYUW_liveText{font-variant-numeric:tabular-nums;color:var(--nf-text-2);font-size:12px}.CUIYUW_bigProgressBar{background:var(--nf-border);border-radius:999px;height:8px;margin-top:10px;overflow:hidden}.CUIYUW_bigProgressBarFill{background:linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2,var(--nf-accent)));border-radius:999px;height:100%;transition:width .3s;display:block}.CUIYUW_diffLegend{flex-wrap:wrap;align-items:center;gap:14px;margin:6px 0 8px;font-size:12px;display:flex}.CUIYUW_legendOld{color:var(--nf-error);font-weight:700}.CUIYUW_legendNew{color:var(--nf-success);font-weight:700}.CUIYUW_onlyChanges{color:var(--nf-text-2);cursor:pointer;align-items:center;gap:4px;margin-left:auto;display:inline-flex}.CUIYUW_diffList{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:8px;flex-direction:column;flex:1;gap:8px;min-height:0;padding:10px 12px;font-size:13px;line-height:1.7;display:flex;overflow-y:auto}.CUIYUW_diffSame{border:1px dashed var(--nf-border);color:var(--nf-text-2);opacity:.85;border-radius:6px;padding:6px 10px}.CUIYUW_diffSame summary{cursor:pointer;user-select:none;font-size:12px}.CUIYUW_diffSameBody{white-space:pre-wrap;margin-top:6px}.CUIYUW_diffChange{border:1px solid var(--nf-border);border-radius:8px;grid-template-columns:1fr 1fr;display:grid;overflow:hidden}.CUIYUW_diffColumn{flex-direction:column;gap:6px;min-width:0;padding:8px 10px;display:flex}.CUIYUW_diffColumn:first-child{border-right:1px solid var(--nf-border)}.CUIYUW_diffTagOld,.CUIYUW_diffTagNew{letter-spacing:.5px;border-radius:4px;flex:none;align-self:flex-start;padding:1px 7px;font-size:11px;font-weight:700}.CUIYUW_diffTagOld{color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-error) 45%, transparent)}.CUIYUW_diffTagNew{color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-success) 45%, transparent)}.CUIYUW_diffOld{color:var(--nf-error);white-space:pre-wrap;text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 55%, transparent)}.CUIYUW_diffNew{color:var(--nf-success);white-space:pre-wrap;font-weight:500}.CUIYUW_diffDel{border:1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);background:color-mix(in srgb, var(--nf-error) 7%, transparent);border-radius:6px;flex-direction:column;gap:4px;padding:6px 10px;display:flex}.CUIYUW_diffAdd{border:1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);background:color-mix(in srgb, var(--nf-success) 7%, transparent);border-radius:6px;flex-direction:column;gap:4px;padding:6px 10px;display:flex}.CUIYUW_diffText{white-space:pre-wrap}.CUIYUW_diffDel .CUIYUW_diffText{color:var(--nf-error);text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 50%, transparent)}.CUIYUW_diffAdd .CUIYUW_diffText{color:var(--nf-success)}.CUIYUW_wsPage{flex-direction:column;flex:1;gap:10px;min-height:0;display:flex}.CUIYUW_wsPageHeader{flex-wrap:wrap;flex:none;align-items:center;gap:8px;display:flex}.CUIYUW_wsAppliedBanner{border:1px solid var(--nf-success);background:color-mix(in srgb, var(--nf-success) 8%, transparent);border-radius:10px;flex-wrap:wrap;flex:none;align-items:center;gap:8px;padding:8px 12px;font-size:12px;font-weight:600;display:flex}.CUIYUW_wsColumns{flex:1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;min-height:0;display:grid}.CUIYUW_wsColumn{flex-direction:column;gap:8px;min-width:0;min-height:0;display:flex}.CUIYUW_wsEditor{resize:vertical;min-height:0;font-family:var(--nf-font);white-space:pre-wrap;flex:1;font-size:13px;line-height:1.75}.CUIYUW_wsSelected{border:1px solid var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 8%, transparent);border-radius:6px;max-height:120px;padding:6px 10px;overflow:auto}.CUIYUW_wsSelectedText{color:var(--nf-text-2);white-space:pre-wrap;margin-top:4px;font-size:12px}.CUIYUW_wsPreview{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:8px;flex-direction:column;gap:8px;padding:8px 10px;display:flex}.CUIYUW_wsPreviewText{white-space:pre-wrap;min-height:0;color:var(--nf-text);flex:1;margin:0;font-size:13px;line-height:1.7;overflow:auto}.CUIYUW_assetGrid{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;display:grid}.CUIYUW_assetStat{border:1px solid var(--nf-glass-border);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;flex-direction:column;gap:4px;padding:10px 12px;display:flex}.CUIYUW_assetStatLabel{color:var(--nf-text-2);opacity:.9;font-size:11px}.CUIYUW_assetStatValue{color:var(--nf-text);font-size:15px;font-weight:700;line-height:1.2}.CUIYUW_assetStatDetail{color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.CUIYUW_dashHero{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);border-radius:22px;flex-direction:column;gap:14px;padding:18px 20px;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.CUIYUW_dashHero:before{content:\"\";border-radius:inherit;pointer-events:none;background:radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%), var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.CUIYUW_dashHero:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.CUIYUW_dashHero:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.CUIYUW_dashHero>*{z-index:1;position:relative}.CUIYUW_dashHeroEyebrow{color:var(--nf-accent);align-items:center;gap:6px;font-size:13px;font-weight:600;display:inline-flex}.CUIYUW_dashHeroSparkle{font-size:14px}.CUIYUW_dashHeroTitle{flex-direction:column;gap:2px;display:flex}.CUIYUW_dashHeroBook{letter-spacing:-.3px;margin:0;font-size:24px;font-weight:700;line-height:1.25}.CUIYUW_dashHeroAction{border:1px solid var(--nf-glass-border);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;align-items:center;gap:12px;padding:10px 14px;display:flex}.CUIYUW_dashHeroArrow{background:var(--nf-accent);color:#fff;border-radius:50%;flex:none;justify-content:center;align-items:center;width:28px;height:28px;font-size:14px;display:inline-flex}.CUIYUW_dashHeroActionBody{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.CUIYUW_dashHeroActionTitle{font-size:14px;font-weight:600}.CUIYUW_dashJourney{flex-direction:column;gap:6px;display:flex}.CUIYUW_dashJourneyBar{background:var(--nf-border);border-radius:999px;height:6px;overflow:hidden}.CUIYUW_dashJourneyFill{background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));border-radius:999px;height:100%;transition:width .4s;display:block}.CUIYUW_dashJourneyStages{grid-template-columns:repeat(6,minmax(0,1fr));gap:4px;display:grid}.CUIYUW_dashStage{color:var(--nf-text-3);text-align:center;white-space:nowrap;flex-direction:column;align-items:center;gap:3px;font-size:11px;display:flex}.CUIYUW_dashStageDot{border:1px solid var(--nf-border-strong,var(--nf-text-3));background:var(--nf-bg-base);border-radius:50%;justify-content:center;align-items:center;width:18px;height:18px;font-size:10px;display:inline-flex}.CUIYUW_dashStageDone{color:var(--nf-text-2)}.CUIYUW_dashStageDone .CUIYUW_dashStageDot{background:var(--nf-success);border-color:var(--nf-success);color:#fff}.CUIYUW_dashStageCurrent{color:var(--nf-accent);font-weight:600}.CUIYUW_dashStageCurrent .CUIYUW_dashStageDot{border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent)}.CUIYUW_dashFacts{border-top:1px solid var(--nf-border);grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding-top:12px;display:grid}.CUIYUW_dashFact{flex-direction:column;gap:2px;min-width:0;display:flex}.CUIYUW_dashFact b{white-space:nowrap;text-overflow:ellipsis;font-size:13px;overflow:hidden}.CUIYUW_dashGrid{grid-template-columns:minmax(0,3fr) minmax(0,2fr);align-items:start;gap:14px;display:grid}.CUIYUW_todoItem{border:1px solid var(--nf-border);border-radius:8px;align-items:center;gap:10px;padding:8px 12px;font-size:12.5px;display:flex}.CUIYUW_todoDanger{border-color:color-mix(in srgb, var(--nf-error) 40%, transparent);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.CUIYUW_todoWarning{border-color:color-mix(in srgb, var(--nf-warn) 40%, transparent);background:color-mix(in srgb, var(--nf-warn) 8%, transparent)}.CUIYUW_todoInfo{border-color:color-mix(in srgb, var(--nf-info) 40%, transparent);background:color-mix(in srgb, var(--nf-info) 7%, transparent)}.CUIYUW_todoText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.CUIYUW_outlineReadonly{border:1px solid var(--nf-border);background:var(--nf-bg-inset);white-space:pre-wrap;user-select:text;border-radius:12px;max-height:480px;margin:0;padding:12px 14px;font-size:12.5px;line-height:1.8;overflow:auto}.CUIYUW_bookCreateOutline{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.CUIYUW_assistantFloat{z-index:80;border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);border-radius:16px;flex-direction:column;min-width:320px;min-height:220px;display:flex;position:absolute;overflow:hidden}.CUIYUW_assistantFloatHeader{cursor:grab;user-select:none;border-bottom:1px solid var(--nf-border);background:var(--nf-bg-inset);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px 8px 14px;font-size:13px;font-weight:600;display:flex}.CUIYUW_assistantFloatHeader:active{cursor:grabbing}.CUIYUW_assistantFloatBody{flex:1;min-height:0;padding:10px;display:flex;overflow:hidden}.CUIYUW_assistantFloatBody>*{flex:1;min-width:0}.CUIYUW_assistantResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;width:20px;height:20px;position:absolute;bottom:0;right:0}.CUIYUW_coverPreview{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:12px;flex:none;justify-content:center;align-items:center;width:150px;height:200px;display:flex;overflow:hidden}.CUIYUW_coverPreview img{object-fit:contain;width:100%;height:100%;display:block}.CUIYUW_coverPlaceholder{color:var(--nf-text-3);font-size:12px}.CUIYUW_shelfView{flex-direction:column;flex:1;gap:16px;min-height:0;padding:18px;display:flex;overflow:auto}.CUIYUW_shelfHeader{flex-direction:column;gap:10px;display:flex}.CUIYUW_shelfTitleRow{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}.CUIYUW_shelfToolbar{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.CUIYUW_shelfSearch{flex:1;min-width:180px;max-width:320px}.CUIYUW_shelfFilters{flex-wrap:wrap;gap:6px;display:flex}.CUIYUW_shelfEmpty{border:1px dashed var(--nf-border-strong);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);text-align:center;border-radius:16px;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:10px;padding:40px 20px;display:flex}.CUIYUW_shelfEmptyIcon{font-size:42px}.CUIYUW_shelfEmptyTitle{font-size:16px;font-weight:700}.CUIYUW_shelfGrid{grid-template-columns:repeat(auto-fill,minmax(190px,1fr));align-content:start;gap:14px;display:grid}.CUIYUW_bookCard{border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow);cursor:pointer;border-radius:16px;flex-direction:column;gap:8px;padding:12px;transition:border-color .15s,transform .1s,box-shadow .15s;display:flex}.CUIYUW_bookCard:hover{border-color:var(--nf-accent);box-shadow:var(--nf-shadow-lg);transform:translateY(-2px)}.CUIYUW_bookCardActive{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.CUIYUW_bookCardCover{aspect-ratio:3/4;background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:12px;flex:none;justify-content:center;align-items:center;display:flex;overflow:hidden}.CUIYUW_bookCardCover img{object-fit:contain;width:100%;height:100%;display:block}.CUIYUW_bookCardCoverFallback{background:radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%), linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));flex-direction:column;justify-content:center;align-items:center;gap:6px;width:100%;height:100%;display:flex}.CUIYUW_bookCardCoverTitle{color:var(--nf-accent);letter-spacing:2px;font-size:22px;font-weight:800}.CUIYUW_bookCardBody{flex-direction:column;gap:5px;min-width:0;display:flex}.CUIYUW_bookCardTitleRow{justify-content:space-between;align-items:center;gap:6px;display:flex}.CUIYUW_bookCardName{text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;font-weight:700;overflow:hidden}.CUIYUW_bookCardBlurb{-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;display:-webkit-box;overflow:hidden}.CUIYUW_bookCardMetaRow{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:6px;display:flex}.CUIYUW_bookCardProgressBar{background:var(--nf-border);border-radius:999px;height:5px;overflow:hidden}.CUIYUW_bookCardProgressFill{background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));border-radius:999px;height:100%;transition:width .3s;display:block}.CUIYUW_bookAddCard{text-align:center;color:var(--nf-text-2);border-style:dashed;justify-content:center;align-items:center;gap:8px;min-height:260px}.CUIYUW_bookAddCard:hover{color:var(--nf-accent)}.CUIYUW_bookAddIcon{color:var(--nf-accent);font-size:34px;line-height:1}.CUIYUW_bookCreateCard{border-color:var(--nf-accent);min-height:260px}.CUIYUW_createBookView{flex-direction:column;flex:1;gap:14px;min-height:0;padding:14px 18px 24px;display:flex;overflow:auto}.CUIYUW_createBookTop{align-items:center;display:flex}.CUIYUW_createBookCard{border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);width:min(520px,100%);box-shadow:var(--nf-shadow-lg);border-radius:20px;flex-direction:column;align-self:center;gap:12px;padding:26px 28px;display:flex}.CUIYUW_createBookIcon{font-size:34px;line-height:1}.CUIYUW_createBookTitle{letter-spacing:-.3px;margin:0;font-size:22px;font-weight:800}.CUIYUW_ideaCard{border:1px dashed var(--nf-border-strong);background:color-mix(in srgb, var(--nf-accent) 3%, transparent);border-radius:14px;flex-direction:column;gap:8px;padding:10px 12px;display:flex}.CUIYUW_ideaToggle{color:var(--nf-accent);cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:6px;padding:0;font-size:13px;font-weight:700;display:flex}.CUIYUW_ideaCandidate{border:1px solid var(--nf-border);background:var(--nf-bg);border-radius:12px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}.CUIYUW_progressLineDone{color:var(--nf-success);font-weight:600}.CUIYUW_progressLineError{color:var(--nf-error);font-weight:600}.CUIYUW_meta{color:var(--nf-text-2);opacity:.9;font-size:12px}.CUIYUW_genreDesc{-webkit-line-clamp:2;-webkit-box-orient:vertical;max-width:560px;display:-webkit-box;overflow:hidden}.CUIYUW_fileList{color:var(--nf-text-2);opacity:.9;word-break:break-all;flex-direction:column;gap:3px;font-size:12px;display:flex}.CUIYUW_panelContent::-webkit-scrollbar,.CUIYUW_chatScroll::-webkit-scrollbar,.CUIYUW_chapterPreview::-webkit-scrollbar,.CUIYUW_progress::-webkit-scrollbar,.CUIYUW_toolLive::-webkit-scrollbar{width:8px;height:8px}.CUIYUW_panelContent::-webkit-scrollbar-thumb,.CUIYUW_chatScroll::-webkit-scrollbar-thumb,.CUIYUW_chapterPreview::-webkit-scrollbar-thumb,.CUIYUW_progress::-webkit-scrollbar-thumb,.CUIYUW_toolLive::-webkit-scrollbar-thumb{background:var(--nf-border-strong);border-radius:4px}.CUIYUW_panelContent::-webkit-scrollbar-thumb:hover,.CUIYUW_chatScroll::-webkit-scrollbar-thumb:hover,.CUIYUW_chapterPreview::-webkit-scrollbar-thumb:hover,.CUIYUW_progress::-webkit-scrollbar-thumb:hover,.CUIYUW_toolLive::-webkit-scrollbar-thumb:hover{background:var(--nf-text-3)}.CUIYUW_workflowList{flex-direction:column;gap:0;display:flex}.CUIYUW_workflowRow{align-items:flex-start;gap:12px;padding:8px 4px;display:flex;position:relative}.CUIYUW_workflowRow:before{content:\"\";background:var(--nf-border);width:2px;position:absolute;top:34px;bottom:-8px;left:13px}.CUIYUW_workflowRow:last-child:before{display:none}.CUIYUW_workflowDot{border:2px solid var(--nf-border-strong);background:var(--nf-bg-raise);width:28px;height:28px;color:var(--nf-text-2);z-index:1;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:12px;font-weight:700;display:inline-flex}.CUIYUW_workflowDotDone{border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));color:var(--nf-success)}.CUIYUW_workflowDotActive{border-color:var(--nf-accent);background:var(--nf-accent);color:var(--nf-accent-fg);box-shadow:0 0 0 4px var(--nf-accent-soft)}.CUIYUW_workflowBody{flex-direction:column;flex:1;gap:4px;min-width:0;padding-top:2px;display:flex}.CUIYUW_workflowLabel{color:var(--nf-text);font-size:13px;font-weight:600}.CUIYUW_workflowHint{color:var(--nf-text-2);font-size:12px}@keyframes CUIYUW_pulse{0%,to{opacity:1}50%{opacity:.45}}@keyframes CUIYUW_fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.CUIYUW_card{animation:.2s CUIYUW_fadeIn}.CUIYUW_bookshelf{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);z-index:1;border-radius:16px;flex-wrap:wrap;flex-shrink:0;align-items:center;gap:10px;margin:10px 12px 0;padding:8px 14px;display:flex;position:relative}.CUIYUW_bookshelfLabel{color:var(--nf-text-3);letter-spacing:1px;flex-shrink:0;font-size:12px;font-weight:700}.CUIYUW_bookshelfList{flex-wrap:wrap;flex:1;align-items:center;gap:6px;min-width:0;display:flex}.CUIYUW_bookChip{border:1px solid var(--nf-border);background:var(--nf-bg-inset);cursor:pointer;border-radius:999px;align-items:center;gap:6px;max-width:220px;padding:4px 8px 4px 10px;font-size:12px;transition:border-color .15s,background .15s;display:flex}.CUIYUW_bookChip:hover{border-color:var(--nf-border-strong)}.CUIYUW_bookChipActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.CUIYUW_bookChipName{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.CUIYUW_bookChipMeta{opacity:.7;white-space:nowrap;font-size:11px}.CUIYUW_bookChipRemove{color:var(--nf-text-3);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:0 2px;font-size:13px;line-height:1}.CUIYUW_bookChipRemove:hover{color:var(--nf-error)}.CUIYUW_bookAdd{border:1px dashed var(--nf-border-strong);color:var(--nf-text-2);cursor:pointer;background:0 0;border-radius:999px;padding:4px 12px;font-size:12px;transition:border-color .15s,color .15s}.CUIYUW_bookAdd:hover{border-color:var(--nf-accent);color:var(--nf-accent)}.CUIYUW_bookCreateForm{align-items:center;gap:6px;display:flex}.CUIYUW_dropzone{border:2px dashed var(--nf-border-strong);text-align:center;color:var(--nf-text-2);cursor:pointer;border-radius:10px;flex-direction:column;align-items:center;gap:6px;padding:18px 14px;font-size:13px;transition:border-color .15s,background .15s;display:flex}.CUIYUW_dropzone:hover,.CUIYUW_dropzoneActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.CUIYUW_dropzoneIcon{font-size:22px;line-height:1}.CUIYUW_bookCardActions{align-items:center;gap:6px;margin-top:2px;display:flex}.CUIYUW_bookCardActions .CUIYUW_button{flex:1;justify-content:center}.CUIYUW_readerView{flex-direction:column;transition:background .2s,color .2s;display:flex;position:absolute;inset:0;overflow:hidden}.CUIYUW_readerHeader{border-bottom:1px solid;flex-wrap:wrap;flex:none;align-items:center;gap:8px;padding:8px 12px;display:flex}.CUIYUW_readerTitle{font-size:14px;font-weight:700}.CUIYUW_readerSeg{border-radius:8px;align-items:center;gap:2px;display:flex;overflow:hidden}.CUIYUW_readerSegBtn{cursor:pointer;opacity:.75;background:0 0;border:none;border-radius:6px;padding:3px 8px;font-size:12px}.CUIYUW_readerSegBtn:hover,.CUIYUW_readerSegActive{opacity:1}.CUIYUW_readerBody{flex:1;align-items:stretch;min-height:0;display:flex}.CUIYUW_readerSidebar{scrollbar-width:thin;border-right:1px solid;flex-direction:column;flex:none;gap:10px;width:220px;min-width:220px;padding:8px 6px 24px;display:flex;overflow-y:auto}.CUIYUW_readerGroup{flex-direction:column;gap:1px;display:flex}.CUIYUW_readerGroupTitle{opacity:.9;cursor:pointer;text-align:left;background:0 0;border:none;border-radius:6px;align-items:center;gap:6px;width:100%;padding:6px 8px 4px;font-size:12px;font-weight:700;display:flex}.CUIYUW_readerGroupTitle:hover{opacity:1;background:#8080801f}.CUIYUW_readerGroupArrow{text-align:center;flex:none;width:12px;font-size:10px}.CUIYUW_readerGroupCount{opacity:.6;flex:none;margin-left:auto;padding-right:2px;font-size:11px;font-weight:400}.CUIYUW_readerItem{text-align:left;cursor:pointer;opacity:.8;background:0 0;border:1px solid;border-radius:8px;align-items:center;gap:6px;min-width:0;padding:4px 8px;font-size:12px;transition:opacity .15s,background .15s;display:flex}.CUIYUW_readerItem:hover{opacity:1}.CUIYUW_readerItemActive{opacity:1;font-weight:700}.CUIYUW_readerItemNo{text-align:right;opacity:.75;flex:none;min-width:26px;font-weight:700}.CUIYUW_readerItemTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.CUIYUW_readerItemBadge{flex:none;font-size:11px}.CUIYUW_readerMain{scrollbar-width:thin;flex:1;justify-content:center;min-height:0;padding:20px 16px 48px;display:flex;overflow-y:auto}.CUIYUW_readerArticle{flex-direction:column;gap:12px;width:100%;display:flex}.CUIYUW_readerChapterTitle{letter-spacing:1px;margin:0;font-size:24px;font-weight:800}.CUIYUW_readerChapterMeta{align-items:center;gap:8px;font-size:12px;display:flex}.CUIYUW_readerText{text-align:justify;letter-spacing:.02em}.CUIYUW_readerPara{text-indent:2em;margin:0 0 .85em}.CUIYUW_readerFoot{border-top:1px dashed;justify-content:space-between;align-items:center;gap:8px;margin-top:12px;padding-top:12px;display:flex}.CUIYUW_readerLoading,.CUIYUW_readerError{opacity:.7;align-self:center;padding:32px 0;font-size:13px}.CUIYUW_readerError{color:var(--nf-error)}";
820
870
  const tagId = "@waterwx/dsh-novel-forge/panel.module.css";
821
871
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
822
872
  const tag = document.createElement("style");
@@ -826,205 +876,248 @@ window.__ModuleLoader__.load({
826
876
  document.head.appendChild(tag);
827
877
  }
828
878
  var panel_module_css_default = {
879
+ "iconButton": "CUIYUW_iconButton",
880
+ "progressBar": "CUIYUW_progressBar",
881
+ "dashHeroActionTitle": "CUIYUW_dashHeroActionTitle",
882
+ "panelBody": "CUIYUW_panelBody",
883
+ "navAbout": "CUIYUW_navAbout",
884
+ "panelContent": "CUIYUW_panelContent",
885
+ "chapterFocusPulse": "CUIYUW_chapterFocusPulse",
886
+ "badgeWritten": "CUIYUW_badgeWritten",
887
+ "dashFacts": "CUIYUW_dashFacts",
888
+ "wsSelectedText": "CUIYUW_wsSelectedText",
889
+ "dashHeroAction": "CUIYUW_dashHeroAction",
890
+ "bookCardName": "CUIYUW_bookCardName",
891
+ "chatRole": "CUIYUW_chatRole",
892
+ "bookCardActive": "CUIYUW_bookCardActive",
893
+ "bookCreateForm": "CUIYUW_bookCreateForm",
829
894
  "createBookView": "CUIYUW_createBookView",
830
- "tabBar": "CUIYUW_tabBar",
895
+ "readerItemActive": "CUIYUW_readerItemActive",
896
+ "headerProgressDot": "CUIYUW_headerProgressDot",
897
+ "assetGrid": "CUIYUW_assetGrid",
898
+ "bookChipName": "CUIYUW_bookChipName",
831
899
  "badgeGenerating": "CUIYUW_badgeGenerating",
832
- "workflowDotDone": "CUIYUW_workflowDotDone",
833
- "bookAdd": "CUIYUW_bookAdd",
834
- "toolStepName": "CUIYUW_toolStepName",
835
- "volumeGroupToggle": "CUIYUW_volumeGroupToggle",
836
- "dashHeroActionBody": "CUIYUW_dashHeroActionBody",
837
- "wsSelected": "CUIYUW_wsSelected",
838
- "navAboutUpdate": "CUIYUW_navAboutUpdate",
839
- "chapterList": "CUIYUW_chapterList",
840
- "dashGrid": "CUIYUW_dashGrid",
841
- "dashJourney": "CUIYUW_dashJourney",
842
- "assistantFloatHeader": "CUIYUW_assistantFloatHeader",
843
- "assistantFloat": "CUIYUW_assistantFloat",
844
- "bookCardCover": "CUIYUW_bookCardCover",
845
- "dashStageCurrent": "CUIYUW_dashStageCurrent",
846
900
  "progressLineLive": "CUIYUW_progressLineLive",
847
- "diffDel": "CUIYUW_diffDel",
848
- "dashHeroTitle": "CUIYUW_dashHeroTitle",
849
- "createBookCard": "CUIYUW_createBookCard",
850
- "shelfView": "CUIYUW_shelfView",
851
- "createBookIcon": "CUIYUW_createBookIcon",
852
- "createBookTitle": "CUIYUW_createBookTitle",
853
- "navGroupLabel": "CUIYUW_navGroupLabel",
854
- "textarea": "CUIYUW_textarea",
901
+ "volumeGroupHeader": "CUIYUW_volumeGroupHeader",
902
+ "toolStepName": "CUIYUW_toolStepName",
903
+ "buttonPrimary": "CUIYUW_buttonPrimary",
904
+ "createBookTop": "CUIYUW_createBookTop",
905
+ "workflowLabel": "CUIYUW_workflowLabel",
906
+ "dashHero": "CUIYUW_dashHero",
907
+ "navAboutRow": "CUIYUW_navAboutRow",
908
+ "onlyChanges": "CUIYUW_onlyChanges",
909
+ "workflowHint": "CUIYUW_workflowHint",
910
+ "shelfEmptyTitle": "CUIYUW_shelfEmptyTitle",
911
+ "workflowBody": "CUIYUW_workflowBody",
912
+ "workflowDotDone": "CUIYUW_workflowDotDone",
913
+ "chapterTitle": "CUIYUW_chapterTitle",
855
914
  "row": "CUIYUW_row",
856
- "headerProgressDot": "CUIYUW_headerProgressDot",
857
- "buttonDanger": "CUIYUW_buttonDanger",
858
- "assetStatDetail": "CUIYUW_assetStatDetail",
859
- "assistantStatus": "CUIYUW_assistantStatus",
860
- "badgeDone": "CUIYUW_badgeDone",
861
- "navTabBadgeWarn": "CUIYUW_navTabBadgeWarn",
862
- "wsEditor": "CUIYUW_wsEditor",
863
- "chapterMain": "CUIYUW_chapterMain",
864
- "progressBar": "CUIYUW_progressBar",
865
- "chapter": "CUIYUW_chapter",
866
- "navTabBadgeDone": "CUIYUW_navTabBadgeDone",
867
- "diffLegend": "CUIYUW_diffLegend",
868
915
  "diffSameBody": "CUIYUW_diffSameBody",
916
+ "diffChange": "CUIYUW_diffChange",
917
+ "bookCardTitleRow": "CUIYUW_bookCardTitleRow",
918
+ "readerChapterMeta": "CUIYUW_readerChapterMeta",
919
+ "navAboutUpdate": "CUIYUW_navAboutUpdate",
920
+ "wsEditor": "CUIYUW_wsEditor",
921
+ "workflowList": "CUIYUW_workflowList",
922
+ "readerError": "CUIYUW_readerError",
923
+ "diffSame": "CUIYUW_diffSame",
924
+ "assistantFloatBody": "CUIYUW_assistantFloatBody",
925
+ "bookCard": "CUIYUW_bookCard",
926
+ "assistantResize": "CUIYUW_assistantResize",
927
+ "navGroupLabel": "CUIYUW_navGroupLabel",
928
+ "liveText": "CUIYUW_liveText",
929
+ "dashJourneyBar": "CUIYUW_dashJourneyBar",
930
+ "readerHeader": "CUIYUW_readerHeader",
931
+ "reviewBox": "CUIYUW_reviewBox",
932
+ "input": "CUIYUW_input",
933
+ "dashHeroActionBody": "CUIYUW_dashHeroActionBody",
934
+ "bookChipMeta": "CUIYUW_bookChipMeta",
935
+ "dashStageCurrent": "CUIYUW_dashStageCurrent",
936
+ "bigProgressBar": "CUIYUW_bigProgressBar",
869
937
  "diffList": "CUIYUW_diffList",
870
- "wsSelectedText": "CUIYUW_wsSelectedText",
871
- "dashStage": "CUIYUW_dashStage",
872
- "shelfHeader": "CUIYUW_shelfHeader",
938
+ "wsColumns": "CUIYUW_wsColumns",
939
+ "navGroupSep": "CUIYUW_navGroupSep",
940
+ "readerBody": "CUIYUW_readerBody",
941
+ "dashFact": "CUIYUW_dashFact",
873
942
  "bookCardCoverTitle": "CUIYUW_bookCardCoverTitle",
874
- "progressLineDone": "CUIYUW_progressLineDone",
875
- "bookshelfList": "CUIYUW_bookshelfList",
943
+ "field": "CUIYUW_field",
944
+ "assistantStatusBusy": "CUIYUW_assistantStatusBusy",
945
+ "toolStepStatus": "CUIYUW_toolStepStatus",
946
+ "todoInfo": "CUIYUW_todoInfo",
947
+ "badgeError": "CUIYUW_badgeError",
948
+ "dashHeroSparkle": "CUIYUW_dashHeroSparkle",
949
+ "bookCardActions": "CUIYUW_bookCardActions",
950
+ "dashJourney": "CUIYUW_dashJourney",
951
+ "diffOld": "CUIYUW_diffOld",
876
952
  "dropzone": "CUIYUW_dropzone",
953
+ "navBadgePulse": "CUIYUW_navBadgePulse",
954
+ "dashGrid": "CUIYUW_dashGrid",
877
955
  "entryIcon": "CUIYUW_entryIcon",
878
- "chapterBeats": "CUIYUW_chapterBeats",
879
- "dashStageDot": "CUIYUW_dashStageDot",
880
- "bookCard": "CUIYUW_bookCard",
881
- "chapterTitle": "CUIYUW_chapterTitle",
882
- "view": "CUIYUW_view",
956
+ "shelfEmptyIcon": "CUIYUW_shelfEmptyIcon",
957
+ "readerGroupCount": "CUIYUW_readerGroupCount",
958
+ "navTabIcon": "CUIYUW_navTabIcon",
959
+ "meta": "CUIYUW_meta",
960
+ "chapter": "CUIYUW_chapter",
961
+ "dashHeroEyebrow": "CUIYUW_dashHeroEyebrow",
962
+ "dashJourneyStages": "CUIYUW_dashJourneyStages",
963
+ "readerItem": "CUIYUW_readerItem",
964
+ "assistantStatus": "CUIYUW_assistantStatus",
965
+ "chapterPreview": "CUIYUW_chapterPreview",
966
+ "wsPageHeader": "CUIYUW_wsPageHeader",
967
+ "todoText": "CUIYUW_todoText",
968
+ "shelfTitleRow": "CUIYUW_shelfTitleRow",
969
+ "coverPreview": "CUIYUW_coverPreview",
970
+ "workflowDotActive": "CUIYUW_workflowDotActive",
971
+ "toolSteps": "CUIYUW_toolSteps",
972
+ "bookChipRemove": "CUIYUW_bookChipRemove",
973
+ "panelNav": "CUIYUW_panelNav",
974
+ "readerSegActive": "CUIYUW_readerSegActive",
975
+ "readerText": "CUIYUW_readerText",
976
+ "headerProgress": "CUIYUW_headerProgress",
977
+ "dashJourneyFill": "CUIYUW_dashJourneyFill",
978
+ "readerItemBadge": "CUIYUW_readerItemBadge",
979
+ "readerGroup": "CUIYUW_readerGroup",
980
+ "navGroup": "CUIYUW_navGroup",
981
+ "readerSidebar": "CUIYUW_readerSidebar",
982
+ "toolLive": "CUIYUW_toolLive",
983
+ "workflowDot": "CUIYUW_workflowDot",
984
+ "button": "CUIYUW_button",
985
+ "bookCreateOutline": "CUIYUW_bookCreateOutline",
986
+ "bookshelfList": "CUIYUW_bookshelfList",
987
+ "navTabBadgeDanger": "CUIYUW_navTabBadgeDanger",
988
+ "bookCardBlurb": "CUIYUW_bookCardBlurb",
989
+ "readerItemTitle": "CUIYUW_readerItemTitle",
990
+ "bookshelf": "CUIYUW_bookshelf",
991
+ "wsAppliedBanner": "CUIYUW_wsAppliedBanner",
992
+ "ideaCard": "CUIYUW_ideaCard",
993
+ "pulse": "CUIYUW_pulse",
994
+ "diffAdd": "CUIYUW_diffAdd",
883
995
  "navSpacer": "CUIYUW_navSpacer",
884
- "panelBody": "CUIYUW_panelBody",
996
+ "volumeGroupToggle": "CUIYUW_volumeGroupToggle",
997
+ "navTabLabel": "CUIYUW_navTabLabel",
998
+ "navTabBadgeDone": "CUIYUW_navTabBadgeDone",
999
+ "cardTitle": "CUIYUW_cardTitle",
1000
+ "assetStatDetail": "CUIYUW_assetStatDetail",
1001
+ "card": "CUIYUW_card",
1002
+ "dashHeroTitle": "CUIYUW_dashHeroTitle",
1003
+ "navTabBadgeWarn": "CUIYUW_navTabBadgeWarn",
1004
+ "coverPlaceholder": "CUIYUW_coverPlaceholder",
1005
+ "createBookTitle": "CUIYUW_createBookTitle",
1006
+ "tabBar": "CUIYUW_tabBar",
1007
+ "progressLineError": "CUIYUW_progressLineError",
885
1008
  "panelNavCollapsed": "CUIYUW_panelNavCollapsed",
886
- "navTabBadgeDanger": "CUIYUW_navTabBadgeDanger",
887
- "toolStepDetail": "CUIYUW_toolStepDetail",
888
- "diffColumn": "CUIYUW_diffColumn",
889
- "wsColumns": "CUIYUW_wsColumns",
890
- "bookCardActive": "CUIYUW_bookCardActive",
891
- "wsPreviewText": "CUIYUW_wsPreviewText",
892
- "bookAddIcon": "CUIYUW_bookAddIcon",
1009
+ "panelSubtitle": "CUIYUW_panelSubtitle",
1010
+ "buttonSmall": "CUIYUW_buttonSmall",
893
1011
  "panelTitle": "CUIYUW_panelTitle",
894
- "busyRow": "CUIYUW_busyRow",
895
- "bookCardCoverFallback": "CUIYUW_bookCardCoverFallback",
896
- "reviewBox": "CUIYUW_reviewBox",
897
- "meta": "CUIYUW_meta",
898
- "workflowBody": "CUIYUW_workflowBody",
899
- "assistantFloatBody": "CUIYUW_assistantFloatBody",
900
- "workflowList": "CUIYUW_workflowList",
901
- "bookshelfLabel": "CUIYUW_bookshelfLabel",
1012
+ "readerItemNo": "CUIYUW_readerItemNo",
1013
+ "readerTitle": "CUIYUW_readerTitle",
1014
+ "navTab": "CUIYUW_navTab",
1015
+ "shelfHeader": "CUIYUW_shelfHeader",
1016
+ "shelfFilters": "CUIYUW_shelfFilters",
1017
+ "shelfEmpty": "CUIYUW_shelfEmpty",
1018
+ "badgeDone": "CUIYUW_badgeDone",
1019
+ "diffLegend": "CUIYUW_diffLegend",
1020
+ "readerSegBtn": "CUIYUW_readerSegBtn",
1021
+ "spaceBetween": "CUIYUW_spaceBetween",
1022
+ "todoDanger": "CUIYUW_todoDanger",
1023
+ "createBookCard": "CUIYUW_createBookCard",
1024
+ "entryLabel": "CUIYUW_entryLabel",
902
1025
  "bookChipActive": "CUIYUW_bookChipActive",
903
- "assistantResize": "CUIYUW_assistantResize",
904
- "chatRole": "CUIYUW_chatRole",
905
- "wsPageHeader": "CUIYUW_wsPageHeader",
906
- "legendOld": "CUIYUW_legendOld",
907
- "bookCardProgressBar": "CUIYUW_bookCardProgressBar",
1026
+ "chapterFocus": "CUIYUW_chapterFocus",
1027
+ "badge": "CUIYUW_badge",
1028
+ "toolStep": "CUIYUW_toolStep",
1029
+ "busyRow": "CUIYUW_busyRow",
1030
+ "diffTagOld": "CUIYUW_diffTagOld",
1031
+ "textarea": "CUIYUW_textarea",
1032
+ "dashHeroArrow": "CUIYUW_dashHeroArrow",
1033
+ "shelfSearch": "CUIYUW_shelfSearch",
1034
+ "bookCardCover": "CUIYUW_bookCardCover",
1035
+ "bookCreateCard": "CUIYUW_bookCreateCard",
1036
+ "fadeIn": "CUIYUW_fadeIn",
1037
+ "view": "CUIYUW_view",
1038
+ "assistantFloat": "CUIYUW_assistantFloat",
1039
+ "readerGroupTitle": "CUIYUW_readerGroupTitle",
908
1040
  "tab": "CUIYUW_tab",
909
- "button": "CUIYUW_button",
910
- "volumeGroup": "CUIYUW_volumeGroup",
911
- "entryLabel": "CUIYUW_entryLabel",
912
- "dashHeroBook": "CUIYUW_dashHeroBook",
913
- "badgeRejected": "CUIYUW_badgeRejected",
914
- "workflowDot": "CUIYUW_workflowDot",
915
- "panel": "CUIYUW_panel",
916
- "navGroup": "CUIYUW_navGroup",
917
- "navAbout": "CUIYUW_navAbout",
918
- "navTabBadge": "CUIYUW_navTabBadge",
919
- "field": "CUIYUW_field",
920
- "volumeGroupHeader": "CUIYUW_volumeGroupHeader",
921
- "toolLive": "CUIYUW_toolLive",
922
- "toolSteps": "CUIYUW_toolSteps",
923
- "bigProgressBar": "CUIYUW_bigProgressBar",
924
1041
  "diffTagNew": "CUIYUW_diffTagNew",
925
- "outlineReadonly": "CUIYUW_outlineReadonly",
1042
+ "todoWarning": "CUIYUW_todoWarning",
1043
+ "toolStepIcon": "CUIYUW_toolStepIcon",
1044
+ "assetStat": "CUIYUW_assetStat",
1045
+ "readerSeg": "CUIYUW_readerSeg",
1046
+ "ideaCandidate": "CUIYUW_ideaCandidate",
1047
+ "assetStatValue": "CUIYUW_assetStatValue",
1048
+ "legendNew": "CUIYUW_legendNew",
1049
+ "bookshelfLabel": "CUIYUW_bookshelfLabel",
1050
+ "wsPreviewText": "CUIYUW_wsPreviewText",
1051
+ "panelHeader": "CUIYUW_panelHeader",
1052
+ "wsSelected": "CUIYUW_wsSelected",
1053
+ "assistantFloatHeader": "CUIYUW_assistantFloatHeader",
1054
+ "readerFoot": "CUIYUW_readerFoot",
1055
+ "navTabBadgeLive": "CUIYUW_navTabBadgeLive",
1056
+ "panel": "CUIYUW_panel",
1057
+ "readerMain": "CUIYUW_readerMain",
1058
+ "chapterNum": "CUIYUW_chapterNum",
1059
+ "bookCardProgressBar": "CUIYUW_bookCardProgressBar",
926
1060
  "bookCardBody": "CUIYUW_bookCardBody",
927
- "bookCardTitleRow": "CUIYUW_bookCardTitleRow",
1061
+ "ideaToggle": "CUIYUW_ideaToggle",
1062
+ "progressLine": "CUIYUW_progressLine",
928
1063
  "diffNew": "CUIYUW_diffNew",
929
- "bookCardProgressFill": "CUIYUW_bookCardProgressFill",
930
- "headerProgress": "CUIYUW_headerProgress",
931
- "progressLineError": "CUIYUW_progressLineError",
932
- "diffAdd": "CUIYUW_diffAdd",
933
- "assetStatValue": "CUIYUW_assetStatValue",
1064
+ "bigProgressBarFill": "CUIYUW_bigProgressBarFill",
934
1065
  "workflowRow": "CUIYUW_workflowRow",
935
- "fadeIn": "CUIYUW_fadeIn",
1066
+ "dashHeroBook": "CUIYUW_dashHeroBook",
1067
+ "shelfToolbar": "CUIYUW_shelfToolbar",
1068
+ "readerLoading": "CUIYUW_readerLoading",
1069
+ "readerPara": "CUIYUW_readerPara",
1070
+ "shelfGrid": "CUIYUW_shelfGrid",
1071
+ "chapterList": "CUIYUW_chapterList",
1072
+ "dashStageDot": "CUIYUW_dashStageDot",
1073
+ "createBookIcon": "CUIYUW_createBookIcon",
936
1074
  "chatBubbleUser": "CUIYUW_chatBubbleUser",
937
- "bookChipName": "CUIYUW_bookChipName",
938
- "dropzoneIcon": "CUIYUW_dropzoneIcon",
939
- "panelSubtitle": "CUIYUW_panelSubtitle",
1075
+ "outlineReadonly": "CUIYUW_outlineReadonly",
1076
+ "genreDesc": "CUIYUW_genreDesc",
1077
+ "progressBarFill": "CUIYUW_progressBarFill",
1078
+ "readerView": "CUIYUW_readerView",
940
1079
  "entry": "CUIYUW_entry",
941
- "panelContent": "CUIYUW_panelContent",
942
- "buttonSmall": "CUIYUW_buttonSmall",
943
- "fieldLabel": "CUIYUW_fieldLabel",
944
- "todoDanger": "CUIYUW_todoDanger",
945
- "dropzoneActive": "CUIYUW_dropzoneActive",
946
- "cardTitle": "CUIYUW_cardTitle",
947
- "chatBubbleAssistant": "CUIYUW_chatBubbleAssistant",
948
- "spaceBetween": "CUIYUW_spaceBetween",
949
- "badgeError": "CUIYUW_badgeError",
1080
+ "progress": "CUIYUW_progress",
950
1081
  "toolStepActive": "CUIYUW_toolStepActive",
951
- "dashJourneyBar": "CUIYUW_dashJourneyBar",
952
- "progress": "CUIYUW_progress",
953
- "dashJourneyStages": "CUIYUW_dashJourneyStages",
954
- "navTabIcon": "CUIYUW_navTabIcon",
955
- "diffTagOld": "CUIYUW_diffTagOld",
956
- "navAboutRow": "CUIYUW_navAboutRow",
957
- "bookCreateForm": "CUIYUW_bookCreateForm",
958
- "bookCardName": "CUIYUW_bookCardName",
959
- "chapterPreview": "CUIYUW_chapterPreview",
960
- "assetStat": "CUIYUW_assetStat",
961
- "pulse": "CUIYUW_pulse",
962
- "bookCardBlurb": "CUIYUW_bookCardBlurb",
963
- "workflowDotActive": "CUIYUW_workflowDotActive",
964
- "bookshelf": "CUIYUW_bookshelf",
965
- "dashHeroActionTitle": "CUIYUW_dashHeroActionTitle",
966
- "diffOld": "CUIYUW_diffOld",
967
- "bookAddCard": "CUIYUW_bookAddCard",
1082
+ "chatScroll": "CUIYUW_chatScroll",
1083
+ "legendOld": "CUIYUW_legendOld",
1084
+ "volumeGroup": "CUIYUW_volumeGroup",
1085
+ "navTabBadge": "CUIYUW_navTabBadge",
1086
+ "diffText": "CUIYUW_diffText",
1087
+ "dashStage": "CUIYUW_dashStage",
1088
+ "readerArticle": "CUIYUW_readerArticle",
1089
+ "shelfView": "CUIYUW_shelfView",
968
1090
  "fileList": "CUIYUW_fileList",
969
- "dashHero": "CUIYUW_dashHero",
970
- "workflowHint": "CUIYUW_workflowHint",
971
- "wsColumn": "CUIYUW_wsColumn",
972
- "bookCreateOutline": "CUIYUW_bookCreateOutline",
973
- "diffChange": "CUIYUW_diffChange",
974
- "progressBarFill": "CUIYUW_progressBarFill",
975
- "liveText": "CUIYUW_liveText",
976
- "shelfGrid": "CUIYUW_shelfGrid",
977
- "iconButton": "CUIYUW_iconButton",
1091
+ "buttonDanger": "CUIYUW_buttonDanger",
1092
+ "wsPage": "CUIYUW_wsPage",
978
1093
  "todoItem": "CUIYUW_todoItem",
979
- "badgePending": "CUIYUW_badgePending",
1094
+ "fieldLabel": "CUIYUW_fieldLabel",
1095
+ "chapterBeats": "CUIYUW_chapterBeats",
1096
+ "badgeRejected": "CUIYUW_badgeRejected",
1097
+ "diffColumn": "CUIYUW_diffColumn",
980
1098
  "assetStatLabel": "CUIYUW_assetStatLabel",
981
- "card": "CUIYUW_card",
982
- "chapterNum": "CUIYUW_chapterNum",
983
- "diffText": "CUIYUW_diffText",
984
- "dashFact": "CUIYUW_dashFact",
985
- "assetGrid": "CUIYUW_assetGrid",
986
- "assistantStatusBusy": "CUIYUW_assistantStatusBusy",
987
- "toolStep": "CUIYUW_toolStep",
988
- "badge": "CUIYUW_badge",
989
- "buttonPrimary": "CUIYUW_buttonPrimary",
990
- "toolStepStatus": "CUIYUW_toolStepStatus",
991
- "panelHeader": "CUIYUW_panelHeader",
992
- "bigProgressBarFill": "CUIYUW_bigProgressBarFill",
993
- "onlyChanges": "CUIYUW_onlyChanges",
994
- "wsPreview": "CUIYUW_wsPreview",
995
- "dashHeroEyebrow": "CUIYUW_dashHeroEyebrow",
1099
+ "bookChip": "CUIYUW_bookChip",
1100
+ "chatBubbleAssistant": "CUIYUW_chatBubbleAssistant",
1101
+ "toolStepDetail": "CUIYUW_toolStepDetail",
996
1102
  "toolStepError": "CUIYUW_toolStepError",
997
- "dashHeroArrow": "CUIYUW_dashHeroArrow",
998
- "chapterActions": "CUIYUW_chapterActions",
999
- "todoWarning": "CUIYUW_todoWarning",
1000
- "navGroupSep": "CUIYUW_navGroupSep",
1001
- "todoInfo": "CUIYUW_todoInfo",
1002
- "wsPage": "CUIYUW_wsPage",
1003
- "coverPreview": "CUIYUW_coverPreview",
1004
- "badgeWritten": "CUIYUW_badgeWritten",
1005
- "dashHeroAction": "CUIYUW_dashHeroAction",
1006
- "bookCreateCard": "CUIYUW_bookCreateCard",
1103
+ "wsPreview": "CUIYUW_wsPreview",
1104
+ "diffDel": "CUIYUW_diffDel",
1105
+ "readerGroupArrow": "CUIYUW_readerGroupArrow",
1106
+ "bookCardCoverFallback": "CUIYUW_bookCardCoverFallback",
1107
+ "bookAdd": "CUIYUW_bookAdd",
1108
+ "dropzoneActive": "CUIYUW_dropzoneActive",
1109
+ "dropzoneIcon": "CUIYUW_dropzoneIcon",
1110
+ "readerChapterTitle": "CUIYUW_readerChapterTitle",
1111
+ "bookCardMetaRow": "CUIYUW_bookCardMetaRow",
1112
+ "bookAddIcon": "CUIYUW_bookAddIcon",
1113
+ "badgePending": "CUIYUW_badgePending",
1007
1114
  "dashStageDone": "CUIYUW_dashStageDone",
1008
- "dashHeroSparkle": "CUIYUW_dashHeroSparkle",
1009
- "dashFacts": "CUIYUW_dashFacts",
1010
- "toolStepIcon": "CUIYUW_toolStepIcon",
1011
- "createBookTop": "CUIYUW_createBookTop",
1012
- "genreDesc": "CUIYUW_genreDesc",
1013
- "bookChip": "CUIYUW_bookChip",
1014
- "navTab": "CUIYUW_navTab",
1015
- "bookChipMeta": "CUIYUW_bookChipMeta",
1016
- "progressLine": "CUIYUW_progressLine",
1017
- "panelNav": "CUIYUW_panelNav",
1018
- "dashJourneyFill": "CUIYUW_dashJourneyFill",
1019
- "diffSame": "CUIYUW_diffSame",
1020
- "workflowLabel": "CUIYUW_workflowLabel",
1021
- "bookChipRemove": "CUIYUW_bookChipRemove",
1022
- "input": "CUIYUW_input",
1023
- "navTabLabel": "CUIYUW_navTabLabel",
1024
- "todoText": "CUIYUW_todoText",
1025
- "chatScroll": "CUIYUW_chatScroll",
1026
- "legendNew": "CUIYUW_legendNew",
1027
- "coverPlaceholder": "CUIYUW_coverPlaceholder"
1115
+ "progressLineDone": "CUIYUW_progressLineDone",
1116
+ "bookAddCard": "CUIYUW_bookAddCard",
1117
+ "chapterMain": "CUIYUW_chapterMain",
1118
+ "wsColumn": "CUIYUW_wsColumn",
1119
+ "chapterActions": "CUIYUW_chapterActions",
1120
+ "bookCardProgressFill": "CUIYUW_bookCardProgressFill"
1028
1121
  };
1029
1122
  //#endregion
1030
1123
  //#region src/client/panel/AssistantTab.tsx
@@ -2244,11 +2337,30 @@ window.__ModuleLoader__.load({
2244
2337
  //#endregion
2245
2338
  //#region src/client/panel/ShelfView.tsx
2246
2339
  /**
2247
- * 书架首页视图:书卡网格(封面/书名/简介/进度)+ 开书入口。
2340
+ * 书架首页视图:书卡网格(封面/书名/简介/进度)+ 搜索筛选 + 开书入口。
2248
2341
  * 进入小说工坊默认展示;点击书卡进入该书工作台,+ 进入开书向导页。
2249
2342
  */
2343
+ /** 相对时间(人性化:刚刚 / N 分钟前 / N 小时前 / N 天前 / 日期)。 */
2344
+ function relativeTime(iso) {
2345
+ const t = new Date(iso).getTime();
2346
+ if (!Number.isFinite(t)) return "—";
2347
+ const diff = Date.now() - t;
2348
+ if (diff < 6e4) return "刚刚";
2349
+ if (diff < 36e5) return `${Math.floor(diff / 6e4)} 分钟前`;
2350
+ if (diff < 864e5) return `${Math.floor(diff / 36e5)} 小时前`;
2351
+ if (diff < 7 * 864e5) return `${Math.floor(diff / 864e5)} 天前`;
2352
+ return new Date(t).toLocaleDateString("zh-CN", {
2353
+ month: "numeric",
2354
+ day: "numeric"
2355
+ });
2356
+ }
2357
+ /** 一本书的状态标签。 */
2358
+ function bookStatus(book) {
2359
+ if (!book.hasProject) return "none";
2360
+ return book.total > 0 && book.done >= book.total ? "done" : "active";
2361
+ }
2250
2362
  /** 一张书卡(封面懒加载)。 */
2251
- function BookCard({ api, book, active, onOpen }) {
2363
+ function BookCard({ api, book, active, onOpen, onRead }) {
2252
2364
  const [cover, setCover] = (0, react.useState)(null);
2253
2365
  (0, react.useEffect)(() => {
2254
2366
  if (!book.hasCover) return;
@@ -2265,7 +2377,8 @@ window.__ModuleLoader__.load({
2265
2377
  book.outputDir
2266
2378
  ]);
2267
2379
  const ratio = book.total > 0 ? Math.min(book.done / book.total, 1) : 0;
2268
- const statusLabel = !book.hasProject ? "未开书" : book.total > 0 && book.done >= book.total ? "已完结" : "进行中";
2380
+ const status = bookStatus(book);
2381
+ const statusLabel = status === "none" ? "未开书" : status === "done" ? "已完结" : "进行中";
2269
2382
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2270
2383
  className: `${panel_module_css_default.bookCard} ${active ? panel_module_css_default.bookCardActive : ""}`,
2271
2384
  onClick: onOpen,
@@ -2294,7 +2407,7 @@ window.__ModuleLoader__.load({
2294
2407
  className: panel_module_css_default.bookCardName,
2295
2408
  children: book.bookName
2296
2409
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2297
- className: `${panel_module_css_default.badge} ${book.hasProject ? book.total > 0 && book.done >= book.total ? panel_module_css_default.badgeDone : panel_module_css_default.badgeWritten : panel_module_css_default.badgePending}`,
2410
+ className: `${panel_module_css_default.badge} ${status === "none" ? panel_module_css_default.badgePending : status === "done" ? panel_module_css_default.badgeDone : panel_module_css_default.badgeWritten}`,
2298
2411
  children: statusLabel
2299
2412
  })]
2300
2413
  }),
@@ -2310,36 +2423,189 @@ window.__ModuleLoader__.load({
2310
2423
  style: { width: `${Math.round(ratio * 100)}%` }
2311
2424
  })
2312
2425
  }),
2313
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2314
- className: panel_module_css_default.meta,
2315
- children: book.total > 0 ? `已完成 ${book.done} / ${book.total} 章` : "尚未规划章节"
2426
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2427
+ className: panel_module_css_default.bookCardMetaRow,
2428
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2429
+ className: panel_module_css_default.meta,
2430
+ children: book.total > 0 ? `已完成 ${book.done} / ${book.total} 章` : "尚未规划章节"
2431
+ }), book.hasProject && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2432
+ className: panel_module_css_default.meta,
2433
+ title: "最近活动时间",
2434
+ children: ["更新于 ", relativeTime(book.updatedAt)]
2435
+ })]
2436
+ }),
2437
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2438
+ className: panel_module_css_default.bookCardActions,
2439
+ onClick: (e) => {
2440
+ e.stopPropagation();
2441
+ },
2442
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2443
+ type: "button",
2444
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
2445
+ onClick: onOpen,
2446
+ title: "进入创作工作台(大纲/章节/审稿/设定)",
2447
+ children: "📝 进入工作台"
2448
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2449
+ type: "button",
2450
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
2451
+ disabled: !book.hasProject || book.done === 0,
2452
+ onClick: onRead,
2453
+ title: book.hasProject && book.done > 0 ? "沉浸式阅读已写章节" : "尚无已写章节,先去工作台创作",
2454
+ children: "📖 阅读"
2455
+ })]
2316
2456
  })
2317
2457
  ]
2318
2458
  })]
2319
2459
  });
2320
2460
  }
2321
2461
  /** 书架首页。 */
2322
- function ShelfView({ api, shelf, onOpenBook, onAddBook }) {
2462
+ function ShelfView({ api, shelf, onOpenBook, onReadBook, onAddBook }) {
2463
+ const [query, setQuery] = (0, react.useState)("");
2464
+ /** 筛选:all=全部 / active=进行中 / done=已完结 / none=未开书。 */
2465
+ const [filter, setFilter] = (0, react.useState)("all");
2466
+ const stats = (0, react.useMemo)(() => {
2467
+ let active = 0, done = 0, none = 0;
2468
+ for (const b of shelf.books) {
2469
+ const s = bookStatus(b);
2470
+ if (s === "none") none++;
2471
+ else if (s === "done") done++;
2472
+ else active++;
2473
+ }
2474
+ return {
2475
+ active,
2476
+ done,
2477
+ none
2478
+ };
2479
+ }, [shelf.books]);
2480
+ const visible = (0, react.useMemo)(() => {
2481
+ const q = query.trim().toLowerCase();
2482
+ return shelf.books.filter((b) => {
2483
+ if (filter !== "all" && bookStatus(b) !== filter) return false;
2484
+ if (q === "") return true;
2485
+ return b.bookName.toLowerCase().includes(q) || (b.blurb ?? "").toLowerCase().includes(q);
2486
+ });
2487
+ }, [
2488
+ shelf.books,
2489
+ query,
2490
+ filter
2491
+ ]);
2492
+ const filters = [
2493
+ {
2494
+ id: "all",
2495
+ label: "全部",
2496
+ count: shelf.books.length
2497
+ },
2498
+ {
2499
+ id: "active",
2500
+ label: "进行中",
2501
+ count: stats.active
2502
+ },
2503
+ {
2504
+ id: "done",
2505
+ label: "已完结",
2506
+ count: stats.done
2507
+ },
2508
+ {
2509
+ id: "none",
2510
+ label: "未开书",
2511
+ count: stats.none
2512
+ }
2513
+ ];
2323
2514
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2324
2515
  className: panel_module_css_default.shelfView,
2325
2516
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2326
2517
  className: panel_module_css_default.shelfHeader,
2327
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
2328
- className: panel_module_css_default.panelTitle,
2329
- style: { margin: 0 },
2330
- children: "📚 书架"
2331
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2332
- className: panel_module_css_default.meta,
2333
- children: "选择一本书进入工作台,或开一本新书"
2518
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2519
+ className: panel_module_css_default.shelfTitleRow,
2520
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
2521
+ className: panel_module_css_default.panelTitle,
2522
+ style: { margin: 0 },
2523
+ children: "📚 书架"
2524
+ }), shelf.books.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2525
+ className: panel_module_css_default.meta,
2526
+ children: [
2527
+ shelf.books.length,
2528
+ " 本书 · ",
2529
+ stats.active,
2530
+ " 进行中 · ",
2531
+ stats.done,
2532
+ " 已完结 · ",
2533
+ stats.none,
2534
+ " 未开书"
2535
+ ]
2536
+ })]
2537
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2538
+ className: panel_module_css_default.shelfToolbar,
2539
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2540
+ className: `${panel_module_css_default.input} ${panel_module_css_default.shelfSearch}`,
2541
+ type: "search",
2542
+ placeholder: "🔍 搜索书名 / 简介…",
2543
+ value: query,
2544
+ onChange: (e) => {
2545
+ setQuery(e.target.value);
2546
+ }
2547
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2548
+ className: panel_module_css_default.shelfFilters,
2549
+ children: filters.map((f) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2550
+ type: "button",
2551
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${filter === f.id ? panel_module_css_default.buttonPrimary : ""}`,
2552
+ onClick: () => {
2553
+ setFilter(f.id);
2554
+ },
2555
+ children: [f.label, f.count > 0 ? `(${f.count})` : ""]
2556
+ }, f.id))
2557
+ })]
2334
2558
  })]
2335
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2559
+ }), shelf.books.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2560
+ className: panel_module_css_default.shelfEmpty,
2561
+ children: [
2562
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2563
+ className: panel_module_css_default.shelfEmptyIcon,
2564
+ children: "📖"
2565
+ }),
2566
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2567
+ className: panel_module_css_default.shelfEmptyTitle,
2568
+ children: "你的创作从这里开始"
2569
+ }),
2570
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2571
+ className: panel_module_css_default.meta,
2572
+ children: "开一本书:粘贴大纲或导入 docx,书名自动识别,开书即建项目"
2573
+ }),
2574
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2575
+ type: "button",
2576
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
2577
+ onClick: onAddBook,
2578
+ children: "+ 开第一本书"
2579
+ })
2580
+ ]
2581
+ }) : visible.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2582
+ className: panel_module_css_default.shelfEmpty,
2583
+ style: { minHeight: 160 },
2584
+ children: [
2585
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2586
+ className: panel_module_css_default.shelfEmptyIcon,
2587
+ children: "🔍"
2588
+ }),
2589
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2590
+ className: panel_module_css_default.shelfEmptyTitle,
2591
+ children: "没有符合条件的书"
2592
+ }),
2593
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2594
+ className: panel_module_css_default.meta,
2595
+ children: "换个关键词或筛选条件试试"
2596
+ })
2597
+ ]
2598
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2336
2599
  className: panel_module_css_default.shelfGrid,
2337
- children: [shelf.books.map((book) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BookCard, {
2600
+ children: [visible.map((book) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BookCard, {
2338
2601
  api,
2339
2602
  book,
2340
2603
  active: book.id === shelf.activeBookId,
2341
2604
  onOpen: () => {
2342
2605
  onOpenBook(book.id);
2606
+ },
2607
+ onRead: () => {
2608
+ onReadBook(book.id);
2343
2609
  }
2344
2610
  }, book.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2345
2611
  className: `${panel_module_css_default.bookCard} ${panel_module_css_default.bookAddCard}`,
@@ -2360,89 +2626,551 @@ window.__ModuleLoader__.load({
2360
2626
  });
2361
2627
  }
2362
2628
  //#endregion
2363
- //#region node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/browser.js
2364
- var u8 = Uint8Array;
2365
- var u16 = Uint16Array;
2366
- var i32 = Int32Array;
2367
- var fleb = new u8([
2368
- 0,
2369
- 0,
2370
- 0,
2371
- 0,
2372
- 0,
2373
- 0,
2374
- 0,
2375
- 0,
2376
- 1,
2377
- 1,
2378
- 1,
2379
- 1,
2380
- 2,
2381
- 2,
2382
- 2,
2383
- 2,
2384
- 3,
2385
- 3,
2386
- 3,
2387
- 3,
2388
- 4,
2389
- 4,
2390
- 4,
2391
- 4,
2392
- 5,
2393
- 5,
2394
- 5,
2395
- 5,
2396
- 0,
2397
- 0,
2398
- 0,
2399
- 0
2400
- ]);
2401
- var fdeb = new u8([
2402
- 0,
2403
- 0,
2404
- 0,
2405
- 0,
2406
- 1,
2407
- 1,
2408
- 2,
2409
- 2,
2410
- 3,
2411
- 3,
2412
- 4,
2413
- 4,
2414
- 5,
2415
- 5,
2416
- 6,
2417
- 6,
2418
- 7,
2419
- 7,
2420
- 8,
2421
- 8,
2422
- 9,
2423
- 9,
2424
- 10,
2425
- 10,
2426
- 11,
2427
- 11,
2428
- 12,
2429
- 12,
2430
- 13,
2431
- 13,
2432
- 0,
2433
- 0
2434
- ]);
2435
- var clim = new u8([
2436
- 16,
2437
- 17,
2438
- 18,
2439
- 0,
2440
- 8,
2441
- 7,
2442
- 9,
2443
- 6,
2444
- 10,
2445
- 5,
2629
+ //#region src/client/panel/ReaderView.tsx
2630
+ /**
2631
+ * 阅读页:沉浸式章节阅读(纯只读,零 LLM 消耗)。
2632
+ * 布局:顶部工具栏 + 左侧可折叠目录栏(按卷分组)+ 阅读区。
2633
+ * 轻量渲染:去掉 md 首行标题,按行分段;字号/主题/阅读进度 localStorage 记忆。
2634
+ */
2635
+ const FONT_SIZES = [
2636
+ {
2637
+ id: "sm",
2638
+ px: 15,
2639
+ label: "A-"
2640
+ },
2641
+ {
2642
+ id: "md",
2643
+ px: 17,
2644
+ label: "A"
2645
+ },
2646
+ {
2647
+ id: "lg",
2648
+ px: 20,
2649
+ label: "A+"
2650
+ }
2651
+ ];
2652
+ const THEMES = [
2653
+ {
2654
+ id: "paper",
2655
+ label: "📄 纸白",
2656
+ bg: "#f7f1e3",
2657
+ fg: "#3b3226",
2658
+ accent: "#8b6f47",
2659
+ dim: "#8a7d66"
2660
+ },
2661
+ {
2662
+ id: "eye",
2663
+ label: "🌿 护眼",
2664
+ bg: "#e8f0e3",
2665
+ fg: "#2f3d2e",
2666
+ accent: "#5f7d5a",
2667
+ dim: "#6f836b"
2668
+ },
2669
+ {
2670
+ id: "night",
2671
+ label: "🌙 夜间",
2672
+ bg: "#1d2226",
2673
+ fg: "#c9d1d9",
2674
+ accent: "#8aa5c0",
2675
+ dim: "#6d7882"
2676
+ }
2677
+ ];
2678
+ function readPref(key, fallback) {
2679
+ try {
2680
+ const raw = window.localStorage.getItem(key);
2681
+ if (raw !== null) return JSON.parse(raw);
2682
+ } catch {}
2683
+ return fallback;
2684
+ }
2685
+ function writePref(key, value) {
2686
+ try {
2687
+ window.localStorage.setItem(key, JSON.stringify(value));
2688
+ } catch {}
2689
+ }
2690
+ /** 章节状态小标(阅读视角)。 */
2691
+ function statusBadge$1(ch) {
2692
+ switch (ch.status) {
2693
+ case "approved": return {
2694
+ label: "✅",
2695
+ cls: panel_module_css_default.badgeDone
2696
+ };
2697
+ case "written": return {
2698
+ label: "📝",
2699
+ cls: panel_module_css_default.badgeWritten
2700
+ };
2701
+ case "rejected": return {
2702
+ label: "⚠️",
2703
+ cls: panel_module_css_default.badgePending
2704
+ };
2705
+ default: return {
2706
+ label: "",
2707
+ cls: panel_module_css_default.badgePending
2708
+ };
2709
+ }
2710
+ }
2711
+ /** 目录分组:按卷区间过滤可读章节;卷外章节归入「未分卷」。 */
2712
+ function buildGroups(project, readable) {
2713
+ const vols = project.volumes ?? [];
2714
+ if (vols.length === 0) return [{
2715
+ title: "全部章节",
2716
+ no: 0,
2717
+ chapters: readable
2718
+ }];
2719
+ const groups = [];
2720
+ for (const v of vols) {
2721
+ const inVol = readable.filter((c) => c.no >= v.chapterStart && c.no <= v.chapterEnd);
2722
+ if (inVol.length > 0) groups.push({
2723
+ title: `第${v.no}卷 ${v.title}`,
2724
+ no: v.no,
2725
+ chapters: inVol
2726
+ });
2727
+ }
2728
+ const rest = readable.filter((c) => !vols.some((v) => c.no >= v.chapterStart && c.no <= v.chapterEnd));
2729
+ if (rest.length > 0) groups.push({
2730
+ title: "未分卷",
2731
+ no: 0,
2732
+ chapters: rest
2733
+ });
2734
+ return groups;
2735
+ }
2736
+ function ReaderView({ api, project, onBack, onOpenWorkspace }) {
2737
+ const prefKey = (0, react.useMemo)(() => {
2738
+ return `dsh-novel-forge.reader.${project.bookName || "book"}`;
2739
+ }, [project.bookName]);
2740
+ /** 可读章节(有正文落盘):approved / written / rejected。 */
2741
+ const readable = (0, react.useMemo)(() => project.chapters.filter((c) => c.status === "approved" || c.status === "written" || c.status === "rejected"), [project.chapters]);
2742
+ const groups = (0, react.useMemo)(() => buildGroups(project, readable), [project, readable]);
2743
+ const [currentNo, setCurrentNo] = (0, react.useState)(() => {
2744
+ const saved = readPref(`${prefKey}.no`, null);
2745
+ if (saved !== null && readable.some((c) => c.no === saved)) return saved;
2746
+ return [...readable].reverse().find((c) => c.status === "approved")?.no ?? readable[0]?.no ?? 0;
2747
+ });
2748
+ const [markdown, setMarkdown] = (0, react.useState)("");
2749
+ const [loading, setLoading] = (0, react.useState)(false);
2750
+ const [loadError, setLoadError] = (0, react.useState)("");
2751
+ const [font, setFont] = (0, react.useState)(() => readPref(`${prefKey}.font`, "md"));
2752
+ const [theme, setTheme] = (0, react.useState)(() => readPref(`${prefKey}.theme`, "paper"));
2753
+ const [navOpen, setNavOpen] = (0, react.useState)(() => readPref(`${prefKey}.nav`, true));
2754
+ /** 折叠的卷号(点击卷标题切换;记忆在 localStorage)。 */
2755
+ const [collapsedVols, setCollapsedVols] = (0, react.useState)(() => readPref(`${prefKey}.collapsed`, []));
2756
+ const sidebarRef = (0, react.useRef)(null);
2757
+ const toggleVol = (0, react.useCallback)((no) => {
2758
+ setCollapsedVols((prev) => {
2759
+ const next = prev.includes(no) ? prev.filter((v) => v !== no) : [...prev, no];
2760
+ writePref(`${prefKey}.collapsed`, next);
2761
+ return next;
2762
+ });
2763
+ }, [prefKey]);
2764
+ const current = (0, react.useMemo)(() => project.chapters.find((c) => c.no === currentNo), [project.chapters, currentNo]);
2765
+ const idx = readable.findIndex((c) => c.no === currentNo);
2766
+ const prevCh = idx > 0 ? readable[idx - 1] : void 0;
2767
+ const nextCh = idx >= 0 && idx < readable.length - 1 ? readable[idx + 1] : void 0;
2768
+ const load = (0, react.useCallback)(async (no) => {
2769
+ if (no === 0) return;
2770
+ setLoading(true);
2771
+ setLoadError("");
2772
+ try {
2773
+ const res = await api.chapter(no);
2774
+ setMarkdown(res.markdown);
2775
+ setCurrentNo(no);
2776
+ writePref(`${prefKey}.no`, no);
2777
+ } catch (err) {
2778
+ setLoadError(err.message);
2779
+ } finally {
2780
+ setLoading(false);
2781
+ }
2782
+ }, [api, prefKey]);
2783
+ const initialNo = (0, react.useRef)(0);
2784
+ (0, react.useEffect)(() => {
2785
+ if (initialNo.current === currentNo && markdown !== "") return;
2786
+ if (currentNo === 0) return;
2787
+ initialNo.current = currentNo;
2788
+ load(currentNo);
2789
+ }, [
2790
+ currentNo,
2791
+ load,
2792
+ markdown
2793
+ ]);
2794
+ (0, react.useEffect)(() => {
2795
+ const onKey = (e) => {
2796
+ if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;
2797
+ if (e.key === "ArrowLeft" && prevCh !== void 0) load(prevCh.no);
2798
+ if (e.key === "ArrowRight" && nextCh !== void 0) load(nextCh.no);
2799
+ };
2800
+ window.addEventListener("keydown", onKey);
2801
+ return () => window.removeEventListener("keydown", onKey);
2802
+ }, [
2803
+ prevCh,
2804
+ nextCh,
2805
+ load
2806
+ ]);
2807
+ (0, react.useEffect)(() => {
2808
+ sidebarRef.current?.querySelector(`[data-no="${currentNo}"]`)?.scrollIntoView({
2809
+ block: "nearest",
2810
+ behavior: "smooth"
2811
+ });
2812
+ }, [currentNo]);
2813
+ const themeMeta = THEMES.find((t) => t.id === theme) ?? THEMES[0];
2814
+ const fontMeta = FONT_SIZES.find((f) => f.id === font) ?? FONT_SIZES[1];
2815
+ /** 轻量渲染:去标题行、按行分段(网文每行一段)。 */
2816
+ const paragraphs = (0, react.useMemo)(() => {
2817
+ return markdown.split(/\r?\n/).map((l) => l.replace(/^#{1,6}\s*/, "").trim()).filter(Boolean);
2818
+ }, [markdown]);
2819
+ const itemBg = theme === "night" ? "rgba(255,255,255,0.03)" : "rgba(0,0,0,0.025)";
2820
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2821
+ className: panel_module_css_default.readerView,
2822
+ style: {
2823
+ background: themeMeta.bg,
2824
+ color: themeMeta.fg
2825
+ },
2826
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2827
+ className: panel_module_css_default.readerHeader,
2828
+ style: { borderColor: themeMeta.dim },
2829
+ children: [
2830
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2831
+ type: "button",
2832
+ className: panel_module_css_default.iconButton,
2833
+ title: "返回书架",
2834
+ "aria-label": "返回书架",
2835
+ onClick: onBack,
2836
+ children: "←"
2837
+ }),
2838
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2839
+ className: panel_module_css_default.readerTitle,
2840
+ children: [
2841
+ "📖 《",
2842
+ project.bookName,
2843
+ "》"
2844
+ ]
2845
+ }),
2846
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2847
+ className: panel_module_css_default.meta,
2848
+ style: { color: themeMeta.dim },
2849
+ children: readable.length > 0 && currentNo > 0 ? `第 ${currentNo} 章 · ${idx + 1}/${readable.length}` : ""
2850
+ }),
2851
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2852
+ type: "button",
2853
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${navOpen ? panel_module_css_default.buttonPrimary : ""}`,
2854
+ style: { marginLeft: 4 },
2855
+ onClick: () => {
2856
+ setNavOpen((v) => {
2857
+ const next = !v;
2858
+ writePref(`${prefKey}.nav`, next);
2859
+ return next;
2860
+ });
2861
+ },
2862
+ title: navOpen ? "收起目录" : "展开目录",
2863
+ children: "☰ 目录"
2864
+ }),
2865
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: { flex: 1 } }),
2866
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2867
+ className: panel_module_css_default.meta,
2868
+ style: { color: themeMeta.dim },
2869
+ children: "字号"
2870
+ }),
2871
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2872
+ className: panel_module_css_default.readerSeg,
2873
+ children: FONT_SIZES.map((f) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2874
+ type: "button",
2875
+ className: `${panel_module_css_default.readerSegBtn} ${font === f.id ? panel_module_css_default.readerSegActive : ""}`,
2876
+ style: font === f.id ? {
2877
+ background: themeMeta.accent,
2878
+ color: themeMeta.bg
2879
+ } : void 0,
2880
+ onClick: () => {
2881
+ setFont(f.id);
2882
+ writePref(`${prefKey}.font`, f.id);
2883
+ },
2884
+ title: `字号 ${f.label}`,
2885
+ children: f.label
2886
+ }, f.id))
2887
+ }),
2888
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2889
+ className: panel_module_css_default.readerSeg,
2890
+ style: { marginLeft: 8 },
2891
+ children: THEMES.map((t) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2892
+ type: "button",
2893
+ className: `${panel_module_css_default.readerSegBtn} ${theme === t.id ? panel_module_css_default.readerSegActive : ""}`,
2894
+ style: theme === t.id ? {
2895
+ background: themeMeta.accent,
2896
+ color: themeMeta.bg
2897
+ } : void 0,
2898
+ onClick: () => {
2899
+ setTheme(t.id);
2900
+ writePref(`${prefKey}.theme`, t.id);
2901
+ },
2902
+ title: t.label,
2903
+ children: t.label
2904
+ }, t.id))
2905
+ }),
2906
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2907
+ type: "button",
2908
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
2909
+ style: { marginLeft: 10 },
2910
+ onClick: onOpenWorkspace,
2911
+ title: "回到创作工作台",
2912
+ children: "✏️ 去工作台"
2913
+ })
2914
+ ]
2915
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2916
+ className: panel_module_css_default.readerBody,
2917
+ children: [navOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
2918
+ className: panel_module_css_default.readerSidebar,
2919
+ style: {
2920
+ borderColor: themeMeta.dim,
2921
+ background: theme === "night" ? "rgba(0,0,0,0.25)" : "rgba(255,255,255,0.35)"
2922
+ },
2923
+ ref: sidebarRef,
2924
+ children: groups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2925
+ className: panel_module_css_default.meta,
2926
+ style: {
2927
+ color: themeMeta.dim,
2928
+ padding: 12
2929
+ },
2930
+ children: "还没有已写章节,先去工作台创作吧"
2931
+ }) : groups.map((g) => {
2932
+ const collapsed = collapsedVols.includes(g.no);
2933
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2934
+ className: panel_module_css_default.readerGroup,
2935
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2936
+ type: "button",
2937
+ className: panel_module_css_default.readerGroupTitle,
2938
+ style: { color: themeMeta.accent },
2939
+ onClick: () => {
2940
+ toggleVol(g.no);
2941
+ },
2942
+ title: collapsed ? `展开${g.title}` : `收起${g.title}`,
2943
+ children: [
2944
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2945
+ className: panel_module_css_default.readerGroupArrow,
2946
+ children: collapsed ? "▸" : "▾"
2947
+ }),
2948
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: g.title }),
2949
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2950
+ className: panel_module_css_default.readerGroupCount,
2951
+ children: g.chapters.length
2952
+ })
2953
+ ]
2954
+ }), !collapsed && g.chapters.map((ch) => {
2955
+ const badge = statusBadge$1(ch);
2956
+ const active = ch.no === currentNo;
2957
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2958
+ type: "button",
2959
+ "data-no": ch.no,
2960
+ className: `${panel_module_css_default.readerItem} ${active ? panel_module_css_default.readerItemActive : ""}`,
2961
+ style: active ? {
2962
+ background: themeMeta.accent,
2963
+ color: themeMeta.bg,
2964
+ borderColor: themeMeta.accent
2965
+ } : {
2966
+ borderColor: "transparent",
2967
+ color: themeMeta.fg
2968
+ },
2969
+ onClick: () => {
2970
+ load(ch.no);
2971
+ },
2972
+ title: `第${ch.no}章 ${ch.title}`,
2973
+ children: [
2974
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2975
+ className: panel_module_css_default.readerItemNo,
2976
+ children: ch.no
2977
+ }),
2978
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2979
+ className: panel_module_css_default.readerItemTitle,
2980
+ children: ch.title
2981
+ }),
2982
+ badge.label !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2983
+ className: panel_module_css_default.readerItemBadge,
2984
+ children: badge.label
2985
+ })
2986
+ ]
2987
+ }, ch.no);
2988
+ })]
2989
+ }, g.no);
2990
+ })
2991
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2992
+ className: panel_module_css_default.readerMain,
2993
+ style: { background: itemBg },
2994
+ children: loadError !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2995
+ className: panel_module_css_default.readerError,
2996
+ children: loadError
2997
+ }) : loading && markdown === "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2998
+ className: panel_module_css_default.readerLoading,
2999
+ children: "⏳ 加载中…"
3000
+ }) : current !== void 0 && currentNo > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
3001
+ className: panel_module_css_default.readerArticle,
3002
+ style: { maxWidth: 720 },
3003
+ children: [
3004
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
3005
+ className: panel_module_css_default.readerChapterTitle,
3006
+ style: { color: themeMeta.accent },
3007
+ children: current.title
3008
+ }),
3009
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3010
+ className: panel_module_css_default.readerChapterMeta,
3011
+ style: { color: themeMeta.dim },
3012
+ children: [
3013
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: statusBadge$1(current).label }),
3014
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
3015
+ "第 ",
3016
+ current.no,
3017
+ " 章"
3018
+ ] }),
3019
+ current.chars !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
3020
+ " · ",
3021
+ current.chars.toLocaleString(),
3022
+ " 字"
3023
+ ] })
3024
+ ]
3025
+ }),
3026
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3027
+ className: panel_module_css_default.readerText,
3028
+ style: {
3029
+ fontSize: fontMeta.px,
3030
+ lineHeight: 1.9
3031
+ },
3032
+ children: paragraphs.map((p, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3033
+ className: panel_module_css_default.readerPara,
3034
+ children: p
3035
+ }, i))
3036
+ }),
3037
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3038
+ className: panel_module_css_default.readerFoot,
3039
+ children: [
3040
+ prevCh !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3041
+ type: "button",
3042
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
3043
+ style: {
3044
+ borderColor: themeMeta.dim,
3045
+ color: themeMeta.fg
3046
+ },
3047
+ onClick: () => {
3048
+ load(prevCh.no);
3049
+ },
3050
+ title: "← 上一章",
3051
+ children: [
3052
+ "← 第",
3053
+ prevCh.no,
3054
+ "章"
3055
+ ]
3056
+ }),
3057
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3058
+ className: panel_module_css_default.meta,
3059
+ style: { color: themeMeta.dim },
3060
+ children: "← → 键盘翻章"
3061
+ }),
3062
+ nextCh !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3063
+ type: "button",
3064
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
3065
+ style: {
3066
+ borderColor: themeMeta.accent,
3067
+ color: themeMeta.accent
3068
+ },
3069
+ onClick: () => {
3070
+ load(nextCh.no);
3071
+ },
3072
+ title: "下一章 →",
3073
+ children: [
3074
+ "第",
3075
+ nextCh.no,
3076
+ "章 →"
3077
+ ]
3078
+ })
3079
+ ]
3080
+ })
3081
+ ]
3082
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3083
+ className: panel_module_css_default.readerLoading,
3084
+ children: "暂无内容"
3085
+ })
3086
+ })]
3087
+ })]
3088
+ });
3089
+ }
3090
+ //#endregion
3091
+ //#region node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/browser.js
3092
+ var u8 = Uint8Array;
3093
+ var u16 = Uint16Array;
3094
+ var i32 = Int32Array;
3095
+ var fleb = new u8([
3096
+ 0,
3097
+ 0,
3098
+ 0,
3099
+ 0,
3100
+ 0,
3101
+ 0,
3102
+ 0,
3103
+ 0,
3104
+ 1,
3105
+ 1,
3106
+ 1,
3107
+ 1,
3108
+ 2,
3109
+ 2,
3110
+ 2,
3111
+ 2,
3112
+ 3,
3113
+ 3,
3114
+ 3,
3115
+ 3,
3116
+ 4,
3117
+ 4,
3118
+ 4,
3119
+ 4,
3120
+ 5,
3121
+ 5,
3122
+ 5,
3123
+ 5,
3124
+ 0,
3125
+ 0,
3126
+ 0,
3127
+ 0
3128
+ ]);
3129
+ var fdeb = new u8([
3130
+ 0,
3131
+ 0,
3132
+ 0,
3133
+ 0,
3134
+ 1,
3135
+ 1,
3136
+ 2,
3137
+ 2,
3138
+ 3,
3139
+ 3,
3140
+ 4,
3141
+ 4,
3142
+ 5,
3143
+ 5,
3144
+ 6,
3145
+ 6,
3146
+ 7,
3147
+ 7,
3148
+ 8,
3149
+ 8,
3150
+ 9,
3151
+ 9,
3152
+ 10,
3153
+ 10,
3154
+ 11,
3155
+ 11,
3156
+ 12,
3157
+ 12,
3158
+ 13,
3159
+ 13,
3160
+ 0,
3161
+ 0
3162
+ ]);
3163
+ var clim = new u8([
3164
+ 16,
3165
+ 17,
3166
+ 18,
3167
+ 0,
3168
+ 8,
3169
+ 7,
3170
+ 9,
3171
+ 6,
3172
+ 10,
3173
+ 5,
2446
3174
  11,
2447
3175
  4,
2448
3176
  12,
@@ -2839,6 +3567,7 @@ window.__ModuleLoader__.load({
2839
3567
  /**
2840
3568
  * 开书向导:独立页面视图 —— 书名 + 大纲(选择 docx / 拖拽 / 粘贴),
2841
3569
  * 实时书名识别与题材提示,开书即建项目并进入工作台。
3570
+ * 另含「想法 → AI 大纲」:输入一句话想法生成 2-3 个方案,可暂留换批,选中后回填大纲框。
2842
3571
  */
2843
3572
  /** 从大纲首行推断书名(与服务端 inferBookName 一致,供实时预览)。 */
2844
3573
  function inferBookNamePreview(outline) {
@@ -2911,6 +3640,13 @@ window.__ModuleLoader__.load({
2911
3640
  const [busy, setBusy] = (0, react.useState)(false);
2912
3641
  const [error, setError] = (0, react.useState)("");
2913
3642
  const outlineFileRef = (0, react.useRef)(null);
3643
+ const [ideaOpen, setIdeaOpen] = (0, react.useState)(false);
3644
+ const [idea, setIdea] = (0, react.useState)("");
3645
+ const [suggesting, setSuggesting] = (0, react.useState)(false);
3646
+ const [candidates, setCandidates] = (0, react.useState)([]);
3647
+ const [pinned, setPinned] = (0, react.useState)([]);
3648
+ /** 回填后提示(如「已填入方案A,可继续修改」)。 */
3649
+ const [fillNotice, setFillNotice] = (0, react.useState)("");
2914
3650
  const autoName = inferBookNamePreview(outlineText);
2915
3651
  const effectiveName = name.trim() !== "" ? name.trim() : autoName;
2916
3652
  const genre = guessGenre(outlineText);
@@ -2930,6 +3666,43 @@ window.__ModuleLoader__.load({
2930
3666
  setError(`读取大纲失败:${err.message}`);
2931
3667
  }
2932
3668
  };
3669
+ /** 生成/换批:只补未暂留的空槽;exclude 传已暂留方案的卖点方向。 */
3670
+ const handleSuggest = async () => {
3671
+ if (idea.trim().length < 50) {
3672
+ setError("想法太短(<50 字):多写一两句——主角是谁、什么世界、想要什么爽点");
3673
+ return;
3674
+ }
3675
+ setSuggesting(true);
3676
+ setError("");
3677
+ try {
3678
+ const exclude = candidates.filter((c) => pinned.includes(c.id)).map((c) => `${c.bookName}:${c.sellingPoint}${c.genre !== "" ? `(${c.genre})` : ""}`);
3679
+ const count = Math.max(1, 3 - pinned.length);
3680
+ const result = await api.outlineSuggest(idea.trim(), count, exclude);
3681
+ setCandidates((prev) => {
3682
+ return [...prev.filter((c) => pinned.includes(c.id)), ...result.candidates].slice(0, 3);
3683
+ });
3684
+ setFillNotice("");
3685
+ } catch (err) {
3686
+ setError(err.message);
3687
+ } finally {
3688
+ setSuggesting(false);
3689
+ }
3690
+ };
3691
+ /** 暂留/取消暂留。 */
3692
+ const togglePin = (id) => {
3693
+ setPinned((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]);
3694
+ };
3695
+ /** 选中方案:回填大纲框 + 书名,滚动到上方。 */
3696
+ const handlePick = (candidate) => {
3697
+ setOutlineText(candidate.outline);
3698
+ setName(candidate.bookName);
3699
+ setFillNotice(`已填入方案《${candidate.bookName}》(${candidate.genre}),可继续修改后开书`);
3700
+ setIdeaOpen(false);
3701
+ window.scrollTo({
3702
+ top: 0,
3703
+ behavior: "smooth"
3704
+ });
3705
+ };
2933
3706
  const handleCreate = async () => {
2934
3707
  if (effectiveName === "") {
2935
3708
  setError("请填写书名,或提供大纲自动识别");
@@ -2989,10 +3762,24 @@ window.__ModuleLoader__.load({
2989
3762
  children: error
2990
3763
  })
2991
3764
  }),
2992
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2993
- className: panel_module_css_default.field,
2994
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
2995
- className: panel_module_css_default.fieldLabel,
3765
+ fillNotice !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3766
+ className: panel_module_css_default.card,
3767
+ style: {
3768
+ borderColor: "var(--nf-success)",
3769
+ padding: "8px 12px"
3770
+ },
3771
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3772
+ style: {
3773
+ color: "var(--nf-success)",
3774
+ fontSize: 12
3775
+ },
3776
+ children: ["✅ ", fillNotice]
3777
+ })
3778
+ }),
3779
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3780
+ className: panel_module_css_default.field,
3781
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
3782
+ className: panel_module_css_default.fieldLabel,
2996
3783
  children: "书名"
2997
3784
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2998
3785
  className: panel_module_css_default.input,
@@ -3087,6 +3874,160 @@ window.__ModuleLoader__.load({
3087
3874
  })
3088
3875
  ]
3089
3876
  }),
3877
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3878
+ className: panel_module_css_default.ideaCard,
3879
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3880
+ type: "button",
3881
+ className: panel_module_css_default.ideaToggle,
3882
+ onClick: () => {
3883
+ setIdeaOpen((v) => !v);
3884
+ },
3885
+ "aria-expanded": ideaOpen,
3886
+ children: [
3887
+ "✨ ",
3888
+ ideaOpen ? "▾" : "▸",
3889
+ " 没有大纲?用一句话想法让 AI 生成"
3890
+ ]
3891
+ }), ideaOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3892
+ style: {
3893
+ display: "flex",
3894
+ flexDirection: "column",
3895
+ gap: 8
3896
+ },
3897
+ children: [
3898
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
3899
+ className: panel_module_css_default.textarea,
3900
+ style: { minHeight: 60 },
3901
+ placeholder: "例如:现代外卖员被雷劈穿越到修仙世界,靠祖传古玉捡漏发育,苟着苟着成了大佬…(≥50 字)",
3902
+ value: idea,
3903
+ onChange: (e) => {
3904
+ setIdea(e.target.value);
3905
+ },
3906
+ spellCheck: false
3907
+ }),
3908
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3909
+ className: panel_module_css_default.row,
3910
+ style: { flexWrap: "wrap" },
3911
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3912
+ type: "button",
3913
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
3914
+ disabled: suggesting || idea.trim().length < 50,
3915
+ onClick: () => {
3916
+ handleSuggest();
3917
+ },
3918
+ title: "生成 3 个方向不同的大纲方案供选择(约消耗 6-8k token)",
3919
+ children: suggesting ? "⏳ 生成中…" : candidates.length === 0 ? "✨ 生成大纲方案" : `↻ 换一批(${Math.max(1, 3 - pinned.length)} 个)`
3920
+ }), candidates.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3921
+ className: panel_module_css_default.meta,
3922
+ children: [
3923
+ "已暂留 ",
3924
+ pinned.length,
3925
+ "/3 · 换批保留已暂留,只补新方案"
3926
+ ]
3927
+ })]
3928
+ }),
3929
+ candidates.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3930
+ style: {
3931
+ display: "flex",
3932
+ flexDirection: "column",
3933
+ gap: 8
3934
+ },
3935
+ children: [candidates.map((candidate) => {
3936
+ const isPinned = pinned.includes(candidate.id);
3937
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3938
+ className: panel_module_css_default.ideaCandidate,
3939
+ style: isPinned ? {
3940
+ borderColor: "var(--nf-accent)",
3941
+ boxShadow: "0 0 0 2px var(--nf-accent-soft)"
3942
+ } : void 0,
3943
+ children: [
3944
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3945
+ className: panel_module_css_default.row,
3946
+ style: {
3947
+ justifyContent: "space-between",
3948
+ flexWrap: "wrap",
3949
+ gap: 6
3950
+ },
3951
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3952
+ style: {
3953
+ display: "flex",
3954
+ alignItems: "center",
3955
+ gap: 8,
3956
+ flexWrap: "wrap"
3957
+ },
3958
+ children: [
3959
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
3960
+ "《",
3961
+ candidate.bookName,
3962
+ "》"
3963
+ ] }),
3964
+ candidate.genre !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3965
+ className: panel_module_css_default.badge,
3966
+ style: {
3967
+ borderColor: "var(--nf-accent)",
3968
+ color: "var(--nf-accent)"
3969
+ },
3970
+ children: candidate.genre
3971
+ }),
3972
+ isPinned && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3973
+ className: panel_module_css_default.badge,
3974
+ style: {
3975
+ borderColor: "var(--nf-warn)",
3976
+ color: "var(--nf-warn)"
3977
+ },
3978
+ children: "★ 已暂留"
3979
+ })
3980
+ ]
3981
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3982
+ style: {
3983
+ display: "flex",
3984
+ gap: 6
3985
+ },
3986
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3987
+ type: "button",
3988
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${isPinned ? "" : panel_module_css_default.buttonPrimary}`,
3989
+ onClick: () => {
3990
+ togglePin(candidate.id);
3991
+ },
3992
+ title: isPinned ? "取消暂留:下次换批会覆盖此槽位" : "暂留此方案:换批时保留,继续对比新方案",
3993
+ children: isPinned ? "★ 取消暂留" : "☆ 暂留"
3994
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3995
+ type: "button",
3996
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
3997
+ onClick: () => {
3998
+ handlePick(candidate);
3999
+ },
4000
+ title: "将这份大纲填入上方大纲框(可继续修改后开书)",
4001
+ children: "选这个"
4002
+ })]
4003
+ })]
4004
+ }),
4005
+ candidate.sellingPoint !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4006
+ className: panel_module_css_default.meta,
4007
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "卖点:" }), candidate.sellingPoint]
4008
+ }),
4009
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4010
+ className: panel_module_css_default.meta,
4011
+ style: {
4012
+ display: "-webkit-box",
4013
+ WebkitLineClamp: 4,
4014
+ WebkitBoxOrient: "vertical",
4015
+ overflow: "hidden",
4016
+ whiteSpace: "pre-wrap"
4017
+ },
4018
+ title: candidate.outline,
4019
+ children: candidate.outline
4020
+ })
4021
+ ]
4022
+ }, candidate.id);
4023
+ }), pinned.length >= 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4024
+ className: panel_module_css_default.meta,
4025
+ children: "已暂留全部方案——直接挑一个「选这个」即可;换批需先取消某个暂留。"
4026
+ })]
4027
+ })
4028
+ ]
4029
+ })]
4030
+ }),
3090
4031
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3091
4032
  type: "button",
3092
4033
  className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
@@ -4087,15 +5028,28 @@ window.__ModuleLoader__.load({
4087
5028
  {
4088
5029
  id: "tools",
4089
5030
  label: "工具",
4090
- items: [{
4091
- id: "assistant",
4092
- label: tt("tab.assistant"),
4093
- icon: "💬"
4094
- }, {
4095
- id: "progress",
4096
- label: "工作进度",
4097
- icon: "📊"
4098
- }]
5031
+ items: [
5032
+ {
5033
+ id: "assistant",
5034
+ label: tt("tab.assistant"),
5035
+ icon: "💬"
5036
+ },
5037
+ {
5038
+ id: "progress",
5039
+ label: "工作进度",
5040
+ icon: "📊"
5041
+ },
5042
+ {
5043
+ id: "breakdown",
5044
+ label: "拆书分析",
5045
+ icon: "🔍"
5046
+ },
5047
+ {
5048
+ id: "storyboard",
5049
+ label: "漫剧工坊",
5050
+ icon: "🎬"
5051
+ }
5052
+ ]
4099
5053
  },
4100
5054
  {
4101
5055
  id: "db",
@@ -4165,7 +5119,7 @@ window.__ModuleLoader__.load({
4165
5119
  label: tt("tab.settings"),
4166
5120
  icon: "⚙️"
4167
5121
  };
4168
- const PLUGIN_VERSION = "1.1.7";
5122
+ const PLUGIN_VERSION = "1.1.8";
4169
5123
  /** GitHub 仓库地址(关于区块点击跳转)。 */
4170
5124
  const REPO_URL = "https://github.com/watersxya/dsh-novel-forge";
4171
5125
  /** Whether any chapter is being generated right now. */
@@ -4458,6 +5412,8 @@ window.__ModuleLoader__.load({
4458
5412
  const [wsCheckReport, setWsCheckReport] = (0, react.useState)(null);
4459
5413
  /** 手动审查结果中作者勾选要修复的问题(issue 下标)。 */
4460
5414
  const [wsChecked, setWsChecked] = (0, react.useState)([]);
5415
+ /** 工作区「一键修订结果」模式:顶部显示「✅ 修订完成」横幅,不展示旧意见选择。 */
5416
+ const [wsResultMode, setWsResultMode] = (0, react.useState)(false);
4461
5417
  /** 编辑页字号(localStorage 记忆,仅影响显示)。 */
4462
5418
  const [editorFontSize, setEditorFontSize] = (0, react.useState)(() => {
4463
5419
  try {
@@ -4511,6 +5467,8 @@ window.__ModuleLoader__.load({
4511
5467
  const [collapsedVolumes, setCollapsedVolumes] = (0, react.useState)([]);
4512
5468
  /** 章节页当前选中的卷('all' = 全部卷显示在一起)。 */
4513
5469
  const [selectedVolume, setSelectedVolume] = (0, react.useState)("all");
5470
+ /** 待办/主行动卡「定位章节」的目标章号(用于展开+滚动+高亮,消费后清空)。 */
5471
+ const [focusNo, setFocusNo] = (0, react.useState)(null);
4514
5472
  /** 剧情线编辑草稿(null = 未在编辑)。 */
4515
5473
  const [plotlineDraft, setPlotlineDraft] = (0, react.useState)(null);
4516
5474
  /** 角色知情度编辑草稿(角色名 → 文本,每行一条)。 */
@@ -4538,6 +5496,20 @@ window.__ModuleLoader__.load({
4538
5496
  /** 全书敏感词检查结果(null = 未运行)。 */
4539
5497
  const [sensHits, setSensHits] = (0, react.useState)(null);
4540
5498
  const [sensScanned, setSensScanned] = (0, react.useState)(0);
5499
+ /** 拆书分析结果(null = 未运行)。 */
5500
+ const [breakdownResult, setBreakdownResult] = (0, react.useState)(null);
5501
+ const [breakdownScope, setBreakdownScope] = (0, react.useState)("recent");
5502
+ const [breakdownPreset, setBreakdownPreset] = (0, react.useState)("quick");
5503
+ /** 漫剧分镜结果(null = 未生成)。 */
5504
+ const [storyboardResult, setStoryboardResult] = (0, react.useState)(null);
5505
+ const [storyboardTool, setStoryboardTool] = (0, react.useState)("doubao");
5506
+ /** 漫剧工坊当前选中的章节号。 */
5507
+ const [storyboardChapterNo, setStoryboardChapterNo] = (0, react.useState)(0);
5508
+ /** 漫剧分集计划结果(null = 未生成)。 */
5509
+ const [storyboardPlanResult, setStoryboardPlanResult] = (0, react.useState)(null);
5510
+ const [storyboardPlanVolume, setStoryboardPlanVolume] = (0, react.useState)(1);
5511
+ /** 漫剧工坊子视图:single=单集分镜 / plan=按卷规划。 */
5512
+ const [storyboardView, setStoryboardView] = (0, react.useState)("single");
4541
5513
  /** AI 建议的剧情线候选(null = 未运行)。 */
4542
5514
  const [plotlineSuggestions, setPlotlineSuggestions] = (0, react.useState)(null);
4543
5515
  /** 剧情健康检查报告(null = 未运行)。 */
@@ -4752,6 +5724,33 @@ window.__ModuleLoader__.load({
4752
5724
  if (showError) setError(err.message);
4753
5725
  }
4754
5726
  }, [api, outlineText]);
5727
+ /** 激活一本书(书架入口共用):重置本地编辑状态 → 拉取目标书 → 进入工作台或阅读页。 */
5728
+ const activateBook = (0, react.useCallback)(async (id, mode) => {
5729
+ setBusy(true);
5730
+ setError("");
5731
+ try {
5732
+ await api.bookActivate(id);
5733
+ setOutlineText("");
5734
+ setProject(null);
5735
+ setGeneratedFiles([]);
5736
+ setChapterText("");
5737
+ setExpandedChapter(null);
5738
+ setProgress([]);
5739
+ setAuditIssues(null);
5740
+ setCharCards(null);
5741
+ await refresh(false, true);
5742
+ await refreshShelf();
5743
+ setViewMode(mode);
5744
+ } catch (err) {
5745
+ setError(err.message);
5746
+ } finally {
5747
+ setBusy(false);
5748
+ }
5749
+ }, [
5750
+ api,
5751
+ refresh,
5752
+ refreshShelf
5753
+ ]);
4755
5754
  /** Handle a docx file (pick or drag): parse locally, save outline. */
4756
5755
  const handleDocxFile = (0, react.useCallback)(async (file) => {
4757
5756
  setBusy(true);
@@ -5140,6 +6139,57 @@ window.__ModuleLoader__.load({
5140
6139
  setBusyLabel("");
5141
6140
  }
5142
6141
  };
6142
+ /** 拆书分析:对已写章节做结构/人物/文风/卖点体检(两阶段 LLM 管道,约 1-3 分钟)。 */
6143
+ const handleBreakdown = async () => {
6144
+ setBusy(true);
6145
+ setBusyLabel("拆书分析中…");
6146
+ setError("");
6147
+ try {
6148
+ const result = await api.breakdown(breakdownScope, breakdownPreset);
6149
+ setBreakdownResult(result);
6150
+ pushProgress(`拆书分析完成:${result.chaptersScanned} 章 · ${result.sections.length} 个小节 · 约 ${result.usedTokens} token`, "done");
6151
+ } catch (err) {
6152
+ setError(err.message);
6153
+ pushProgress(`拆书分析失败:${err.message}`, "error");
6154
+ } finally {
6155
+ setBusy(false);
6156
+ setBusyLabel("");
6157
+ }
6158
+ };
6159
+ /** 漫剧分镜:对某章生成角色锚点 + 分镜表(约 1-2 分钟)。 */
6160
+ const handleStoryboard = async (no) => {
6161
+ setBusy(true);
6162
+ setBusyLabel(`生成第${no}章漫剧分镜…`);
6163
+ setError("");
6164
+ try {
6165
+ const result = await api.storyboard(no, void 0, "抖音", storyboardTool);
6166
+ setStoryboardResult(result);
6167
+ pushProgress(`第${no}章分镜完成:${result.panels.length} 格 · 角色卡 ${result.characters.length} 张`, "done");
6168
+ } catch (err) {
6169
+ setError(err.message);
6170
+ pushProgress(`分镜生成失败:${err.message}`, "error");
6171
+ } finally {
6172
+ setBusy(false);
6173
+ setBusyLabel("");
6174
+ }
6175
+ };
6176
+ /** 漫剧分集计划:AI 读一卷 → 按故事弧线分集。 */
6177
+ const handleStoryboardPlan = async () => {
6178
+ setBusy(true);
6179
+ setBusyLabel(`规划第${storyboardPlanVolume}卷漫剧分集…`);
6180
+ setError("");
6181
+ try {
6182
+ const result = await api.storyboardPlan(storyboardPlanVolume, "抖音", 25);
6183
+ setStoryboardPlanResult(result);
6184
+ pushProgress(`第${storyboardPlanVolume}卷分集计划完成:${result.episodes.length} 集(覆盖 ${result.chaptersScanned} 章)`, "done");
6185
+ } catch (err) {
6186
+ setError(err.message);
6187
+ pushProgress(`分集计划失败:${err.message}`, "error");
6188
+ } finally {
6189
+ setBusy(false);
6190
+ setBusyLabel("");
6191
+ }
6192
+ };
5143
6193
  /** 作者复盘补跑:全书缺失章节(流式)。 */
5144
6194
  const handleAuthorBackfillAll = async () => {
5145
6195
  const missing = chapters.filter((c) => c.status !== "pending" && c.status !== "generating" && c.authorReview === void 0).length;
@@ -5412,7 +6462,8 @@ window.__ModuleLoader__.load({
5412
6462
  setBusyLabel("");
5413
6463
  }
5414
6464
  };
5415
- /** 工作区:保存手动编辑的正文(备份 .bak;沿用审查报告或自动审稿,保存即出结论)。 */
6465
+ /** 工作区「应用并保存」:有草稿(修订/润色产物)→ 应用草稿落盘;无草稿(手动编辑)→ 保存原文。
6466
+ * 沿用已有审查报告(wsCheckReport)或后端自动审稿;成功后原地进入「已采纳」结论态,返回定位到该章。 */
5416
6467
  const handleWsSave = async () => {
5417
6468
  if (workspace === null) return;
5418
6469
  if (workspace.original.trim().length < 50) {
@@ -5421,15 +6472,32 @@ window.__ModuleLoader__.load({
5421
6472
  }
5422
6473
  setBusy(true);
5423
6474
  setError("");
6475
+ const no = workspace.no;
5424
6476
  try {
5425
- const result = await api.chapterSave(workspace.no, workspace.original, wsCheckReport ?? void 0);
5426
- const report = result.report;
5427
- setWorkspace(null);
6477
+ let report = void 0;
6478
+ let chars = workspace.original.length;
6479
+ if (workspace.draft !== null) {
6480
+ setBusyLabel(`应用草稿 第${no}章`);
6481
+ const result = await api.draftApply(no, wsCheckReport ?? void 0);
6482
+ report = wsCheckReport ?? void 0;
6483
+ chars = result.chars;
6484
+ setWorkspace((prev) => prev === null ? prev : {
6485
+ ...prev,
6486
+ original: result.markdown ?? prev.original,
6487
+ draft: null,
6488
+ applied: true
6489
+ });
6490
+ } else {
6491
+ setBusyLabel(`AI 审查 第${no}章`);
6492
+ report = (await api.chapterSave(no, workspace.original, wsCheckReport ?? void 0)).report;
6493
+ setWorkspace((prev) => prev === null ? prev : {
6494
+ ...prev,
6495
+ applied: true
6496
+ });
6497
+ }
5428
6498
  setDraftNo(null);
5429
- setWsCheckReport(null);
5430
- setWsChecked([]);
5431
6499
  if (report !== void 0) pushProgress(`已保存并审稿:${report.score} 分 — ${report.verdict}(${report.passed ? "通过" : "未通过"})`, report.passed ? "done" : "error");
5432
- else pushProgress(`已保存第 ${workspace.no} 章编辑(${result.chars} 字,原稿已备份 .bak)`, "done");
6500
+ else pushProgress(`已保存第 ${no} 章(${chars} 字,原稿已备份 .bak)`, "done");
5433
6501
  } catch (err) {
5434
6502
  setError(err.message);
5435
6503
  pushProgress(`保存失败:${err.message}`, "error");
@@ -5557,16 +6625,12 @@ window.__ModuleLoader__.load({
5557
6625
  }
5558
6626
  };
5559
6627
  /** 打开某章的工作区(读取服务器原文;有遗留草稿时预载草稿;可预填修订指令)。 */
5560
- const openWorkspace = (0, react.useCallback)(async (no, instruction) => {
6628
+ const openWorkspace = (0, react.useCallback)(async (no, instruction, mode) => {
5561
6629
  try {
5562
6630
  const [chapterRes, statusRes] = await Promise.all([api.chapter(no), api.status()]);
5563
6631
  const chapter = statusRes.project?.chapters.find((c) => c.no === no);
5564
6632
  if (chapter === void 0) return;
5565
- let autoInstruction = instruction ?? "";
5566
- if (autoInstruction === "" && chapter.review !== void 0 && !chapter.review.passed) {
5567
- const high = chapter.review.issues.filter((i) => i.severity === "high");
5568
- autoInstruction = "按审稿意见修订(优先处理):\n" + (high.length > 0 ? high.slice(0, 3) : chapter.review.issues.slice(0, 3)).map((i) => `[${i.severity}] ${i.item} → ${i.suggestion}`).join("\n");
5569
- }
6633
+ const autoInstruction = instruction ?? "";
5570
6634
  setWorkspace({
5571
6635
  no,
5572
6636
  title: chapter.title,
@@ -5576,8 +6640,26 @@ window.__ModuleLoader__.load({
5576
6640
  });
5577
6641
  setWsSelected("");
5578
6642
  setWsShowDiff(true);
5579
- setWsCheckReport(null);
5580
- setWsChecked([]);
6643
+ if (mode === "result") {
6644
+ setWsCheckReport(null);
6645
+ setWsChecked([]);
6646
+ setWsResultMode(true);
6647
+ } else {
6648
+ setWsResultMode(false);
6649
+ const carried = chapter.review;
6650
+ setWsCheckReport(carried ?? null);
6651
+ if (carried !== void 0 && carried.issues.length > 0) {
6652
+ const highIdx = carried.issues.map((it, i) => ({
6653
+ it,
6654
+ i
6655
+ })).filter((x) => x.it.severity === "high").map((x) => x.i);
6656
+ const mediumIdx = carried.issues.map((it, i) => ({
6657
+ it,
6658
+ i
6659
+ })).filter((x) => x.it.severity === "medium").map((x) => x.i);
6660
+ setWsChecked(highIdx.length > 0 ? highIdx : mediumIdx);
6661
+ } else setWsChecked([]);
6662
+ }
5581
6663
  } catch {}
5582
6664
  }, [api]);
5583
6665
  /** 捕获工作区原文 textarea 中选中的文字(局部修订目标)。 */
@@ -5609,54 +6691,110 @@ window.__ModuleLoader__.load({
5609
6691
  }
5610
6692
  };
5611
6693
  /** 工作区:按指令修订(whole=true 整章,false 仅修订选中片段)。 */
6694
+ /** 工作区:对草稿自动跑一次 AI 审查(不落盘),刷新「当前意见」为草稿版本。 */
6695
+ /**
6696
+ * 主观项豁免判定(方案 B):修订后审查中,剩余问题若没有 high(逻辑/设定/事实矛盾),
6697
+ * 即使分数未达阈值也视为可接受——主观项(文笔/节奏/套话)不再无限循环卡修订。
6698
+ */
6699
+ const reviseAcceptable = (report) => report.passed || report.issues.every((i) => i.severity !== "high");
6700
+ const autoCheckDraft = async (no, previousReport) => {
6701
+ const draft = project?.chapters.find((c) => c.no === no)?.pendingDraft;
6702
+ if (draft === void 0 || draft === "") return;
6703
+ setBusyLabel(`AI 审查草稿 第${no}章`);
6704
+ try {
6705
+ const result = await api.chapterCheck(no, draft, previousReport ?? void 0);
6706
+ const acceptable = reviseAcceptable(result.report);
6707
+ const report = acceptable ? {
6708
+ ...result.report,
6709
+ passed: true
6710
+ } : result.report;
6711
+ setWsCheckReport(report);
6712
+ const highIdx = report.issues.map((it, i) => ({
6713
+ it,
6714
+ i
6715
+ })).filter((x) => x.it.severity === "high").map((x) => x.i);
6716
+ const mediumIdx = report.issues.map((it, i) => ({
6717
+ it,
6718
+ i
6719
+ })).filter((x) => x.it.severity === "medium").map((x) => x.i);
6720
+ setWsChecked(highIdx.length > 0 ? highIdx : mediumIdx);
6721
+ if (acceptable && !result.report.passed) pushProgress(`草稿审查:${report.score} 分 — 可接受(剩余均为主观项,无逻辑/设定矛盾)`, "done");
6722
+ else pushProgress(`草稿审查:${report.score} 分 — ${report.verdict}`, report.passed ? "done" : "error");
6723
+ } catch (err) {
6724
+ pushProgress(`草稿审查失败:${err.message}`, "error");
6725
+ } finally {
6726
+ setBusyLabel("");
6727
+ }
6728
+ };
5612
6729
  const handleWsRewrite = async (whole, overrideInstruction) => {
5613
6730
  if (workspace === null) return;
5614
6731
  const target = whole ? "" : wsSelected;
5615
6732
  const instruction = overrideInstruction ?? workspace.instruction;
6733
+ if (workspace.applied === true) setWorkspace({
6734
+ ...workspace,
6735
+ applied: false
6736
+ });
5616
6737
  setBusy(true);
5617
6738
  setBusyLabel(`${tt("plan.rewrite")} 第${workspace.no}章`);
5618
6739
  setError("");
6740
+ const no = workspace.no;
5619
6741
  try {
5620
- await api.rewrite(workspace.no, instruction, target, (frame) => {
6742
+ await api.rewrite(no, instruction, target, (frame) => {
5621
6743
  applyJobFrame(frame, (n) => tt("progress.rewriting", { no: n }));
5622
6744
  });
5623
6745
  } catch (err) {
5624
6746
  setError(err.message);
5625
- pushProgress(`第 ${workspace.no} 章修订失败:${err.message}`, "error");
6747
+ pushProgress(`第 ${no} 章修订失败:${err.message}`, "error");
5626
6748
  } finally {
5627
6749
  setBusy(false);
5628
6750
  setBusyLabel("");
5629
6751
  await refresh(false);
6752
+ if (config?.autoReviewAfterRevise !== false) {
6753
+ setBusy(true);
6754
+ await autoCheckDraft(no, wsCheckReport);
6755
+ setBusy(false);
6756
+ }
5630
6757
  }
5631
6758
  };
5632
- /** 工作区:按审查报告中勾选的问题一键修订(预填指令 + 立即整章修订到草稿)。 */
6759
+ /** 工作区:按审查报告中勾选的问题一键修订(按勾选意见整章修订到草稿,不污染指令框)。 */
5633
6760
  const handleWsReviseByReport = async () => {
5634
6761
  if (workspace === null || wsCheckReport === null) return;
5635
6762
  const picked = wsChecked.map((i) => wsCheckReport.issues[i]).filter((it) => it !== void 0).slice(0, 5);
5636
6763
  if (picked.length === 0) return;
5637
6764
  const instruction = "按审稿意见修订(优先处理):\n" + picked.map((i) => `[${i.severity}] ${i.item} → ${i.suggestion}`).join("\n");
5638
- setWorkspace({
5639
- ...workspace,
5640
- instruction
5641
- });
5642
6765
  await handleWsRewrite(true, instruction);
5643
6766
  };
5644
- /** 采纳草稿:覆盖正文文件并刷新。 */
5645
- const handleDraftApply = async (no) => {
6767
+ /** 列表页「按意见修订」一键直达:不进工作区,直接按该章审稿意见全部修订(high 优先,
6768
+ * 无 high medium,不足取前 3 条),修订完自动打开工作区展示草稿 + 自动审查结果。 */
6769
+ const handleReviseNow = async (no) => {
6770
+ const chapter = chapters.find((c) => c.no === no);
6771
+ if (chapter?.review === void 0 || chapter.review.issues.length === 0) {
6772
+ openWorkspace(no);
6773
+ return;
6774
+ }
6775
+ const issues = chapter.review.issues;
6776
+ const high = issues.filter((i) => i.severity === "high");
6777
+ const medium = issues.filter((i) => i.severity === "medium");
6778
+ const instruction = "按审稿意见修订(优先处理):\n" + (high.length > 0 ? high : medium.length > 0 ? medium : issues).slice(0, 5).map((i) => `[${i.severity}] ${i.item} → ${i.suggestion}`).join("\n");
5646
6779
  setBusy(true);
6780
+ setBusyLabel(`${tt("plan.rewrite")} 第${no}章`);
5647
6781
  setError("");
5648
6782
  try {
5649
- const result = await api.draftApply(no);
5650
- setWorkspace(null);
5651
- setDraftNo(null);
5652
- pushProgress(`已采纳第 ${no} 章新稿(${result.chars} 字)→ ${result.file}`, "done");
6783
+ await api.rewrite(no, instruction, "", (frame) => {
6784
+ applyJobFrame(frame, (n) => tt("progress.rewriting", { no: n }));
6785
+ });
6786
+ await refresh(false);
6787
+ await openWorkspace(no, void 0, "result");
6788
+ if (config?.autoReviewAfterRevise !== false) {
6789
+ setBusy(true);
6790
+ await autoCheckDraft(no, chapter.review);
6791
+ }
5653
6792
  } catch (err) {
5654
6793
  setError(err.message);
5655
- pushProgress(`采纳第 ${no} 章草稿失败:${err.message}`, "error");
6794
+ pushProgress(`第 ${no} 章修订失败:${err.message}`, "error");
5656
6795
  } finally {
5657
6796
  setBusy(false);
5658
6797
  setBusyLabel("");
5659
- await refresh(false);
5660
6798
  }
5661
6799
  };
5662
6800
  /** 放弃草稿:保留原稿,仅清空草稿。 */
@@ -5666,6 +6804,7 @@ window.__ModuleLoader__.load({
5666
6804
  try {
5667
6805
  await api.draftDiscard(no);
5668
6806
  setWorkspace(null);
6807
+ setWsResultMode(false);
5669
6808
  setDraftNo(null);
5670
6809
  pushProgress(`已放弃第 ${no} 章草稿,保留原稿`, "info");
5671
6810
  } catch (err) {
@@ -5685,7 +6824,6 @@ window.__ModuleLoader__.load({
5685
6824
  lastDeltaChars.current = 0;
5686
6825
  liveChars.current = 0;
5687
6826
  currentJobNo.current = frame.no;
5688
- setProgressOpen(true);
5689
6827
  setProject((prev) => prev === null ? prev : {
5690
6828
  ...prev,
5691
6829
  chapters: prev.chapters.map((c) => c.no === frame.no ? {
@@ -5934,7 +7072,9 @@ window.__ModuleLoader__.load({
5934
7072
  chapterChars: configDraft.chapterChars,
5935
7073
  maxTokens: configDraft.maxTokens,
5936
7074
  reviewPassScore: configDraft.reviewPassScore,
5937
- autoReview: configDraft.autoReview
7075
+ autoReview: configDraft.autoReview,
7076
+ autoAuthorReview: configDraft.autoAuthorReview,
7077
+ autoReviewAfterRevise: configDraft.autoReviewAfterRevise
5938
7078
  });
5939
7079
  setConfig(result.config);
5940
7080
  setConfigDraft(result.config);
@@ -5976,6 +7116,39 @@ window.__ModuleLoader__.load({
5976
7116
  const bible = project?.bible;
5977
7117
  const volumes = project?.volumes;
5978
7118
  const foreshadows = project?.foreshadows ?? [];
7119
+ /**
7120
+ * 定位章节:从待办/主行动卡跳到章节页的目标章——切 tab、解除卷筛选、
7121
+ * 展开所在卷,并滚动高亮(focusNo 驱动 useEffect 执行)。
7122
+ * 不强行展开章节详情:保持章节原有收起/展开状态,避免页面被撑开。
7123
+ */
7124
+ const gotoChapter = (0, react.useCallback)((no) => {
7125
+ setActiveTab("plan");
7126
+ setSelectedVolume("all");
7127
+ const chapter = chapters.find((c) => c.no === no);
7128
+ if (chapter !== void 0 && chapter.volume > 0) setCollapsedVolumes((prev) => prev.filter((v) => v !== chapter.volume));
7129
+ setFocusNo(no);
7130
+ }, [chapters]);
7131
+ /** focusNo 驱动:等 DOM 渲染后滚动到目标章并短暂高亮(3 秒后清除)。 */
7132
+ (0, react.useEffect)(() => {
7133
+ if (focusNo === null) return;
7134
+ const timer = window.setTimeout(() => {
7135
+ const el = document.querySelector(`[data-chapter-no="${focusNo}"]`);
7136
+ if (el !== null) {
7137
+ el.scrollIntoView({
7138
+ behavior: "smooth",
7139
+ block: "center"
7140
+ });
7141
+ el.classList.add(panel_module_css_default.chapterFocus);
7142
+ window.setTimeout(() => {
7143
+ el.classList.remove(panel_module_css_default.chapterFocus);
7144
+ }, 3e3);
7145
+ }
7146
+ setFocusNo(null);
7147
+ }, 350);
7148
+ return () => {
7149
+ window.clearTimeout(timer);
7150
+ };
7151
+ }, [focusNo]);
5979
7152
  /** 章节按卷分组(未分卷章节单独一组;章节多时可按卷折叠浏览)。 */
5980
7153
  const chapterGroups = (0, react.useMemo)(() => {
5981
7154
  const groups = [];
@@ -6108,15 +7281,18 @@ window.__ModuleLoader__.load({
6108
7281
  handleWriteAll();
6109
7282
  }
6110
7283
  };
6111
- if (reviewPendingCount > 0) return {
6112
- eyebrow: "推荐下一步",
6113
- title: `${reviewPendingCount} 章待审稿`,
6114
- reason: "审稿通过后章节才算完成;不通过的可按意见在工作区修订。",
6115
- actionLabel: "去审稿",
6116
- onClick: () => {
6117
- setActiveTab("plan");
6118
- }
6119
- };
7284
+ if (reviewPendingCount > 0) {
7285
+ const firstPending = chapters.find((c) => c.status === "written" || c.status === "rejected");
7286
+ return {
7287
+ eyebrow: "推荐下一步",
7288
+ title: `${reviewPendingCount} 章待审稿`,
7289
+ reason: "审稿通过后章节才算完成;不通过的可按意见在工作区修订。",
7290
+ actionLabel: "去审稿",
7291
+ onClick: () => {
7292
+ if (firstPending !== void 0) gotoChapter(firstPending.no);
7293
+ }
7294
+ };
7295
+ }
6120
7296
  return {
6121
7297
  eyebrow: "全部完成 🎉",
6122
7298
  title: "《" + project.bookName + "》已全部生成",
@@ -6133,7 +7309,8 @@ window.__ModuleLoader__.load({
6133
7309
  chapters,
6134
7310
  pendingCount,
6135
7311
  reviewPendingCount,
6136
- openWorkspace
7312
+ openWorkspace,
7313
+ gotoChapter
6137
7314
  ]);
6138
7315
  /** 待办队列(失败/草稿/待审稿,点击直达)。 */
6139
7316
  const todos = (0, react.useMemo)(() => {
@@ -6145,7 +7322,7 @@ window.__ModuleLoader__.load({
6145
7322
  description: chapter.error ?? "",
6146
7323
  actionLabel: "去处理",
6147
7324
  onClick: () => {
6148
- setActiveTab("plan");
7325
+ gotoChapter(chapter.no);
6149
7326
  }
6150
7327
  });
6151
7328
  if (items.length >= 3) return items;
@@ -6166,11 +7343,15 @@ window.__ModuleLoader__.load({
6166
7343
  description: chapter.status === "rejected" ? "审稿未通过,可按意见修订" : "等待 AI 审稿确认",
6167
7344
  actionLabel: "去审稿",
6168
7345
  onClick: () => {
6169
- setActiveTab("plan");
7346
+ gotoChapter(chapter.no);
6170
7347
  }
6171
7348
  });
6172
7349
  return items;
6173
- }, [chapters, openWorkspace]);
7350
+ }, [
7351
+ chapters,
7352
+ openWorkspace,
7353
+ gotoChapter
7354
+ ]);
6174
7355
  /** 资产健康(设定/卷/写作资产/伏笔)。 */
6175
7356
  const assetSummary = (() => {
6176
7357
  const assets = project?.assets;
@@ -6201,25 +7382,10 @@ window.__ModuleLoader__.load({
6201
7382
  activeBookId: null
6202
7383
  },
6203
7384
  onOpenBook: async (id) => {
6204
- setBusy(true);
6205
- try {
6206
- await api.bookActivate(id);
6207
- setOutlineText("");
6208
- setProject(null);
6209
- setGeneratedFiles([]);
6210
- setChapterText("");
6211
- setExpandedChapter(null);
6212
- setProgress([]);
6213
- setAuditIssues(null);
6214
- setCharCards(null);
6215
- await refresh(false, true);
6216
- await refreshShelf();
6217
- setViewMode("workspace");
6218
- } catch (err) {
6219
- setError(err.message);
6220
- } finally {
6221
- setBusy(false);
6222
- }
7385
+ await activateBook(id, "workspace");
7386
+ },
7387
+ onReadBook: async (id) => {
7388
+ await activateBook(id, "reader");
6223
7389
  },
6224
7390
  onAddBook: () => {
6225
7391
  setViewMode("create");
@@ -6249,6 +7415,22 @@ window.__ModuleLoader__.load({
6249
7415
  setBusy(false);
6250
7416
  }
6251
7417
  }
7418
+ }) : viewMode === "reader" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReaderView, {
7419
+ api,
7420
+ project: project ?? {
7421
+ bookName: "",
7422
+ outline: "",
7423
+ chapters: [],
7424
+ foreshadows: [],
7425
+ createdAt: "",
7426
+ updatedAt: ""
7427
+ },
7428
+ onBack: () => {
7429
+ setViewMode("shelf");
7430
+ },
7431
+ onOpenWorkspace: () => {
7432
+ setViewMode("workspace");
7433
+ }
6252
7434
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6253
7435
  className: panel_module_css_default.panelHeader,
6254
7436
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -6364,6 +7546,11 @@ window.__ModuleLoader__.load({
6364
7546
  tab.id === "workflow" && chapters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6365
7547
  className: `${panel_module_css_default.navTabBadge} ${panel_module_css_default.navTabBadgeDone}`,
6366
7548
  children: [journeyPercent, "%"]
7549
+ }),
7550
+ tab.id === "progress" && busy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7551
+ className: `${panel_module_css_default.navTabBadge} ${panel_module_css_default.navTabBadgeLive}`,
7552
+ title: busyLabel !== "" ? `任务中:${busyLabel}` : "任务进行中",
7553
+ children: "●"
6367
7554
  })
6368
7555
  ]
6369
7556
  }, tab.id)),
@@ -6474,344 +7661,393 @@ window.__ModuleLoader__.load({
6474
7661
  }),
6475
7662
  workspace !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6476
7663
  className: panel_module_css_default.wsPage,
6477
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6478
- className: panel_module_css_default.wsPageHeader,
6479
- children: [
6480
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6481
- type: "button",
6482
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
6483
- onClick: () => {
6484
- setWorkspace(null);
6485
- },
6486
- title: "返回章节列表(草稿不丢失)",
6487
- children: "← 返回"
6488
- }),
6489
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6490
- className: panel_module_css_default.cardTitle,
6491
- children: [
6492
- "第 ",
6493
- workspace.no,
6494
- " 章《",
6495
- workspace.title,
6496
- "》"
6497
- ]
6498
- }),
6499
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6500
- className: panel_module_css_default.meta,
6501
- children: [workspace.original.length, " 字"]
6502
- }),
6503
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6504
- style: {
6505
- display: "flex",
6506
- gap: 4,
6507
- alignItems: "center",
6508
- marginLeft: "auto"
6509
- },
6510
- children: [
6511
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6512
- type: "button",
6513
- className: panel_module_css_default.iconButton,
6514
- title: "减小字号",
6515
- "aria-label": "减小字号",
6516
- onClick: () => {
6517
- changeEditorFontSize(editorFontSize - 1);
6518
- },
6519
- children: "A−"
6520
- }),
6521
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6522
- className: panel_module_css_default.meta,
6523
- children: [editorFontSize, "px"]
6524
- }),
6525
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6526
- type: "button",
6527
- className: panel_module_css_default.iconButton,
6528
- title: "增大字号",
6529
- "aria-label": "增大字号",
6530
- onClick: () => {
6531
- changeEditorFontSize(editorFontSize + 1);
6532
- },
6533
- children: "A+"
6534
- }),
6535
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6536
- type: "button",
6537
- className: panel_module_css_default.iconButton,
6538
- title: "关闭工作区",
6539
- "aria-label": "关闭工作区",
6540
- onClick: () => {
6541
- setWorkspace(null);
6542
- },
6543
- children: "×"
6544
- })
6545
- ]
6546
- })
6547
- ]
6548
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6549
- className: panel_module_css_default.wsColumns,
6550
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6551
- className: panel_module_css_default.wsColumn,
6552
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6553
- className: panel_module_css_default.meta,
6554
- children: [
6555
- "原文(",
6556
- workspace.original.length,
6557
- " 字)— 在正文中选中文字可作为「修订选中」的局部目标"
6558
- ]
6559
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
6560
- ref: wsEditorRef,
6561
- className: `${panel_module_css_default.textarea} ${panel_module_css_default.wsEditor}`,
6562
- style: { fontSize: editorFontSize },
6563
- value: workspace.original,
6564
- onChange: (e) => {
6565
- setWorkspace({
6566
- ...workspace,
6567
- original: e.target.value
6568
- });
6569
- },
6570
- onMouseUp: captureWsSelection,
6571
- onKeyUp: captureWsSelection,
6572
- onSelect: captureWsSelection,
6573
- spellCheck: false
6574
- })]
6575
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6576
- className: panel_module_css_default.wsColumn,
7664
+ children: [
7665
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7666
+ className: panel_module_css_default.wsPageHeader,
6577
7667
  children: [
6578
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6579
- className: panel_module_css_default.meta,
6580
- style: { fontWeight: 600 },
6581
- children: "AI 修正指令"
7668
+ workspace.applied === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7669
+ type: "button",
7670
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
7671
+ onClick: () => {
7672
+ setWorkspace(null);
7673
+ setWsResultMode(false);
7674
+ gotoChapter(workspace.no);
7675
+ },
7676
+ title: "关闭工作区,返回章节页并定位到本章(滚动 + 高亮)",
7677
+ children: "← 返回章节页"
7678
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7679
+ type: "button",
7680
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
7681
+ onClick: () => {
7682
+ setWorkspace(null);
7683
+ setWsResultMode(false);
7684
+ },
7685
+ title: "返回章节列表(草稿不丢失)",
7686
+ children: "← 返回"
6582
7687
  }),
6583
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
6584
- className: panel_module_css_default.textarea,
6585
- style: { minHeight: 60 },
6586
- placeholder: "输入修正要求,例如:压缩冗余、加强冲突、这段对话更口语化…(可留空)",
6587
- value: workspace.instruction,
6588
- onChange: (e) => {
6589
- setWorkspace({
6590
- ...workspace,
6591
- instruction: e.target.value
6592
- });
6593
- }
7688
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7689
+ className: panel_module_css_default.cardTitle,
7690
+ children: [
7691
+ "第 ",
7692
+ workspace.no,
7693
+ " 章《",
7694
+ workspace.title,
7695
+ "》"
7696
+ ]
6594
7697
  }),
6595
- wsSelected !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6596
- className: panel_module_css_default.wsSelected,
6597
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6598
- className: panel_module_css_default.meta,
6599
- children: "当前选中内容(将用于精准修订)"
6600
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6601
- className: panel_module_css_default.wsSelectedText,
6602
- children: wsSelected
6603
- })]
6604
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7698
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6605
7699
  className: panel_module_css_default.meta,
6606
- children: "未选中内容时仅支持整章润色/修订。"
7700
+ children: [workspace.original.length, ""]
6607
7701
  }),
6608
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6609
- className: panel_module_css_default.row,
6610
- style: { flexWrap: "wrap" },
7702
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7703
+ style: {
7704
+ display: "flex",
7705
+ gap: 4,
7706
+ alignItems: "center",
7707
+ marginLeft: "auto"
7708
+ },
6611
7709
  children: [
6612
- workspace.instruction.includes("按审稿意见修订") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6613
- type: "button",
6614
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
6615
- disabled: busy,
6616
- onClick: () => {
6617
- handleWsRewrite(true);
6618
- },
6619
- title: "AI 按已预填的审稿意见自动修订整章(无需自己找问题)",
6620
- children: "🔧 按意见修订"
6621
- }),
6622
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6623
- type: "button",
6624
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
6625
- disabled: busy,
6626
- onClick: () => {
6627
- handleWsPolish();
6628
- },
6629
- children: "✨ 去AI味润色"
6630
- }),
6631
7710
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6632
7711
  type: "button",
6633
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
6634
- disabled: busy || workspace.instruction.trim() === "",
7712
+ className: panel_module_css_default.iconButton,
7713
+ title: "减小字号",
7714
+ "aria-label": "减小字号",
6635
7715
  onClick: () => {
6636
- handleWsRewrite(true);
7716
+ changeEditorFontSize(editorFontSize - 1);
6637
7717
  },
6638
- children: "整章修订"
7718
+ children: "A−"
6639
7719
  }),
6640
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6641
- type: "button",
6642
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
6643
- disabled: busy || wsSelected === "",
6644
- onClick: () => {
6645
- handleWsRewrite(false);
6646
- },
6647
- children: "修订选中"
7720
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7721
+ className: panel_module_css_default.meta,
7722
+ children: [editorFontSize, "px"]
6648
7723
  }),
6649
7724
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6650
7725
  type: "button",
6651
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
6652
- disabled: busy || workspace.original.trim().length < 50,
7726
+ className: panel_module_css_default.iconButton,
7727
+ title: "增大字号",
7728
+ "aria-label": "增大字号",
6653
7729
  onClick: () => {
6654
- handleWsCheck();
7730
+ changeEditorFontSize(editorFontSize + 1);
6655
7731
  },
6656
- children: "🔍 AI 审查"
7732
+ children: "A+"
6657
7733
  }),
6658
7734
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6659
7735
  type: "button",
6660
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
6661
- disabled: busy || workspace.original.trim().length < 50,
7736
+ className: panel_module_css_default.iconButton,
7737
+ title: "关闭工作区",
7738
+ "aria-label": "关闭工作区",
6662
7739
  onClick: () => {
6663
- handleWsSave();
7740
+ setWorkspace(null);
7741
+ setWsResultMode(false);
6664
7742
  },
6665
- children: "💾 保存并审稿"
7743
+ children: "×"
6666
7744
  })
6667
7745
  ]
7746
+ })
7747
+ ]
7748
+ }),
7749
+ workspace.applied === true && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7750
+ className: panel_module_css_default.wsAppliedBanner,
7751
+ children: [
7752
+ "✅ 已采纳第 ",
7753
+ workspace.no,
7754
+ " 章新稿(",
7755
+ workspace.original.length,
7756
+ " 字)· 原稿已自动备份 .bak",
7757
+ wsCheckReport !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7758
+ style: { color: wsCheckReport.passed ? "var(--nf-success)" : "var(--nf-error)" },
7759
+ children: [
7760
+ " · ",
7761
+ "修订时审查:",
7762
+ wsCheckReport.score,
7763
+ " 分 — ",
7764
+ wsCheckReport.passed ? "通过 ✓" : "未通过,可继续勾选意见修订"
7765
+ ]
7766
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7767
+ className: panel_module_css_default.meta,
7768
+ children: [" · ", "需要结论?点「🔍 AI 审查」查看"]
7769
+ })
7770
+ ]
7771
+ }),
7772
+ workspace.applied !== true && wsResultMode && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7773
+ className: panel_module_css_default.wsAppliedBanner,
7774
+ style: {
7775
+ borderColor: "var(--nf-accent)",
7776
+ background: "color-mix(in srgb, var(--nf-accent) 8%, transparent)"
7777
+ },
7778
+ children: [
7779
+ "✅ 修订完成,请查看草稿对比",
7780
+ wsCheckReport !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7781
+ style: { color: wsCheckReport.passed ? "var(--nf-success)" : "var(--nf-error)" },
7782
+ children: [
7783
+ " · ",
7784
+ "草稿审查:",
7785
+ wsCheckReport.score,
7786
+ " 分 — ",
7787
+ wsCheckReport.passed ? "通过 ✓" : "未通过,可勾选意见继续修订"
7788
+ ]
6668
7789
  }),
6669
- wsCheckReport !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6670
- className: panel_module_css_default.wsPreview,
6671
- style: { borderColor: wsCheckReport.passed ? "var(--nf-success)" : "var(--nf-warn)" },
7790
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7791
+ className: panel_module_css_default.meta,
7792
+ children: [" · ", "满意后点「✅ 应用并保存」落盘"]
7793
+ })
7794
+ ]
7795
+ }),
7796
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7797
+ className: panel_module_css_default.wsColumns,
7798
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7799
+ className: panel_module_css_default.wsColumn,
7800
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7801
+ className: panel_module_css_default.meta,
6672
7802
  children: [
6673
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6674
- className: panel_module_css_default.busyRow,
6675
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6676
- className: panel_module_css_default.meta,
6677
- style: { fontWeight: 600 },
6678
- children: "AI 审查结果"
6679
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6680
- style: { color: wsCheckReport.passed ? "var(--nf-success)" : "var(--nf-error)" },
6681
- children: [
6682
- wsCheckReport.score,
6683
- " 分 — ",
6684
- wsCheckReport.passed ? "通过" : "未通过"
6685
- ]
6686
- })]
6687
- }),
6688
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6689
- className: panel_module_css_default.meta,
6690
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "总评:" }), wsCheckReport.verdict]
6691
- }),
6692
- wsCheckReport.issues.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
6693
- style: {
6694
- margin: 0,
6695
- paddingLeft: 16,
6696
- display: "flex",
6697
- flexDirection: "column",
6698
- gap: 3,
6699
- fontSize: editorFontSize - 1,
6700
- maxHeight: "45vh",
6701
- overflowY: "auto"
6702
- },
6703
- children: wsCheckReport.issues.map((issue, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
6704
- style: {
6705
- color: severityColor(issue.severity),
6706
- display: "flex",
6707
- gap: 6,
6708
- alignItems: "flex-start"
6709
- },
6710
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6711
- type: "checkbox",
6712
- style: { marginTop: 1 },
6713
- checked: wsChecked.includes(i),
6714
- onChange: (e) => {
6715
- setWsChecked((prev) => e.target.checked ? [...prev, i] : prev.filter((x) => x !== i));
6716
- },
6717
- title: "勾选后可由「修复所选问题」一起修订"
6718
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6719
- "[",
6720
- issue.severity,
6721
- "] ",
6722
- issue.item,
6723
- issue.suggestion !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6724
- style: { color: "var(--nf-text-2)" },
6725
- children: [" → ", issue.suggestion]
6726
- })
6727
- ] })]
6728
- }, i))
6729
- }),
6730
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7803
+ "原文(",
7804
+ workspace.original.length,
7805
+ " 字)— 在正文中选中文字可作为「修订选中」的局部目标"
7806
+ ]
7807
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
7808
+ ref: wsEditorRef,
7809
+ className: `${panel_module_css_default.textarea} ${panel_module_css_default.wsEditor}`,
7810
+ style: { fontSize: editorFontSize },
7811
+ value: workspace.original,
7812
+ onChange: (e) => {
7813
+ setWorkspace({
7814
+ ...workspace,
7815
+ original: e.target.value
7816
+ });
7817
+ },
7818
+ onMouseUp: captureWsSelection,
7819
+ onKeyUp: captureWsSelection,
7820
+ onSelect: captureWsSelection,
7821
+ spellCheck: false
7822
+ })]
7823
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7824
+ className: panel_module_css_default.wsColumn,
7825
+ children: [
7826
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7827
+ className: panel_module_css_default.meta,
7828
+ style: { fontWeight: 600 },
7829
+ children: "AI 修正指令"
7830
+ }),
7831
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
7832
+ className: panel_module_css_default.textarea,
7833
+ style: { minHeight: 60 },
7834
+ placeholder: "输入修正要求,例如:压缩冗余、加强冲突、这段对话更口语化…(可留空)",
7835
+ value: workspace.instruction,
7836
+ onChange: (e) => {
7837
+ setWorkspace({
7838
+ ...workspace,
7839
+ instruction: e.target.value
7840
+ });
7841
+ }
7842
+ }),
7843
+ wsSelected !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7844
+ className: panel_module_css_default.wsSelected,
7845
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6731
7846
  className: panel_module_css_default.meta,
6732
- children: "审查只读不落盘;勾选要修的问题,点下方按钮一键修订;改完点「💾 保存为正文」才写入文件(原稿自动备份 .bak)。"
6733
- }),
6734
- wsCheckReport.issues.length > 0 && wsChecked.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6735
- style: { marginTop: 8 },
6736
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
7847
+ children: "当前选中内容(将用于精准修订)"
7848
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7849
+ className: panel_module_css_default.wsSelectedText,
7850
+ children: wsSelected
7851
+ })]
7852
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7853
+ className: panel_module_css_default.meta,
7854
+ children: "未选中内容时仅支持整章润色/修订。"
7855
+ }),
7856
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7857
+ className: panel_module_css_default.row,
7858
+ style: { flexWrap: "wrap" },
7859
+ children: [
7860
+ wsCheckReport !== null && wsCheckReport.issues.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
6737
7861
  type: "button",
6738
7862
  className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
6739
- disabled: busy,
7863
+ disabled: busy || wsChecked.length === 0,
6740
7864
  onClick: () => {
6741
7865
  handleWsReviseByReport();
6742
7866
  },
6743
- title: "自动按勾选的问题修订整章,产出草稿预览(不落盘),对比后应用或放弃",
7867
+ title: "按下方勾选的意见自动修订整章;产出草稿后自动附带一次 AI 审查",
6744
7868
  children: [
6745
- "🔧 修复所选问题(",
7869
+ "🔧 按意见修订(",
6746
7870
  wsChecked.length,
6747
7871
  ")"
6748
7872
  ]
7873
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7874
+ type: "button",
7875
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
7876
+ disabled: busy || workspace.instruction.trim() === "",
7877
+ onClick: () => {
7878
+ handleWsRewrite(true);
7879
+ },
7880
+ title: "按指令框内容整章修订",
7881
+ children: "🔧 整章修订"
7882
+ }),
7883
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7884
+ type: "button",
7885
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
7886
+ disabled: busy,
7887
+ onClick: () => {
7888
+ handleWsPolish();
7889
+ },
7890
+ children: "✨ 去AI味润色"
7891
+ }),
7892
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7893
+ type: "button",
7894
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
7895
+ disabled: busy || workspace.original.trim().length < 50,
7896
+ onClick: () => {
7897
+ handleWsSave();
7898
+ },
7899
+ title: "有草稿则应用草稿,无草稿则保存当前编辑;沿用审查结论或自动审稿,落盘后原地显示结果",
7900
+ children: "✅ 应用并保存"
7901
+ }),
7902
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7903
+ type: "button",
7904
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
7905
+ disabled: busy || wsSelected === "",
7906
+ onClick: () => {
7907
+ handleWsRewrite(false);
7908
+ },
7909
+ title: "只修订在左栏选中的文字片段",
7910
+ children: "📝 修订选中"
7911
+ }),
7912
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7913
+ type: "button",
7914
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
7915
+ disabled: busy || workspace.original.trim().length < 50,
7916
+ onClick: () => {
7917
+ handleWsCheck();
7918
+ },
7919
+ title: "对当前正文跑一次 AI 审查(不落盘)",
7920
+ children: "🔍 AI 审查"
7921
+ }),
7922
+ workspace.draft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7923
+ type: "button",
7924
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
7925
+ disabled: busy,
7926
+ onClick: () => {
7927
+ handleDraftDiscard(workspace.no);
7928
+ },
7929
+ title: "放弃草稿,保留原稿",
7930
+ children: "↩️ 放弃草稿"
6749
7931
  })
6750
- })
6751
- ]
6752
- }),
6753
- workspace.draft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6754
- className: panel_module_css_default.wsPreview,
6755
- style: {
6756
- flex: 1,
6757
- minHeight: 0
6758
- },
6759
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6760
- className: panel_module_css_default.busyRow,
6761
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6762
- className: panel_module_css_default.meta,
6763
- children: [
6764
- "优化预览(",
6765
- workspace.draft.length,
6766
- " 字)"
6767
- ]
6768
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6769
- style: {
6770
- display: "flex",
6771
- gap: 8
6772
- },
6773
- children: [
6774
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6775
- type: "button",
6776
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
6777
- onClick: () => {
6778
- setWsShowDiff((v) => !v);
6779
- },
6780
- children: wsShowDiff ? "显示文本" : "查看对比"
6781
- }),
6782
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6783
- type: "button",
6784
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
6785
- disabled: busy,
6786
- onClick: () => {
6787
- handleDraftApply(workspace.no);
7932
+ ]
7933
+ }),
7934
+ wsCheckReport !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7935
+ className: panel_module_css_default.wsPreview,
7936
+ style: { borderColor: wsCheckReport.passed ? "var(--nf-success)" : "var(--nf-warn)" },
7937
+ children: [
7938
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7939
+ className: panel_module_css_default.busyRow,
7940
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7941
+ className: panel_module_css_default.meta,
7942
+ style: { fontWeight: 600 },
7943
+ children: "AI 审查结果"
7944
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7945
+ style: { color: wsCheckReport.passed ? "var(--nf-success)" : "var(--nf-error)" },
7946
+ children: [
7947
+ wsCheckReport.score,
7948
+ " 分 — ",
7949
+ wsCheckReport.passed ? "通过" : "未通过"
7950
+ ]
7951
+ })]
7952
+ }),
7953
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7954
+ className: panel_module_css_default.meta,
7955
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "总评:" }), wsCheckReport.verdict]
7956
+ }),
7957
+ wsCheckReport.issues.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
7958
+ style: {
7959
+ margin: 0,
7960
+ paddingLeft: 16,
7961
+ display: "flex",
7962
+ flexDirection: "column",
7963
+ gap: 3,
7964
+ fontSize: editorFontSize - 1,
7965
+ maxHeight: "45vh",
7966
+ overflowY: "auto"
7967
+ },
7968
+ children: wsCheckReport.issues.map((issue, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
7969
+ style: {
7970
+ color: severityColor(issue.severity),
7971
+ display: "flex",
7972
+ gap: 6,
7973
+ alignItems: "flex-start"
6788
7974
  },
6789
- children: " 应用预览"
6790
- }),
6791
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6792
- type: "button",
6793
- className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
6794
- disabled: busy,
6795
- onClick: () => {
6796
- handleDraftDiscard(workspace.no);
7975
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
7976
+ type: "checkbox",
7977
+ style: { marginTop: 1 },
7978
+ checked: wsChecked.includes(i),
7979
+ onChange: (e) => {
7980
+ setWsChecked((prev) => e.target.checked ? [...prev, i] : prev.filter((x) => x !== i));
7981
+ },
7982
+ title: "勾选后由「按意见修订」一起修订"
7983
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
7984
+ "[",
7985
+ issue.severity,
7986
+ "] ",
7987
+ issue.item,
7988
+ issue.suggestion !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7989
+ style: { color: "var(--nf-text-2)" },
7990
+ children: [" → ", issue.suggestion]
7991
+ })
7992
+ ] })]
7993
+ }, i))
7994
+ }),
7995
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7996
+ className: panel_module_css_default.meta,
7997
+ children: wsCheckReport.passed ? "当前意见:已通过。勾选想微调的问题点「按意见修订」,或直接「✅ 应用并保存」。" : "意见只读不落盘;勾选要修的问题点「🔧 按意见修订」一键修订(默认已勾 high),满意后点「✅ 应用并保存」写入文件(原稿自动备份 .bak)。"
7998
+ })
7999
+ ]
8000
+ }),
8001
+ workspace.draft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8002
+ className: panel_module_css_default.wsPreview,
8003
+ style: {
8004
+ flex: 1,
8005
+ minHeight: 0
8006
+ },
8007
+ children: [
8008
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8009
+ className: panel_module_css_default.busyRow,
8010
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8011
+ className: panel_module_css_default.meta,
8012
+ children: [
8013
+ "优化预览(",
8014
+ workspace.draft.length,
8015
+ " 字)"
8016
+ ]
8017
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8018
+ style: {
8019
+ display: "flex",
8020
+ gap: 8
6797
8021
  },
6798
- children: "↩️ 放弃"
6799
- })
6800
- ]
6801
- })]
6802
- }), wsShowDiff ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DiffList, {
6803
- original: workspace.original,
6804
- draft: workspace.draft,
6805
- fontSize: editorFontSize
6806
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
6807
- className: panel_module_css_default.wsPreviewText,
6808
- style: { fontSize: editorFontSize },
6809
- children: workspace.draft
6810
- })]
6811
- })
6812
- ]
6813
- })]
6814
- })]
8022
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8023
+ type: "button",
8024
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
8025
+ onClick: () => {
8026
+ setWsShowDiff((v) => !v);
8027
+ },
8028
+ children: wsShowDiff ? "显示文本" : "查看对比"
8029
+ })
8030
+ })]
8031
+ }),
8032
+ wsShowDiff ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DiffList, {
8033
+ original: workspace.original,
8034
+ draft: workspace.draft,
8035
+ fontSize: editorFontSize
8036
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
8037
+ className: panel_module_css_default.wsPreviewText,
8038
+ style: { fontSize: editorFontSize },
8039
+ children: workspace.draft
8040
+ }),
8041
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8042
+ className: panel_module_css_default.meta,
8043
+ children: "满意后点上方「✅ 应用并保存」落盘(原稿自动备份 .bak);不满意可继续修订。"
8044
+ })
8045
+ ]
8046
+ })
8047
+ ]
8048
+ })]
8049
+ })
8050
+ ]
6815
8051
  }),
6816
8052
  workspace === null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
6817
8053
  activeTab === "workflow" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -7759,6 +8995,7 @@ window.__ModuleLoader__.load({
7759
8995
  const review = chapter.review;
7760
8996
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7761
8997
  className: panel_module_css_default.chapter,
8998
+ "data-chapter-no": chapter.no,
7762
8999
  children: [
7763
9000
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7764
9001
  className: panel_module_css_default.chapterNum,
@@ -8016,9 +9253,9 @@ window.__ModuleLoader__.load({
8016
9253
  className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
8017
9254
  disabled: busy || busyAny,
8018
9255
  onClick: () => {
8019
- openWorkspace(chapter.no);
9256
+ handleReviseNow(chapter.no);
8020
9257
  },
8021
- title: "按审稿意见修订(自动带入意见)",
9258
+ title: "一键按该章审稿意见全部修订(high 优先,无需进工作区选择);修订完自动打开工作区看草稿与审查",
8022
9259
  children: "按意见修订"
8023
9260
  }),
8024
9261
  chapter.status === "rejected" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -9075,6 +10312,37 @@ window.__ModuleLoader__.load({
9075
10312
  children: tt("settings.autoAuthorReviewHint")
9076
10313
  })
9077
10314
  ]
10315
+ }),
10316
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10317
+ className: panel_module_css_default.field,
10318
+ style: { flex: 1 },
10319
+ children: [
10320
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
10321
+ className: panel_module_css_default.fieldLabel,
10322
+ children: tt("settings.autoReviewAfterRevise")
10323
+ }),
10324
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
10325
+ className: panel_module_css_default.input,
10326
+ value: configDraft.autoReviewAfterRevise ? "1" : "0",
10327
+ onChange: (e) => {
10328
+ setConfigDraft({
10329
+ ...configDraft,
10330
+ autoReviewAfterRevise: e.target.value === "1"
10331
+ });
10332
+ },
10333
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
10334
+ value: "1",
10335
+ children: "✓ 是"
10336
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
10337
+ value: "0",
10338
+ children: "✗ 否"
10339
+ })]
10340
+ }),
10341
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10342
+ className: panel_module_css_default.meta,
10343
+ children: tt("settings.autoReviewAfterReviseHint")
10344
+ })
10345
+ ]
9078
10346
  })
9079
10347
  ]
9080
10348
  }),
@@ -9553,6 +10821,568 @@ window.__ModuleLoader__.load({
9553
10821
  }, line.id))
9554
10822
  })
9555
10823
  ]
10824
+ }),
10825
+ activeTab === "breakdown" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10826
+ className: panel_module_css_default.card,
10827
+ children: [
10828
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10829
+ className: panel_module_css_default.row,
10830
+ style: {
10831
+ justifyContent: "space-between",
10832
+ flexWrap: "wrap"
10833
+ },
10834
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10835
+ className: panel_module_css_default.cardTitle,
10836
+ children: "🔍 拆书分析"
10837
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10838
+ className: panel_module_css_default.row,
10839
+ style: { flexWrap: "wrap" },
10840
+ children: [
10841
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
10842
+ className: panel_module_css_default.input,
10843
+ style: { width: 130 },
10844
+ value: breakdownScope,
10845
+ onChange: (e) => {
10846
+ setBreakdownScope(e.target.value);
10847
+ },
10848
+ title: "分析范围",
10849
+ children: [
10850
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
10851
+ value: "recent",
10852
+ children: "最近 20 章"
10853
+ }),
10854
+ volumes !== void 0 && volumes.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
10855
+ value: `volume:${v.no}`,
10856
+ children: [
10857
+ "第",
10858
+ v.no,
10859
+ "卷"
10860
+ ]
10861
+ }, v.no)),
10862
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
10863
+ value: "all",
10864
+ children: "全书"
10865
+ })
10866
+ ]
10867
+ }),
10868
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
10869
+ className: panel_module_css_default.input,
10870
+ style: { width: 100 },
10871
+ value: breakdownPreset,
10872
+ onChange: (e) => {
10873
+ setBreakdownPreset(e.target.value);
10874
+ },
10875
+ title: "分析档位",
10876
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
10877
+ value: "quick",
10878
+ children: "快速(4 维)"
10879
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
10880
+ value: "standard",
10881
+ children: "标准(+卖点)"
10882
+ })]
10883
+ }),
10884
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10885
+ type: "button",
10886
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
10887
+ disabled: busy,
10888
+ onClick: () => {
10889
+ handleBreakdown();
10890
+ },
10891
+ title: "对已写章节做结构/人物/文风/卖点体检(约 1-3 分钟,消耗 LLM 额度)",
10892
+ children: busy ? "⏳ 分析中…" : "✨ 开始拆书"
10893
+ })
10894
+ ]
10895
+ })]
10896
+ }),
10897
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10898
+ className: panel_module_css_default.meta,
10899
+ children: "拆书分析 = 整卷复盘工具:定位、剧情结构、人物系统、文风技法(标准档加商业化卖点)。每条结论基于实际章节归纳,帮你发现「写偏了/人物变形/文风漂移」——与单章审稿互补。"
10900
+ }),
10901
+ breakdownResult === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10902
+ className: panel_module_css_default.shelfEmpty,
10903
+ style: { minHeight: 140 },
10904
+ children: [
10905
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10906
+ className: panel_module_css_default.shelfEmptyIcon,
10907
+ children: "📖"
10908
+ }),
10909
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10910
+ className: panel_module_css_default.shelfEmptyTitle,
10911
+ children: "尚未运行拆书分析"
10912
+ }),
10913
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10914
+ className: panel_module_css_default.meta,
10915
+ children: "选择范围与档位,点「开始拆书」对已写章节做整卷体检"
10916
+ })
10917
+ ]
10918
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10919
+ style: {
10920
+ display: "flex",
10921
+ flexDirection: "column",
10922
+ gap: 10
10923
+ },
10924
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
10925
+ className: panel_module_css_default.meta,
10926
+ children: [
10927
+ "分析 ",
10928
+ breakdownResult.chaptersScanned,
10929
+ " 章 · ",
10930
+ breakdownResult.sections.length,
10931
+ " 个小节 · 约 ",
10932
+ breakdownResult.usedTokens,
10933
+ " token"
10934
+ ]
10935
+ }), breakdownResult.sections.map((sec) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10936
+ className: panel_module_css_default.wsPreview,
10937
+ style: { borderColor: "var(--nf-info)" },
10938
+ children: [
10939
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10940
+ className: panel_module_css_default.busyRow,
10941
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: sec.title })
10942
+ }),
10943
+ Object.keys(sec.structured).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10944
+ style: {
10945
+ display: "flex",
10946
+ flexDirection: "column",
10947
+ gap: 2,
10948
+ fontSize: 12,
10949
+ marginBottom: 6
10950
+ },
10951
+ children: Object.entries(sec.structured).map(([k, v]) => {
10952
+ const label = typeof v === "string" ? v : Array.isArray(v) ? v.join("、") : JSON.stringify(v);
10953
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10954
+ className: panel_module_css_default.meta,
10955
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [k, ":"] }), label]
10956
+ }, k);
10957
+ })
10958
+ }),
10959
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
10960
+ className: panel_module_css_default.meta,
10961
+ style: {
10962
+ whiteSpace: "pre-wrap",
10963
+ fontSize: 12
10964
+ },
10965
+ children: sec.markdown
10966
+ })
10967
+ ]
10968
+ }, sec.key))]
10969
+ })
10970
+ ]
10971
+ }),
10972
+ activeTab === "storyboard" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10973
+ className: panel_module_css_default.card,
10974
+ children: [
10975
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10976
+ className: panel_module_css_default.row,
10977
+ style: {
10978
+ justifyContent: "space-between",
10979
+ flexWrap: "wrap"
10980
+ },
10981
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10982
+ className: panel_module_css_default.cardTitle,
10983
+ children: "🎬 漫剧工坊"
10984
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
10985
+ className: panel_module_css_default.row,
10986
+ style: {
10987
+ flexWrap: "wrap",
10988
+ gap: 6
10989
+ },
10990
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10991
+ type: "button",
10992
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${storyboardView === "single" ? panel_module_css_default.buttonPrimary : ""}`,
10993
+ onClick: () => {
10994
+ setStoryboardView("single");
10995
+ },
10996
+ children: "🎞️ 单集分镜"
10997
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
10998
+ type: "button",
10999
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${storyboardView === "plan" ? panel_module_css_default.buttonPrimary : ""}`,
11000
+ onClick: () => {
11001
+ setStoryboardView("plan");
11002
+ },
11003
+ children: "📺 按卷规划"
11004
+ })]
11005
+ })]
11006
+ }),
11007
+ storyboardView === "plan" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11008
+ style: {
11009
+ display: "flex",
11010
+ flexDirection: "column",
11011
+ gap: 10
11012
+ },
11013
+ children: [
11014
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11015
+ className: panel_module_css_default.row,
11016
+ style: {
11017
+ flexWrap: "wrap",
11018
+ gap: 6
11019
+ },
11020
+ children: [
11021
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
11022
+ className: panel_module_css_default.input,
11023
+ style: { width: 170 },
11024
+ value: storyboardPlanVolume,
11025
+ onChange: (e) => {
11026
+ setStoryboardPlanVolume(Number(e.target.value));
11027
+ },
11028
+ title: "选择要规划的卷",
11029
+ children: volumes !== void 0 && volumes.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
11030
+ value: v.no,
11031
+ children: [
11032
+ "第",
11033
+ v.no,
11034
+ "卷《",
11035
+ v.title,
11036
+ "》"
11037
+ ]
11038
+ }, v.no))
11039
+ }),
11040
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
11041
+ type: "button",
11042
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
11043
+ disabled: busy,
11044
+ onClick: () => {
11045
+ handleStoryboardPlan();
11046
+ },
11047
+ title: "AI 通读整卷章节摘要,按故事弧线把章节分组成漫剧集(高潮章单独成集、过渡章合并),约 1-3 分钟",
11048
+ children: busy ? "⏳ 规划中…" : "✨ 生成分集计划"
11049
+ }),
11050
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11051
+ className: panel_module_css_default.meta,
11052
+ children: "AI 读卷 → 按弧线分集(不再是固定一章一集)"
11053
+ })
11054
+ ]
11055
+ }),
11056
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11057
+ className: panel_module_css_default.meta,
11058
+ children: "分集原则:高潮章单独成集或两章一集;过渡章 2-3 章合并;断点选在钩子最强处;每集 60-120 秒。生成后逐集确认,满意再用「单集分镜」为某集生成分镜。"
11059
+ }),
11060
+ storyboardPlanResult === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11061
+ className: panel_module_css_default.shelfEmpty,
11062
+ style: { minHeight: 140 },
11063
+ children: [
11064
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11065
+ className: panel_module_css_default.shelfEmptyIcon,
11066
+ children: "📺"
11067
+ }),
11068
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11069
+ className: panel_module_css_default.shelfEmptyTitle,
11070
+ children: "尚未生成分集计划"
11071
+ }),
11072
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11073
+ className: panel_module_css_default.meta,
11074
+ children: "选卷后点「生成分集计划」,AI 把整卷按故事弧线分成漫剧集"
11075
+ })
11076
+ ]
11077
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11078
+ style: {
11079
+ display: "flex",
11080
+ flexDirection: "column",
11081
+ gap: 6
11082
+ },
11083
+ children: [
11084
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11085
+ className: panel_module_css_default.meta,
11086
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "策略:" }), storyboardPlanResult.strategy]
11087
+ }),
11088
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11089
+ className: panel_module_css_default.meta,
11090
+ children: [
11091
+ "共 ",
11092
+ storyboardPlanResult.episodes.length,
11093
+ " 集 · 覆盖 ",
11094
+ storyboardPlanResult.chaptersScanned,
11095
+ " 章"
11096
+ ]
11097
+ }),
11098
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11099
+ style: {
11100
+ display: "flex",
11101
+ flexDirection: "column",
11102
+ gap: 4,
11103
+ maxHeight: 380,
11104
+ overflowY: "auto"
11105
+ },
11106
+ children: storyboardPlanResult.episodes.map((ep) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11107
+ style: {
11108
+ border: "1px solid var(--nf-border)",
11109
+ borderRadius: 8,
11110
+ padding: "6px 10px",
11111
+ fontSize: 12
11112
+ },
11113
+ children: [
11114
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11115
+ className: panel_module_css_default.row,
11116
+ style: {
11117
+ flexWrap: "wrap",
11118
+ gap: 6
11119
+ },
11120
+ children: [
11121
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
11122
+ className: panel_module_css_default.badge,
11123
+ style: {
11124
+ borderColor: "var(--nf-accent)",
11125
+ color: "var(--nf-accent)",
11126
+ flex: "none"
11127
+ },
11128
+ children: [
11129
+ "第",
11130
+ ep.index,
11131
+ "集"
11132
+ ]
11133
+ }),
11134
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: ep.title }),
11135
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
11136
+ className: panel_module_css_default.meta,
11137
+ children: [
11138
+ "涵盖:第",
11139
+ ep.chapters[0],
11140
+ "-",
11141
+ ep.chapters[ep.chapters.length - 1],
11142
+ "章(",
11143
+ ep.chapters.length,
11144
+ "章)"
11145
+ ]
11146
+ })
11147
+ ]
11148
+ }),
11149
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11150
+ className: panel_module_css_default.meta,
11151
+ children: ep.narrativeJob
11152
+ }),
11153
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11154
+ className: panel_module_css_default.meta,
11155
+ style: { color: "var(--nf-info)" },
11156
+ children: ["开头钩子:", ep.openingHook]
11157
+ }),
11158
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11159
+ className: panel_module_css_default.meta,
11160
+ style: { color: "var(--nf-warn)" },
11161
+ children: ["结尾钩子:", ep.endingHook]
11162
+ })
11163
+ ]
11164
+ }, ep.index))
11165
+ })
11166
+ ]
11167
+ })
11168
+ ]
11169
+ }),
11170
+ storyboardView === "single" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11171
+ className: panel_module_css_default.row,
11172
+ style: {
11173
+ justifyContent: "space-between",
11174
+ flexWrap: "wrap"
11175
+ },
11176
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11177
+ className: panel_module_css_default.meta,
11178
+ children: "把一章网文改编为高完播率的漫剧分镜:角色视觉锚点(复用角色库形象词)+ 8-12 格分镜表(画面/台词/转场/AI 提示词),可直接用于豆包/即梦/SD 出图或视频。黄金开局 3 秒 + 每 10 秒小高潮 + 结尾钩子。"
11179
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11180
+ className: panel_module_css_default.row,
11181
+ style: { flexWrap: "wrap" },
11182
+ children: [
11183
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
11184
+ className: panel_module_css_default.input,
11185
+ style: { width: 150 },
11186
+ value: storyboardChapterNo,
11187
+ onChange: (e) => {
11188
+ setStoryboardChapterNo(Number(e.target.value));
11189
+ },
11190
+ title: "选择要改编的章节",
11191
+ children: chapters.filter((c) => c.status !== "pending" && c.status !== "generating").map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
11192
+ value: c.no,
11193
+ children: [
11194
+ "第",
11195
+ c.no,
11196
+ "章 ",
11197
+ c.title
11198
+ ]
11199
+ }, c.no))
11200
+ }),
11201
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
11202
+ className: panel_module_css_default.input,
11203
+ style: { width: 100 },
11204
+ value: storyboardTool,
11205
+ onChange: (e) => {
11206
+ setStoryboardTool(e.target.value);
11207
+ },
11208
+ title: "AI 工具(影响提示词格式)",
11209
+ children: [
11210
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
11211
+ value: "doubao",
11212
+ children: "豆包"
11213
+ }),
11214
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
11215
+ value: "seedance",
11216
+ children: "Seedance"
11217
+ }),
11218
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
11219
+ value: "sd",
11220
+ children: "SD/ComfyUI"
11221
+ }),
11222
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
11223
+ value: "mj",
11224
+ children: "Midjourney"
11225
+ })
11226
+ ]
11227
+ }),
11228
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
11229
+ type: "button",
11230
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
11231
+ disabled: busy,
11232
+ onClick: () => {
11233
+ handleStoryboard(storyboardChapterNo);
11234
+ },
11235
+ title: "把所选章节改编为抖音漫剧分镜(约 1-2 分钟,消耗 LLM 额度)",
11236
+ children: busy ? "⏳ 生成中…" : "✨ 生成分镜"
11237
+ })
11238
+ ]
11239
+ })]
11240
+ }), storyboardResult === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11241
+ className: panel_module_css_default.shelfEmpty,
11242
+ style: { minHeight: 140 },
11243
+ children: [
11244
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11245
+ className: panel_module_css_default.shelfEmptyIcon,
11246
+ children: "🎬"
11247
+ }),
11248
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11249
+ className: panel_module_css_default.shelfEmptyTitle,
11250
+ children: "尚未生成分镜"
11251
+ }),
11252
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11253
+ className: panel_module_css_default.meta,
11254
+ children: "选择章节与 AI 工具,点「生成分镜」开始"
11255
+ })
11256
+ ]
11257
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11258
+ style: {
11259
+ display: "flex",
11260
+ flexDirection: "column",
11261
+ gap: 10
11262
+ },
11263
+ children: [
11264
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11265
+ className: panel_module_css_default.meta,
11266
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "本集:" }), storyboardResult.title]
11267
+ }),
11268
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11269
+ className: panel_module_css_default.meta,
11270
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "赛道节奏:" }), storyboardResult.pacingNote]
11271
+ }),
11272
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11273
+ className: panel_module_css_default.meta,
11274
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "本集钩子:" }), storyboardResult.hook]
11275
+ }),
11276
+ storyboardResult.characters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11277
+ style: {
11278
+ display: "flex",
11279
+ flexDirection: "column",
11280
+ gap: 6
11281
+ },
11282
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "角色视觉锚点(全分镜强制复用)" }), storyboardResult.characters.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11283
+ style: {
11284
+ border: "1px solid var(--nf-border)",
11285
+ borderRadius: 8,
11286
+ padding: "6px 10px",
11287
+ fontSize: 12
11288
+ },
11289
+ children: [
11290
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: c.name }) }),
11291
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11292
+ className: panel_module_css_default.meta,
11293
+ children: c.visualAnchor
11294
+ }),
11295
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11296
+ className: panel_module_css_default.meta,
11297
+ style: {
11298
+ fontFamily: "monospace",
11299
+ fontSize: 11
11300
+ },
11301
+ children: c.tags
11302
+ })
11303
+ ]
11304
+ }, c.name))]
11305
+ }),
11306
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11307
+ style: {
11308
+ display: "flex",
11309
+ flexDirection: "column",
11310
+ gap: 6
11311
+ },
11312
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11313
+ className: panel_module_css_default.row,
11314
+ style: { justifyContent: "space-between" },
11315
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
11316
+ "分镜表(",
11317
+ storyboardResult.panels.length,
11318
+ " 格)"
11319
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
11320
+ type: "button",
11321
+ className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
11322
+ onClick: () => {
11323
+ const text = storyboardResult.panels.map((p) => `[${p.timecode}] ${p.shot}\n画面:${p.visual}\n台词:${p.dialogue}\n转场:${p.transition}\n提示词:${p.prompt}`).join("\n\n");
11324
+ navigator.clipboard?.writeText(text).then(() => {
11325
+ pushProgress("分镜表已复制到剪贴板", "done");
11326
+ }).catch(() => {});
11327
+ },
11328
+ title: "复制全部分镜提示词",
11329
+ children: "📋 复制全部"
11330
+ })]
11331
+ }), storyboardResult.panels.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11332
+ style: {
11333
+ border: "1px solid var(--nf-border)",
11334
+ borderRadius: 8,
11335
+ padding: "6px 10px",
11336
+ fontSize: 12
11337
+ },
11338
+ children: [
11339
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11340
+ className: panel_module_css_default.row,
11341
+ style: {
11342
+ flexWrap: "wrap",
11343
+ gap: 6
11344
+ },
11345
+ children: [
11346
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
11347
+ className: panel_module_css_default.badge,
11348
+ style: {
11349
+ borderColor: "var(--nf-accent)",
11350
+ color: "var(--nf-accent)",
11351
+ flex: "none"
11352
+ },
11353
+ children: p.timecode
11354
+ }),
11355
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: p.shot }),
11356
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
11357
+ className: panel_module_css_default.meta,
11358
+ children: ["转场:", p.transition]
11359
+ })
11360
+ ]
11361
+ }),
11362
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11363
+ className: panel_module_css_default.meta,
11364
+ children: p.visual
11365
+ }),
11366
+ p.dialogue !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
11367
+ className: panel_module_css_default.meta,
11368
+ style: { color: "var(--nf-info)" },
11369
+ children: ["💬 ", p.dialogue]
11370
+ }),
11371
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11372
+ className: panel_module_css_default.meta,
11373
+ style: {
11374
+ fontFamily: "monospace",
11375
+ fontSize: 11,
11376
+ color: "var(--nf-text-2)"
11377
+ },
11378
+ children: p.prompt
11379
+ })
11380
+ ]
11381
+ }, p.index))]
11382
+ })
11383
+ ]
11384
+ })] })
11385
+ ]
9556
11386
  })
9557
11387
  ] })
9558
11388
  ]