dsh-data-domain-knowledge 0.1.1-alpha.8 → 0.1.1-alpha.9

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.
Files changed (125) hide show
  1. package/lib/client.js +6 -19
  2. package/lib/pages.js +3392 -424
  3. package/lib/types/extract-model.d.ts +2 -0
  4. package/lib/types/extract-model.d.ts.map +1 -1
  5. package/lib/types/extract-model.js.map +1 -1
  6. package/lib/types/extract-table-contract.d.ts +66 -0
  7. package/lib/types/extract-table-contract.d.ts.map +1 -1
  8. package/lib/types/extract-table-contract.js +38 -21
  9. package/lib/types/extract-table-contract.js.map +1 -1
  10. package/lib/types/extract-table.d.ts +1 -1
  11. package/lib/types/extract-table.d.ts.map +1 -1
  12. package/lib/types/extract-table.js +14 -8
  13. package/lib/types/extract-table.js.map +1 -1
  14. package/lib/types/extraction-reply.d.ts +3 -1
  15. package/lib/types/extraction-reply.d.ts.map +1 -1
  16. package/lib/types/extraction-reply.js +3 -3
  17. package/lib/types/extraction-reply.js.map +1 -1
  18. package/lib/types/index.d.ts.map +1 -1
  19. package/lib/types/index.js +57 -4
  20. package/lib/types/index.js.map +1 -1
  21. package/lib/types/knowledge.d.ts.map +1 -1
  22. package/lib/types/knowledge.js +18 -6
  23. package/lib/types/knowledge.js.map +1 -1
  24. package/lib/types/pipeline/coverage.d.ts +5 -0
  25. package/lib/types/pipeline/coverage.d.ts.map +1 -1
  26. package/lib/types/pipeline/coverage.js +1 -0
  27. package/lib/types/pipeline/coverage.js.map +1 -1
  28. package/lib/types/pipeline/engine.d.ts +3 -1
  29. package/lib/types/pipeline/engine.d.ts.map +1 -1
  30. package/lib/types/pipeline/engine.js +27 -8
  31. package/lib/types/pipeline/engine.js.map +1 -1
  32. package/lib/types/pipeline/resumable-extract.d.ts +10 -1
  33. package/lib/types/pipeline/resumable-extract.d.ts.map +1 -1
  34. package/lib/types/pipeline/resumable-extract.js +231 -58
  35. package/lib/types/pipeline/resumable-extract.js.map +1 -1
  36. package/lib/types/pipeline/store.d.ts.map +1 -1
  37. package/lib/types/pipeline/store.js +2 -1
  38. package/lib/types/pipeline/store.js.map +1 -1
  39. package/lib/types/pipeline/toon-recovery.d.ts +9 -0
  40. package/lib/types/pipeline/toon-recovery.d.ts.map +1 -0
  41. package/lib/types/pipeline/toon-recovery.js +14 -0
  42. package/lib/types/pipeline/toon-recovery.js.map +1 -0
  43. package/lib/types/pipeline/types.d.ts +5 -0
  44. package/lib/types/pipeline/types.d.ts.map +1 -1
  45. package/lib/types/pipeline/types.js.map +1 -1
  46. package/lib/types/reading-marks.d.ts +75 -0
  47. package/lib/types/reading-marks.d.ts.map +1 -0
  48. package/lib/types/reading-marks.js +162 -0
  49. package/lib/types/reading-marks.js.map +1 -0
  50. package/lib/types/runtime.d.ts +30 -0
  51. package/lib/types/runtime.d.ts.map +1 -1
  52. package/lib/types/runtime.js +78 -4
  53. package/lib/types/runtime.js.map +1 -1
  54. package/lib/types/store/knowledge-db.d.ts +2 -0
  55. package/lib/types/store/knowledge-db.d.ts.map +1 -1
  56. package/lib/types/store/knowledge-db.js +19 -0
  57. package/lib/types/store/knowledge-db.js.map +1 -1
  58. package/lib/types/tool-approval.d.ts +29 -0
  59. package/lib/types/tool-approval.d.ts.map +1 -0
  60. package/lib/types/tool-approval.js +28 -0
  61. package/lib/types/tool-approval.js.map +1 -0
  62. package/lib/types/wiki-trial-types.d.ts +21 -0
  63. package/lib/types/wiki-trial-types.d.ts.map +1 -1
  64. package/lib/types/wiki-trial.d.ts.map +1 -1
  65. package/lib/types/wiki-trial.js +63 -11
  66. package/lib/types/wiki-trial.js.map +1 -1
  67. package/lib/wire/contracts.d.ts +1 -0
  68. package/lib/wire/contracts.d.ts.map +1 -1
  69. package/lib/wire/contracts.js +8 -3
  70. package/lib/wire/contracts.js.map +1 -1
  71. package/lib/wire/toon-codec.d.ts +27 -0
  72. package/lib/wire/toon-codec.d.ts.map +1 -0
  73. package/lib/wire/toon-codec.js +158 -0
  74. package/lib/wire/toon-codec.js.map +1 -0
  75. package/lib/wire/toon-grammar.d.ts +9 -0
  76. package/lib/wire/toon-grammar.d.ts.map +1 -0
  77. package/lib/wire/toon-grammar.js +42 -0
  78. package/lib/wire/toon-grammar.js.map +1 -0
  79. package/lib/wire/toon-kit.d.ts +8 -0
  80. package/lib/wire/toon-kit.d.ts.map +1 -0
  81. package/lib/wire/toon-kit.js +8 -0
  82. package/lib/wire/toon-kit.js.map +1 -0
  83. package/lib/wire/toon-pages.d.ts +17 -0
  84. package/lib/wire/toon-pages.d.ts.map +1 -0
  85. package/lib/wire/toon-pages.js +21 -0
  86. package/lib/wire/toon-pages.js.map +1 -0
  87. package/lib/wire/toon-repair.d.ts +46 -0
  88. package/lib/wire/toon-repair.d.ts.map +1 -0
  89. package/lib/wire/toon-repair.js +226 -0
  90. package/lib/wire/toon-repair.js.map +1 -0
  91. package/lib/wire/toon-session.d.ts +56 -0
  92. package/lib/wire/toon-session.d.ts.map +1 -0
  93. package/lib/wire/toon-session.js +104 -0
  94. package/lib/wire/toon-session.js.map +1 -0
  95. package/lib/wire/toon.d.ts +19 -0
  96. package/lib/wire/toon.d.ts.map +1 -1
  97. package/lib/wire/toon.js +102 -40
  98. package/lib/wire/toon.js.map +1 -1
  99. package/package.json +1 -1
  100. package/src/client/DocumentExtractionView.tsx +29 -102
  101. package/src/client/ExtractionTasksPage.tsx +26 -4
  102. package/src/client/FileImportView.tsx +66 -19
  103. package/src/client/ImportFilesDialog.tsx +5 -18
  104. package/src/client/KnowledgeBaseTab.tsx +3 -5
  105. package/src/client/NormalizeAxesPanel.tsx +166 -0
  106. package/src/client/ReadingView.tsx +565 -0
  107. package/src/client/tasks-page.css +471 -60
  108. package/src/extract-model.ts +2 -0
  109. package/src/extract-table-contract.ts +40 -21
  110. package/src/extract-table.ts +13 -8
  111. package/src/extraction-reply.ts +6 -4
  112. package/src/index.ts +46 -3
  113. package/src/knowledge.ts +21 -7
  114. package/src/pipeline/coverage.ts +6 -0
  115. package/src/pipeline/engine.ts +30 -8
  116. package/src/pipeline/resumable-extract.ts +200 -46
  117. package/src/pipeline/store.ts +2 -1
  118. package/src/pipeline/toon-recovery.ts +15 -0
  119. package/src/pipeline/types.ts +5 -0
  120. package/src/reading-marks.ts +172 -0
  121. package/src/runtime.ts +64 -3
  122. package/src/store/knowledge-db.ts +18 -0
  123. package/src/tool-approval.ts +46 -0
  124. package/src/wiki-trial-types.ts +19 -0
  125. package/src/wiki-trial.ts +56 -11
package/lib/pages.js CHANGED
@@ -5223,7 +5223,7 @@
5223
5223
  if (5 === d || 6 === d) a = a.stateNode, b ? c.insertBefore(a, b) : c.appendChild(a);
5224
5224
  else if (4 !== d && (a = a.child, null !== a)) for (Xj(a, b, c), a = a.sibling; null !== a; ) Xj(a, b, c), a = a.sibling;
5225
5225
  }
5226
- var X4 = null;
5226
+ var X3 = null;
5227
5227
  var Yj = false;
5228
5228
  function Zj(a, b, c) {
5229
5229
  for (c = c.child; null !== c; ) ak(a, b, c), c = c.sibling;
@@ -5237,23 +5237,23 @@
5237
5237
  case 5:
5238
5238
  U2 || Mj(c, b);
5239
5239
  case 6:
5240
- var d = X4, e = Yj;
5241
- X4 = null;
5240
+ var d = X3, e = Yj;
5241
+ X3 = null;
5242
5242
  Zj(a, b, c);
5243
- X4 = d;
5243
+ X3 = d;
5244
5244
  Yj = e;
5245
- null !== X4 && (Yj ? (a = X4, c = c.stateNode, 8 === a.nodeType ? a.parentNode.removeChild(c) : a.removeChild(c)) : X4.removeChild(c.stateNode));
5245
+ null !== X3 && (Yj ? (a = X3, c = c.stateNode, 8 === a.nodeType ? a.parentNode.removeChild(c) : a.removeChild(c)) : X3.removeChild(c.stateNode));
5246
5246
  break;
5247
5247
  case 18:
5248
- null !== X4 && (Yj ? (a = X4, c = c.stateNode, 8 === a.nodeType ? Kf(a.parentNode, c) : 1 === a.nodeType && Kf(a, c), bd(a)) : Kf(X4, c.stateNode));
5248
+ null !== X3 && (Yj ? (a = X3, c = c.stateNode, 8 === a.nodeType ? Kf(a.parentNode, c) : 1 === a.nodeType && Kf(a, c), bd(a)) : Kf(X3, c.stateNode));
5249
5249
  break;
5250
5250
  case 4:
5251
- d = X4;
5251
+ d = X3;
5252
5252
  e = Yj;
5253
- X4 = c.stateNode.containerInfo;
5253
+ X3 = c.stateNode.containerInfo;
5254
5254
  Yj = true;
5255
5255
  Zj(a, b, c);
5256
- X4 = d;
5256
+ X3 = d;
5257
5257
  Yj = e;
5258
5258
  break;
5259
5259
  case 0:
@@ -5310,23 +5310,23 @@
5310
5310
  a: for (; null !== h; ) {
5311
5311
  switch (h.tag) {
5312
5312
  case 5:
5313
- X4 = h.stateNode;
5313
+ X3 = h.stateNode;
5314
5314
  Yj = false;
5315
5315
  break a;
5316
5316
  case 3:
5317
- X4 = h.stateNode.containerInfo;
5317
+ X3 = h.stateNode.containerInfo;
5318
5318
  Yj = true;
5319
5319
  break a;
5320
5320
  case 4:
5321
- X4 = h.stateNode.containerInfo;
5321
+ X3 = h.stateNode.containerInfo;
5322
5322
  Yj = true;
5323
5323
  break a;
5324
5324
  }
5325
5325
  h = h.return;
5326
5326
  }
5327
- if (null === X4) throw Error(p2(160));
5327
+ if (null === X3) throw Error(p2(160));
5328
5328
  ak(f, g, e);
5329
- X4 = null;
5329
+ X3 = null;
5330
5330
  Yj = false;
5331
5331
  var k3 = e.alternate;
5332
5332
  null !== k3 && (k3.return = null);
@@ -7285,7 +7285,7 @@
7285
7285
  });
7286
7286
 
7287
7287
  // src/client/pages.tsx
7288
- var import_react22 = __toESM(require_react(), 1);
7288
+ var import_react23 = __toESM(require_react(), 1);
7289
7289
  var import_client = __toESM(require_client(), 1);
7290
7290
 
7291
7291
  // data-domain-knowledge-css:/Users/fuzz/Documents/github/dsh-personal/packages/ui/lib/styles.css
@@ -7323,7 +7323,1413 @@
7323
7323
  }
7324
7324
 
7325
7325
  // data-domain-knowledge-css:/Users/fuzz/Documents/github/dsh-personal/plugins/dsh-data-domain-knowledge/src/client/tasks-page.css
7326
- var css4 = "/*\n * \u77E5\u8BC6\u5904\u7406\u6574\u9875\uFF08`/knowledge/pages/tasks`\uFF09\u81EA\u5DF1\u7684\u5DE5\u4F5C\u53F0\u6837\u5F0F\u3002\n *\n * ## \u4E3A\u4EC0\u4E48\u8FD9\u4E00\u9875\u4E0D\u5957 `page-bar`\n *\n * \u5176\u4F59\u6574\u9875\uFF08\u8BD5\u8DD1\u3001\u8F68\u8FF9\u3001\u8BF4\u660E\uFF09\u662F**\u8BFB**\u7684\u4E00\u9875\uFF1A\u4E00\u6761\u5E38\u9A7B\u7A84\u6761 + \u4E00\u680F\u6B63\u6587\u5C31\u591F\u3002\n * \u8FD9\u4E00\u9875\u662F**\u64CD\u4F5C**\u7684\u4E00\u9875\uFF1A\u4EBA\u5728\u8FD9\u91CC\u770B\u4E94\u6BB5\u8DD1\u5230\u54EA\u3001\u6311\u4E00\u4EFD\u6587\u6863\u3001\u7FFB\u5B83\u7684\u62BD\u53D6\u7ED3\u679C\u3002\n * \u6240\u4EE5\u9876\u680F\u4E0D\u662F\u6807\u9898\u6761\uFF0C\u800C\u662F\u4E00\u6761\u771F\u6B63\u7684\u5E94\u7528\u680F \u2014\u2014 \u8EAB\u4EFD\u3001\u89C6\u56FE\u5207\u6362\u3001\u52A8\u4F5C\u90FD\u5728\u91CC\u9762\uFF0C\n * \u800C\u4E14\u5438\u9876\u3002\u6302\u4E24\u5C42\u5934\uFF08\u5916\u58F3\u4E00\u6761\u3001\u9875\u9762\u518D\u4E00\u6761\uFF09\u53EA\u4F1A\u8BA9\u540C\u4E00\u4E2A\u6807\u9898\u51FA\u73B0\u4E24\u904D\u3002\n *\n * ## \u7248\u5F0F\u7684\u4E00\u6761\u7EAA\u5F8B\n *\n * \u9875\u9762\u4ECE\u4E0A\u5230\u4E0B\u53EA\u6709\u4E09\u79CD\u4E1C\u897F\uFF1A**\u5DE5\u5E8F\u5E26**\uFF08\u4E94\u6BB5\u8D70\u5230\u54EA\uFF09\u3001**\u961F\u5217**\uFF08\u6709\u54EA\u4E9B\u5BF9\u8C61\uFF09\u3001\n * **\u68C0\u67E5\u5668**\uFF08\u9009\u4E2D\u90A3\u4E00\u4E2A\u7684\u7EC6\u8282\uFF09\u3002\u4E00\u4E2A\u4E8B\u5B9E\u53EA\u51FA\u73B0\u4E00\u6B21\uFF1A\u9636\u6BB5\u72B6\u6001\u53EA\u5728\u5E26\u4E0A\uFF0C\n * \u5F85\u529E\u6570\u91CF\u53EA\u5728\u961F\u5217\u91CC\uFF0C\u62BD\u53D6\u7ED3\u679C\u53EA\u5728\u68C0\u67E5\u5668\u91CC\u3002\n *\n * \u6240\u6709\u989C\u8272\u8D70\u5171\u4EAB\u4EE4\u724C\uFF08`@tita-agent/ui/styles.css` \u5E26\u8FDB\u6765\u7684\u90A3\u4E00\u5957\uFF09\uFF0C\n * \u6240\u4EE5\u6DF1\u8272\u4E3B\u9898\u8DDF\u7740\u5BBF\u4E3B\u8D70\uFF0C\u8FD9\u4E00\u9875\u4E0D\u9700\u8981\u7B2C\u4E8C\u4EFD\u914D\u8272\u3002\n */\n\n.kwPage {\n min-height: 100dvh;\n background: var(--tita-canvas);\n color: var(--tita-ink);\n font-family: var(--tita-font);\n}\n.kwTabs::-webkit-scrollbar { display: none; }\n.kwPage input,\n.kwPage textarea { caret-color: var(--tita-primary); }\n.kwPage ::selection { background: var(--tita-primary-soft); color: var(--tita-ink); }\n\n/* ------------------------------------------------------------------ \u5E94\u7528\u680F */\n\n/* \u5438\u9876\u680F\uFF1A\u6EDA\u52A8\u65F6\u300C\u8FD9\u662F\u54EA\u4E2A\u5E93\u3001\u5728\u54EA\u4E00\u9875\u300D\u4E00\u76F4\u5728\u3002\u7528\u5B9E\u8272 + \u53D1\u4E1D\u7EBF\uFF0C\n \u4E0D\u505A\u6BDB\u73BB\u7483 \u2014\u2014 \u5185\u5BB9\u4ECE\u5E95\u4E0B\u7A7F\u8FC7\u65F6\uFF0C\u534A\u900F\u660E\u4F1A\u540C\u65F6\u8BFB\u51FA\u4E24\u5C42\u6587\u5B57\u3002 */\n.kwBar {\n position: sticky;\n top: 0;\n z-index: 30;\n border-bottom: 1px solid var(--tita-line);\n background: var(--tita-surface);\n}\n.kwBarInner {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 10px 18px;\n max-width: 1440px;\n margin-inline: auto;\n padding: 10px 28px;\n}\n.kwIdent { display: flex; min-width: 0; align-items: center; gap: 11px; }\n.kwMark {\n display: inline-flex;\n width: 32px;\n height: 32px;\n flex: 0 0 auto;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--tita-primary-line);\n border-radius: 9px;\n background: var(--tita-primary-soft);\n color: var(--tita-primary);\n}\n.kwIdentCopy { display: grid; min-width: 0; gap: 1px; }\n.kwIdentCopy h1 {\n margin: 0;\n font-size: 14.5px;\n font-weight: 720;\n letter-spacing: -.015em;\n line-height: 1.4;\n}\n.kwIdentCopy p {\n margin: 0;\n overflow: hidden;\n color: var(--tita-ink-muted);\n font-size: 11px;\n line-height: 1.45;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.kwIdentCopy b { color: var(--tita-ink); font-weight: 620; }\n\n/* \u89C6\u56FE\u5207\u6362\uFF1A\u540C\u4E00\u9875\u7684\u4E09\u79CD\u8BFB\u6CD5\uFF0C\u4E0D\u662F\u7B2C\u4E8C\u6B65\u5BFC\u822A\u3002 */\n.kwTabs {\n display: inline-flex;\n align-items: center;\n overflow-x: auto;\n scrollbar-width: none;\n gap: 2px;\n border: 1px solid var(--tita-line);\n border-radius: 9px;\n background: var(--tita-surface-muted);\n padding: 2px;\n}\n.kwTab {\n border: 0;\n border-radius: 7px;\n background: transparent;\n padding: 5px 13px;\n color: var(--tita-ink-muted);\n font: inherit;\n font-size: 11.5px;\n font-weight: 620;\n line-height: 1.4;\n white-space: nowrap;\n cursor: pointer;\n transition: background-color 120ms ease, color 120ms ease;\n}\n.kwTab:hover { color: var(--tita-ink); }\n.kwTab[aria-pressed='true'] {\n background: var(--tita-surface);\n color: var(--tita-ink);\n box-shadow: 0 1px 2px rgb(16 24 40 / .1);\n}\n.kwTab:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }\n.kwActions { display: flex; align-items: center; gap: 6px; }\n\n/* --------------------------------------------------------------- \u4E3B\u5185\u5BB9\u533A */\n\n.kwMain { max-width: 1440px; margin-inline: auto; padding: 18px 28px 96px; }\n.kwColumn { display: grid; min-width: 0; gap: 14px; }\n\n/* \u4E00\u6761\u63D0\u793A\uFF1A\u6210\u529F\u3001\u5931\u8D25\u3001\u6216\u300C\u8FD9\u4E00\u9875\u8BFB\u4E0D\u5230\u6570\u636E\u300D\u3002 */\n.kwNotice {\n display: flex;\n align-items: flex-start;\n gap: 9px;\n border: 1px solid var(--tita-line);\n border-radius: 10px;\n padding: 9px 10px 9px 12px;\n font-size: 12px;\n line-height: 1.55;\n}\n.kwNotice > svg { flex: 0 0 auto; margin-top: 2px; }\n.kwNotice > span { min-width: 0; flex: 1 1 auto; overflow-wrap: anywhere; }\n.kwNotice-success { border-color: var(--tita-tone-green-line); background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }\n.kwNotice-error { border-color: color-mix(in srgb, var(--tita-danger) 32%, var(--tita-surface)); background: color-mix(in srgb, var(--tita-danger) 7%, var(--tita-surface)); color: var(--tita-danger); }\n.kwNotice-warn { border-color: color-mix(in srgb, var(--tita-warning) 30%, var(--tita-surface)); background: color-mix(in srgb, var(--tita-warning) 6%, var(--tita-surface)); color: var(--tita-warning); }\n.kwNotice-info { border-color: var(--tita-line); background: var(--tita-surface-muted); color: var(--tita-ink-muted); }\n\n/* ------------------------------------------------------------------ \u5DE5\u5E8F\u5E26\n *\n * \u4E94\u6BB5\u662F\u8FD9\u6761\u6D41\u6C34\u7EBF\u7684\u9AA8\u67B6\uFF0C\u6240\u4EE5\u5B83\u662F\u4E00\u6761**\u8D2F\u7A7F\u6574\u9875\u7684\u5E26**\uFF0C\u4E0D\u662F\u4E00\u4E2A\u5361\u7247\u533A\u3002\n * \u6BCF\u683C\u9876\u8FB9 2px \u662F\u8FD9\u4E00\u6BB5\u7684**\u72B6\u6001\u8272**\uFF08\u6210\u529F\u7EFF / \u8FD0\u884C\u84DD / \u5F85\u91CD\u8DD1\u7425\u73C0\uFF09\uFF0C\n * \u5E95\u8FB9\u7EC6\u7EBF\u662F\u5B8C\u6210\u6BD4\u4F8B\u3002\u4E24\u8005\u90FD\u4E0D\u5199\u5B57\uFF0C\u6240\u4EE5\u626B\u4E00\u773C\u5C31\u6709\u8BFB\u6570\uFF0C\u8BFB\u5B57\u662F\u7B2C\u4E8C\u6B65\u3002\n */\n.kwBand {\n display: flex;\n align-items: stretch;\n gap: 8px;\n min-width: 0;\n}\n.kwGate {\n flex: 1 1 0;\n min-width: 0;\n overflow: hidden;\n border: 1px solid var(--tita-line);\n border-radius: 10px;\n background: var(--tita-surface);\n transition: border-color 140ms ease, background-color 140ms ease;\n}\n.kwGate:hover { border-color: var(--tita-line-strong); }\n/* \u9009\u4E2D\u7684\u90A3\u4E00\u6B65\u7528**\u8FB9\u6846 + \u5E95\u8272**\u8868\u6001\uFF0C\u4E0D\u9760\u4E00\u6761\u76D6\u5728\u6574\u6761\u5E26\u4E0A\u7684\u8272\u6761\uFF1A\n \u4E94\u6B65\u662F\u4E94\u4E2A\u683C\u5B50\uFF0C\u4E0D\u662F\u4E00\u4E2A\u8868\u683C\u3002 */\n.kwGate[data-on] { border-color: var(--tita-primary-line); background: var(--tita-primary-soft); }\n.kwBandArrow {\n display: inline-flex;\n flex: 0 0 auto;\n align-items: center;\n align-self: center;\n color: var(--tita-ink-faint);\n}\n.kwGateBtn {\n display: grid;\n width: 100%;\n min-width: 0;\n gap: 4px;\n border: 0;\n background: none;\n padding: 11px 13px 12px;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n transition: background-color 140ms ease;\n}\n.kwGateBtn:hover { background: color-mix(in srgb, var(--tita-surface-muted) 62%, var(--tita-surface)); }\n.kwGateBtn:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }\n.kwGate[data-on] .kwGateBtn { background: transparent; }\n.kwGateTop { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.kwGateIndex {\n color: var(--tita-ink-faint);\n font-family: var(--tita-mono);\n font-size: 9.5px;\n font-weight: 600;\n letter-spacing: .1em;\n}\n.kwGateState {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n color: var(--tita-ink-muted);\n font-size: 10px;\n font-weight: 620;\n line-height: 1.4;\n white-space: nowrap;\n}\n.kwGate[data-tone='success'] .kwGateState { color: var(--tita-tone-green); }\n.kwGate[data-tone='warning'] .kwGateState { color: var(--tita-warning); }\n.kwGate[data-tone='blue'] .kwGateState { color: var(--tita-primary); }\n.kwGateName {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 6px;\n color: var(--tita-ink);\n font-size: 12.5px;\n font-weight: 650;\n line-height: 1.4;\n}\n.kwGateName svg { flex: 0 0 auto; color: var(--tita-ink-muted); }\n.kwGate[data-on] .kwGateName svg,\n.kwGate[data-tone='blue'] .kwGateName svg { color: var(--tita-primary); }\n.kwGateFact {\n overflow: hidden;\n color: var(--tita-ink-muted);\n font-size: 11px;\n line-height: 1.45;\n font-variant-numeric: tabular-nums;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.kwGateBar {\n height: 2px;\n margin-top: 3px;\n overflow: hidden;\n border-radius: 2px;\n background: var(--tita-surface-muted);\n}\n.kwGateBar > span {\n display: block;\n width: 100%;\n height: 100%;\n border-radius: 2px;\n background: var(--tita-ink-faint);\n transform-origin: left center;\n transition: transform 260ms cubic-bezier(.22, .7, .2, 1), background-color 180ms ease;\n}\n.kwGate[data-tone='success'] .kwGateBar > span { background: var(--tita-tone-green); }\n.kwGate[data-tone='warning'] .kwGateBar > span { background: var(--tita-warning); }\n.kwGate[data-tone='blue'] .kwGateBar > span { background: var(--tita-primary); }\n\n/* \u5E26\u4E0B\u9762\u7684\u4E00\u884C\uFF1A\u672C\u8F6E\u4F1A\u4E0D\u4F1A\u52A8\u3001\u51ED\u4EC0\u4E48\u8FD9\u4E48\u5224\u3002\u5B83\u4E0D\u662F\u4E00\u5757\u5361\u7247\uFF0C\u662F\u4E00\u6761\u8BFB\u6570\u3002 */\n.kwScope {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n justify-content: space-between;\n gap: 2px 18px;\n padding: 0 2px;\n}\n.kwScopeNow { margin: 0; color: var(--tita-ink); font-size: 12px; line-height: 1.6; font-variant-numeric: tabular-nums; }\n.kwScopeKey { margin: 0; color: var(--tita-ink-faint); font-size: 11px; line-height: 1.6; }\n\n/* \u8FD0\u884C\u4E2D\u7684\u90A3\u4E00\u6BB5\uFF1A\u72B6\u6001\u5B57\u524D\u9762\u4E00\u9897\u4F1A\u547C\u5438\u7684\u70B9\u3002\u5168\u9875\u53EA\u6709\u8FD9\u4E00\u5904\u52A8\u6548\u5E38\u9A7B\u3002 */\n.kwLive {\n width: 6px;\n height: 6px;\n flex: 0 0 auto;\n border-radius: 999px;\n background: var(--tita-primary);\n animation: kwPulse 1.9s ease-out infinite;\n}\n@keyframes kwPulse {\n 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tita-primary) 34%, transparent); }\n 70% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--tita-primary) 0%, transparent); }\n 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tita-primary) 0%, transparent); }\n}\n\n/* ------------------------------------------------------- \u961F\u5217 + \u68C0\u67E5\u5668 \u53CC\u680F */\n\n.kwBody {\n display: grid;\n grid-template-columns: minmax(286px, 332px) minmax(0, 1fr);\n align-items: start;\n gap: 16px;\n min-width: 0;\n}\n\n/* \u961F\u5217\uFF1A\u5BF9\u8C61\u662F\u63A5\u4E0B\u6765\u8981\u52A8\u624B\u7684\u90A3\u4E00\u6279\u3002\u5B83\u5438\u9876\u5E76\u81EA\u5DF1\u6EDA \u2014\u2014\n \u53F3\u680F\u7684\u7ED3\u679C\u53EF\u80FD\u6709\u51E0\u5341\u5C4F\uFF0C\u9009\u6587\u6863\u4E0D\u8BE5\u9700\u8981\u5148\u6EDA\u56DE\u9875\u9876\u3002 */\n.kwQueue {\n position: sticky;\n top: 76px;\n display: grid;\n grid-template-rows: auto minmax(0, 1fr) auto;\n max-height: calc(100dvh - 100px);\n overflow: hidden;\n border: 1px solid var(--tita-line);\n border-radius: 12px;\n background: var(--tita-surface);\n}\n.kwQueueHead {\n display: grid;\n gap: 9px;\n border-bottom: 1px solid var(--tita-line);\n padding: 12px 14px 11px;\n}\n.kwQueueTitle { display: flex; align-items: center; gap: 7px; }\n.kwQueueTitle strong { color: var(--tita-ink); font-size: 12px; font-weight: 680; }\n.kwQueueTitle > span { color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n/* \u5165\u5E93\u662F\u8FD9\u4E00\u6BB5\u81EA\u5DF1\u7684\u52A8\u4F5C\uFF1A\u5B83\u8DDF\u7740\u6587\u6863\u5217\u8868\u8D70\uFF0C\u4E0D\u518D\u5360\u9876\u680F\u3002 */\n.kwQueueAdd { margin-left: auto; min-height: 26px; padding-inline: 9px; font-size: 11px; gap: 4px; }\n.kwQueueTools { display: flex; align-items: center; gap: 6px; }\n.kwSearch { position: relative; display: flex; min-width: 0; flex: 1 1 auto; align-items: center; }\n.kwSearch > svg { position: absolute; left: 8px; color: var(--tita-ink-faint); pointer-events: none; }\n.kwSearch input { padding-left: 26px; }\n.kwList {\n min-height: 0;\n margin: 0;\n padding: 0;\n overflow-y: auto;\n list-style: none;\n scrollbar-width: thin;\n scrollbar-color: var(--tita-line-strong) transparent;\n}\n\n/* \u961F\u5217\u91CC\u7684\u4E00\u884C\uFF1A\u6807\u9898 / \u5B83\u662F\u4EC0\u4E48 / \u62BD\u51FA\u4E86\u591A\u5C11\u3002\u4E09\u884C\u90FD\u662F\u4E8B\u5B9E\uFF0C\u4E0D\u662F\u6309\u94AE\u3002\n \u6574\u884C\u662F\u4E00\u4E2A\u6309\u94AE \u2014\u2014 \u9009\u5B83\u5C31\u662F\u770B\u5B83\u3002 */\n.kwDoc {\n display: grid;\n width: 100%;\n min-width: 0;\n gap: 4px;\n border: 0;\n border-bottom: 1px solid var(--tita-line);\n background: none;\n padding: 12px 14px 13px;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n transition: background-color 120ms ease;\n}\n.kwDoc:last-child { border-bottom: 0; }\n.kwDoc:hover { background: var(--tita-surface-muted); }\n.kwDoc:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }\n.kwDoc[data-on] { background: color-mix(in srgb, var(--tita-primary) 7%, var(--tita-surface)); }\n.kwDocTitle {\n display: -webkit-box;\n overflow: hidden;\n color: var(--tita-ink);\n font-size: 13px;\n font-weight: 620;\n letter-spacing: -.005em;\n line-height: 1.5;\n overflow-wrap: anywhere;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n}\n.kwDoc[data-on] .kwDocTitle { color: var(--tita-primary); }\n.kwDocMeta {\n color: var(--tita-ink-faint);\n font-size: 10.5px;\n line-height: 1.5;\n font-variant-numeric: tabular-nums;\n}\n.kwDocFoot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 3px; }\n.kwDocCount { color: var(--tita-ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }\n\n/* \u72B6\u6001\uFF1A\u4E00\u4E2A\u70B9 + \u4E24\u4E2A\u5B57\u3002\u989C\u8272\u53EA\u8868\u6001\uFF0C\u4E0D\u8868\u6001\u5F3A\u5EA6\u3002 */\n.kwState {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n color: var(--tita-ink-muted);\n font-size: 10.5px;\n font-weight: 600;\n white-space: nowrap;\n}\n.kwState::before { width: 5px; height: 5px; flex: 0 0 auto; border-radius: 999px; background: currentColor; content: ''; }\n.kwState[data-tone='success'] { color: var(--tita-tone-green); }\n.kwState[data-tone='warning'] { color: var(--tita-warning); }\n.kwState[data-tone='blue'] { color: var(--tita-primary); }\n\n/* ---------------------------------------------------------------- \u68C0\u67E5\u5668 */\n\n.kwInspector {\n min-width: 0;\n border: 1px solid var(--tita-line);\n border-radius: 12px;\n background: var(--tita-surface);\n}\n.kwInspectorHead {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: start;\n gap: 10px 16px;\n padding: 16px 20px 14px;\n}\n.kwInspectorTitle { display: grid; min-width: 0; gap: 3px; }\n.kwInspectorTitle h2 {\n margin: 0;\n color: var(--tita-ink);\n font-size: 17px;\n font-weight: 710;\n letter-spacing: -.018em;\n line-height: 1.35;\n overflow-wrap: anywhere;\n}\n.kwInspectorTitle p {\n margin: 0;\n color: var(--tita-ink-muted);\n font-size: 11.5px;\n line-height: 1.5;\n font-variant-numeric: tabular-nums;\n}\n.kwInspectorActions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }\n\n/* \u7248\u672C\u6761\uFF1A\u5B83\u662F**\u8FD9\u4E00\u5C4F\u7684\u65F6\u95F4\u8F74**\uFF0C\u6240\u4EE5\u653E\u5728\u6807\u9898\u4E0E\u9875\u7B7E\u4E4B\u95F4\uFF0C\u8D34\u4E00\u6761\u6D45\u5E95\u3002 */\n.kwVersionBar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n border-top: 1px solid var(--tita-line);\n border-bottom: 1px solid var(--tita-line);\n background: color-mix(in srgb, var(--tita-surface-muted) 52%, var(--tita-surface));\n padding: 8px 20px;\n}\n.kwVersionBar > strong { color: var(--tita-ink); font-size: 11.5px; font-weight: 650; }\n.kwVersionBar > span { color: var(--tita-ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }\n.kwVersionPick { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }\n.kwVersionChip {\n border: 1px solid var(--tita-line);\n border-radius: 999px;\n background: var(--tita-surface);\n padding: 1px 8px;\n color: var(--tita-ink-muted);\n font: inherit;\n font-size: 10.5px;\n font-weight: 650;\n font-variant-numeric: tabular-nums;\n line-height: 1.7;\n cursor: pointer;\n transition: border-color 120ms ease, color 120ms ease, background-color 120ms ease;\n}\n.kwVersionChip:hover { border-color: var(--tita-line-strong); color: var(--tita-ink); }\n.kwVersionChip:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }\n.kwVersionChip[aria-pressed='true'] { border-color: var(--tita-primary-line); background: var(--tita-primary-soft); color: var(--tita-primary); }\n\n/* \u9875\u7B7E\uFF1A\u4E0B\u5212\u7EBF\u90A3\u4E00\u79CD\u3002\u5B83\u662F\u540C\u4E00\u4EFD\u6570\u636E\u7684\u4E0D\u540C\u8BFB\u6CD5\uFF0C\u4E0D\u662F\u53C8\u4E00\u5C42\u5BB9\u5668\u3002 */\n.kwTabsRow { padding: 0 20px; border-bottom: 1px solid var(--tita-line); }\n.kwTabsRow .tita-uiTabsList {\n height: auto;\n gap: 18px;\n border: 0;\n border-radius: 0;\n background: transparent;\n padding: 0;\n}\n.kwTabsRow .tita-uiTabsTrigger {\n border: 0;\n border-bottom: 2px solid transparent;\n border-radius: 0;\n background: transparent;\n padding: 9px 0 7px;\n color: var(--tita-ink-muted);\n font-size: 12px;\n font-weight: 620;\n box-shadow: none;\n}\n.kwTabsRow .tita-uiTabsTrigger:hover { color: var(--tita-ink); }\n.kwTabsRow .tita-uiTabsTrigger[data-state='active'] { border-bottom-color: var(--tita-primary); color: var(--tita-ink); }\n.kwTabsRow .tita-uiTabsTrigger:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }\n\n/* ---- \u7ED3\u679C\u6D41\n *\n * \u4E00\u5C4F\u53EF\u80FD\u6709\u4E00\u767E\u591A\u6761\uFF0C\u6240\u4EE5\u5B83\u662F**\u6D41**\u4E0D\u662F\u5361\u7247\u5899\uFF1A\u7F16\u53F7\u3001\u7C7B\u578B\u3001\u6B63\u6587\u4E09\u5217\uFF0C\n * \u884C\u95F4\u53EA\u6709\u53D1\u4E1D\u7EBF\u3002\u6B63\u6587 12.5px / 1.75\uFF0C\u4E00\u884C\u7EA6 76 \u4E2A\u5B57\u7B26 \u2014\u2014 \u8BFB\u5F97\u4E0B\u53BB\u7684\u957F\u5EA6\u3002\n */\n.kwResultBar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n border-bottom: 1px solid var(--tita-line);\n padding: 10px 20px;\n}\n.kwResultSummary { display: flex; align-items: baseline; gap: 6px; color: var(--tita-ink-muted); font-size: 11.5px; }\n.kwResultSummary strong { color: var(--tita-ink); font-size: 13.5px; font-weight: 680; font-variant-numeric: tabular-nums; }\n.kwChips { display: flex; flex-wrap: wrap; gap: 4px; margin-left: auto; }\n.kwChip {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n border: 1px solid var(--tita-line);\n border-radius: 999px;\n background: var(--tita-surface);\n padding: 2px 9px;\n color: var(--tita-ink-muted);\n font: inherit;\n font-size: 10.5px;\n font-weight: 600;\n line-height: 1.6;\n cursor: pointer;\n transition: border-color 120ms ease, color 120ms ease, background-color 120ms ease;\n}\n.kwChip:hover { border-color: var(--tita-line-strong); color: var(--tita-ink); }\n.kwChip:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }\n.kwChip[aria-pressed='true'] { border-color: var(--tita-primary-line); background: var(--tita-primary-soft); color: var(--tita-primary); }\n.kwChip i { color: var(--tita-ink-faint); font-style: normal; font-variant-numeric: tabular-nums; }\n.kwChip[aria-pressed='true'] i { color: inherit; opacity: .72; }\n\n.kwResults { margin: 0; padding: 0; list-style: none; }\n.kwResult {\n display: grid;\n grid-template-columns: 34px 62px minmax(0, 1fr);\n align-items: start;\n gap: 10px;\n border-bottom: 1px solid var(--tita-line);\n padding: 12px 20px 13px;\n transition: background-color 120ms ease;\n}\n.kwResult:last-child { border-bottom: 0; }\n.kwResult:hover { background: color-mix(in srgb, var(--tita-surface-muted) 56%, var(--tita-surface)); }\n.kwResultIndex {\n padding-top: 2px;\n color: var(--tita-ink-faint);\n font-family: var(--tita-mono);\n font-size: 9.5px;\n font-variant-numeric: tabular-nums;\n letter-spacing: .04em;\n}\n.kwResultText { max-width: 76ch; margin: 0; color: var(--tita-ink); font-size: 12.5px; line-height: 1.75; overflow-wrap: anywhere; }\n\n/* \u7C7B\u578B\u662F\u8FD9\u884C\u7684**\u5750\u6807**\uFF0C\u4E0D\u662F\u4E00\u4E2A\u5F3A\u8C03\u4EF6\uFF1A\u7B49\u5BBD\u3001\u5C0F\u53F7\u3001\u4E00\u4E2A\u8272\u70B9\u3002 */\n.kwKind {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding-top: 4px;\n color: var(--tita-ink-faint);\n font-family: var(--tita-mono);\n font-size: 9.5px;\n font-weight: 600;\n letter-spacing: .07em;\n text-transform: uppercase;\n}\n.kwKind::before { width: 5px; height: 5px; flex: 0 0 auto; border-radius: 999px; background: currentColor; content: ''; }\n.kwKind[data-kind='fact'] { color: var(--tita-tone-blue); }\n.kwKind[data-kind='procedure'] { color: var(--tita-tone-violet); }\n.kwKind[data-kind='case'] { color: var(--tita-tone-amber); }\n.kwResultFoot {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n border-top: 1px solid var(--tita-line);\n padding: 9px 20px;\n color: var(--tita-ink-faint);\n font-size: 10.5px;\n font-variant-numeric: tabular-nums;\n}\n\n/* \u7A7A\u6001\uFF1A\u8BF4\u6E05\u695A**\u4E3A\u4EC0\u4E48\u7A7A**\u548C**\u4E0B\u4E00\u6B65\u505A\u4EC0\u4E48**\uFF0C\u4E0D\u653E\u63D2\u56FE\u3002 */\n.kwEmpty { display: grid; justify-items: center; gap: 5px; padding: 42px 24px 46px; text-align: center; }\n.kwEmptyIcon {\n display: inline-flex;\n width: 34px;\n height: 34px;\n align-items: center;\n justify-content: center;\n margin-bottom: 4px;\n border: 1px solid var(--tita-line);\n border-radius: 10px;\n color: var(--tita-ink-muted);\n}\n.kwEmpty strong { color: var(--tita-ink); font-size: 12.5px; font-weight: 650; }\n.kwEmpty p { max-width: 46ch; margin: 0; color: var(--tita-ink-muted); font-size: 11.5px; line-height: 1.65; }\n.kwEmptyList { padding: 28px 18px 30px; }\n.kwEmptyList .tita-uiButton { margin-top: 6px; }\n\n/* \u8F7D\u5165\u9AA8\u67B6\uFF1A\u5148\u5360\u4F4F\u7248\u5F0F\uFF0C\u522B\u8BA9\u5185\u5BB9\u8DF3\u8FDB\u6765\u3002 */\n.kwSkeleton { display: grid; gap: 8px; padding: 18px 20px 22px; }\n.kwSkeletonRow {\n height: 12px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--tita-surface-muted) 25%, color-mix(in srgb, var(--tita-surface-muted) 45%, var(--tita-surface)) 37%, var(--tita-surface-muted) 63%);\n background-size: 400% 100%;\n animation: kwShimmer 1.5s ease-in-out infinite;\n}\n.kwSkeletonRow:nth-child(2) { width: 82%; }\n.kwSkeletonRow:nth-child(3) { width: 64%; }\n@keyframes kwShimmer {\n from { background-position: 100% 50%; }\n to { background-position: 0 50%; }\n}\n\n/* ------------------------------------------------------------- \u9636\u6BB5\u89C6\u56FE\n *\n * \u62BD\u53D6\u4EE5\u5916\u7684\u56DB\u6BB5\uFF1A\u4E00\u53E5\u5B83\u505A\u4EC0\u4E48\u3001\u672C\u6B65\u8F93\u5165\u3001\u7248\u672C\u8BB0\u5F55\u3001\u7248\u672C\u8BE6\u60C5\u3002\n * \u4E09\u8005\u5404\u81EA\u6210\u5757\uFF0C\u5757\u5185\u4E0D\u518D\u5957\u5361\u3002\n */\n.kwStage { display: grid; min-width: 0; gap: 14px; }\n.kwStageHead {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px 20px;\n border: 1px solid var(--tita-line);\n border-radius: 12px;\n background: var(--tita-surface);\n padding: 17px 20px 16px;\n}\n.kwStageCopy { display: grid; min-width: 0; gap: 3px; }\n.kwStageCopy h2 { margin: 0; color: var(--tita-ink); font-size: 17px; font-weight: 710; letter-spacing: -.018em; line-height: 1.35; }\n.kwStageCopy p { max-width: 66ch; margin: 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.65; }\n.kwStageActions { display: flex; flex: 0 0 auto; flex-wrap: wrap; align-items: center; gap: 8px; }\n\n.kwInput {\n border: 1px solid var(--tita-line);\n border-radius: 12px;\n background: var(--tita-surface);\n padding: 13px 16px 14px;\n}\n.kwInputHead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }\n.kwInputHead strong { color: var(--tita-ink); font-size: 12px; font-weight: 680; }\n.kwInputHead span { margin-right: auto; color: var(--tita-ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }\n.kwInputList {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n max-height: 148px;\n margin: 10px 0 0;\n padding: 0;\n overflow-y: auto;\n list-style: none;\n scrollbar-width: thin;\n scrollbar-color: var(--tita-line-strong) transparent;\n}\n.kwInputItem {\n display: inline-flex;\n max-width: 100%;\n align-items: center;\n gap: 7px;\n border: 1px solid var(--tita-line);\n border-radius: 7px;\n background: var(--tita-surface-muted);\n padding: 4px 8px;\n font-size: 11.5px;\n line-height: 1.5;\n}\n.kwInputItem > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.kwInputItem > small { flex: 0 0 auto; color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n\n.kwSplit { display: grid; grid-template-columns: minmax(220px, 268px) minmax(0, 1fr); align-items: start; gap: 16px; min-width: 0; }\n.kwVersions {\n min-width: 0;\n border: 1px solid var(--tita-line);\n border-radius: 12px;\n background: var(--tita-surface);\n overflow: hidden;\n}\n.kwVersionsHead {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n border-bottom: 1px solid var(--tita-line);\n padding: 11px 14px;\n}\n.kwVersionsHead strong { color: var(--tita-ink); font-size: 12px; font-weight: 680; }\n.kwVersionsHead span { color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n.kwVersionItem {\n display: grid;\n width: 100%;\n gap: 2px;\n border: 0;\n border-bottom: 1px solid var(--tita-line);\n background: none;\n padding: 9px 14px 10px;\n color: inherit;\n font: inherit;\n text-align: left;\n cursor: pointer;\n transition: background-color 120ms ease;\n}\n.kwVersionItem:hover { background: var(--tita-surface-muted); }\n.kwVersionItem:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }\n.kwVersionItem[data-on] { background: color-mix(in srgb, var(--tita-primary) 7%, var(--tita-surface)); }\n.kwVersionItem strong { color: var(--tita-ink); font-size: 11.5px; font-weight: 650; font-variant-numeric: tabular-nums; }\n.kwVersionItem[data-on] strong { color: var(--tita-primary); }\n.kwVersionItem small { color: var(--tita-ink-faint); font-size: 10px; font-variant-numeric: tabular-nums; }\n.kwVersionDocs { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 14px 9px; border-bottom: 1px solid var(--tita-line); }\n.kwPager { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 7px 10px; color: var(--tita-ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }\n\n.kwDetail { min-width: 0; border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); }\n.kwDetailHead {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: start;\n gap: 8px 14px;\n padding: 15px 18px 13px;\n}\n.kwDetailHead h2 { margin: 0; color: var(--tita-ink); font-size: 15px; font-weight: 700; letter-spacing: -.015em; line-height: 1.4; overflow-wrap: anywhere; }\n.kwDetailHead p { margin: 2px 0 0; color: var(--tita-ink-muted); font-size: 11.5px; line-height: 1.6; overflow-wrap: anywhere; }\n.kwMetaLine { display: flex; flex-wrap: wrap; gap: 3px 14px; margin: 0; padding: 0 18px 12px; color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.5; font-variant-numeric: tabular-nums; }\n.kwMetaLine > span { display: inline-flex; align-items: center; gap: 4px; }\n\n.kwLog { border-top: 1px solid var(--tita-line); padding: 4px 18px 16px; }\n.kwLog h3 { margin: 12px 0 4px; color: var(--tita-ink); font-size: 12px; font-weight: 680; }\n.kwTimeline { display: grid; margin: 0; padding: 0; list-style: none; }\n.kwTimeline li { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 12px; border-bottom: 1px solid var(--tita-line); padding: 9px 0; }\n.kwTimeline li:last-child { border-bottom: 0; }\n.kwTimeline time { padding-top: 1px; color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }\n.kwTimeline p { margin: 0; color: var(--tita-ink); font-size: 11.5px; line-height: 1.6; overflow-wrap: anywhere; }\n.kwTimeline li[data-warn] p { color: var(--tita-warning); }\n\n/* \u6A21\u578B\u8BF7\u6C42\uFF1A\u9ED8\u8BA4\u6536\u8D77\u3002\u539F\u59CB\u8F93\u5165\u8F93\u51FA\u662F\u8BC1\u636E\uFF0C\u4E0D\u662F\u9996\u5C4F\u7ED3\u8BBA\u3002 */\n.kwCalls { display: grid; margin-top: 6px; }\n.kwCall { border-bottom: 1px solid var(--tita-line); }\n.kwCall:last-child { border-bottom: 0; }\n.kwCall > summary {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 5px 10px;\n padding: 10px 0;\n color: var(--tita-ink);\n cursor: pointer;\n list-style: none;\n}\n.kwCall > summary::-webkit-details-marker { display: none; }\n.kwCall > summary::before {\n width: 6px;\n height: 6px;\n flex: 0 0 auto;\n border-right: 1.5px solid var(--tita-ink-faint);\n border-bottom: 1.5px solid var(--tita-ink-faint);\n content: '';\n transform: rotate(-45deg);\n transition: transform 140ms ease;\n}\n.kwCall[open] > summary::before { transform: rotate(45deg); }\n.kwCall > summary:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 2px; }\n.kwCall > summary strong { font-size: 11.5px; font-weight: 650; }\n.kwCall > summary small { color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n.kwCall > summary > span { margin-left: auto; }\n.kwCallBody { padding: 2px 0 14px 15px; }\n\n.kwHint { margin: 8px 0 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.6; }\n.kwHintWarn { color: var(--tita-warning); }\n.kwHint a { color: var(--tita-primary); text-decoration: underline; text-underline-offset: 2px; }\n\n/* ------------------------------------------------------------- \u6DFB\u52A0\u6587\u4EF6 */\n\n/* \u5BF9\u8BDD\u6846\u58F3\uFF1A\u6BD4\u9ED8\u8BA4 420px \u5BBD\uFF0C\u88C5\u5F97\u4E0B\u300C\u62D6\u653E\u533A + \u5F85\u5BFC\u5165\u961F\u5217\u300D\u4E24\u5217\u3002 */\n.kwImportDialog { width: min(880px, calc(100vw - 32px)); }\n/* \u8FD0\u884C\u4E2D\u4E0D\u63D0\u4F9B\u5173\u95ED\uFF1A\u5BFC\u5165\u5728\u6D4F\u89C8\u5668\u91CC\u9010\u6761\u5199\uFF0C\u5378\u8F7D\u7EC4\u4EF6\u5C31\u4E22\u8FDB\u5EA6\u3002 */\n.kwImportDialog[data-busy='true'] > button[aria-label='\u5173\u95ED'] { display: none; }\n.kwImportDialog .kwImportLayout { margin-top: 14px; }\n.kwImportDialog .kwDrop { min-height: 208px; }\n.kwImportDialog .kwImportList { max-height: 300px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--tita-line-strong) transparent; }\n.kwImportFoot {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n margin-top: 16px;\n border-top: 1px solid var(--tita-line);\n padding-top: 12px;\n}\n.kwImportFootNote { flex: 1 1 240px; margin: 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.55; }\n.kwImportFootActions { display: flex; align-items: center; gap: 8px; margin-left: auto; }\n@media (max-width: 640px) {\n .kwImportFootNote { flex-basis: 100%; }\n .kwImportFootActions { width: 100%; margin-left: 0; }\n .kwImportFootActions .tita-uiButton { flex: 1 1 0; }\n}\n.kwImportLayout { display: grid; grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); align-items: stretch; gap: 14px; }\n.kwDrop {\n display: flex;\n min-height: 232px;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 9px;\n border: 1px dashed var(--tita-line-strong);\n border-radius: 12px;\n background: var(--tita-surface);\n padding: 26px;\n text-align: center;\n transition: border-color 140ms ease, background-color 140ms ease;\n}\n.kwDrop:hover { border-color: var(--tita-primary-line); background: color-mix(in srgb, var(--tita-primary) 3%, var(--tita-surface)); }\n.kwDropIcon {\n display: inline-flex;\n width: 38px;\n height: 38px;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--tita-primary-line);\n border-radius: 11px;\n background: var(--tita-primary-soft);\n color: var(--tita-primary);\n}\n.kwDrop strong { color: var(--tita-ink); font-size: 13px; font-weight: 650; }\n.kwDrop span { color: var(--tita-ink-muted); font-size: 11.5px; line-height: 1.6; }\n.kwQueuePanel {\n display: flex;\n min-width: 0;\n flex-direction: column;\n border: 1px solid var(--tita-line);\n border-radius: 12px;\n background: var(--tita-surface);\n padding: 14px 16px 15px;\n}\n.kwQueuePanelHead { display: flex; align-items: baseline; gap: 10px; border-bottom: 1px solid var(--tita-line); padding-bottom: 10px; }\n.kwQueuePanelHead h3 { margin: 0; color: var(--tita-ink); font-size: 12.5px; font-weight: 680; }\n.kwQueuePanelHead span { color: var(--tita-ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }\n.kwImportRow {\n display: flex;\n min-width: 0;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 10px;\n border-bottom: 1px solid var(--tita-line);\n padding: 11px 0;\n}\n.kwImportRow > svg { flex: 0 0 auto; color: var(--tita-ink-muted); }\n.kwImportName { display: grid; min-width: 120px; flex: 1 1 160px; gap: 2px; }\n.kwImportName strong { color: var(--tita-ink); font-size: 12px; font-weight: 620; overflow-wrap: anywhere; }\n.kwImportName small { color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n.kwImportState { color: var(--tita-ink-muted); font-size: 11px; }\n\n/* ---------------------------------------------------------------- \u6587\u6863\u94FE\u8DEF */\n\n.kwLineage { display: grid; gap: 12px; }\n.kwLineageBar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }\n.kwLineageBar > label { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; color: var(--tita-ink-muted); font-size: 11.5px; }\n.kwLineageBar > span { color: var(--tita-ink-faint); font-size: 11px; font-variant-numeric: tabular-nums; }\n.kwLineageBar > div:last-child { margin-left: auto; }\n.kwLayers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: start; gap: 12px; }\n.kwLayer { min-width: 0; overflow: hidden; border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); }\n.kwLayer > header {\n display: flex;\n align-items: center;\n gap: 7px;\n border-bottom: 1px solid var(--tita-line);\n padding: 10px 14px;\n color: var(--tita-ink);\n font-size: 12px;\n}\n.kwLayer > header > svg { color: var(--tita-ink-muted); }\n.kwLayer > header > strong { font-weight: 680; }\n.kwLayer > header > span { margin-left: auto; color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n.kwLayerList { margin: 0; padding: 0; list-style: none; }\n.kwLayerMore { display: flex; align-items: center; justify-content: space-between; gap: 8px; border-top: 1px solid var(--tita-line); padding: 4px 10px 4px 14px; color: var(--tita-ink-muted); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n.kwLayerItem { display: grid; gap: 3px; border-bottom: 1px solid var(--tita-line); padding: 9px 14px 10px; }\n.kwLayerItem:last-child { border-bottom: 0; }\n.kwLayerItem:hover { background: color-mix(in srgb, var(--tita-surface-muted) 56%, var(--tita-surface)); }\n.kwLayerRow { display: flex; min-width: 0; align-items: baseline; gap: 8px; }\n.kwLayerText { min-width: 0; flex: 1 1 auto; color: var(--tita-ink); font-size: 11.5px; line-height: 1.6; overflow-wrap: anywhere; }\n.kwLayerItem small { color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.5; overflow-wrap: anywhere; }\n.kwLayerFoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 2px 0; color: var(--tita-ink-faint); font-size: 10.5px; font-variant-numeric: tabular-nums; }\n.kwLayerActions { display: flex; justify-content: flex-end; gap: 6px; }\n\n/* ---------------------------------------------------------------- \u7F16\u8BD1\u8BBE\u7F6E */\n\n.kwSettings { display: grid; gap: 14px; }\n.kwSettingsGrid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: stretch; gap: 12px; }\n.kwSettingStack { display: grid; gap: 12px; align-content: start; }\n/* \u5907\u6CE8\u662F\u4E00\u6BB5\u4F1A\u4E00\u76F4\u6539\u7684\u6587\u5B57\uFF1A\u8BA9\u5B83\u628A\u53F3\u5217\u6491\u6EE1\uFF0C\u800C\u4E0D\u662F\u7F29\u5728\u5361\u9876\u7559\u4E00\u5927\u7247\u7A7A\u767D\u3002 */\n.kwSettingNote { display: flex; flex-direction: column; }\n.kwSettingNote > .tita-uiField { display: flex; flex: 1 1 auto; flex-direction: column; }\n.kwSettingNote textarea { flex: 1 1 auto; min-height: 200px; }\n/* \u5750\u6807\u5B9E\u4F53\u662F\u4E00\u5F20\u4F1A\u957F\u540D\u5355\uFF1A\u884C\u5185\u52A8\u4F5C\u9489\u5728\u7B2C\u4E00\u884C\u53F3\u4FA7\uFF0C\u4E0D\u8DDF\u7740\u300C\u5B9A\u4E49\u300D\u90A3\u4E00\u884C\u4E0B\u6C89\u3002 */\n.kwSettings .tita-axisRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: start;\n gap: 3px 12px;\n padding: 10px 0;\n}\n.kwSettings .tita-axisRow > .tita-axisName { grid-column: 1; grid-row: 1; }\n.kwSettings .tita-axisRow > .tita-axisAliases,\n.kwSettings .tita-axisRow > .tita-axisScope { grid-column: 1 / -1; }\n.kwSettings .tita-axisActions { grid-column: 2; grid-row: 1; justify-self: end; margin-left: 0; }\n.kwSettingCard { min-width: 0; border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); padding: 14px 16px 15px; }\n.kwSettingWide { grid-column: 1 / -1; }\n.kwSettingHead { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 12px; margin-bottom: 10px; }\n.kwSettingHead h2 { margin: 0; color: var(--tita-ink); font-size: 12.5px; font-weight: 680; }\n.kwSettingHead p { margin: 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.55; }\n.kwSettingRows { display: grid; gap: 14px; }\n.kwSettingActions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 11px; border-top: 1px solid var(--tita-line); padding-top: 11px; }\n.kwSettings > .tita-settingsSection { border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); padding: 4px 16px 8px; }\n\n/* ---------------------------------------------------------------- \u7A84\u5C4F */\n\n@media (max-width: 1180px) {\n .kwBody { grid-template-columns: minmax(260px, 300px) minmax(0, 1fr); }\n .kwSplit { grid-template-columns: minmax(200px, 240px) minmax(0, 1fr); }\n}\n\n@media (max-width: 1024px) {\n .kwBody { grid-template-columns: minmax(0, 1fr); }\n .kwQueue { position: static; max-height: 46vh; }\n .kwSplit { grid-template-columns: minmax(0, 1fr); }\n .kwLayers { grid-template-columns: minmax(0, 1fr); }\n}\n\n@media (max-width: 900px) {\n .kwBarInner { grid-template-columns: minmax(0, 1fr) auto; }\n .kwIdent { grid-row: 1; grid-column: 1; }\n .kwActions { grid-row: 1; grid-column: 2; justify-self: end; }\n .kwTabs { grid-column: 1 / -1; grid-row: 2; width: 100%; justify-content: flex-start; }\n .kwTab { flex: 1 1 auto; text-align: center; }\n .kwActions { grid-row: 1; }\n /* \u5DE5\u5E8F\u5E26\u5728\u7A84\u5C4F\u53D8\u6210\u4E00\u6761\u53EF\u6A2A\u6ED1\u7684\u5E26\uFF1A\u4FDD\u6301\u300C\u4E00\u6761\u94FE\u8DEF\u300D\u7684\u5F62\u72B6\uFF0C\u4E0D\u6298\u6210\u5361\u7247\u5899\u3002 */\n .kwGate { flex: 0 0 200px; scroll-snap-align: start; }\n .kwBand {\n scroll-snap-type: x proximity;\n flex-wrap: nowrap;\n overflow-x: auto;\n padding-bottom: 2px;\n scrollbar-width: thin;\n scrollbar-color: var(--tita-line-strong) transparent;\n }\n .kwIdentCopy p { display: none; }\n .kwSettingsGrid { grid-template-columns: minmax(0, 1fr); }\n .kwSettingNote { grid-column: auto; }\n .kwSettingNote textarea { min-height: 150px; }\n .kwImportLayout { grid-template-columns: minmax(0, 1fr); }\n .kwDrop { min-height: 180px; }\n}\n\n@media (max-width: 760px) {\n .kwBarInner { padding: 9px 16px; gap: 8px 12px; }\n .kwActions { gap: 2px; }\n .kwScope { flex-direction: column; gap: 2px; }\n .kwMain { padding: 14px 16px 72px; }\n .kwInspectorHead { grid-template-columns: minmax(0, 1fr); padding: 14px 16px 12px; }\n .kwInspectorActions { justify-content: flex-start; }\n .kwVersionBar { padding-inline: 16px; }\n .kwTabsRow { padding-inline: 16px; }\n .kwTabsRow .tita-uiTabsList { gap: 14px; }\n .kwResultBar { padding-inline: 16px; }\n .kwChips { margin-left: 0; }\n .kwResult { grid-template-columns: 52px minmax(0, 1fr); padding-inline: 16px; }\n .kwResultIndex { display: none; }\n .kwResultText { font-size: 12px; line-height: 1.7; }\n .kwDetailHead { grid-template-columns: minmax(0, 1fr); }\n .kwLineageBar > div:last-child { margin-left: 0; width: 100%; justify-content: flex-start; }\n .kwTimeline li { grid-template-columns: 86px minmax(0, 1fr); gap: 9px; }\n .kwStageHead { padding: 14px 16px; }\n}\n\n@media (max-width: 620px) {\n .kwActionLabel { display: none; }\n .kwActions .tita-uiButton { padding-inline: 8px; }\n}\n\n@media (max-width: 430px) {\n .kwGate { flex-basis: 178px; }\n .kwKind { font-size: 9px; letter-spacing: .05em; }\n .kwResult { grid-template-columns: 46px minmax(0, 1fr); gap: 8px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .kwLive { animation: none; }\n .kwSkeletonRow { animation: none; background: var(--tita-surface-muted); }\n .kwGateBar > span,\n .kwGate::before,\n .kwCall > summary::before { transition: none; }\n}\n\n/* \u51E0\u5904\u53EA\u5728\u4E2A\u522B\u89C6\u56FE\u91CC\u51FA\u73B0\u7684\u6392\u5E03\uFF0C\u7ED9\u6210\u7C7B\u540D\u800C\u4E0D\u662F\u884C\u5185 style\u3002 */\n.kwImportList { margin: 0; padding: 0; list-style: none; }\n.kwImportProgress { display: grid; gap: 6px; margin-top: 12px; }\n.kwEmptyCompact { padding: 34px 12px; }\n.kwVersionsEmpty { padding: 0 14px 12px; }\n.kwResultBar .kwSearch { width: 172px; flex: 0 0 auto; }\n.kwQueueFoot { border-top: 1px solid var(--tita-line); background: var(--tita-surface); padding: 9px 12px; }\n.kwQueueFoot .tita-uiButton { width: 100%; }\n.kwQueueAllDone { display: flex; align-items: center; justify-content: center; gap: 5px; margin: 0; padding: 3px 0; color: var(--tita-ink-muted); font-size: 11px; line-height: 1.5; }\n.kwQueueAllDone svg { color: var(--tita-tone-green); }\n.kwInspector .kwNotice { margin: 12px 20px 0; }\n.kwLayerHint { padding: 0 14px 14px; }\n.kwLayerCount { flex: 0 0 auto; }\n.kwNoteMeta { margin: 6px 0 0; color: var(--tita-ink-faint); font-size: 10.5px; line-height: 1.5; font-variant-numeric: tabular-nums; }\n";
7326
+ var css4 = `/*
7327
+ * \u77E5\u8BC6\u5904\u7406\u6574\u9875\uFF08\`/knowledge/pages/tasks\`\uFF09\u81EA\u5DF1\u7684\u5DE5\u4F5C\u53F0\u6837\u5F0F\u3002
7328
+ *
7329
+ * ## \u4E3A\u4EC0\u4E48\u8FD9\u4E00\u9875\u4E0D\u5957 \`page-bar\`
7330
+ *
7331
+ * \u5176\u4F59\u6574\u9875\uFF08\u8BD5\u8DD1\u3001\u8F68\u8FF9\u3001\u8BF4\u660E\uFF09\u662F**\u8BFB**\u7684\u4E00\u9875\uFF1A\u4E00\u6761\u5E38\u9A7B\u7A84\u6761 + \u4E00\u680F\u6B63\u6587\u5C31\u591F\u3002
7332
+ * \u8FD9\u4E00\u9875\u662F**\u64CD\u4F5C**\u7684\u4E00\u9875\uFF1A\u4EBA\u5728\u8FD9\u91CC\u770B\u4E94\u6BB5\u8DD1\u5230\u54EA\u3001\u6311\u4E00\u4EFD\u6587\u6863\u3001\u7FFB\u5B83\u7684\u62BD\u53D6\u7ED3\u679C\u3002
7333
+ * \u6240\u4EE5\u9876\u680F\u4E0D\u662F\u6807\u9898\u6761\uFF0C\u800C\u662F\u4E00\u6761\u771F\u6B63\u7684\u5E94\u7528\u680F \u2014\u2014 \u8EAB\u4EFD\u3001\u89C6\u56FE\u5207\u6362\u3001\u52A8\u4F5C\u90FD\u5728\u91CC\u9762\uFF0C
7334
+ * \u800C\u4E14\u5438\u9876\u3002\u6302\u4E24\u5C42\u5934\uFF08\u5916\u58F3\u4E00\u6761\u3001\u9875\u9762\u518D\u4E00\u6761\uFF09\u53EA\u4F1A\u8BA9\u540C\u4E00\u4E2A\u6807\u9898\u51FA\u73B0\u4E24\u904D\u3002
7335
+ *
7336
+ * ## \u7248\u5F0F\u7684\u4E00\u6761\u7EAA\u5F8B
7337
+ *
7338
+ * \u9875\u9762\u4ECE\u4E0A\u5230\u4E0B\u53EA\u6709\u4E09\u79CD\u4E1C\u897F\uFF1A**\u5DE5\u5E8F\u5E26**\uFF08\u4E94\u6BB5\u8D70\u5230\u54EA\uFF09\u3001**\u961F\u5217**\uFF08\u6709\u54EA\u4E9B\u5BF9\u8C61\uFF09\u3001
7339
+ * **\u68C0\u67E5\u5668**\uFF08\u9009\u4E2D\u90A3\u4E00\u4E2A\u7684\u7EC6\u8282\uFF09\u3002\u4E00\u4E2A\u4E8B\u5B9E\u53EA\u51FA\u73B0\u4E00\u6B21\uFF1A\u9636\u6BB5\u72B6\u6001\u53EA\u5728\u5E26\u4E0A\uFF0C
7340
+ * \u5F85\u529E\u6570\u91CF\u53EA\u5728\u961F\u5217\u91CC\uFF0C\u62BD\u53D6\u7ED3\u679C\u53EA\u5728\u68C0\u67E5\u5668\u91CC\u3002
7341
+ *
7342
+ * \u6240\u6709\u989C\u8272\u8D70\u5171\u4EAB\u4EE4\u724C\uFF08\`@tita-agent/ui/styles.css\` \u5E26\u8FDB\u6765\u7684\u90A3\u4E00\u5957\uFF09\uFF0C
7343
+ * \u6240\u4EE5\u6DF1\u8272\u4E3B\u9898\u8DDF\u7740\u5BBF\u4E3B\u8D70\uFF0C\u8FD9\u4E00\u9875\u4E0D\u9700\u8981\u7B2C\u4E8C\u4EFD\u914D\u8272\u3002
7344
+ */
7345
+
7346
+ .kwPage {
7347
+ min-height: 100dvh;
7348
+ background: var(--tita-canvas);
7349
+ color: var(--tita-ink);
7350
+ font-family: var(--tita-font);
7351
+ }
7352
+ .kwTabs::-webkit-scrollbar { display: none; }
7353
+ .kwPage input,
7354
+ .kwPage textarea { caret-color: var(--tita-primary); }
7355
+ .kwPage ::selection { background: var(--tita-primary-soft); color: var(--tita-ink); }
7356
+
7357
+ /* ------------------------------------------------------------------ \u5E94\u7528\u680F */
7358
+
7359
+ /* \u5438\u9876\u680F\uFF1A\u6EDA\u52A8\u65F6\u300C\u8FD9\u662F\u54EA\u4E2A\u5E93\u3001\u5728\u54EA\u4E00\u9875\u300D\u4E00\u76F4\u5728\u3002\u7528\u5B9E\u8272 + \u53D1\u4E1D\u7EBF\uFF0C
7360
+ \u4E0D\u505A\u6BDB\u73BB\u7483 \u2014\u2014 \u5185\u5BB9\u4ECE\u5E95\u4E0B\u7A7F\u8FC7\u65F6\uFF0C\u534A\u900F\u660E\u4F1A\u540C\u65F6\u8BFB\u51FA\u4E24\u5C42\u6587\u5B57\u3002 */
7361
+ .kwBar {
7362
+ position: sticky;
7363
+ top: 0;
7364
+ z-index: 30;
7365
+ border-bottom: 1px solid var(--tita-line);
7366
+ background: var(--tita-surface);
7367
+ }
7368
+ .kwBarInner {
7369
+ display: grid;
7370
+ grid-template-columns: minmax(0, 1fr) auto auto;
7371
+ align-items: center;
7372
+ gap: 10px 18px;
7373
+ max-width: 1440px;
7374
+ margin-inline: auto;
7375
+ padding: 10px 28px;
7376
+ }
7377
+ .kwIdent { display: flex; min-width: 0; align-items: center; gap: 11px; }
7378
+ .kwMark {
7379
+ display: inline-flex;
7380
+ width: 32px;
7381
+ height: 32px;
7382
+ flex: 0 0 auto;
7383
+ align-items: center;
7384
+ justify-content: center;
7385
+ border: 1px solid var(--tita-primary-line);
7386
+ border-radius: 9px;
7387
+ background: var(--tita-primary-soft);
7388
+ color: var(--tita-primary);
7389
+ }
7390
+ .kwIdentCopy { display: grid; min-width: 0; gap: 1px; }
7391
+ .kwIdentCopy h1 {
7392
+ margin: 0;
7393
+ font-size: 17px;
7394
+ font-weight: 720;
7395
+ letter-spacing: -.015em;
7396
+ line-height: 1.4;
7397
+ }
7398
+ .kwIdentCopy p {
7399
+ margin: 0;
7400
+ overflow: hidden;
7401
+ color: var(--tita-ink-muted);
7402
+ font-size: 12px;
7403
+ line-height: 1.45;
7404
+ text-overflow: ellipsis;
7405
+ white-space: nowrap;
7406
+ }
7407
+ .kwIdentCopy b { color: var(--tita-ink); font-weight: 620; }
7408
+
7409
+ /* \u89C6\u56FE\u5207\u6362\uFF1A\u540C\u4E00\u9875\u7684\u4E09\u79CD\u8BFB\u6CD5\uFF0C\u4E0D\u662F\u7B2C\u4E8C\u6B65\u5BFC\u822A\u3002 */
7410
+ .kwTabs {
7411
+ display: inline-flex;
7412
+ align-items: center;
7413
+ overflow-x: auto;
7414
+ scrollbar-width: none;
7415
+ gap: 2px;
7416
+ border: 1px solid var(--tita-line);
7417
+ border-radius: 9px;
7418
+ background: var(--tita-surface-muted);
7419
+ padding: 2px;
7420
+ }
7421
+ .kwTab {
7422
+ border: 0;
7423
+ border-radius: 7px;
7424
+ background: transparent;
7425
+ padding: 5px 13px;
7426
+ color: var(--tita-ink-muted);
7427
+ font: inherit;
7428
+ font-size: 12px;
7429
+ font-weight: 620;
7430
+ line-height: 1.4;
7431
+ white-space: nowrap;
7432
+ cursor: pointer;
7433
+ transition: background-color 120ms ease, color 120ms ease;
7434
+ }
7435
+ .kwTab:hover { color: var(--tita-ink); }
7436
+ .kwTab[aria-pressed='true'] {
7437
+ background: var(--tita-surface);
7438
+ color: var(--tita-ink);
7439
+ box-shadow: 0 1px 2px rgb(16 24 40 / .1);
7440
+ }
7441
+ .kwTab:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }
7442
+ .kwActions { display: flex; align-items: center; gap: 6px; }
7443
+
7444
+ /* --------------------------------------------------------------- \u4E3B\u5185\u5BB9\u533A */
7445
+
7446
+ .kwMain { max-width: 1440px; margin-inline: auto; padding: 18px 28px 96px; }
7447
+ .kwColumn { display: grid; min-width: 0; gap: 14px; }
7448
+
7449
+ /* \u4E00\u6761\u63D0\u793A\uFF1A\u6210\u529F\u3001\u5931\u8D25\u3001\u6216\u300C\u8FD9\u4E00\u9875\u8BFB\u4E0D\u5230\u6570\u636E\u300D\u3002 */
7450
+ .kwNotice {
7451
+ display: flex;
7452
+ align-items: flex-start;
7453
+ gap: 9px;
7454
+ border: 1px solid var(--tita-line);
7455
+ border-radius: 10px;
7456
+ padding: 9px 10px 9px 12px;
7457
+ font-size: 12px;
7458
+ line-height: 1.55;
7459
+ }
7460
+ .kwNotice > svg { flex: 0 0 auto; margin-top: 2px; }
7461
+ .kwNotice > span { min-width: 0; flex: 1 1 auto; overflow-wrap: anywhere; }
7462
+ .kwNotice-success { border-color: var(--tita-tone-green-line); background: var(--tita-tone-green-tint); color: var(--tita-tone-green); }
7463
+ .kwNotice-error { border-color: color-mix(in srgb, var(--tita-danger) 32%, var(--tita-surface)); background: color-mix(in srgb, var(--tita-danger) 7%, var(--tita-surface)); color: var(--tita-danger); }
7464
+ .kwNotice-warn { border-color: color-mix(in srgb, var(--tita-warning) 30%, var(--tita-surface)); background: color-mix(in srgb, var(--tita-warning) 6%, var(--tita-surface)); color: var(--tita-warning); }
7465
+ .kwNotice-info { border-color: var(--tita-line); background: var(--tita-surface-muted); color: var(--tita-ink-muted); }
7466
+
7467
+ /* ------------------------------------------------------------------ \u5DE5\u5E8F\u5E26
7468
+ *
7469
+ * \u4E94\u6BB5\u662F\u8FD9\u6761\u6D41\u6C34\u7EBF\u7684\u9AA8\u67B6\uFF0C\u6240\u4EE5\u5B83\u662F\u4E00\u6761**\u8D2F\u7A7F\u6574\u9875\u7684\u5E26**\uFF0C\u4E0D\u662F\u4E00\u4E2A\u5361\u7247\u533A\u3002
7470
+ * \u6BCF\u683C\u9876\u8FB9 2px \u662F\u8FD9\u4E00\u6BB5\u7684**\u72B6\u6001\u8272**\uFF08\u6210\u529F\u7EFF / \u8FD0\u884C\u84DD / \u5F85\u91CD\u8DD1\u7425\u73C0\uFF09\uFF0C
7471
+ * \u5E95\u8FB9\u7EC6\u7EBF\u662F\u5B8C\u6210\u6BD4\u4F8B\u3002\u4E24\u8005\u90FD\u4E0D\u5199\u5B57\uFF0C\u6240\u4EE5\u626B\u4E00\u773C\u5C31\u6709\u8BFB\u6570\uFF0C\u8BFB\u5B57\u662F\u7B2C\u4E8C\u6B65\u3002
7472
+ */
7473
+ .kwBand {
7474
+ display: flex;
7475
+ align-items: stretch;
7476
+ gap: 8px;
7477
+ min-width: 0;
7478
+ }
7479
+ .kwGate {
7480
+ flex: 1 1 0;
7481
+ min-width: 0;
7482
+ overflow: hidden;
7483
+ border: 1px solid var(--tita-line);
7484
+ border-radius: 10px;
7485
+ background: var(--tita-surface);
7486
+ transition: border-color 140ms ease, background-color 140ms ease;
7487
+ }
7488
+ .kwGate:hover { border-color: var(--tita-line-strong); }
7489
+ /* \u9009\u4E2D\u7684\u90A3\u4E00\u6B65\u7528**\u8FB9\u6846 + \u5E95\u8272**\u8868\u6001\uFF0C\u4E0D\u9760\u4E00\u6761\u76D6\u5728\u6574\u6761\u5E26\u4E0A\u7684\u8272\u6761\uFF1A
7490
+ \u4E94\u6B65\u662F\u4E94\u4E2A\u683C\u5B50\uFF0C\u4E0D\u662F\u4E00\u4E2A\u8868\u683C\u3002 */
7491
+ .kwGate[data-on] { border-color: var(--tita-primary-line); background: var(--tita-primary-soft); }
7492
+ .kwBandArrow {
7493
+ display: inline-flex;
7494
+ flex: 0 0 auto;
7495
+ align-items: center;
7496
+ align-self: center;
7497
+ color: var(--tita-ink-faint);
7498
+ }
7499
+ .kwGateBtn {
7500
+ display: grid;
7501
+ width: 100%;
7502
+ min-width: 0;
7503
+ gap: 4px;
7504
+ border: 0;
7505
+ background: none;
7506
+ padding: 11px 13px 12px;
7507
+ color: inherit;
7508
+ font: inherit;
7509
+ text-align: left;
7510
+ cursor: pointer;
7511
+ transition: background-color 140ms ease;
7512
+ }
7513
+ .kwGateBtn:hover { background: color-mix(in srgb, var(--tita-surface-muted) 62%, var(--tita-surface)); }
7514
+ .kwGateBtn:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }
7515
+ .kwGate[data-on] .kwGateBtn { background: transparent; }
7516
+ .kwGateTop { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
7517
+ .kwGateIndex {
7518
+ color: var(--tita-ink-faint);
7519
+ font-family: var(--tita-mono);
7520
+ font-size: 12px;
7521
+ font-weight: 600;
7522
+ letter-spacing: .1em;
7523
+ }
7524
+ .kwGateState {
7525
+ display: inline-flex;
7526
+ align-items: center;
7527
+ gap: 4px;
7528
+ color: var(--tita-ink-muted);
7529
+ font-size: 12px;
7530
+ font-weight: 620;
7531
+ line-height: 1.4;
7532
+ white-space: nowrap;
7533
+ }
7534
+ .kwGate[data-tone='success'] .kwGateState { color: var(--tita-tone-green); }
7535
+ .kwGate[data-tone='warning'] .kwGateState { color: var(--tita-warning); }
7536
+ .kwGate[data-tone='blue'] .kwGateState { color: var(--tita-primary); }
7537
+ .kwGateName {
7538
+ display: flex;
7539
+ min-width: 0;
7540
+ align-items: center;
7541
+ gap: 6px;
7542
+ color: var(--tita-ink);
7543
+ font-size: 13.5px;
7544
+ font-weight: 650;
7545
+ line-height: 1.4;
7546
+ }
7547
+ .kwGateName svg { flex: 0 0 auto; color: var(--tita-ink-muted); }
7548
+ .kwGate[data-on] .kwGateName svg,
7549
+ .kwGate[data-tone='blue'] .kwGateName svg { color: var(--tita-primary); }
7550
+ .kwGateFact {
7551
+ overflow: hidden;
7552
+ color: var(--tita-ink-muted);
7553
+ font-size: 12px;
7554
+ line-height: 1.45;
7555
+ font-variant-numeric: tabular-nums;
7556
+ text-overflow: ellipsis;
7557
+ white-space: nowrap;
7558
+ }
7559
+ .kwGateBar {
7560
+ height: 2px;
7561
+ margin-top: 3px;
7562
+ overflow: hidden;
7563
+ border-radius: 2px;
7564
+ background: var(--tita-surface-muted);
7565
+ }
7566
+ .kwGateBar > span {
7567
+ display: block;
7568
+ width: 100%;
7569
+ height: 100%;
7570
+ border-radius: 2px;
7571
+ background: var(--tita-ink-faint);
7572
+ transform-origin: left center;
7573
+ transition: transform 260ms cubic-bezier(.22, .7, .2, 1), background-color 180ms ease;
7574
+ }
7575
+ .kwGate[data-tone='success'] .kwGateBar > span { background: var(--tita-tone-green); }
7576
+ .kwGate[data-tone='warning'] .kwGateBar > span { background: var(--tita-warning); }
7577
+ .kwGate[data-tone='blue'] .kwGateBar > span { background: var(--tita-primary); }
7578
+
7579
+ /* \u5E26\u4E0B\u9762\u7684\u4E00\u884C\uFF1A\u672C\u8F6E\u4F1A\u4E0D\u4F1A\u52A8\u3001\u51ED\u4EC0\u4E48\u8FD9\u4E48\u5224\u3002\u5B83\u4E0D\u662F\u4E00\u5757\u5361\u7247\uFF0C\u662F\u4E00\u6761\u8BFB\u6570\u3002 */
7580
+ .kwScope {
7581
+ display: flex;
7582
+ flex-wrap: wrap;
7583
+ align-items: baseline;
7584
+ justify-content: space-between;
7585
+ gap: 2px 18px;
7586
+ padding: 0 2px;
7587
+ }
7588
+ .kwScopeNow { margin: 0; color: var(--tita-ink); font-size: 12px; line-height: 1.6; font-variant-numeric: tabular-nums; }
7589
+ .kwScopeKey { margin: 0; color: var(--tita-ink-faint); font-size: 12px; line-height: 1.6; }
7590
+
7591
+ /* \u8FD0\u884C\u4E2D\u7684\u90A3\u4E00\u6BB5\uFF1A\u72B6\u6001\u5B57\u524D\u9762\u4E00\u9897\u4F1A\u547C\u5438\u7684\u70B9\u3002\u5168\u9875\u53EA\u6709\u8FD9\u4E00\u5904\u52A8\u6548\u5E38\u9A7B\u3002 */
7592
+ .kwLive {
7593
+ width: 6px;
7594
+ height: 6px;
7595
+ flex: 0 0 auto;
7596
+ border-radius: 999px;
7597
+ background: var(--tita-primary);
7598
+ animation: kwPulse 1.9s ease-out infinite;
7599
+ }
7600
+ @keyframes kwPulse {
7601
+ 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tita-primary) 34%, transparent); }
7602
+ 70% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--tita-primary) 0%, transparent); }
7603
+ 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tita-primary) 0%, transparent); }
7604
+ }
7605
+
7606
+ /* ------------------------------------------------------- \u961F\u5217 + \u68C0\u67E5\u5668 \u53CC\u680F */
7607
+
7608
+ .kwBody {
7609
+ display: grid;
7610
+ grid-template-columns: minmax(286px, 332px) minmax(0, 1fr);
7611
+ align-items: start;
7612
+ gap: 16px;
7613
+ min-width: 0;
7614
+ }
7615
+
7616
+ /* \u961F\u5217\uFF1A\u5BF9\u8C61\u662F\u63A5\u4E0B\u6765\u8981\u52A8\u624B\u7684\u90A3\u4E00\u6279\u3002\u5B83\u5438\u9876\u5E76\u81EA\u5DF1\u6EDA \u2014\u2014
7617
+ \u53F3\u680F\u7684\u7ED3\u679C\u53EF\u80FD\u6709\u51E0\u5341\u5C4F\uFF0C\u9009\u6587\u6863\u4E0D\u8BE5\u9700\u8981\u5148\u6EDA\u56DE\u9875\u9876\u3002 */
7618
+ .kwQueue {
7619
+ position: sticky;
7620
+ top: 76px;
7621
+ display: grid;
7622
+ grid-template-rows: auto minmax(0, 1fr) auto;
7623
+ max-height: calc(100dvh - 100px);
7624
+ overflow: hidden;
7625
+ border: 1px solid var(--tita-line);
7626
+ border-radius: 12px;
7627
+ background: var(--tita-surface);
7628
+ }
7629
+ .kwQueueHead {
7630
+ display: grid;
7631
+ gap: 9px;
7632
+ border-bottom: 1px solid var(--tita-line);
7633
+ padding: 12px 14px 11px;
7634
+ }
7635
+ .kwQueueTitle { display: flex; align-items: center; gap: 7px; }
7636
+ .kwQueueTitle strong { color: var(--tita-ink); font-size: 12px; font-weight: 680; }
7637
+ .kwQueueTitle > span { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
7638
+ /* \u5165\u5E93\u662F\u8FD9\u4E00\u6BB5\u81EA\u5DF1\u7684\u52A8\u4F5C\uFF1A\u5B83\u8DDF\u7740\u6587\u6863\u5217\u8868\u8D70\uFF0C\u4E0D\u518D\u5360\u9876\u680F\u3002 */
7639
+ .kwQueueAdd { margin-left: auto; min-height: 26px; padding-inline: 9px; font-size: 12px; gap: 4px; }
7640
+ .kwQueueTools { display: flex; align-items: center; gap: 6px; }
7641
+ .kwSearch { position: relative; display: flex; min-width: 0; flex: 1 1 auto; align-items: center; }
7642
+ .kwSearch > svg { position: absolute; left: 8px; color: var(--tita-ink-faint); pointer-events: none; }
7643
+ .kwSearch input { padding-left: 26px; }
7644
+ .kwList {
7645
+ min-height: 0;
7646
+ margin: 0;
7647
+ padding: 0;
7648
+ overflow-y: auto;
7649
+ list-style: none;
7650
+ scrollbar-width: thin;
7651
+ scrollbar-color: var(--tita-line-strong) transparent;
7652
+ }
7653
+
7654
+ /* \u961F\u5217\u91CC\u7684\u4E00\u884C\uFF1A\u6807\u9898 / \u5B83\u662F\u4EC0\u4E48 / \u62BD\u51FA\u4E86\u591A\u5C11\u3002\u4E09\u884C\u90FD\u662F\u4E8B\u5B9E\uFF0C\u4E0D\u662F\u6309\u94AE\u3002
7655
+ \u6574\u884C\u662F\u4E00\u4E2A\u6309\u94AE \u2014\u2014 \u9009\u5B83\u5C31\u662F\u770B\u5B83\u3002 */
7656
+ .kwDoc {
7657
+ display: grid;
7658
+ width: 100%;
7659
+ min-width: 0;
7660
+ gap: 4px;
7661
+ border: 0;
7662
+ border-bottom: 1px solid var(--tita-line);
7663
+ background: none;
7664
+ padding: 12px 14px 13px;
7665
+ color: inherit;
7666
+ font: inherit;
7667
+ text-align: left;
7668
+ cursor: pointer;
7669
+ transition: background-color 120ms ease;
7670
+ }
7671
+ .kwDoc:last-child { border-bottom: 0; }
7672
+ .kwDoc:hover { background: var(--tita-surface-muted); }
7673
+ .kwDoc:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }
7674
+ .kwDoc[data-on] { background: color-mix(in srgb, var(--tita-primary) 7%, var(--tita-surface)); }
7675
+ .kwDocTitle {
7676
+ display: -webkit-box;
7677
+ overflow: hidden;
7678
+ color: var(--tita-ink);
7679
+ font-size: 13.5px;
7680
+ font-weight: 620;
7681
+ letter-spacing: -.005em;
7682
+ line-height: 1.5;
7683
+ overflow-wrap: anywhere;
7684
+ -webkit-box-orient: vertical;
7685
+ -webkit-line-clamp: 2;
7686
+ }
7687
+ .kwDoc[data-on] .kwDocTitle { color: var(--tita-primary); }
7688
+ .kwDocMeta {
7689
+ color: var(--tita-ink-faint);
7690
+ font-size: 12px;
7691
+ line-height: 1.5;
7692
+ font-variant-numeric: tabular-nums;
7693
+ }
7694
+ .kwDocFoot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 3px; }
7695
+ .kwDocCount { color: var(--tita-ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
7696
+
7697
+ /* \u72B6\u6001\uFF1A\u4E00\u4E2A\u70B9 + \u4E24\u4E2A\u5B57\u3002\u989C\u8272\u53EA\u8868\u6001\uFF0C\u4E0D\u8868\u6001\u5F3A\u5EA6\u3002 */
7698
+ .kwState {
7699
+ display: inline-flex;
7700
+ align-items: center;
7701
+ gap: 5px;
7702
+ color: var(--tita-ink-muted);
7703
+ font-size: 12px;
7704
+ font-weight: 600;
7705
+ white-space: nowrap;
7706
+ }
7707
+ .kwState::before { width: 5px; height: 5px; flex: 0 0 auto; border-radius: 999px; background: currentColor; content: ''; }
7708
+ .kwState[data-tone='success'] { color: var(--tita-tone-green); }
7709
+ .kwState[data-tone='warning'] { color: var(--tita-warning); }
7710
+ .kwState[data-tone='blue'] { color: var(--tita-primary); }
7711
+
7712
+ /* ---------------------------------------------------------------- \u68C0\u67E5\u5668 */
7713
+
7714
+ .kwInspector {
7715
+ min-width: 0;
7716
+ border: 1px solid var(--tita-line);
7717
+ border-radius: 12px;
7718
+ background: var(--tita-surface);
7719
+ }
7720
+ .kwInspectorHead {
7721
+ display: grid;
7722
+ grid-template-columns: minmax(0, 1fr) auto;
7723
+ align-items: start;
7724
+ gap: 10px 16px;
7725
+ padding: 16px 20px 14px;
7726
+ }
7727
+ .kwInspectorTitle { display: grid; min-width: 0; gap: 3px; }
7728
+ .kwInspectorTitle h2 {
7729
+ margin: 0;
7730
+ color: var(--tita-ink);
7731
+ font-size: 17px;
7732
+ font-weight: 710;
7733
+ letter-spacing: -.018em;
7734
+ line-height: 1.35;
7735
+ overflow-wrap: anywhere;
7736
+ }
7737
+ .kwInspectorTitle p {
7738
+ margin: 0;
7739
+ color: var(--tita-ink-muted);
7740
+ font-size: 12px;
7741
+ line-height: 1.5;
7742
+ font-variant-numeric: tabular-nums;
7743
+ }
7744
+ .kwInspectorActions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
7745
+
7746
+ /* \u7248\u672C\u6761\uFF1A\u5B83\u662F**\u8FD9\u4E00\u5C4F\u7684\u65F6\u95F4\u8F74**\uFF0C\u6240\u4EE5\u653E\u5728\u6807\u9898\u4E0E\u9875\u7B7E\u4E4B\u95F4\uFF0C\u8D34\u4E00\u6761\u6D45\u5E95\u3002 */
7747
+ .kwVersionBar {
7748
+ display: flex;
7749
+ flex-wrap: wrap;
7750
+ align-items: center;
7751
+ gap: 8px 12px;
7752
+ border-top: 1px solid var(--tita-line);
7753
+ border-bottom: 1px solid var(--tita-line);
7754
+ background: color-mix(in srgb, var(--tita-surface-muted) 52%, var(--tita-surface));
7755
+ padding: 8px 20px;
7756
+ }
7757
+ .kwVersionBar > strong { color: var(--tita-ink); font-size: 12px; font-weight: 650; }
7758
+ .kwVersionBar > span { color: var(--tita-ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
7759
+ .kwVersionPick { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
7760
+ .kwVersionChip {
7761
+ border: 1px solid var(--tita-line);
7762
+ border-radius: 999px;
7763
+ background: var(--tita-surface);
7764
+ padding: 1px 8px;
7765
+ color: var(--tita-ink-muted);
7766
+ font: inherit;
7767
+ font-size: 12px;
7768
+ font-weight: 650;
7769
+ font-variant-numeric: tabular-nums;
7770
+ line-height: 1.7;
7771
+ cursor: pointer;
7772
+ transition: border-color 120ms ease, color 120ms ease, background-color 120ms ease;
7773
+ }
7774
+ .kwVersionChip:hover { border-color: var(--tita-line-strong); color: var(--tita-ink); }
7775
+ .kwVersionChip:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }
7776
+ .kwVersionChip[aria-pressed='true'] { border-color: var(--tita-primary-line); background: var(--tita-primary-soft); color: var(--tita-primary); }
7777
+
7778
+ /* \u9875\u7B7E\uFF1A\u4E0B\u5212\u7EBF\u90A3\u4E00\u79CD\u3002\u5B83\u662F\u540C\u4E00\u4EFD\u6570\u636E\u7684\u4E0D\u540C\u8BFB\u6CD5\uFF0C\u4E0D\u662F\u53C8\u4E00\u5C42\u5BB9\u5668\u3002 */
7779
+ .kwTabsRow { padding: 0 20px; border-bottom: 1px solid var(--tita-line); }
7780
+ .kwTabsRow .tita-uiTabsList {
7781
+ height: auto;
7782
+ gap: 18px;
7783
+ overflow-x: auto;
7784
+ scrollbar-width: none;
7785
+ border: 0;
7786
+ border-radius: 0;
7787
+ background: transparent;
7788
+ padding: 0;
7789
+ }
7790
+ .kwTabsRow .tita-uiTabsTrigger {
7791
+ border: 0;
7792
+ border-bottom: 2px solid transparent;
7793
+ border-radius: 0;
7794
+ background: transparent;
7795
+ padding: 9px 0 7px;
7796
+ color: var(--tita-ink-muted);
7797
+ font-size: 12px;
7798
+ font-weight: 620;
7799
+ box-shadow: none;
7800
+ }
7801
+ .kwTabsRow .tita-uiTabsTrigger:hover { color: var(--tita-ink); }
7802
+ .kwTabsRow .tita-uiTabsTrigger[data-state='active'] { border-bottom-color: var(--tita-primary); color: var(--tita-ink); }
7803
+ .kwTabsRow .tita-uiTabsTrigger:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }
7804
+ .kwTabsRow .tita-uiTabsList::-webkit-scrollbar { display: none; }
7805
+
7806
+ /* ---- \u7ED3\u679C\u6D41
7807
+ *
7808
+ * \u4E00\u5C4F\u53EF\u80FD\u6709\u4E00\u767E\u591A\u6761\uFF0C\u6240\u4EE5\u5B83\u662F**\u6D41**\u4E0D\u662F\u5361\u7247\u5899\uFF1A\u7F16\u53F7\u3001\u7C7B\u578B\u3001\u6B63\u6587\u4E09\u5217\uFF0C
7809
+ * \u884C\u95F4\u53EA\u6709\u53D1\u4E1D\u7EBF\u3002\u6B63\u6587 12.5px / 1.75\uFF0C\u4E00\u884C\u7EA6 76 \u4E2A\u5B57\u7B26 \u2014\u2014 \u8BFB\u5F97\u4E0B\u53BB\u7684\u957F\u5EA6\u3002
7810
+ */
7811
+ .kwResultBar {
7812
+ display: flex;
7813
+ flex-wrap: wrap;
7814
+ align-items: center;
7815
+ gap: 8px 12px;
7816
+ border-bottom: 1px solid var(--tita-line);
7817
+ padding: 10px 20px;
7818
+ }
7819
+ .kwResultSummary { display: flex; align-items: baseline; gap: 6px; color: var(--tita-ink-muted); font-size: 12px; }
7820
+ .kwResultSummary strong { color: var(--tita-ink); font-size: 13.5px; font-weight: 680; font-variant-numeric: tabular-nums; }
7821
+ .kwChips { display: flex; flex-wrap: wrap; gap: 4px; margin-left: auto; }
7822
+ .kwChip {
7823
+ display: inline-flex;
7824
+ align-items: center;
7825
+ gap: 5px;
7826
+ border: 1px solid var(--tita-line);
7827
+ border-radius: 999px;
7828
+ background: var(--tita-surface);
7829
+ padding: 2px 9px;
7830
+ color: var(--tita-ink-muted);
7831
+ font: inherit;
7832
+ font-size: 12px;
7833
+ font-weight: 600;
7834
+ line-height: 1.6;
7835
+ cursor: pointer;
7836
+ transition: border-color 120ms ease, color 120ms ease, background-color 120ms ease;
7837
+ }
7838
+ .kwChip:hover { border-color: var(--tita-line-strong); color: var(--tita-ink); }
7839
+ .kwChip:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }
7840
+ .kwChip[aria-pressed='true'] { border-color: var(--tita-primary-line); background: var(--tita-primary-soft); color: var(--tita-primary); }
7841
+ .kwChip i { color: var(--tita-ink-faint); font-style: normal; font-variant-numeric: tabular-nums; }
7842
+ .kwChip[aria-pressed='true'] i { color: inherit; opacity: .72; }
7843
+
7844
+ .kwResults { margin: 0; padding: 0; list-style: none; }
7845
+ .kwResult {
7846
+ display: grid;
7847
+ grid-template-columns: 34px 62px minmax(0, 1fr);
7848
+ align-items: start;
7849
+ gap: 10px;
7850
+ border-bottom: 1px solid var(--tita-line);
7851
+ padding: 12px 20px 13px;
7852
+ transition: background-color 120ms ease;
7853
+ }
7854
+ .kwResult:last-child { border-bottom: 0; }
7855
+ .kwResult:hover { background: color-mix(in srgb, var(--tita-surface-muted) 56%, var(--tita-surface)); }
7856
+ .kwResultIndex {
7857
+ padding-top: 2px;
7858
+ color: var(--tita-ink-faint);
7859
+ font-family: var(--tita-mono);
7860
+ font-size: 12px;
7861
+ font-variant-numeric: tabular-nums;
7862
+ letter-spacing: .04em;
7863
+ }
7864
+ .kwResultText { max-width: 76ch; margin: 0; color: var(--tita-ink); font-size: 13.5px; line-height: 1.75; overflow-wrap: anywhere; }
7865
+
7866
+ /* \u7C7B\u578B\u662F\u8FD9\u884C\u7684**\u5750\u6807**\uFF0C\u4E0D\u662F\u4E00\u4E2A\u5F3A\u8C03\u4EF6\uFF1A\u7B49\u5BBD\u3001\u5C0F\u53F7\u3001\u4E00\u4E2A\u8272\u70B9\u3002 */
7867
+ .kwKind {
7868
+ display: inline-flex;
7869
+ align-items: center;
7870
+ gap: 5px;
7871
+ padding-top: 4px;
7872
+ color: var(--tita-ink-faint);
7873
+ font-family: var(--tita-mono);
7874
+ font-size: 12px;
7875
+ font-weight: 600;
7876
+ letter-spacing: .07em;
7877
+ text-transform: uppercase;
7878
+ }
7879
+ .kwKind::before { width: 5px; height: 5px; flex: 0 0 auto; border-radius: 999px; background: currentColor; content: ''; }
7880
+ .kwKind[data-kind='fact'] { color: var(--tita-tone-blue); }
7881
+ .kwKind[data-kind='procedure'] { color: var(--tita-tone-violet); }
7882
+ .kwKind[data-kind='case'] { color: var(--tita-tone-amber); }
7883
+ .kwResultFoot {
7884
+ display: flex;
7885
+ flex-wrap: wrap;
7886
+ align-items: center;
7887
+ justify-content: space-between;
7888
+ gap: 8px;
7889
+ border-top: 1px solid var(--tita-line);
7890
+ padding: 9px 20px;
7891
+ color: var(--tita-ink-faint);
7892
+ font-size: 12px;
7893
+ font-variant-numeric: tabular-nums;
7894
+ }
7895
+
7896
+ /* \u7A7A\u6001\uFF1A\u8BF4\u6E05\u695A**\u4E3A\u4EC0\u4E48\u7A7A**\u548C**\u4E0B\u4E00\u6B65\u505A\u4EC0\u4E48**\uFF0C\u4E0D\u653E\u63D2\u56FE\u3002 */
7897
+ .kwEmpty { display: grid; justify-items: center; gap: 5px; padding: 42px 24px 46px; text-align: center; }
7898
+ .kwEmptyIcon {
7899
+ display: inline-flex;
7900
+ width: 34px;
7901
+ height: 34px;
7902
+ align-items: center;
7903
+ justify-content: center;
7904
+ margin-bottom: 4px;
7905
+ border: 1px solid var(--tita-line);
7906
+ border-radius: 10px;
7907
+ color: var(--tita-ink-muted);
7908
+ }
7909
+ .kwEmpty strong { color: var(--tita-ink); font-size: 13.5px; font-weight: 650; }
7910
+ .kwEmpty p { max-width: 46ch; margin: 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.65; }
7911
+ .kwEmptyList { padding: 28px 18px 30px; }
7912
+ .kwEmptyList .tita-uiButton { margin-top: 6px; }
7913
+
7914
+ /* \u8F7D\u5165\u9AA8\u67B6\uFF1A\u5148\u5360\u4F4F\u7248\u5F0F\uFF0C\u522B\u8BA9\u5185\u5BB9\u8DF3\u8FDB\u6765\u3002 */
7915
+ .kwSkeleton { display: grid; gap: 8px; padding: 18px 20px 22px; }
7916
+ .kwSkeletonRow {
7917
+ height: 12px;
7918
+ border-radius: 4px;
7919
+ background: linear-gradient(90deg, var(--tita-surface-muted) 25%, color-mix(in srgb, var(--tita-surface-muted) 45%, var(--tita-surface)) 37%, var(--tita-surface-muted) 63%);
7920
+ background-size: 400% 100%;
7921
+ animation: kwShimmer 1.5s ease-in-out infinite;
7922
+ }
7923
+ .kwSkeletonRow:nth-child(2) { width: 82%; }
7924
+ .kwSkeletonRow:nth-child(3) { width: 64%; }
7925
+ @keyframes kwShimmer {
7926
+ from { background-position: 100% 50%; }
7927
+ to { background-position: 0 50%; }
7928
+ }
7929
+
7930
+ /* ------------------------------------------------------------- \u9636\u6BB5\u89C6\u56FE
7931
+ *
7932
+ * \u62BD\u53D6\u4EE5\u5916\u7684\u56DB\u6BB5\uFF1A\u4E00\u53E5\u5B83\u505A\u4EC0\u4E48\u3001\u672C\u6B65\u8F93\u5165\u3001\u7248\u672C\u8BB0\u5F55\u3001\u7248\u672C\u8BE6\u60C5\u3002
7933
+ * \u4E09\u8005\u5404\u81EA\u6210\u5757\uFF0C\u5757\u5185\u4E0D\u518D\u5957\u5361\u3002
7934
+ */
7935
+ .kwStage { display: grid; min-width: 0; gap: 14px; }
7936
+ .kwStageHead {
7937
+ display: flex;
7938
+ flex-wrap: wrap;
7939
+ align-items: flex-start;
7940
+ justify-content: space-between;
7941
+ gap: 12px 20px;
7942
+ border: 1px solid var(--tita-line);
7943
+ border-radius: 12px;
7944
+ background: var(--tita-surface);
7945
+ padding: 17px 20px 16px;
7946
+ }
7947
+ .kwStageCopy { display: grid; min-width: 0; gap: 3px; }
7948
+ .kwStageCopy h2 { margin: 0; color: var(--tita-ink); font-size: 17px; font-weight: 710; letter-spacing: -.018em; line-height: 1.35; }
7949
+ .kwStageCopy p { max-width: 66ch; margin: 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.65; }
7950
+ .kwStageActions { display: flex; flex: 0 0 auto; flex-wrap: wrap; align-items: center; gap: 8px; }
7951
+
7952
+ .kwInput {
7953
+ border: 1px solid var(--tita-line);
7954
+ border-radius: 12px;
7955
+ background: var(--tita-surface);
7956
+ padding: 13px 16px 14px;
7957
+ }
7958
+ .kwInputHead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }
7959
+ .kwInputHead strong { color: var(--tita-ink); font-size: 12px; font-weight: 680; }
7960
+ .kwInputHead span { margin-right: auto; color: var(--tita-ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
7961
+ .kwInputList {
7962
+ display: flex;
7963
+ flex-wrap: wrap;
7964
+ gap: 6px;
7965
+ max-height: 148px;
7966
+ margin: 10px 0 0;
7967
+ padding: 0;
7968
+ overflow-y: auto;
7969
+ list-style: none;
7970
+ scrollbar-width: thin;
7971
+ scrollbar-color: var(--tita-line-strong) transparent;
7972
+ }
7973
+ .kwInputItem {
7974
+ display: inline-flex;
7975
+ max-width: 100%;
7976
+ align-items: center;
7977
+ gap: 7px;
7978
+ border: 1px solid var(--tita-line);
7979
+ border-radius: 7px;
7980
+ background: var(--tita-surface-muted);
7981
+ padding: 4px 8px;
7982
+ font-size: 12px;
7983
+ line-height: 1.5;
7984
+ }
7985
+ .kwInputItem > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
7986
+ .kwInputItem > small { flex: 0 0 auto; color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
7987
+
7988
+ .kwSplit { display: grid; grid-template-columns: minmax(220px, 268px) minmax(0, 1fr); align-items: start; gap: 16px; min-width: 0; }
7989
+ .kwVersions {
7990
+ min-width: 0;
7991
+ border: 1px solid var(--tita-line);
7992
+ border-radius: 12px;
7993
+ background: var(--tita-surface);
7994
+ overflow: hidden;
7995
+ }
7996
+ .kwVersionsHead {
7997
+ display: flex;
7998
+ align-items: baseline;
7999
+ justify-content: space-between;
8000
+ gap: 8px;
8001
+ border-bottom: 1px solid var(--tita-line);
8002
+ padding: 11px 14px;
8003
+ }
8004
+ .kwVersionsHead strong { color: var(--tita-ink); font-size: 12px; font-weight: 680; }
8005
+ .kwVersionsHead span { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8006
+ .kwVersionItem {
8007
+ display: grid;
8008
+ width: 100%;
8009
+ gap: 2px;
8010
+ border: 0;
8011
+ border-bottom: 1px solid var(--tita-line);
8012
+ background: none;
8013
+ padding: 9px 14px 10px;
8014
+ color: inherit;
8015
+ font: inherit;
8016
+ text-align: left;
8017
+ cursor: pointer;
8018
+ transition: background-color 120ms ease;
8019
+ }
8020
+ .kwVersionItem:hover { background: var(--tita-surface-muted); }
8021
+ .kwVersionItem:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: -2px; }
8022
+ .kwVersionItem[data-on] { background: color-mix(in srgb, var(--tita-primary) 7%, var(--tita-surface)); }
8023
+ .kwVersionItem strong { color: var(--tita-ink); font-size: 12px; font-weight: 650; font-variant-numeric: tabular-nums; }
8024
+ .kwVersionItem[data-on] strong { color: var(--tita-primary); }
8025
+ .kwVersionItem small { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8026
+ .kwVersionDocs { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 14px 9px; border-bottom: 1px solid var(--tita-line); }
8027
+ .kwPager { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 7px 10px; color: var(--tita-ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
8028
+
8029
+ .kwDetail { min-width: 0; border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); }
8030
+ .kwDetailHead {
8031
+ display: grid;
8032
+ grid-template-columns: minmax(0, 1fr) auto;
8033
+ align-items: start;
8034
+ gap: 8px 14px;
8035
+ padding: 15px 18px 13px;
8036
+ }
8037
+ .kwDetailHead h2 { margin: 0; color: var(--tita-ink); font-size: 17px; font-weight: 700; letter-spacing: -.015em; line-height: 1.4; overflow-wrap: anywhere; }
8038
+ .kwDetailHead p { margin: 2px 0 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
8039
+ .kwMetaLine { display: flex; flex-wrap: wrap; gap: 3px 14px; margin: 0; padding: 0 18px 12px; color: var(--tita-ink-faint); font-size: 12px; line-height: 1.5; font-variant-numeric: tabular-nums; }
8040
+ .kwMetaLine > span { display: inline-flex; align-items: center; gap: 4px; }
8041
+
8042
+ .kwLog { border-top: 1px solid var(--tita-line); padding: 4px 18px 16px; }
8043
+ .kwLog h3 { margin: 12px 0 4px; color: var(--tita-ink); font-size: 12px; font-weight: 680; }
8044
+ .kwTimeline { display: grid; margin: 0; padding: 0; list-style: none; }
8045
+ .kwTimeline li { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 12px; border-bottom: 1px solid var(--tita-line); padding: 9px 0; }
8046
+ .kwTimeline li:last-child { border-bottom: 0; }
8047
+ .kwTimeline time { padding-top: 1px; color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
8048
+ .kwTimeline p { margin: 0; color: var(--tita-ink); font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
8049
+ .kwTimeline li[data-warn] p { color: var(--tita-warning); }
8050
+
8051
+ /* \u6A21\u578B\u8BF7\u6C42\uFF1A\u9ED8\u8BA4\u6536\u8D77\u3002\u539F\u59CB\u8F93\u5165\u8F93\u51FA\u662F\u8BC1\u636E\uFF0C\u4E0D\u662F\u9996\u5C4F\u7ED3\u8BBA\u3002 */
8052
+ .kwCalls { display: grid; margin-top: 6px; }
8053
+ .kwCall { border-bottom: 1px solid var(--tita-line); }
8054
+ .kwCall:last-child { border-bottom: 0; }
8055
+ .kwCall > summary {
8056
+ display: flex;
8057
+ flex-wrap: wrap;
8058
+ align-items: center;
8059
+ gap: 5px 10px;
8060
+ padding: 10px 0;
8061
+ color: var(--tita-ink);
8062
+ cursor: pointer;
8063
+ list-style: none;
8064
+ }
8065
+ .kwCall > summary::-webkit-details-marker { display: none; }
8066
+ .kwCall > summary::before {
8067
+ width: 6px;
8068
+ height: 6px;
8069
+ flex: 0 0 auto;
8070
+ border-right: 1.5px solid var(--tita-ink-faint);
8071
+ border-bottom: 1.5px solid var(--tita-ink-faint);
8072
+ content: '';
8073
+ transform: rotate(-45deg);
8074
+ transition: transform 140ms ease;
8075
+ }
8076
+ .kwCall[open] > summary::before { transform: rotate(45deg); }
8077
+ .kwCall > summary:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 2px; }
8078
+ .kwCall > summary strong { font-size: 12px; font-weight: 650; }
8079
+ .kwCall > summary small { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8080
+ .kwCall > summary > span { margin-left: auto; }
8081
+ .kwCallBody { padding: 2px 0 14px 15px; }
8082
+
8083
+ .kwHint { margin: 8px 0 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; }
8084
+ .kwHintWarn { color: var(--tita-warning); }
8085
+ .kwHint a { color: var(--tita-primary); text-decoration: underline; text-underline-offset: 2px; }
8086
+
8087
+ /* ------------------------------------------------------------- \u6DFB\u52A0\u6587\u4EF6 */
8088
+
8089
+ /* \u5BF9\u8BDD\u6846\u58F3\uFF1A\u6BD4\u9ED8\u8BA4 420px \u5BBD\uFF0C\u88C5\u5F97\u4E0B\u300C\u62D6\u653E\u533A + \u5F85\u5BFC\u5165\u961F\u5217\u300D\u4E24\u5217\u3002 */
8090
+ .kwImportDialog { width: min(880px, calc(100vw - 32px)); }
8091
+ /* \u8FD0\u884C\u4E2D\u4E0D\u63D0\u4F9B\u5173\u95ED\uFF1A\u5BFC\u5165\u5728\u6D4F\u89C8\u5668\u91CC\u9010\u6761\u5199\uFF0C\u5378\u8F7D\u7EC4\u4EF6\u5C31\u4E22\u8FDB\u5EA6\u3002 */
8092
+ .kwImportDialog[data-busy='true'] > button[aria-label='\u5173\u95ED'] { display: none; }
8093
+ .kwImportDialog .kwImportLayout { margin-top: 14px; }
8094
+ .kwImportDialog .kwDrop { min-height: 208px; }
8095
+ .kwImportDialog .kwImportList { max-height: 300px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--tita-line-strong) transparent; }
8096
+ .kwImportFoot {
8097
+ display: flex;
8098
+ flex-direction: row;
8099
+ flex-wrap: wrap;
8100
+ align-items: center;
8101
+ gap: 8px;
8102
+ margin-top: 16px;
8103
+ border-top: 1px solid var(--tita-line);
8104
+ padding-top: 12px;
8105
+ }
8106
+ .kwImportFootNote { flex: 1 1 240px; margin: 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.55; }
8107
+ .kwImportFootActions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
8108
+ @media (max-width: 640px) {
8109
+ .kwImportFootNote { flex-basis: 100%; }
8110
+ .kwImportFootActions { width: 100%; margin-left: 0; }
8111
+ .kwImportFootActions .tita-uiButton { flex: 1 1 0; }
8112
+ }
8113
+ .kwImportLayout { display: grid; grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); align-items: stretch; gap: 14px; }
8114
+ .kwDrop {
8115
+ display: flex;
8116
+ min-height: 232px;
8117
+ flex-direction: column;
8118
+ align-items: center;
8119
+ justify-content: center;
8120
+ gap: 9px;
8121
+ border: 1px dashed var(--tita-line-strong);
8122
+ border-radius: 12px;
8123
+ background: var(--tita-surface);
8124
+ padding: 26px;
8125
+ text-align: center;
8126
+ transition: border-color 140ms ease, background-color 140ms ease;
8127
+ }
8128
+ .kwDrop:hover { border-color: var(--tita-primary-line); background: color-mix(in srgb, var(--tita-primary) 3%, var(--tita-surface)); }
8129
+ .kwDropIcon {
8130
+ display: inline-flex;
8131
+ width: 38px;
8132
+ height: 38px;
8133
+ align-items: center;
8134
+ justify-content: center;
8135
+ border: 1px solid var(--tita-primary-line);
8136
+ border-radius: 11px;
8137
+ background: var(--tita-primary-soft);
8138
+ color: var(--tita-primary);
8139
+ }
8140
+ .kwDrop strong { color: var(--tita-ink); font-size: 13.5px; font-weight: 650; }
8141
+ .kwDrop span { color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; }
8142
+ .kwQueuePanel {
8143
+ display: flex;
8144
+ min-width: 0;
8145
+ flex-direction: column;
8146
+ border: 1px solid var(--tita-line);
8147
+ border-radius: 12px;
8148
+ background: var(--tita-surface);
8149
+ padding: 14px 16px 15px;
8150
+ }
8151
+ .kwQueuePanelHead { display: flex; align-items: baseline; gap: 10px; border-bottom: 1px solid var(--tita-line); padding-bottom: 10px; }
8152
+ .kwQueuePanelHead h3 { margin: 0; color: var(--tita-ink); font-size: 13.5px; font-weight: 680; }
8153
+ .kwQueuePanelHead span { color: var(--tita-ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
8154
+ .kwImportRow {
8155
+ display: flex;
8156
+ min-width: 0;
8157
+ flex-wrap: wrap;
8158
+ align-items: center;
8159
+ gap: 8px 10px;
8160
+ border-bottom: 1px solid var(--tita-line);
8161
+ padding: 11px 0;
8162
+ }
8163
+ .kwImportRow > svg { flex: 0 0 auto; color: var(--tita-ink-muted); }
8164
+ .kwImportName { display: grid; min-width: 120px; flex: 1 1 160px; gap: 2px; }
8165
+ .kwImportName strong { color: var(--tita-ink); font-size: 12px; font-weight: 620; overflow-wrap: anywhere; }
8166
+ .kwImportName small { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8167
+ .kwImportState { color: var(--tita-ink-muted); font-size: 12px; }
8168
+
8169
+ /* ---------------------------------------------------------------- \u6587\u6863\u94FE\u8DEF */
8170
+
8171
+ .kwLineage { display: grid; gap: 12px; }
8172
+ .kwLineageBar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
8173
+ .kwLineageBar > label { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; color: var(--tita-ink-muted); font-size: 12px; }
8174
+ .kwLineageBar > span { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8175
+ .kwLineageBar > div:last-child { margin-left: auto; }
8176
+ .kwLayers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: start; gap: 12px; }
8177
+ .kwLayer { min-width: 0; overflow: hidden; border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); }
8178
+ .kwLayer > header {
8179
+ display: flex;
8180
+ align-items: center;
8181
+ gap: 7px;
8182
+ border-bottom: 1px solid var(--tita-line);
8183
+ padding: 10px 14px;
8184
+ color: var(--tita-ink);
8185
+ font-size: 12px;
8186
+ }
8187
+ .kwLayer > header > svg { color: var(--tita-ink-muted); }
8188
+ .kwLayer > header > strong { font-weight: 680; }
8189
+ .kwLayer > header > span { margin-left: auto; color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8190
+ .kwLayerList { margin: 0; padding: 0; list-style: none; }
8191
+ .kwLayerMore { display: flex; align-items: center; justify-content: space-between; gap: 8px; border-top: 1px solid var(--tita-line); padding: 4px 10px 4px 14px; color: var(--tita-ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
8192
+ .kwLayerItem { display: grid; gap: 3px; border-bottom: 1px solid var(--tita-line); padding: 9px 14px 10px; }
8193
+ .kwLayerItem:last-child { border-bottom: 0; }
8194
+ .kwLayerItem:hover { background: color-mix(in srgb, var(--tita-surface-muted) 56%, var(--tita-surface)); }
8195
+ .kwLayerRow { display: flex; min-width: 0; align-items: baseline; gap: 8px; }
8196
+ .kwLayerText { min-width: 0; flex: 1 1 auto; color: var(--tita-ink); font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
8197
+ .kwLayerItem small { color: var(--tita-ink-faint); font-size: 12px; line-height: 1.5; overflow-wrap: anywhere; }
8198
+ .kwLayerFoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 2px 0; color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8199
+ .kwLayerActions { display: flex; justify-content: flex-end; gap: 6px; }
8200
+
8201
+ /* ---------------------------------------------------------------- \u7F16\u8BD1\u8BBE\u7F6E */
8202
+
8203
+ .kwSettings { display: grid; gap: 14px; }
8204
+ .kwSettingsGrid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: stretch; gap: 12px; }
8205
+ .kwSettingStack { display: grid; gap: 12px; align-content: start; }
8206
+ /* \u5907\u6CE8\u662F\u4E00\u6BB5\u4F1A\u4E00\u76F4\u6539\u7684\u6587\u5B57\uFF1A\u8BA9\u5B83\u628A\u53F3\u5217\u6491\u6EE1\uFF0C\u800C\u4E0D\u662F\u7F29\u5728\u5361\u9876\u7559\u4E00\u5927\u7247\u7A7A\u767D\u3002 */
8207
+ .kwSettingNote { display: flex; flex-direction: column; }
8208
+ .kwSettingNote > .tita-uiField { display: flex; flex: 1 1 auto; flex-direction: column; }
8209
+ .kwSettingNote textarea { flex: 1 1 auto; min-height: 200px; }
8210
+ /* \u5750\u6807\u5B9E\u4F53\u662F\u4E00\u5F20\u4F1A\u957F\u540D\u5355\uFF1A\u884C\u5185\u52A8\u4F5C\u9489\u5728\u7B2C\u4E00\u884C\u53F3\u4FA7\uFF0C\u4E0D\u8DDF\u7740\u300C\u5B9A\u4E49\u300D\u90A3\u4E00\u884C\u4E0B\u6C89\u3002 */
8211
+ .kwSettings .tita-axisRow {
8212
+ display: grid;
8213
+ grid-template-columns: minmax(0, 1fr) auto;
8214
+ align-items: start;
8215
+ gap: 3px 12px;
8216
+ padding: 10px 0;
8217
+ }
8218
+ .kwSettings .tita-axisRow > .tita-axisName { grid-column: 1; grid-row: 1; }
8219
+ .kwSettings .tita-axisRow > .tita-axisAliases,
8220
+ .kwSettings .tita-axisRow > .tita-axisScope { grid-column: 1 / -1; }
8221
+ .kwSettings .tita-axisActions { grid-column: 2; grid-row: 1; justify-self: end; margin-left: 0; }
8222
+ .kwSettingCard { min-width: 0; border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); padding: 14px 16px 15px; }
8223
+ .kwSettingWide { grid-column: 1 / -1; }
8224
+ .kwSettingHead { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 12px; margin-bottom: 10px; }
8225
+ .kwSettingHead h2 { margin: 0; color: var(--tita-ink); font-size: 13.5px; font-weight: 680; }
8226
+ .kwSettingHead p { margin: 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.55; }
8227
+ .kwSettingRows { display: grid; gap: 14px; }
8228
+ .kwSettingActions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 11px; border-top: 1px solid var(--tita-line); padding-top: 11px; }
8229
+ .kwSettings > .tita-settingsSection { border: 1px solid var(--tita-line); border-radius: 12px; background: var(--tita-surface); padding: 4px 16px 8px; }
8230
+
8231
+ /* ---------------------------------------------------------------- \u7A84\u5C4F */
8232
+
8233
+ @media (max-width: 1180px) {
8234
+ .kwBody { grid-template-columns: minmax(260px, 300px) minmax(0, 1fr); }
8235
+ .kwSplit { grid-template-columns: minmax(200px, 240px) minmax(0, 1fr); }
8236
+ }
8237
+
8238
+ @media (max-width: 1024px) {
8239
+ .kwBody { grid-template-columns: minmax(0, 1fr); }
8240
+ .kwQueue { position: static; max-height: 46vh; }
8241
+ .kwSplit { grid-template-columns: minmax(0, 1fr); }
8242
+ .kwLayers { grid-template-columns: minmax(0, 1fr); }
8243
+ }
8244
+
8245
+ @media (max-width: 900px) {
8246
+ .kwBarInner { grid-template-columns: minmax(0, 1fr) auto; }
8247
+ .kwIdent { grid-row: 1; grid-column: 1; }
8248
+ .kwActions { grid-row: 1; grid-column: 2; justify-self: end; }
8249
+ .kwTabs { grid-column: 1 / -1; grid-row: 2; width: 100%; justify-content: flex-start; }
8250
+ .kwTab { flex: 1 1 auto; text-align: center; }
8251
+ .kwActions { grid-row: 1; }
8252
+ /* \u5DE5\u5E8F\u5E26\u5728\u7A84\u5C4F\u53D8\u6210\u4E00\u6761\u53EF\u6A2A\u6ED1\u7684\u5E26\uFF1A\u4FDD\u6301\u300C\u4E00\u6761\u94FE\u8DEF\u300D\u7684\u5F62\u72B6\uFF0C\u4E0D\u6298\u6210\u5361\u7247\u5899\u3002 */
8253
+ .kwGate { flex: 0 0 200px; scroll-snap-align: start; }
8254
+ .kwBand {
8255
+ scroll-snap-type: x proximity;
8256
+ flex-wrap: nowrap;
8257
+ overflow-x: auto;
8258
+ padding-bottom: 2px;
8259
+ scrollbar-width: thin;
8260
+ scrollbar-color: var(--tita-line-strong) transparent;
8261
+ }
8262
+ .kwIdentCopy p { display: none; }
8263
+ .kwSettingsGrid { grid-template-columns: minmax(0, 1fr); }
8264
+ .kwSettingNote { grid-column: auto; }
8265
+ .kwSettingNote textarea { min-height: 150px; }
8266
+ .kwImportLayout { grid-template-columns: minmax(0, 1fr); }
8267
+ .kwDrop { min-height: 180px; }
8268
+ }
8269
+
8270
+ @media (max-width: 760px) {
8271
+ .kwBarInner { padding: 9px 16px; gap: 8px 12px; }
8272
+ .kwActions { gap: 2px; }
8273
+ .kwScope { flex-direction: column; gap: 2px; }
8274
+ .kwMain { padding: 14px 16px 72px; }
8275
+ .kwInspectorHead { grid-template-columns: minmax(0, 1fr); padding: 14px 16px 12px; }
8276
+ .kwInspectorActions { justify-content: flex-start; }
8277
+ .kwVersionBar { padding-inline: 16px; }
8278
+ .kwTabsRow { padding-inline: 16px; }
8279
+ .kwTabsRow .tita-uiTabsList { gap: 14px; }
8280
+ .kwResultBar { padding-inline: 16px; }
8281
+ .kwChips { margin-left: 0; }
8282
+ .kwResult { grid-template-columns: 52px minmax(0, 1fr); padding-inline: 16px; }
8283
+ .kwResultIndex { display: none; }
8284
+ .kwResultText { font-size: 12px; line-height: 1.7; }
8285
+ .kwDetailHead { grid-template-columns: minmax(0, 1fr); }
8286
+ .kwLineageBar > div:last-child { margin-left: 0; width: 100%; justify-content: flex-start; }
8287
+ .kwTimeline li { grid-template-columns: 86px minmax(0, 1fr); gap: 9px; }
8288
+ .kwStageHead { padding: 14px 16px; }
8289
+ }
8290
+
8291
+ @media (max-width: 620px) {
8292
+ .kwActionLabel { display: none; }
8293
+ .kwActions .tita-uiButton { padding-inline: 8px; }
8294
+ }
8295
+
8296
+ @media (max-width: 430px) {
8297
+ .kwGate { flex-basis: 178px; }
8298
+ .kwKind { font-size: 12px; letter-spacing: .05em; }
8299
+ .kwResult { grid-template-columns: 46px minmax(0, 1fr); gap: 8px; }
8300
+ }
8301
+
8302
+ @media (prefers-reduced-motion: reduce) {
8303
+ .kwLive { animation: none; }
8304
+ .kwSkeletonRow { animation: none; background: var(--tita-surface-muted); }
8305
+ .kwGateBar > span,
8306
+ .kwGate::before,
8307
+ .kwCall > summary::before { transition: none; }
8308
+ }
8309
+
8310
+ /* \u51E0\u5904\u53EA\u5728\u4E2A\u522B\u89C6\u56FE\u91CC\u51FA\u73B0\u7684\u6392\u5E03\uFF0C\u7ED9\u6210\u7C7B\u540D\u800C\u4E0D\u662F\u884C\u5185 style\u3002 */
8311
+ .kwImportList { margin: 0; padding: 0; list-style: none; }
8312
+ .kwImportProgress { display: grid; gap: 6px; margin-top: 12px; }
8313
+ .kwEmptyCompact { padding: 34px 12px; }
8314
+ .kwVersionsEmpty { padding: 0 14px 12px; }
8315
+ .kwResultBar .kwSearch { width: 172px; flex: 0 0 auto; }
8316
+ .kwQueueFoot { border-top: 1px solid var(--tita-line); background: var(--tita-surface); padding: 9px 12px; }
8317
+ .kwQueueFoot .tita-uiButton { width: 100%; }
8318
+ .kwQueueAllDone { display: flex; align-items: center; justify-content: center; gap: 5px; margin: 0; padding: 3px 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.5; }
8319
+ .kwQueueAllDone svg { color: var(--tita-tone-green); }
8320
+ .kwInspector .kwNotice { margin: 12px 20px 0; }
8321
+ .kwLayerHint { padding: 0 14px 14px; }
8322
+ .kwLayerCount { flex: 0 0 auto; }
8323
+ .kwNoteMeta { margin: 6px 0 0; color: var(--tita-ink-faint); font-size: 12px; line-height: 1.5; font-variant-numeric: tabular-nums; }
8324
+
8325
+ /* ---------------------------------------------------------- \u8986\u76D6\u7F3A\u53E3\uFF08\u9875\u7B7E\uFF09
8326
+
8327
+ * \u5B83\u56DE\u7B54\u7684\u662F\u300C\u539F\u6587\u91CC\u54EA\u4E9B\u5730\u65B9\u6CA1\u6709\u4EFB\u4F55\u5F15\u6587\u300D\uFF1A\u6309\u7AE0\u8282 / \u8868\u884C / \u5185\u5BB9\u5757\u5206\u7EC4\uFF0C
8328
+ * \u6BCF\u6761\u7ED9\u51FA\u7B2C\u51E0\u884C\u4E0E\u539F\u6587\u5F00\u5934\uFF0C\u4FBF\u4E8E\u56DE\u5230\u6587\u6863\u91CC\u6838\u5BF9\u3002\u4E0D\u662F\u5361\u7247\uFF0C\u662F\u4E00\u6761\u6761\u5BF9\u8D26\u8BB0\u5F55\u3002
8329
+ */
8330
+ .kwTabCount { margin-left: 5px; color: var(--tita-warning); font-size: 12px; font-weight: 750; font-variant-numeric: tabular-nums; }
8331
+ .kwNoticeAction { margin-left: auto; flex: 0 0 auto; }
8332
+ .kwGaps { min-width: 0; }
8333
+ .kwGapSummary {
8334
+ display: flex;
8335
+ flex-wrap: wrap;
8336
+ align-items: baseline;
8337
+ gap: 4px 22px;
8338
+ border-bottom: 1px solid var(--tita-line);
8339
+ padding: 14px 20px 11px;
8340
+ color: var(--tita-ink-muted);
8341
+ font-size: 12px;
8342
+ font-variant-numeric: tabular-nums;
8343
+ }
8344
+ .kwGapSummary strong { color: var(--tita-ink); font-size: 17px; font-weight: 680; }
8345
+ .kwGapSummaryNote { margin-left: auto; color: var(--tita-ink-faint); font-size: 12px; }
8346
+ .kwGapHint { margin: 0; padding: 10px 20px 4px; color: var(--tita-ink-faint); font-size: 12px; line-height: 1.6; }
8347
+ .kwGapGroup { border-top: 1px solid var(--tita-line); margin-top: 12px; }
8348
+ .kwGapGroup > header {
8349
+ display: flex;
8350
+ align-items: baseline;
8351
+ justify-content: space-between;
8352
+ gap: 10px;
8353
+ padding: 10px 20px 8px;
8354
+ color: var(--tita-ink);
8355
+ font-size: 12px;
8356
+ }
8357
+ .kwGapGroup > header strong { font-weight: 680; }
8358
+ .kwGapGroup > header span { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8359
+ .kwGapList { margin: 0; padding: 0; list-style: none; }
8360
+ .kwGapRow { border-bottom: 1px solid var(--tita-line); padding: 10px 20px 11px; }
8361
+ .kwGapRow:last-child { border-bottom: 0; }
8362
+ .kwGapDetail { margin: 0; color: var(--tita-ink); font-size: 12px; line-height: 1.6; overflow-wrap: anywhere; }
8363
+ .kwGapLine { margin-left: 7px; color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
8364
+ .kwGapExcerpt {
8365
+ display: -webkit-box;
8366
+ overflow: hidden;
8367
+ margin: 4px 0 0;
8368
+ color: var(--tita-ink-muted);
8369
+ font-size: 12px;
8370
+ line-height: 1.6;
8371
+ overflow-wrap: anywhere;
8372
+ white-space: pre-wrap;
8373
+ -webkit-box-orient: vertical;
8374
+ -webkit-line-clamp: 3;
8375
+ }
8376
+ @media (max-width: 760px) {
8377
+ .kwGapSummary { padding-inline: 16px; }
8378
+ .kwGapSummaryNote { margin-left: 0; }
8379
+ .kwGapHint { padding-inline: 16px; }
8380
+ .kwGapGroup > header { padding-inline: 16px; }
8381
+ .kwGapRow { padding-inline: 16px; }
8382
+ }
8383
+
8384
+ /* \u7ED3\u679C\u6D41\u91CC\u7684\u5750\u6807\u884C\uFF1A\u5BF9\u8C61 / \u52A8\u4F5C / \u573A\u666F\u662F\u62BD\u53D6\u7ED9\u51FA\u7684\u539F\u540D\uFF0C\u6392\u5728\u6B63\u6587\u4E0B\u9762\u4E00\u6863\u3002 */
8385
+ .kwResultBody { display: grid; min-width: 0; gap: 3px; }
8386
+ .kwResultAxes {
8387
+ display: flex;
8388
+ flex-wrap: wrap;
8389
+ align-items: baseline;
8390
+ gap: 2px 12px;
8391
+ margin: 0;
8392
+ color: var(--tita-ink-muted);
8393
+ font-size: 12px;
8394
+ line-height: 1.5;
8395
+ overflow-wrap: anywhere;
8396
+ }
8397
+ .kwResultAxes i { margin-right: 4px; color: var(--tita-ink-faint); font-style: normal; }
8398
+ .kwResultAxesNone { color: var(--tita-ink-faint); }
8399
+
8400
+ /* \u987A\u5E8F\u95F8\u95E8\uFF1A\u4E00\u6BB5\u5728\u8DD1\u65F6\uFF0C\u4E0B\u4E00\u6BB5\u53EA\u80FD\u770B\u4E0D\u80FD\u542F\u52A8\u3002 */
8401
+ .kwRunBusy {
8402
+ display: flex;
8403
+ align-items: center;
8404
+ gap: 6px;
8405
+ margin: 0;
8406
+ color: var(--tita-ink-muted);
8407
+ font-size: 12px;
8408
+ line-height: 1.6;
8409
+ }
8410
+ .kwRunBusy svg { flex: 0 0 auto; color: var(--tita-primary); }
8411
+
8412
+ /* ---------------------------------------------------------------- \u539F\u6587\u5BF9\u7167 */
8413
+ /* \u4E00\u5F20\u539F\u6587 + \u4E00\u6761\u6E05\u5355\u3002\u6587\u5B57\u662F\u4E3B\u4F53\uFF0C\u6E05\u5355\u53EA\u505A\u8DF3\u8F6C\u548C\u7B5B\u9009\u3002 */
8414
+ .kwRead {
8415
+ display: grid;
8416
+ grid-template-columns: minmax(0, 1fr) 320px;
8417
+ align-items: start;
8418
+ min-width: 0;
8419
+ }
8420
+ .kwReadMain { min-width: 0; padding: 14px 20px 30px; }
8421
+ .kwReadBar {
8422
+ display: flex;
8423
+ flex-wrap: wrap;
8424
+ align-items: center;
8425
+ gap: 8px 14px;
8426
+ border-bottom: 1px solid var(--tita-line);
8427
+ padding-bottom: 12px;
8428
+ margin-bottom: 14px;
8429
+ }
8430
+ .kwReadStats { display: flex; flex-wrap: wrap; gap: 6px 14px; color: var(--tita-ink-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
8431
+ .kwReadStats strong { color: var(--tita-ink); font-size: 13.5px; font-weight: 680; }
8432
+ .kwReadNoCoverage { display: inline-flex; align-items: center; gap: 5px; color: var(--tita-warning); }
8433
+ .kwReadLegend { display: flex; gap: 12px; margin-left: auto; color: var(--tita-ink-faint); font-size: 12px; }
8434
+ .kwReadLegend i { display: inline-block; width: 16px; height: 2.5px; margin-right: 5px; border-radius: 2px; background: var(--tita-tone-green); vertical-align: middle; }
8435
+ .kwReadLegend [data-tone="gap"] i { background: var(--tita-tone-amber); }
8436
+ .kwReadFilter { display: inline-flex; align-items: center; gap: 2px; border-radius: 8px; background: var(--tita-surface-muted); padding: 2px; }
8437
+ .kwReadFilter button {
8438
+ display: inline-flex; align-items: center; gap: 5px;
8439
+ border: 0; border-radius: 6px; background: transparent;
8440
+ padding: 4px 8px; color: var(--tita-ink-muted);
8441
+ font: inherit; font-size: 12px; cursor: pointer;
8442
+ }
8443
+ .kwReadFilter button i { color: var(--tita-ink-faint); font-style: normal; font-variant-numeric: tabular-nums; }
8444
+ .kwReadFilter button[aria-pressed="true"] { background: var(--tita-surface); color: var(--tita-ink); box-shadow: 0 1px 3px rgb(16 24 40 / 0.08); }
8445
+ .kwReadFilter button:disabled { opacity: .45; cursor: default; }
8446
+ .kwReadSearch { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--tita-line); border-radius: 7px; background: var(--tita-surface); padding: 0 8px; height: 28px; min-width: 190px; }
8447
+ .kwReadSearch svg { flex: 0 0 auto; color: var(--tita-ink-faint); }
8448
+ .kwReadSearch input { border: 0 !important; box-shadow: none !important; height: 26px; padding: 0; font-size: 12px; background: transparent; }
8449
+
8450
+ .kwReadText { max-width: 760px; color: var(--tita-ink); font-size: 13.5px; line-height: 1.95; overflow-wrap: anywhere; }
8451
+ .kwReadP { margin: 0 0 8px; }
8452
+ .kwReadH { margin: 24px 0 8px; color: var(--tita-ink); font-weight: 700; letter-spacing: -.018em; line-height: 1.4; }
8453
+ .kwReadH1 { font-size: 24.0px; }
8454
+ .kwReadH2 { font-size: 20px; }
8455
+ .kwReadH3 { font-size: 17px; }
8456
+ .kwReadBlank { height: 9px; }
8457
+ .kwReadLi { display: flex; align-items: baseline; gap: 8px; margin: 0 0 5px; }
8458
+ .kwReadLiMark { flex: 0 0 18px; color: var(--tita-ink-faint); font-size: 12px; text-align: right; }
8459
+ .kwReadRule { height: 1px; margin: 18px 0; background: var(--tita-line); }
8460
+ .kwReadTableRule { height: 1px; margin: 1px 0 5px; background: var(--tita-line); }
8461
+ .kwReadTr {
8462
+ display: grid;
8463
+ gap: 12px;
8464
+ border-bottom: 1px solid var(--tita-line);
8465
+ padding: 7px 9px;
8466
+ font-size: 12px;
8467
+ line-height: 1.65;
8468
+ }
8469
+ .kwReadTr[data-head] { border-top: 1px solid var(--tita-line); background: color-mix(in srgb, var(--tita-surface-muted) 55%, var(--tita-surface)); font-weight: 620; }
8470
+ .kwReadTd { min-width: 0; overflow-wrap: anywhere; }
8471
+ .kwReadCode { margin: 0 0 6px; padding: 8px 10px; border-radius: 6px; background: var(--tita-surface-muted); color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; }
8472
+ .kwReadFigure { display: inline-flex; align-items: center; min-height: 24px; margin: 0 0 8px; border: 1px dashed var(--tita-line-strong); border-radius: 5px; padding: 2px 8px; color: var(--tita-ink-faint); font-size: 12px; }
8473
+ .kwReadEnd { display: flex; align-items: center; gap: 5px; margin: 22px 0 0; border-top: 1px solid var(--tita-line); padding-top: 10px; color: var(--tita-ink-faint); font-size: 12px; }
8474
+ .kwReadMark {
8475
+ border-radius: 2px;
8476
+ text-decoration: underline;
8477
+ text-decoration-thickness: 2px;
8478
+ text-underline-offset: 3px;
8479
+ text-decoration-color: var(--tita-tone-green);
8480
+ cursor: help;
8481
+ }
8482
+ .kwReadMark[data-tone="gap"] { text-decoration-color: var(--tita-tone-amber); }
8483
+ .kwReadMark:hover, .kwReadMark[data-active] { background: color-mix(in srgb, var(--tita-tone-green) 9%, transparent); }
8484
+ .kwReadMark[data-tone="gap"]:hover, .kwReadMark[data-tone="gap"][data-active] { background: color-mix(in srgb, var(--tita-tone-amber) 10%, transparent); }
8485
+ .kwReadMark:focus-visible { outline: 2px solid var(--tita-focus-ring); outline-offset: 1px; }
8486
+
8487
+ .kwReadSkeleton { display: grid; gap: 12px; padding: 12px 0; }
8488
+ .kwReadSkeleton span { display: block; height: 13px; border-radius: 4px; background: linear-gradient(90deg, var(--tita-surface-muted), color-mix(in srgb, var(--tita-surface-muted) 40%, var(--tita-surface)), var(--tita-surface-muted)); background-size: 200% 100%; animation: kwReadShimmer 1.4s ease-in-out infinite; }
8489
+ .kwReadSkeleton span:nth-child(1) { width: 48%; }
8490
+ .kwReadSkeleton span:nth-child(2) { width: 92%; }
8491
+ .kwReadSkeleton span:nth-child(3) { width: 86%; }
8492
+ .kwReadSkeleton span:nth-child(4) { width: 63%; }
8493
+ @keyframes kwReadShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
8494
+ .kwReadError { display: flex; align-items: flex-start; gap: 10px; border: 1px solid var(--tita-line); border-radius: 8px; padding: 12px; color: var(--tita-ink-muted); font-size: 12px; }
8495
+ .kwReadError > svg { flex: 0 0 auto; margin-top: 1px; color: var(--tita-warning); }
8496
+ .kwReadError div { flex: 1; min-width: 0; }
8497
+ .kwReadError strong { display: block; color: var(--tita-ink); }
8498
+ .kwReadError p { margin: 2px 0 0; overflow-wrap: anywhere; }
8499
+
8500
+ .kwReadRail {
8501
+ position: sticky;
8502
+ top: 76px;
8503
+ align-self: start;
8504
+ max-height: calc(100vh - 96px);
8505
+ overflow: auto;
8506
+ border-left: 1px solid var(--tita-line);
8507
+ padding: 14px 18px 24px;
8508
+ scrollbar-width: thin;
8509
+ }
8510
+ .kwReadRailHead { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; border-bottom: 1px solid var(--tita-line); padding-bottom: 9px; }
8511
+ .kwReadRailHead strong { color: var(--tita-ink); font-size: 12px; font-weight: 680; }
8512
+ .kwReadRailHead span { color: var(--tita-ink-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
8513
+ .kwReadRailBody { padding-top: 2px; }
8514
+ .kwReadGroup h3 { display: flex; align-items: center; gap: 6px; margin: 14px 0 4px; color: var(--tita-ink-muted); font-size: 12px; font-weight: 620; letter-spacing: .02em; }
8515
+ .kwReadGroup h3 i { color: var(--tita-ink-faint); font-style: normal; font-weight: 500; }
8516
+ .kwReadDot { width: 6px; height: 6px; flex: 0 0 6px; border-radius: 50%; background: var(--tita-tone-green); }
8517
+ .kwReadDot[data-tone="gap"] { background: var(--tita-tone-amber); }
8518
+ .kwReadGroup ul { margin: 0; padding: 0; list-style: none; }
8519
+ .kwReadRow {
8520
+ display: grid;
8521
+ width: 100%;
8522
+ gap: 3px;
8523
+ border: 0;
8524
+ border-bottom: 1px solid var(--tita-line);
8525
+ background: transparent;
8526
+ padding: 8px 4px 9px;
8527
+ text-align: left;
8528
+ cursor: pointer;
8529
+ font: inherit;
8530
+ }
8531
+ .kwReadRow:hover { background: color-mix(in srgb, var(--tita-surface-muted) 55%, transparent); }
8532
+ .kwReadRowKind { color: var(--tita-tone-blue); font-size: 12px; font-weight: 600; letter-spacing: .06em; }
8533
+ .kwReadRowKind[data-kind="procedure"] { color: var(--tita-tone-violet); }
8534
+ .kwReadRowKind[data-kind="case"] { color: var(--tita-tone-amber); }
8535
+ .kwReadRow[data-tone="gap"] .kwReadRowKind { color: var(--tita-tone-amber); }
8536
+ .kwReadRow strong { display: -webkit-box; overflow: hidden; color: var(--tita-ink); font-size: 12px; font-weight: 540; line-height: 1.55; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
8537
+ .kwReadRow small { overflow: hidden; color: var(--tita-ink-faint); font-size: 12px; line-height: 1.45; text-overflow: ellipsis; white-space: nowrap; }
8538
+
8539
+ /* \u6D6E\u5C42\uFF1A\u53EA\u8BFB\uFF0C\u4E0D\u63A5\u6307\u9488\uFF0C\u907F\u514D\u60AC\u505C\u65F6\u548C\u5212\u7EBF\u7684 mouseleave \u6253\u67B6\u3002 */
8540
+ .kwReadPop {
8541
+ position: fixed;
8542
+ z-index: 60;
8543
+ width: 380px;
8544
+ max-height: 300px;
8545
+ overflow: auto;
8546
+ border: 1px solid var(--tita-line);
8547
+ border-radius: 10px;
8548
+ background: var(--tita-surface);
8549
+ box-shadow: 0 14px 36px rgb(16 24 40 / 0.16);
8550
+ padding: 11px 13px 10px;
8551
+ pointer-events: none;
8552
+ }
8553
+ .kwReadPop header { display: flex; align-items: center; gap: 6px; color: var(--tita-ink-faint); font-size: 12px; }
8554
+ .kwReadPop header strong { color: var(--tita-ink-muted); font-size: 12px; font-weight: 650; }
8555
+ .kwReadPop header em { color: var(--tita-ink-faint); font-style: normal; }
8556
+ .kwReadPop header span:last-child { margin-left: auto; font-variant-numeric: tabular-nums; }
8557
+ .kwReadPopTitle { margin: 7px 0 3px; color: var(--tita-ink); font-size: 12px; font-weight: 650; }
8558
+ .kwReadPopText { margin: 0; color: var(--tita-ink-muted); font-size: 12px; line-height: 1.6; }
8559
+ .kwReadPopQuote { margin: 6px 0 0; border-left: 1px solid var(--tita-line-strong); padding-left: 8px; color: var(--tita-ink-faint); font-size: 12px; line-height: 1.55; }
8560
+ .kwReadPopList { display: grid; gap: 8px; margin: 8px 0 4px; }
8561
+ .kwReadPopItem p { margin: 2px 0; color: var(--tita-ink); font-size: 12px; line-height: 1.55; }
8562
+ .kwReadPopItem small { color: var(--tita-ink-faint); font-size: 12px; }
8563
+ .kwReadPopMore { margin: 0; color: var(--tita-ink-faint); font-size: 12px; }
8564
+ .kwReadPop footer { margin-top: 8px; border-top: 1px solid var(--tita-line); padding-top: 7px; color: var(--tita-ink-faint); font-size: 12px; }
8565
+
8566
+ @media (max-width: 1100px) {
8567
+ .kwRead { grid-template-columns: minmax(0, 1fr); }
8568
+ .kwReadRail { position: static; max-height: none; margin-top: 18px; border-left: 0; border-top: 1px solid var(--tita-line); padding: 16px 20px 24px; }
8569
+ }
8570
+ @media (max-width: 760px) {
8571
+ .kwReadMain { padding: 12px 14px 22px; }
8572
+ .kwReadBar { gap: 7px 10px; }
8573
+ .kwReadLegend { margin-left: 0; }
8574
+ .kwReadSearch { min-width: 0; flex: 1 1 160px; }
8575
+ .kwReadText { font-size: 13.5px; }
8576
+ .kwReadRail { padding: 14px 14px 22px; }
8577
+ .kwReadPop { width: min(360px, calc(100vw - 24px)); }
8578
+ }
8579
+ .kwReadMeter { display: flex; height: 4px; margin: -2px 0 14px; overflow: hidden; border-radius: 2px; background: var(--tita-line); }
8580
+ .kwReadMeter span { display: block; height: 100%; }
8581
+ .kwReadMeter [data-tone="covered"] { background: var(--tita-tone-green); }
8582
+ .kwReadMeter [data-tone="gap"] { flex: 1; background: var(--tita-tone-amber); }
8583
+ .kwReadMore { width: 100%; border: 0; border-bottom: 1px solid var(--tita-line); background: transparent; padding: 8px 4px; color: var(--tita-primary); font: inherit; font-size: 12px; text-align: left; cursor: pointer; }
8584
+ .kwReadMore:hover { background: color-mix(in srgb, var(--tita-surface-muted) 55%, transparent); }
8585
+ .kwReadRow[data-on] { background: color-mix(in srgb, var(--tita-surface-muted) 65%, transparent); }
8586
+ .kwReadRow[data-on] strong { color: var(--tita-ink); }
8587
+ .kwReadPop[data-above="true"]::after,
8588
+ .kwReadPop[data-above="false"]::after {
8589
+ content: "";
8590
+ position: absolute;
8591
+ left: 26px;
8592
+ width: 9px;
8593
+ height: 9px;
8594
+ background: var(--tita-surface);
8595
+ transform: rotate(45deg);
8596
+ }
8597
+ .kwReadPop[data-above="true"]::after { bottom: -5px; border-right: 1px solid var(--tita-line); border-bottom: 1px solid var(--tita-line); }
8598
+ .kwReadPop[data-above="false"]::after { top: -5px; border-left: 1px solid var(--tita-line); border-top: 1px solid var(--tita-line); }
8599
+ .kwReadMeter { max-width: 760px; }
8600
+ .kwReadRow small { white-space: normal; display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
8601
+ .kwNotice-info { color: var(--tita-ink-muted); }
8602
+ .kwNotice-info svg { color: var(--tita-primary); }
8603
+ .kwReadJump { display: none; align-items: center; border: 1px solid var(--tita-line); border-radius: 6px; padding: 4px 8px; color: var(--tita-primary); font-size: 12px; text-decoration: none; }
8604
+ @media (max-width: 1100px) {
8605
+ .kwReadJump { display: inline-flex; }
8606
+ .kwReadRail { scroll-margin-top: 76px; }
8607
+ }
8608
+ .kwReadText[data-scope="gap"] .kwReadMark[data-tone="covered"],
8609
+ .kwReadText[data-scope="covered"] .kwReadMark[data-tone="gap"] { text-decoration-color: var(--tita-line-strong); opacity: .55; }
8610
+ .kwReadRailNote { margin: 10px 0 0; color: var(--tita-ink-faint); font-size: 12px; line-height: 1.55; }
8611
+ .kwReadPop[data-above="true"]::after, .kwReadPop[data-above="false"]::after { left: var(--kw-caret, 26px); }
8612
+ /* \u6587\u6863\u5217\u8868\u53EA\u7559\u4E24\u884C\uFF1A\u6807\u9898\u4E00\u884C\u3001\u7248\u672C\u4E0E\u72B6\u6001\u4E00\u884C\u3002\u7B2C\u4E09\u884C\uFF08\u77E5\u8BC6\u6761\u6570\u53E6\u8D77\u4E00\u884C\uFF09\u5728\u5C0F\u961F\u5217\u91CC
8613
+ \u628A\u4E00\u5C4F\u80FD\u770B\u5230\u7684\u6587\u6863\u6570\u538B\u6389\u4E09\u5206\u4E4B\u4E00\uFF0C\u6761\u6570\u5E76\u5165\u7B2C\u4E8C\u884C\u5C31\u591F\u3002 */
8614
+ .kwDoc { gap: 2px; }
8615
+ .kwDocMeta { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
8616
+ .kwDocMeta > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
8617
+ .kwDocFoot { display: none; }
8618
+ .kwDocCount { display: none; }
8619
+
8620
+ /* \u9605\u8BFB\u5BC6\u5EA6\uFF1A\u6B63\u6587\u539F\u6765\u6309\u957F\u6587\u9605\u8BFB\u6392\uFF081.95 \u884C\u9AD8\u300124px \u6BB5\u8DDD\uFF09\uFF0C\u5728\u9762\u677F\u91CC\u592A\u6563\u3002
8621
+ \u6536\u5230 1.72 / 5px\uFF0C\u8868\u683C\u4E0E\u4EE3\u7801\u5404\u81EA\u518D\u7D27\u4E00\u6863\u3002 */
8622
+ .kwReadText { font-size: 13.5px; line-height: 1.72; }
8623
+ .kwReadP { margin: 0 0 5px; }
8624
+ .kwReadH { margin: 17px 0 5px; }
8625
+ .kwReadH1 { font-size: 24px; }
8626
+ .kwReadH2 { font-size: 20px; }
8627
+ .kwReadH3 { font-size: 17px; }
8628
+ .kwReadBlank { height: 5px; }
8629
+ .kwReadLi { margin: 0 0 3px; line-height: 1.65; }
8630
+ .kwReadTr { gap: 8px; padding: 5px 8px; font-size: 12px; line-height: 1.5; }
8631
+ .kwReadTableRule { margin: 1px 0 3px; }
8632
+ .kwReadCode { margin: 0 0 3px; padding: 5px 7px; font-size: 10.5px; line-height: 1.4; }
8633
+ .kwReadFigure { min-height: 20px; margin: 0 0 5px; padding: 1px 6px; }
8634
+ .kwReadEnd { margin-top: 14px; padding-top: 7px; }
8635
+ .kwReadMain { padding: 12px 20px 24px; }
8636
+ .kwReadMark { text-decoration-color: var(--kw-mark-color, var(--tita-tone-green)); }
8637
+ .kwReadMark:hover, .kwReadMark[data-active] { background: color-mix(in srgb, var(--kw-mark-color, var(--tita-tone-green)) 9%, transparent); }
8638
+ .kwReadMark[data-tone="gap"] { text-decoration-color: var(--tita-tone-amber); }
8639
+ .kwReadLegend [data-tone="covered"] i { background: linear-gradient(90deg, #137d59 0 25%, #2d64be 25% 50%, #634cc2 50% 75%, #9a3f6e 75% 100%); }
8640
+ .kwReadPop { pointer-events: auto; max-height: min(320px, calc(100vh - 24px)); overflow: auto; box-sizing: border-box; }
8641
+ .kwReadPopText, .kwReadPopQuote, .kwReadPopItem p, .kwReadPopTitle, .kwReadPop footer { overflow-wrap: anywhere; word-break: break-word; }
8642
+ .kwReadImg { display: block; max-width: 100%; height: auto; margin: 8px 0; border: 1px solid var(--tita-line); border-radius: 6px; background: var(--tita-surface-muted); }
8643
+ .kwReadTd .kwReadImg { margin: 4px 0; }
8644
+ .kwReadUpload {
8645
+ display: flex;
8646
+ align-items: center;
8647
+ justify-content: space-between;
8648
+ gap: 12px;
8649
+ border: 1px solid var(--tita-line);
8650
+ border-radius: 8px;
8651
+ background: var(--tita-surface-muted);
8652
+ padding: 8px 10px;
8653
+ margin: 0 0 12px;
8654
+ }
8655
+ .kwReadUpload > div { display: grid; min-width: 0; gap: 1px; }
8656
+ .kwReadUpload strong { color: var(--tita-ink); font-size: 11px; font-weight: 620; }
8657
+ .kwReadUpload span { color: var(--tita-ink-muted); font-size: 10px; }
8658
+ .kwReadUpload em { color: var(--tita-warning); font-size: 10px; font-style: normal; }
8659
+ .kwReadUploadAction {
8660
+ flex: 0 0 auto;
8661
+ border: 1px solid var(--tita-line-strong);
8662
+ border-radius: 6px;
8663
+ background: var(--tita-surface);
8664
+ padding: 4px 8px;
8665
+ color: var(--tita-ink);
8666
+ font-size: 10.5px;
8667
+ cursor: pointer;
8668
+ }
8669
+ .kwReadUploadAction:hover { border-color: var(--tita-primary); color: var(--tita-primary); }
8670
+ .kwReadImg { max-height: 560px; object-fit: contain; margin-left: auto; margin-right: auto; }
8671
+ .kwReadTd .kwReadImg { max-height: 220px; }
8672
+
8673
+ /* ---------------------------------------------------------------- \u5F52\u4E00\u5750\u6807\u660E\u7EC6 */
8674
+ .kwAxes { border-top: 1px solid var(--tita-line); padding: 14px 20px 6px; }
8675
+ .kwAxesHead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
8676
+ .kwAxesHead h3 { margin: 0; color: var(--tita-ink); font-size: 12.5px; font-weight: 680; }
8677
+ .kwAxesHead p { margin: 2px 0 0; color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.5; }
8678
+ .kwAxesState { display: flex; align-items: center; gap: 6px; margin: 10px 0; color: var(--tita-ink-muted); font-size: 11px; }
8679
+ .kwAxesState[data-tone="error"] { color: var(--tita-warning); }
8680
+ .kwAxesSummary { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 12px; margin: 10px 0 4px; color: var(--tita-ink-muted); font-size: 10.5px; font-variant-numeric: tabular-nums; }
8681
+ .kwAxesSummary strong { color: var(--tita-ink); font-weight: 650; }
8682
+ .kwAxesSummary [data-tone="success"] strong { color: var(--tita-success); }
8683
+ .kwAxesSummary [data-tone="warning"] strong { color: var(--tita-warning); }
8684
+ .kwAxesSummary [data-tone="blue"] strong { color: var(--tita-tone-blue); }
8685
+ .kwAxesSource { margin-left: auto; color: var(--tita-ink-faint); }
8686
+ .kwAxesGroup { margin-top: 12px; }
8687
+ .kwAxesGroup h4 { display: flex; align-items: baseline; gap: 6px; margin: 0 0 4px; color: var(--tita-ink); font-size: 11px; font-weight: 650; }
8688
+ .kwAxesGroup h4 span { color: var(--tita-ink-faint); font-size: 10px; font-weight: 400; }
8689
+ .kwAxesGroup ul { margin: 0; padding: 0; list-style: none; }
8690
+ .kwAxesGroup > ul > li { border-top: 1px solid var(--tita-line); padding: 7px 0; }
8691
+ .kwAxesGroup > ul > li:first-child { border-top: 0; }
8692
+ .kwAxesGroup > ul > li.kwAxesRow { display: grid; gap: 2px; }
8693
+ .kwAxesGroup > ul > li:not(.kwAxesRow) { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; font-size: 11px; }
8694
+ .kwAxesKind { flex: 0 0 auto; color: var(--tita-ink-faint); font-size: 9.5px; }
8695
+ .kwAxesGroup > ul > li strong { color: var(--tita-ink); font-size: 11.5px; font-weight: 600; }
8696
+ .kwAxesArrow { color: var(--tita-ink-faint); }
8697
+ .kwAxesMentions { color: var(--tita-ink-muted); font-size: 10.5px; }
8698
+ .kwAxesRowHead { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
8699
+ .kwAxesRowHead strong { font-size: 11.5px; }
8700
+ .kwAxesTarget { color: var(--tita-ink-muted); font-size: 10.5px; }
8701
+ .kwAxesRow p { margin: 0; color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.55; overflow-wrap: anywhere; }
8702
+ .kwAxesEvidence { color: var(--tita-ink-faint) !important; }
8703
+ .kwAxesWhy { color: var(--tita-warning) !important; }
8704
+ .kwAxesHint { margin: 12px 0 6px; border-top: 1px solid var(--tita-line); padding-top: 8px; color: var(--tita-ink-faint); font-size: 10px; line-height: 1.55; }
8705
+ @media (max-width: 760px) {
8706
+ .kwAxes { padding: 12px 14px 4px; }
8707
+ .kwAxesSource { margin-left: 0; width: 100%; }
8708
+ }
8709
+ .kwAxesScroll { max-height: 420px; overflow: auto; scrollbar-width: thin; scrollbar-color: var(--tita-line-strong) transparent; }
8710
+ .kwAxesLink { margin-left: 8px; border: 0; background: none; padding: 0; color: var(--tita-primary); font: inherit; font-size: 10px; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
8711
+ .kwAxesTip { margin: 8px 0 2px; color: var(--tita-ink-muted); font-size: 10.5px; line-height: 1.55; }
8712
+ .kwAxesNone { margin: 6px 0 0; color: var(--tita-ink-faint); font-size: 10px; }
8713
+ .kwImportImages { margin: 8px 0 0; color: var(--tita-ink-muted); font-size: 10.5px; }
8714
+ .kwUsage { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 0 0 10px; padding: 8px 10px; border: 1px solid var(--tita-line); border-radius: 7px; background: var(--tita-surface-muted); }
8715
+ .kwUsage > div { display: flex; align-items: baseline; gap: 5px; }
8716
+ .kwUsage dt { color: var(--tita-ink-faint); font-size: 9.5px; }
8717
+ .kwUsage dd { margin: 0; color: var(--tita-ink); font-size: 11px; font-weight: 620; font-variant-numeric: tabular-nums; }
8718
+ .kwUsageMissing { margin: 0 0 8px; color: var(--tita-ink-faint); font-size: 10px; }
8719
+ /* \u6D6E\u5C42\u56FA\u5B9A\u5BBD\u3001\u53EA\u7EB5\u5411\u6EDA\uFF1B\u6EDA\u52A8\u5B83\u81EA\u5DF1\u4E0D\u80FD\u88AB\u5F53\u6210\u9875\u9762\u6EDA\u52A8\u800C\u5173\u6389\u3002 */
8720
+ .kwReadPop { width: 380px; max-width: calc(100vw - 24px); overflow-x: hidden; overflow-y: auto; }
8721
+ .kwReadPop * { min-width: 0; }
8722
+ .kwReadImg { max-width: 320px; max-height: 220px; width: auto; height: auto; margin: 6px 0; }
8723
+ .kwReadTd .kwReadImg { max-width: 180px; max-height: 140px; }
8724
+ .kwReadCode { margin: 7px 0 9px; }
8725
+ .kwTimeline li { grid-template-columns: 112px minmax(0, 1fr); gap: 12px; }
8726
+ .kwTimeline time { font-size: 11.5px; }
8727
+ @media (max-width: 760px) {
8728
+ .kwTimeline li { grid-template-columns: 100px minmax(0, 1fr); gap: 8px; }
8729
+ .kwTimeline time { font-size: 10.5px; }
8730
+ }
8731
+ .kwCallUsage { color: var(--tita-ink-faint); font-size: 9.5px; font-variant-numeric: tabular-nums; }
8732
+ `;
7327
8733
  var tagId4 = "dsh-data-domain-knowledge//Users/fuzz/Documents/github/dsh-personal/plugins/dsh-data-domain-knowledge/src/client/tasks-page.css";
7328
8734
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId4) + "]") === null) {
7329
8735
  const tag = document.createElement("style");
@@ -11273,14 +12679,14 @@
11273
12679
  }
11274
12680
  function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
11275
12681
  const alignment = getAlignment(placement);
11276
- let list = getSideList(getSide(placement), direction === "start", rtl);
12682
+ let list2 = getSideList(getSide(placement), direction === "start", rtl);
11277
12683
  if (alignment) {
11278
- list = list.map((side) => side + "-" + alignment);
12684
+ list2 = list2.map((side) => side + "-" + alignment);
11279
12685
  if (flipAlignment) {
11280
- list = list.concat(list.map(getOppositeAlignmentPlacement));
12686
+ list2 = list2.concat(list2.map(getOppositeAlignmentPlacement));
11281
12687
  }
11282
12688
  }
11283
- return list;
12689
+ return list2;
11284
12690
  }
11285
12691
  function getOppositePlacement(placement) {
11286
12692
  const side = getSide(placement);
@@ -12154,10 +13560,10 @@
12154
13560
  }
12155
13561
  return getNearestOverflowAncestor(parentNode);
12156
13562
  }
12157
- function getOverflowAncestors(node, list, traverseIframes) {
13563
+ function getOverflowAncestors(node, list2, traverseIframes) {
12158
13564
  var _node$ownerDocument2;
12159
- if (list === void 0) {
12160
- list = [];
13565
+ if (list2 === void 0) {
13566
+ list2 = [];
12161
13567
  }
12162
13568
  if (traverseIframes === void 0) {
12163
13569
  traverseIframes = true;
@@ -12167,9 +13573,9 @@
12167
13573
  const win = getWindow(scrollableAncestor);
12168
13574
  if (isBody) {
12169
13575
  const frameElement = getFrameElement(win);
12170
- return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
13576
+ return list2.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
12171
13577
  } else {
12172
- return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
13578
+ return list2.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
12173
13579
  }
12174
13580
  }
12175
13581
  function getFrameElement(win) {
@@ -19824,30 +21230,658 @@ Defaulting to \`null\`.`;
19824
21230
  ];
19825
21231
  var AXIS_CONTRACT = AXIS_CONTRACT_LINES.join("\n");
19826
21232
 
21233
+ // ../../node_modules/.pnpm/@toon-format+toon@4.4.0/node_modules/@toon-format/toon/dist/index.mjs
21234
+ var NULL_LITERAL = "null";
21235
+ var DELIMITERS = {
21236
+ comma: ",",
21237
+ tab: " ",
21238
+ pipe: "|"
21239
+ };
21240
+ var DEFAULT_DELIMITER = DELIMITERS.comma;
21241
+ function escapeString(value) {
21242
+ return value.replace(/\\/g, `\\\\`).replace(/"/g, `\\"`).replace(/\n/g, `\\n`).replace(/\r/g, `\\r`).replace(/\t/g, `\\t`).replace(/[\u0000-\u001F]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`);
21243
+ }
21244
+ var FETCH_LINE = Symbol("fetch-line");
21245
+ function isBooleanOrNullLiteral(token) {
21246
+ return token === "true" || token === "false" || token === "null";
21247
+ }
21248
+ function setOwnProperty(target, key, value) {
21249
+ if (key === "__proto__") {
21250
+ Object.defineProperty(target, key, {
21251
+ value,
21252
+ enumerable: true,
21253
+ writable: true,
21254
+ configurable: true
21255
+ });
21256
+ return;
21257
+ }
21258
+ target[key] = value;
21259
+ }
21260
+ var COMMENT_LINE_PATTERN = new RegExp(`(?:^\uFEFF?|\\n) *#`);
21261
+ var RawString = class {
21262
+ constructor(value) {
21263
+ if (COMMENT_LINE_PATTERN.test(value)) throw new TypeError(`Raw string must not contain a line starting with "#": ${JSON.stringify(value)}`);
21264
+ this.value = value;
21265
+ }
21266
+ };
21267
+ function isRawString(value) {
21268
+ return value instanceof RawString;
21269
+ }
21270
+ var SURROGATE_PATTERN = /[\uD800-\uDFFF]/;
21271
+ function normalizeValue(value) {
21272
+ if (value === null) return null;
21273
+ if (isRawString(value)) return value;
21274
+ if (typeof value === "object" && value !== null && "toJSON" in value && typeof value.toJSON === "function") {
21275
+ const next = value.toJSON();
21276
+ if (next !== value) return normalizeValue(next);
21277
+ }
21278
+ if (typeof value === "string") {
21279
+ assertNoLoneSurrogate(value, "string value");
21280
+ return value;
21281
+ }
21282
+ if (typeof value === "boolean") return value;
21283
+ if (typeof value === "number") {
21284
+ if (Object.is(value, -0)) return 0;
21285
+ if (!Number.isFinite(value)) return null;
21286
+ return value;
21287
+ }
21288
+ if (typeof value === "bigint") {
21289
+ if (value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER) return Number(value);
21290
+ return value.toString();
21291
+ }
21292
+ if (value instanceof Date) return value.toISOString();
21293
+ if (Array.isArray(value)) return Array.from(value, normalizeValue);
21294
+ if (value instanceof Set) return Array.from(value).map(normalizeValue);
21295
+ if (value instanceof Map) return Object.fromEntries(Array.from(value, ([k3, v]) => [String(k3), normalizeValue(v)]));
21296
+ if (isPlainObject(value)) {
21297
+ const encodedValues = {};
21298
+ for (const key in value) if (Object.hasOwn(value, key)) {
21299
+ assertNoLoneSurrogate(key, "object key");
21300
+ setOwnProperty(encodedValues, key, normalizeValue(value[key]));
21301
+ }
21302
+ return encodedValues;
21303
+ }
21304
+ return null;
21305
+ }
21306
+ function assertNoLoneSurrogate(value, context) {
21307
+ if (!SURROGATE_PATTERN.test(value)) return;
21308
+ for (let index2 = 0; index2 < value.length; index2++) {
21309
+ const code = value.charCodeAt(index2);
21310
+ if (code < 55296 || code > 57343) continue;
21311
+ const isHighSurrogate = code <= 56319;
21312
+ const next = value.charCodeAt(index2 + 1);
21313
+ if (isHighSurrogate && next >= 56320 && next <= 57343) {
21314
+ index2++;
21315
+ continue;
21316
+ }
21317
+ throw new TypeError(`Cannot encode ${context} containing an unpaired surrogate U+${code.toString(16).toUpperCase()} at index ${index2}`);
21318
+ }
21319
+ }
21320
+ function isJsonPrimitive(value) {
21321
+ return value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
21322
+ }
21323
+ function isEncodablePrimitive(value) {
21324
+ return isJsonPrimitive(value) || isRawString(value);
21325
+ }
21326
+ function isJsonArray(value) {
21327
+ return Array.isArray(value);
21328
+ }
21329
+ function isJsonObject(value) {
21330
+ return value !== null && typeof value === "object" && !Array.isArray(value) && !isRawString(value);
21331
+ }
21332
+ function isEmptyObject(value) {
21333
+ return Object.keys(value).length === 0;
21334
+ }
21335
+ function isPlainObject(value) {
21336
+ if (value === null || typeof value !== "object") return false;
21337
+ const prototype = Object.getPrototypeOf(value);
21338
+ return prototype === null || prototype === Object.prototype;
21339
+ }
21340
+ function isArrayOfPrimitives(value) {
21341
+ return value.length === 0 || value.every((item) => isEncodablePrimitive(item));
21342
+ }
21343
+ function isArrayOfArrays(value) {
21344
+ return value.length === 0 || value.every((item) => isJsonArray(item));
21345
+ }
21346
+ function isArrayOfObjects(value) {
21347
+ return value.length === 0 || value.every((item) => isJsonObject(item));
21348
+ }
21349
+ var NUMERIC_LIKE_PATTERN = /^[+-]?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i;
21350
+ function assertValidDelimiter(delimiter) {
21351
+ if (!Object.values(DELIMITERS).includes(delimiter)) throw new TypeError(`Invalid delimiter ${JSON.stringify(delimiter)}. Valid delimiters are: comma (,), tab (\\t), pipe (|)`);
21352
+ }
21353
+ function isValidUnquotedKey(key) {
21354
+ return /^[A-Z_][\w.]*$/i.test(key);
21355
+ }
21356
+ function isSafeUnquoted(value, delimiter = DEFAULT_DELIMITER) {
21357
+ if (!value) return false;
21358
+ if (/^[ \t]|[ \t]$/.test(value)) return false;
21359
+ if (isBooleanOrNullLiteral(value) || isNumericLike(value)) return false;
21360
+ if (value.includes(":")) return false;
21361
+ if (value.includes('"') || value.includes("\\")) return false;
21362
+ if (/[[\]{}]/.test(value)) return false;
21363
+ if (/[\u0000-\u001F]/.test(value)) return false;
21364
+ if (value.includes(delimiter)) return false;
21365
+ if (value.startsWith("-")) return false;
21366
+ if (value.startsWith("#")) return false;
21367
+ return true;
21368
+ }
21369
+ function isNumericLike(value) {
21370
+ return NUMERIC_LIKE_PATTERN.test(value);
21371
+ }
21372
+ function encodePrimitive(value, delimiter) {
21373
+ if (isRawString(value)) return value.value;
21374
+ if (value === null) return NULL_LITERAL;
21375
+ if (typeof value === "boolean") return String(value);
21376
+ if (typeof value === "number") return String(value);
21377
+ return encodeStringLiteral(value, delimiter);
21378
+ }
21379
+ function encodeStringLiteral(value, delimiter = DEFAULT_DELIMITER) {
21380
+ if (isSafeUnquoted(value, delimiter)) return value;
21381
+ return `"${escapeString(value)}"`;
21382
+ }
21383
+ function encodeKey(key) {
21384
+ if (isValidUnquotedKey(key)) return key;
21385
+ return `"${escapeString(key)}"`;
21386
+ }
21387
+ function encodeAndJoinPrimitives(values, delimiter = DEFAULT_DELIMITER) {
21388
+ return values.map((v) => encodePrimitive(v, delimiter)).join(delimiter);
21389
+ }
21390
+ function formatHeader(length, options) {
21391
+ const key = options?.key;
21392
+ const fields = options?.fields;
21393
+ const delimiter = options?.delimiter ?? ",";
21394
+ let header = "";
21395
+ if (key != null) header += encodeKey(key);
21396
+ header += `[${length}${options?.keyed ? ":" : ""}${delimiter !== DEFAULT_DELIMITER ? delimiter : ""}]`;
21397
+ if (fields) header += `{${formatFieldSegment(fields, delimiter)}}`;
21398
+ header += ":";
21399
+ return header;
21400
+ }
21401
+ function formatFieldSegment(fields, delimiter) {
21402
+ return fields.map((field) => encodeKey(field.name) + (field.children ? `{${formatFieldSegment(field.children, delimiter)}}` : "")).join(delimiter);
21403
+ }
21404
+ function extractTabularFields(rows) {
21405
+ if (rows.length === 0) return;
21406
+ const firstKeys = Object.keys(rows[0]);
21407
+ if (firstKeys.length === 0) return;
21408
+ for (const row of rows) {
21409
+ if (Object.keys(row).length !== firstKeys.length) return;
21410
+ for (const key of firstKeys) if (!Object.hasOwn(row, key)) return;
21411
+ }
21412
+ const fieldNodes = [];
21413
+ for (const key of firstKeys) {
21414
+ const fieldNode = classifyColumn(key, rows.map((row) => row[key]));
21415
+ if (!fieldNode) return;
21416
+ fieldNodes.push(fieldNode);
21417
+ }
21418
+ return fieldNodes;
21419
+ }
21420
+ function extractKeyedTabularFields(value) {
21421
+ const entryValues = Object.values(value);
21422
+ if (entryValues.length < 2) return;
21423
+ if (!entryValues.every((entryValue) => isJsonObject(entryValue) && !isEmptyObject(entryValue))) return;
21424
+ return extractTabularFields(entryValues);
21425
+ }
21426
+ function collectRowLeaves(row, fields) {
21427
+ const leaves = [];
21428
+ collectLeafValues(row, fields, leaves);
21429
+ return leaves;
21430
+ }
21431
+ function classifyColumn(name, values) {
21432
+ if (values.every((value) => isEncodablePrimitive(value))) return { name };
21433
+ if (!values.every((value) => isJsonObject(value) && !isEmptyObject(value))) return;
21434
+ const children = extractTabularFields(values);
21435
+ if (!children) return;
21436
+ return {
21437
+ name,
21438
+ children
21439
+ };
21440
+ }
21441
+ function collectLeafValues(row, fields, leaves) {
21442
+ for (const field of fields) {
21443
+ const value = row[field.name];
21444
+ if (field.children) collectLeafValues(value, field.children, leaves);
21445
+ else leaves.push(value);
21446
+ }
21447
+ }
21448
+ function* encodeJsonValue(value, options, depth) {
21449
+ if (isEncodablePrimitive(value)) {
21450
+ const encodedPrimitive = typeof value === "string" && value.startsWith("\uFEFF") ? `"${escapeString(value)}"` : encodePrimitive(value, options.delimiter);
21451
+ if (encodedPrimitive !== "") yield encodedPrimitive;
21452
+ return;
21453
+ }
21454
+ if (isJsonArray(value)) yield* encodeArrayLines(void 0, value, depth, options);
21455
+ else if (isJsonObject(value)) {
21456
+ const keyedFields = extractKeyedTabularFields(value);
21457
+ if (keyedFields) {
21458
+ yield* encodeKeyedObjectLines(void 0, value, keyedFields, depth, options);
21459
+ return;
21460
+ }
21461
+ yield* encodeObjectLines(value, depth, options);
21462
+ }
21463
+ }
21464
+ function* encodeObjectLines(value, depth, options) {
21465
+ for (const [key, val] of Object.entries(value)) yield* encodeKeyValuePairLines(key, val, depth, options);
21466
+ }
21467
+ function* encodeKeyValuePairLines(key, value, depth, options) {
21468
+ const encodedKey = encodeKey(key);
21469
+ if (isEncodablePrimitive(value)) yield indentedLine(depth, `${encodedKey}: ${encodePrimitive(value, options.delimiter)}`, options.indentSize);
21470
+ else if (isJsonArray(value)) yield* encodeArrayLines(key, value, depth, options);
21471
+ else if (isJsonObject(value)) {
21472
+ const keyedFields = extractKeyedTabularFields(value);
21473
+ if (keyedFields) {
21474
+ yield* encodeKeyedObjectLines(key, value, keyedFields, depth, options);
21475
+ return;
21476
+ }
21477
+ yield indentedLine(depth, `${encodedKey}:`, options.indentSize);
21478
+ if (!isEmptyObject(value)) yield* encodeObjectLines(value, depth + 1, options);
21479
+ }
21480
+ }
21481
+ function* encodeKeyedObjectLines(key, value, fields, depth, options) {
21482
+ const entries = Object.entries(value);
21483
+ yield indentedLine(depth, formatHeader(entries.length, {
21484
+ key,
21485
+ fields,
21486
+ delimiter: options.delimiter,
21487
+ keyed: true
21488
+ }), options.indentSize);
21489
+ yield* encodeKeyedEntryRowsLines(entries, fields, depth + 1, options);
21490
+ }
21491
+ function* encodeKeyedEntryRowsLines(entries, fields, depth, options) {
21492
+ for (const [entryKey, entryValue] of entries) {
21493
+ const leaves = collectRowLeaves(entryValue, fields);
21494
+ yield indentedLine(depth, `${encodeKey(entryKey)}: ${encodeAndJoinPrimitives(leaves, options.delimiter)}`, options.indentSize);
21495
+ }
21496
+ }
21497
+ function* encodeArrayLines(key, value, depth, options) {
21498
+ if (value.length === 0) {
21499
+ yield indentedLine(depth, key != null ? `${encodeKey(key)}: []` : "[]", options.indentSize);
21500
+ return;
21501
+ }
21502
+ if (isArrayOfPrimitives(value)) {
21503
+ yield indentedLine(depth, encodeInlineArrayLine(value, options.delimiter, key), options.indentSize);
21504
+ return;
21505
+ }
21506
+ if (isArrayOfArrays(value)) {
21507
+ if (value.every((arr) => isArrayOfPrimitives(arr))) {
21508
+ yield* encodeArrayOfArraysAsListItemsLines(key, value, depth, options);
21509
+ return;
21510
+ }
21511
+ }
21512
+ if (isArrayOfObjects(value)) {
21513
+ const fields = extractTabularFields(value);
21514
+ if (fields) yield* encodeArrayOfObjectsAsTabularLines(key, value, fields, depth, options);
21515
+ else yield* encodeMixedArrayAsListItemsLines(key, value, depth, options);
21516
+ return;
21517
+ }
21518
+ yield* encodeMixedArrayAsListItemsLines(key, value, depth, options);
21519
+ }
21520
+ function* encodeArrayOfArraysAsListItemsLines(prefix, values, depth, options) {
21521
+ yield indentedLine(depth, formatHeader(values.length, {
21522
+ key: prefix,
21523
+ delimiter: options.delimiter
21524
+ }), options.indentSize);
21525
+ for (const arr of values) if (isArrayOfPrimitives(arr)) {
21526
+ const arrayLine = encodeInlineArrayLine(arr, options.delimiter);
21527
+ yield indentedListItem(depth + 1, arrayLine, options.indentSize);
21528
+ }
21529
+ }
21530
+ function encodeInlineArrayLine(values, delimiter, prefix) {
21531
+ const header = formatHeader(values.length, {
21532
+ key: prefix,
21533
+ delimiter
21534
+ });
21535
+ const joinedValue = encodeAndJoinPrimitives(values, delimiter);
21536
+ if (values.length === 0) return header;
21537
+ return `${header} ${joinedValue}`;
21538
+ }
21539
+ function* encodeArrayOfObjectsAsTabularLines(prefix, rows, fields, depth, options) {
21540
+ yield indentedLine(depth, formatHeader(rows.length, {
21541
+ key: prefix,
21542
+ fields,
21543
+ delimiter: options.delimiter
21544
+ }), options.indentSize);
21545
+ yield* writeTabularRowsLines(rows, fields, depth + 1, options);
21546
+ }
21547
+ function* writeTabularRowsLines(rows, fields, depth, options) {
21548
+ for (const row of rows) yield indentedLine(depth, encodeAndJoinPrimitives(collectRowLeaves(row, fields), options.delimiter), options.indentSize);
21549
+ }
21550
+ function* encodeMixedArrayAsListItemsLines(prefix, items, depth, options) {
21551
+ yield indentedLine(depth, formatHeader(items.length, {
21552
+ key: prefix,
21553
+ delimiter: options.delimiter
21554
+ }), options.indentSize);
21555
+ for (const item of items) yield* encodeListItemValueLines(item, depth + 1, options);
21556
+ }
21557
+ function* encodeObjectAsListItemLines(obj, depth, options) {
21558
+ if (isEmptyObject(obj)) {
21559
+ yield indentedLine(depth, "-", options.indentSize);
21560
+ return;
21561
+ }
21562
+ const entries = Object.entries(obj);
21563
+ const [firstKey, firstValue] = entries[0];
21564
+ const restEntries = entries.slice(1);
21565
+ if (isJsonArray(firstValue) && isArrayOfObjects(firstValue)) {
21566
+ const fields = extractTabularFields(firstValue);
21567
+ if (fields) {
21568
+ yield indentedListItem(depth, formatHeader(firstValue.length, {
21569
+ key: firstKey,
21570
+ fields,
21571
+ delimiter: options.delimiter
21572
+ }), options.indentSize);
21573
+ yield* writeTabularRowsLines(firstValue, fields, depth + 2, options);
21574
+ if (restEntries.length > 0) yield* encodeObjectLines(Object.fromEntries(restEntries), depth + 1, options);
21575
+ return;
21576
+ }
21577
+ }
21578
+ if (isJsonObject(firstValue)) {
21579
+ const keyedFields = extractKeyedTabularFields(firstValue);
21580
+ if (keyedFields) {
21581
+ const keyedEntries = Object.entries(firstValue);
21582
+ yield indentedListItem(depth, formatHeader(keyedEntries.length, {
21583
+ key: firstKey,
21584
+ fields: keyedFields,
21585
+ delimiter: options.delimiter,
21586
+ keyed: true
21587
+ }), options.indentSize);
21588
+ yield* encodeKeyedEntryRowsLines(keyedEntries, keyedFields, depth + 2, options);
21589
+ if (restEntries.length > 0) yield* encodeObjectLines(Object.fromEntries(restEntries), depth + 1, options);
21590
+ return;
21591
+ }
21592
+ }
21593
+ const encodedKey = encodeKey(firstKey);
21594
+ if (isEncodablePrimitive(firstValue)) yield indentedListItem(depth, `${encodedKey}: ${encodePrimitive(firstValue, options.delimiter)}`, options.indentSize);
21595
+ else if (isJsonArray(firstValue)) {
21596
+ if (firstValue.length === 0) yield indentedListItem(depth, `${encodedKey}: []`, options.indentSize);
21597
+ else if (isArrayOfPrimitives(firstValue)) yield indentedListItem(depth, `${encodedKey}${encodeInlineArrayLine(firstValue, options.delimiter)}`, options.indentSize);
21598
+ else {
21599
+ yield indentedListItem(depth, `${encodedKey}${formatHeader(firstValue.length, { delimiter: options.delimiter })}`, options.indentSize);
21600
+ for (const item of firstValue) yield* encodeListItemValueLines(item, depth + 2, options);
21601
+ }
21602
+ } else if (isJsonObject(firstValue)) {
21603
+ yield indentedListItem(depth, `${encodedKey}:`, options.indentSize);
21604
+ if (!isEmptyObject(firstValue)) yield* encodeObjectLines(firstValue, depth + 2, options);
21605
+ }
21606
+ if (restEntries.length > 0) yield* encodeObjectLines(Object.fromEntries(restEntries), depth + 1, options);
21607
+ }
21608
+ function* encodeListItemValueLines(value, depth, options) {
21609
+ if (isEncodablePrimitive(value)) yield indentedListItem(depth, encodePrimitive(value, options.delimiter), options.indentSize);
21610
+ else if (isJsonArray(value)) {
21611
+ if (isArrayOfPrimitives(value)) yield indentedListItem(depth, encodeInlineArrayLine(value, options.delimiter), options.indentSize);
21612
+ else {
21613
+ yield indentedListItem(depth, formatHeader(value.length, { delimiter: options.delimiter }), options.indentSize);
21614
+ for (const item of value) yield* encodeListItemValueLines(item, depth + 1, options);
21615
+ }
21616
+ } else if (isJsonObject(value)) yield* encodeObjectAsListItemLines(value, depth, options);
21617
+ }
21618
+ function indentedLine(depth, content, indentSize) {
21619
+ return " ".repeat(indentSize * depth) + content;
21620
+ }
21621
+ function indentedListItem(depth, content, indentSize) {
21622
+ return indentedLine(depth, "- " + content, indentSize);
21623
+ }
21624
+ function applyReplacer(root, replacer) {
21625
+ const replacedRoot = replacer("", root, []);
21626
+ if (replacedRoot === void 0) return transformChildren(root, replacer, []);
21627
+ return transformReplaced(root, replacedRoot, replacer, []);
21628
+ }
21629
+ function transformReplaced(original, replaced, replacer, path) {
21630
+ if (isRawString(replaced) && !isEncodablePrimitive(original)) return transformChildren(original, replacer, path);
21631
+ return transformChildren(normalizeValue(replaced), replacer, path);
21632
+ }
21633
+ function transformChildren(value, replacer, path) {
21634
+ if (isJsonObject(value)) return transformObject(value, replacer, path);
21635
+ if (isJsonArray(value)) return transformArray(value, replacer, path);
21636
+ return value;
21637
+ }
21638
+ function transformObject(obj, replacer, path) {
21639
+ const result = {};
21640
+ for (const [key, value] of Object.entries(obj)) {
21641
+ const childPath = [...path, key];
21642
+ const replacedValue = replacer(key, value, childPath);
21643
+ if (replacedValue === void 0) continue;
21644
+ setOwnProperty(result, key, transformReplaced(value, replacedValue, replacer, childPath));
21645
+ }
21646
+ return result;
21647
+ }
21648
+ function transformArray(arr, replacer, path) {
21649
+ const result = [];
21650
+ for (let i = 0; i < arr.length; i++) {
21651
+ const value = arr[i];
21652
+ const childPath = [...path, i];
21653
+ const replacedValue = replacer(String(i), value, childPath);
21654
+ if (replacedValue === void 0) continue;
21655
+ result.push(transformReplaced(value, replacedValue, replacer, childPath));
21656
+ }
21657
+ return result;
21658
+ }
21659
+ function encode(input, options) {
21660
+ return Array.from(encodeLines(input, options)).join("\n");
21661
+ }
21662
+ function encodeLines(input, options) {
21663
+ const normalizedValue = normalizeValue(input);
21664
+ const resolvedOptions = resolveOptions(options);
21665
+ return encodeJsonValue(resolvedOptions.replacer ? applyReplacer(normalizedValue, resolvedOptions.replacer) : normalizedValue, resolvedOptions, 0);
21666
+ }
21667
+ function resolveOptions(options) {
21668
+ const delimiter = options?.delimiter ?? DEFAULT_DELIMITER;
21669
+ assertValidDelimiter(delimiter);
21670
+ return {
21671
+ indentSize: options?.indentSize ?? options?.indent ?? 2,
21672
+ delimiter,
21673
+ replacer: options?.replacer
21674
+ };
21675
+ }
21676
+
21677
+ // lib/wire/contracts.js
21678
+ var TOON_OUTPUT_RULES = [
21679
+ "\u53EA\u8FD4\u56DE TOON \u56FA\u5B9A\u5217\u8868\u683C\uFF0C\u4E0D\u52A0 Markdown \u56F4\u680F\u3002",
21680
+ "\u6570\u7EC4\u5934 [N] \u4E3A\u5B9E\u9645\u884C\u6570\uFF0C\u7A7A\u6570\u7EC4\u5199 \u540D\u79F0[0]: \u6216 \u540D\u79F0: []\uFF0C\u6BCF\u884C\u5217\u6570\u4E0E\u8868\u5934\u4E00\u81F4\u3002",
21681
+ "\u9017\u53F7\u5206\u5217\uFF0C\u590D\u6742\u5B57\u7B26\u4E32\u6309 TOON \u8F6C\u4E49\u3002\u7F3A\u5931\u503C\u4E3A null\u3002\u6570\u7EC4\u5B57\u6BB5\u4E3A JSON \u6570\u7EC4\u5B57\u7B26\u4E32\u3002",
21682
+ "\u6BCF\u6761\u8BB0\u5F55\u5360\u4E00\u4E2A\u7269\u7406\u884C\uFF0C\u7F29\u8FDB\u4E24\u7A7A\u683C\uFF1B\u5355\u5143\u683C\u5185\u6362\u884C\u5199 \\n\uFF1B\u8868\u540D\u548C\u5217\u540D\u4E0D\u5F97\u91CD\u590D\u3002"
21683
+ ];
21684
+
21685
+ // lib/wire/toon-codec.js
21686
+ function validateChildren(children) {
21687
+ const tables = new Set(children.map((child) => child.table));
21688
+ if (tables.size !== children.length || children.some((child) => tables.has(child.parent)))
21689
+ throw new Error("TOON children \u4EC5\u652F\u6301\u4E0D\u91CD\u590D\u7684\u5355\u5C42\u5B50\u8868\uFF0C\u4E0D\u80FD\u5FAA\u73AF\u6216\u5D4C\u5957");
21690
+ }
21691
+ function validateJSON(value, seen = /* @__PURE__ */ new Set()) {
21692
+ if (value === null || typeof value === "string" || typeof value === "boolean")
21693
+ return;
21694
+ if (typeof value === "number" && Number.isFinite(value))
21695
+ return;
21696
+ if (typeof value !== "object" || !value || seen.has(value))
21697
+ throw new Error("TOON \u8F93\u5165\u4E0D\u662F\u6709\u9650\u3001\u65E0\u5FAA\u73AF\u7684 JSON \u503C");
21698
+ if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
21699
+ throw new Error("TOON \u8F93\u5165\u53EA\u63A5\u53D7\u666E\u901A JSON \u5BF9\u8C61");
21700
+ seen.add(value);
21701
+ for (const item of Array.isArray(value) ? value : Object.values(value))
21702
+ validateJSON(item, seen);
21703
+ seen.delete(value);
21704
+ }
21705
+ var validId = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && Number.isFinite(value);
21706
+ function toonOutputContract(schema, example) {
21707
+ return [...TOON_OUTPUT_RULES, `format \u5FC5\u987B\u662F ${schema.format}\u3002`, "\u4E0B\u9762\u662F\u683C\u5F0F\u793A\u4F8B\uFF0C\u5FC5\u987B\u66FF\u6362\u4E3A\u539F\u6587\u5B9E\u9645\u5185\u5BB9\uFF1A", encodeToonInput(example, schema)].join("\n");
21708
+ }
21709
+ var record = (value) => {
21710
+ if (!value || typeof value !== "object" || Array.isArray(value))
21711
+ throw new Error("TOON \u8868\u683C\u8BB0\u5F55\u5FC5\u987B\u4E3A\u5BF9\u8C61");
21712
+ return value;
21713
+ };
21714
+ var own = (value, key) => value && Object.hasOwn(value, key) ? value[key] : void 0;
21715
+ var list = (value) => {
21716
+ if (Array.isArray(value))
21717
+ return value;
21718
+ if (typeof value === "string") {
21719
+ const parsed = JSON.parse(value);
21720
+ if (Array.isArray(parsed))
21721
+ return parsed;
21722
+ }
21723
+ if (value === void 0 || value === null)
21724
+ return [];
21725
+ throw new Error("\u5B50\u8868\u6765\u6E90\u5FC5\u987B\u4E3A\u6570\u7EC4\u6216 JSON \u6570\u7EC4\u5B57\u7B26\u4E32");
21726
+ };
21727
+ function encodeToonInput(value, schema) {
21728
+ const input = { ...value };
21729
+ const topKeys = /* @__PURE__ */ new Set(["format", ...schema.scalars ?? [], ...Object.keys(schema.columns)]);
21730
+ if (!schema.allowExtraColumns && Object.keys(input).some((key) => !topKeys.has(key)))
21731
+ throw new Error("TOON \u8F93\u5165\u5305\u542B\u672A\u58F0\u660E\u7684\u9876\u5C42\u5B57\u6BB5");
21732
+ validateChildren(schema.children ?? []);
21733
+ validateJSON(input);
21734
+ for (const child of schema.children ?? []) {
21735
+ if (Array.isArray(input[child.table]) && input[child.table].length) {
21736
+ if (list(input[child.parent]).some((parent) => list(record(parent)[child.field]).length))
21737
+ throw new Error("\u663E\u5F0F\u5B50\u8868\u4E0E\u7236\u8BB0\u5F55\u5185\u7684\u5B50\u9879\u51B2\u7A81");
21738
+ continue;
21739
+ }
21740
+ const childRows = [];
21741
+ input[child.parent] = list(input[child.parent]).map((entry) => {
21742
+ const parent = record(entry);
21743
+ list(parent[child.field]).forEach((step, index2) => {
21744
+ const row = typeof step === "string" ? { [child.valueKey]: step } : record(step);
21745
+ childRows.push({
21746
+ ...Object.fromEntries(Object.entries(child.inherit ?? {}).map(([key, source]) => [key, parent[source]])),
21747
+ ...row,
21748
+ [child.foreignKey]: parent[child.parentKey],
21749
+ [child.orderKey]: index2 + 1
21750
+ });
21751
+ });
21752
+ return parent;
21753
+ });
21754
+ input[child.table] = childRows;
21755
+ }
21756
+ const output = { format: schema.format };
21757
+ for (const key of schema.scalars ?? [])
21758
+ if (Object.hasOwn(input, key))
21759
+ Object.defineProperty(output, key, { value: input[key], enumerable: true });
21760
+ for (const [name, columns] of Object.entries(schema.columns)) {
21761
+ if (!Object.hasOwn(input, name)) {
21762
+ if (schema.required.includes(name))
21763
+ throw new Error(`TOON \u8F93\u5165\u7F3A\u5C11\u5FC5\u9700\u8868 ${name}`);
21764
+ continue;
21765
+ }
21766
+ const values = list(input[name]).map((entry) => {
21767
+ const row = record(entry);
21768
+ const extra = Object.keys(row).filter((key) => !columns.includes(key) && !(schema.children ?? []).some((child) => child.parent === name && child.field === key));
21769
+ if (extra.length && !schema.allowExtraColumns)
21770
+ throw new Error(`${name} \u5305\u542B\u672A\u58F0\u660E\u7684\u5217 ${extra.join(",")}`);
21771
+ return Object.fromEntries(columns.map((column) => {
21772
+ let cell = Object.hasOwn(row, column) ? row[column] : null;
21773
+ if (Array.isArray(cell)) {
21774
+ if (own(schema.referenceColumns, name)?.includes(column)) {
21775
+ if (cell.some((v) => typeof v !== "string" || !v || /\s/.test(v)))
21776
+ throw new Error(`${name}.${column} \u5F15\u7528\u5FC5\u987B\u662F\u975E\u7A7A\u3001\u65E0\u7A7A\u767D\u5B57\u7B26\u4E32`);
21777
+ cell = cell.join(" ");
21778
+ } else if (own(schema.jsonColumns, name)?.includes(column))
21779
+ cell = JSON.stringify(cell);
21780
+ else
21781
+ throw new Error(`${name}.${column} \u7684\u6570\u7EC4\u7F16\u7801\u6CA1\u6709\u5B9A\u4E49`);
21782
+ }
21783
+ if (cell !== null && typeof cell === "object")
21784
+ throw new Error(`${name}.${column} \u4E0D\u662F\u6807\u91CF\uFF1B\u8BF7\u58F0\u660E\u5B50\u8868`);
21785
+ if (cell === void 0 || !["string", "number", "boolean", "object"].includes(typeof cell) || typeof cell === "number" && !Number.isFinite(cell))
21786
+ throw new Error(`${name}.${column} \u4E0D\u662F\u6709\u6548 JSON \u6807\u91CF`);
21787
+ return [column, cell];
21788
+ }));
21789
+ });
21790
+ Object.defineProperty(output, name, { value: values, enumerable: true });
21791
+ }
21792
+ expandToonChildren(output, schema.children);
21793
+ return encode(output);
21794
+ }
21795
+ function expandToonChildren(value, children = []) {
21796
+ const result = { ...value };
21797
+ validateChildren(children);
21798
+ for (const child of children) {
21799
+ const parents = list(result[child.parent]).map(record);
21800
+ const ids = new Set(parents.map((row) => row[child.parentKey]));
21801
+ if (ids.size !== parents.length || parents.some((parent) => !Object.hasOwn(parent, child.parentKey) || !validId(parent[child.parentKey])))
21802
+ throw new Error(`${child.parent} \u7684\u7236\u8BB0\u5F55 ID \u65E0\u6548\u6216\u91CD\u590D`);
21803
+ if (!Object.hasOwn(value, child.table))
21804
+ continue;
21805
+ if (parents.some((parent) => list(parent[child.field]).length))
21806
+ throw new Error("\u663E\u5F0F\u5B50\u8868\u4E0E\u7236\u8BB0\u5F55\u5185\u7684\u5B50\u9879\u51B2\u7A81");
21807
+ const positions = /* @__PURE__ */ new Set();
21808
+ const rows = list(value[child.table]).map(record);
21809
+ for (const row of rows) {
21810
+ if (!Object.hasOwn(row, child.foreignKey) || !ids.has(row[child.foreignKey]))
21811
+ throw new Error(`${child.table} \u5F15\u7528\u4E0D\u5B58\u5728\u7684 ${child.parent}`);
21812
+ const key = JSON.stringify([row[child.foreignKey], row[child.orderKey]]);
21813
+ if (!Object.hasOwn(row, child.orderKey) || !Number.isSafeInteger(row[child.orderKey]) || Number(row[child.orderKey]) < 1 || positions.has(key))
21814
+ throw new Error(`${child.table} \u7684\u6B65\u9AA4\u987A\u5E8F\u65E0\u6548\u6216\u91CD\u590D`);
21815
+ positions.add(key);
21816
+ }
21817
+ const byParent = /* @__PURE__ */ new Map();
21818
+ for (const row of rows) {
21819
+ const group = byParent.get(row[child.foreignKey]) ?? [];
21820
+ group.push(row);
21821
+ byParent.set(row[child.foreignKey], group);
21822
+ }
21823
+ result[child.parent] = parents.map((parent) => ({ ...parent, [child.field]: (byParent.get(parent[child.parentKey]) ?? []).sort((a, b) => Number(a[child.orderKey]) - Number(b[child.orderKey])) }));
21824
+ }
21825
+ return result;
21826
+ }
21827
+
19827
21828
  // src/extract-table-contract.ts
21829
+ var LEGACY_EXTRACTION_TABLE_COLUMNS = {
21830
+ facts: ["id", "text", "object", "action", "scene", "conditions", "evidence"],
21831
+ procedures: ["id", "question", "object", "action", "scene", "applies_when", "method", "result_checks", "limitations", "missing", "completeness", "case_refs", "evidence"],
21832
+ cases: ["id", "external_id", "title", "summary", "object", "action", "scene", "occurred_at", "symptom", "root_cause", "root_cause_status", "outcome", "missing", "evidence"],
21833
+ timeline: ["case_id", "order", "type", "description", "result", "at", "evidence"],
21834
+ objects: ["mention", "definition", "evidence", "existing", "parent"],
21835
+ actions: ["mention", "definition", "evidence", "existing", "parent"],
21836
+ scenes: ["mention", "definition", "evidence", "existing", "parent"],
21837
+ evidence: ["id", "quote", "heading_path"],
21838
+ dropped: ["quote", "why"]
21839
+ };
21840
+ var EXTRACTION_TABLE_COLUMNS = {
21841
+ ...LEGACY_EXTRACTION_TABLE_COLUMNS,
21842
+ procedures: LEGACY_EXTRACTION_TABLE_COLUMNS.procedures.filter((column) => column !== "method"),
21843
+ steps: ["procedure_id", "order", "text", "evidence"]
21844
+ };
21845
+ var EXTRACTION_STEP_RELATION = { parent: "procedures", field: "method", table: "steps", parentKey: "id", foreignKey: "procedure_id", orderKey: "order", valueKey: "text", inherit: { evidence: "evidence" } };
21846
+ var EXTRACTION_TABLE_IDENTITIES = {
21847
+ facts: ["id"],
21848
+ procedures: ["id"],
21849
+ cases: ["id"],
21850
+ evidence: ["id"],
21851
+ objects: ["mention"],
21852
+ actions: ["mention"],
21853
+ scenes: ["mention"],
21854
+ timeline: ["case_id", "order"],
21855
+ steps: ["procedure_id", "order"]
21856
+ };
21857
+ var EXTRACTION_TOON_SCHEMA = {
21858
+ format: "knowledge-table-v3",
21859
+ columns: EXTRACTION_TABLE_COLUMNS,
21860
+ identityColumns: EXTRACTION_TABLE_IDENTITIES,
21861
+ required: ["facts", "procedures", "cases", "evidence", "steps"],
21862
+ scalars: ["subject"],
21863
+ optional: Object.fromEntries(["objects", "actions", "scenes"].map((key) => [key, ["existing", "parent"]])),
21864
+ jsonColumns: { facts: ["conditions"], procedures: ["applies_when", "result_checks", "limitations", "missing", "case_refs"], cases: ["missing"], evidence: ["heading_path"] },
21865
+ referenceColumns: Object.fromEntries(Object.keys(EXTRACTION_TABLE_COLUMNS).map((key) => [key, ["evidence"]])),
21866
+ children: [EXTRACTION_STEP_RELATION]
21867
+ };
19828
21868
  var TABLE_OUTPUT_CONTRACT = [
19829
- "\u53EA\u8FD4\u56DE TOON \u56FA\u5B9A\u5217\u8868\u683C\uFF0C\u4E0D\u52A0 Markdown \u56F4\u680F\u3002format \u5FC5\u987B\u662F knowledge-table-v2\u3002",
19830
- "\u6570\u7EC4\u5934 [N] \u4E3A\u5B9E\u9645\u884C\u6570\uFF0C\u7A7A\u6570\u7EC4\u5199 \u540D\u79F0[0]:\uFF0C\u6BCF\u884C\u5217\u6570\u4E0E\u8868\u5934\u4E00\u81F4\u3002",
19831
- "\u9017\u53F7\u5206\u5217\uFF0C\u590D\u6742\u5B57\u7B26\u4E32\u6309 TOON \u8F6C\u4E49\u3002\u7F3A\u5931\u503C\u4E3A null\u3002\u6570\u7EC4\u5B57\u6BB5\u4E3A JSON \u6570\u7EC4\u5B57\u7B26\u4E32\u3002",
21869
+ toonOutputContract(EXTRACTION_TOON_SCHEMA, {
21870
+ subject: "\u4E1A\u52A1\u4E3B\u4F53",
21871
+ facts: [{ id: "f1", text: "\u5B8C\u6574\u4E8B\u5B9E\u53CA\u5FC5\u8981\u9650\u5B9A", object: "\u5BF9\u8C61\u540D", action: null, scene: null, conditions: [], evidence: ["q1"] }],
21872
+ procedures: [],
21873
+ cases: [],
21874
+ timeline: [],
21875
+ objects: [{ mention: "\u539F\u6587\u53EB\u6CD5", definition: "\u6765\u6E90\u652F\u6301\u7684\u5B9A\u4E49", evidence: ["q1"], existing: null, parent: null }],
21876
+ actions: [],
21877
+ scenes: [],
21878
+ evidence: [{ id: "q1", quote: "\u539F\u6587\u9010\u5B57\u5F15\u6587", heading_path: [] }],
21879
+ dropped: []
21880
+ }),
19832
21881
  "evidence \u5217\u4E3A\u5F15\u6587 ID\uFF0C\u591A\u4E2A\u7528\u7A7A\u683C\u5206\u9694\uFF1B\u6BCF\u4E2A\u539F\u6837\u5F15\u6587\u5728 evidence \u8868\u53EA\u51FA\u73B0\u4E00\u6B21\u3002",
19833
- "\u4E0B\u5217\u793A\u4F8B\u5FC5\u987B\u66FF\u6362\u4E3A\u539F\u6587\u5B9E\u9645\u5185\u5BB9\uFF1A",
19834
- "format: knowledge-table-v2",
19835
- "subject: \u4E1A\u52A1\u4E3B\u4F53",
19836
- "facts[1]{id,text,object,action,scene,conditions,evidence}:",
19837
- ' f1,\u5B8C\u6574\u4E8B\u5B9E\u53CA\u5FC5\u8981\u9650\u5B9A,\u5BF9\u8C61\u540D,null,null,"[]",q1',
19838
- "procedures[0]:",
19839
- "cases[0]:",
19840
- "timeline[0]:",
19841
- "objects[1]{mention,definition,evidence,existing,parent}:",
19842
- " \u539F\u6587\u53EB\u6CD5,\u6765\u6E90\u652F\u6301\u7684\u5B9A\u4E49,q1,null,null",
19843
- "actions[0]:",
19844
- "scenes[0]:",
19845
- "evidence[1]{id,quote,heading_path}:",
19846
- ' q1,\u539F\u6587\u9010\u5B57\u5F15\u6587,"[]"',
19847
- "dropped[0]:",
19848
- "procedures \u975E\u7A7A\u65F6\u5217\u4E3A {id,question,object,action,scene,applies_when,method,result_checks,limitations,missing,completeness,case_refs,evidence}\uFF1Bmethod \u662F\u6B65\u9AA4\u5B57\u7B26\u4E32\u6570\u7EC4\u6216\u5E26 text/evidence \u7684\u5BF9\u8C61\u6570\u7EC4\u3002",
19849
- "cases \u975E\u7A7A\u65F6\u5217\u4E3A {id,external_id,title,summary,object,action,scene,occurred_at,symptom,root_cause,root_cause_status,outcome,missing,evidence}\u3002",
19850
- "timeline \u975E\u7A7A\u65F6\u5217\u4E3A {case_id,order,type,description,result,at,evidence}\uFF1Btype \u4E3A observation/check/action/result/conclusion\u3002",
21882
+ `procedures \u975E\u7A7A\u65F6\u5217\u4E3A {${EXTRACTION_TABLE_COLUMNS.procedures.join(",")}}\u3002\u6BCF\u4E2A\u6B65\u9AA4\u5199\u5165 steps \u8868 {${EXTRACTION_TABLE_COLUMNS.steps.join(",")}}\uFF0Corder \u4E3A\u8BE5\u65B9\u6CD5\u5185\u4E0D\u91CD\u590D\u7684\u6B63\u6574\u6570\uFF1B\u4E0D\u8981\u5728\u5355\u5143\u683C\u5185\u5D4C\u5957\u6B65\u9AA4\u6570\u7EC4\u3002`,
21883
+ `cases \u975E\u7A7A\u65F6\u5217\u4E3A {${EXTRACTION_TABLE_COLUMNS.cases.join(",")}}\u3002`,
21884
+ `timeline \u975E\u7A7A\u65F6\u5217\u4E3A {${EXTRACTION_TABLE_COLUMNS.timeline.join(",")}}\uFF1Btype \u4E3A observation/check/action/result/conclusion\u3002`,
19851
21885
  "root_cause_status \u4E3A confirmed/suspected/null\uFF0Cdropped \u975E\u7A7A\u65F6\u5217\u4E3A {quote,why}\u3002"
19852
21886
  ];
19853
21887
 
@@ -21627,7 +23661,7 @@ Defaulting to \`null\`.`;
21627
23661
  }) {
21628
23662
  const unitLabel = view.unitLabel ?? "\u77E5\u8BC6";
21629
23663
  const cellOf = (object, action) => view.cells.find((cell) => cell.object === object && cell.action === action);
21630
- const looseOf = (list, name) => list.find((entry) => entry.name === name);
23664
+ const looseOf = (list2, name) => list2.find((entry) => entry.name === name);
21631
23665
  const groupsOf = (object, action) => {
21632
23666
  if (object !== null && action !== null) return cellOf(object, action)?.groups ?? [];
21633
23667
  if (object !== null) return looseOf(view.noAction, object)?.groups ?? [];
@@ -22342,10 +24376,10 @@ ${report.prompt.user}`;
22342
24376
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("b", { children: "\u62BD\u53D6" }),
22343
24377
  "\u8FD9\u4E00\u6B65\u3002\u2461 \u5F52\u4E00\u3001\u2462 \u7269\u5316\u3001\u2463 \u5EFA\u7D22\u5F15\u5728\u8FD9\u4E2A\u5E93\u91CC\u662F\u72EC\u7ACB\u9636\u6BB5\uFF0C \u5404\u6709\u81EA\u5DF1\u7684\u8F68\u8FF9\u4E0E\u4EFB\u52A1\uFF1B\u4E0B\u9762\u662F\u62BD\u53D6\u65F6\u6309\u673A\u68B0\u89C4\u5219\u987A\u5E26\u7B97\u7684\u9884\u89C8\uFF0C\u4E0D\u4EE3\u8868\u5E93\u91CC\u7684\u73B0\u72B6\u3002"
22344
24378
  ] }),
22345
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ol", { className: styles.trialSteps, children: (extractOnly ? report.steps.filter((step) => step.id === "extract") : report.steps).map((step, index2, list) => {
24379
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ol", { className: styles.trialSteps, children: (extractOnly ? report.steps.filter((step) => step.id === "extract") : report.steps).map((step, index2, list2) => {
22346
24380
  const expanded = openStep === step.id;
22347
24381
  const items = step.items ?? [];
22348
- const phaseStart = index2 === 0 || list[index2 - 1].phase !== step.phase;
24382
+ const phaseStart = index2 === 0 || list2[index2 - 1].phase !== step.phase;
22349
24383
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("li", { className: styles.trialStepWrap, children: [
22350
24384
  phaseStart && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: styles.trialPhaseHead, children: step.phase }),
22351
24385
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn(styles.trialStep, step.needsHuman && styles.trialStepWarn), children: [
@@ -22983,7 +25017,7 @@ ${report.prompt.user}`;
22983
25017
  }
22984
25018
 
22985
25019
  // src/client/ExtractionTasksPage.tsx
22986
- var import_react21 = __toESM(require_react(), 1);
25020
+ var import_react22 = __toESM(require_react(), 1);
22987
25021
 
22988
25022
  // ../../packages/ui/lib/file-picker.js
22989
25023
  var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
@@ -23457,20 +25491,20 @@ ${report.prompt.user}`;
23457
25491
  });
23458
25492
  function parseTransform(transform) {
23459
25493
  if (transform.startsWith("matrix3d(")) {
23460
- const transformArray = transform.slice(9, -1).split(/, /);
25494
+ const transformArray2 = transform.slice(9, -1).split(/, /);
23461
25495
  return {
23462
- x: +transformArray[12],
23463
- y: +transformArray[13],
23464
- scaleX: +transformArray[0],
23465
- scaleY: +transformArray[5]
25496
+ x: +transformArray2[12],
25497
+ y: +transformArray2[13],
25498
+ scaleX: +transformArray2[0],
25499
+ scaleY: +transformArray2[5]
23466
25500
  };
23467
25501
  } else if (transform.startsWith("matrix(")) {
23468
- const transformArray = transform.slice(7, -1).split(/, /);
25502
+ const transformArray2 = transform.slice(7, -1).split(/, /);
23469
25503
  return {
23470
- x: +transformArray[4],
23471
- y: +transformArray[5],
23472
- scaleX: +transformArray[0],
23473
- scaleY: +transformArray[3]
25504
+ x: +transformArray2[4],
25505
+ y: +transformArray2[5],
25506
+ scaleX: +transformArray2[0],
25507
+ scaleY: +transformArray2[3]
23474
25508
  };
23475
25509
  }
23476
25510
  return null;
@@ -24528,7 +26562,7 @@ ${report.prompt.user}`;
24528
26562
  var e;
24529
26563
  return Array.from(((e = I.current) == null ? void 0 : e.querySelectorAll(ce)) || []);
24530
26564
  }
24531
- function X4(e) {
26565
+ function X3(e) {
24532
26566
  let s = V()[e];
24533
26567
  s && E.setState("value", s.getAttribute(T));
24534
26568
  }
@@ -24542,10 +26576,10 @@ ${report.prompt.user}`;
24542
26576
  for (; s && !i; ) s = e > 0 ? we(s, N) : De(s, N), i = s == null ? void 0 : s.querySelector(ce);
24543
26577
  i ? E.setState("value", i.getAttribute(T)) : Q(e);
24544
26578
  }
24545
- let oe = () => X4(V().length - 1), ie = (e) => {
26579
+ let oe = () => X3(V().length - 1), ie = (e) => {
24546
26580
  e.preventDefault(), e.metaKey ? oe() : e.altKey ? re(1) : Q(1);
24547
26581
  }, se = (e) => {
24548
- e.preventDefault(), e.metaKey ? X4(0) : e.altKey ? re(-1) : Q(-1);
26582
+ e.preventDefault(), e.metaKey ? X3(0) : e.altKey ? re(-1) : Q(-1);
24549
26583
  };
24550
26584
  return t.createElement(Primitive.div, { ref: o, tabIndex: -1, ...O, "cmdk-root": "", onKeyDown: (e) => {
24551
26585
  var s;
@@ -24571,7 +26605,7 @@ ${report.prompt.user}`;
24571
26605
  break;
24572
26606
  }
24573
26607
  case "Home": {
24574
- e.preventDefault(), X4(0);
26608
+ e.preventDefault(), X3(0);
24575
26609
  break;
24576
26610
  }
24577
26611
  case "End": {
@@ -24722,7 +26756,7 @@ ${report.prompt.user}`;
24722
26756
  const [highlighted, setHighlighted] = React50.useState(value);
24723
26757
  const trigger = React50.useRef(null);
24724
26758
  const input = React50.useRef(null);
24725
- const list = React50.useRef(null);
26759
+ const list2 = React50.useRef(null);
24726
26760
  const restoreFocus = React50.useRef(false);
24727
26761
  const selected = options.find((option) => option.value === value);
24728
26762
  const groups = React50.useMemo(() => {
@@ -24759,7 +26793,7 @@ ${report.prompt.user}`;
24759
26793
  if (!input.current?.isConnected || input.current.value)
24760
26794
  return;
24761
26795
  setHighlighted(selected?.disabled ? "" : value);
24762
- list.current?.querySelector('[aria-checked="true"]')?.scrollIntoView({ block: "nearest" });
26796
+ list2.current?.querySelector('[aria-checked="true"]')?.scrollIntoView({ block: "nearest" });
24763
26797
  });
24764
26798
  }, onCloseAutoFocus: (event) => {
24765
26799
  if (!restoreFocus.current)
@@ -24783,7 +26817,7 @@ ${report.prompt.user}`;
24783
26817
  }, children: [(0, import_jsx_runtime44.jsxs)("div", { className: "flex min-w-0 items-center gap-1 px-2", children: [(0, import_jsx_runtime44.jsx)(_e.Input, { ref: input, value: query, onValueChange: setQuery, placeholder: searchPlaceholder, "aria-label": searchPlaceholder, className: "box-border h-9 min-w-0 flex-1 border-0 bg-transparent p-0 font-tita text-[13px] font-normal text-tita-ink caret-tita-primary outline-none placeholder:text-tita-ink-faint" }), query && (0, import_jsx_runtime44.jsx)(Button, { variant: "ghost", size: "icon", "aria-label": "\u6E05\u7A7A\u641C\u7D22", className: "h-6 min-h-6 w-6 min-w-6 border-0", onClick: () => {
24784
26818
  setQuery("");
24785
26819
  input.current?.focus();
24786
- }, children: (0, import_jsx_runtime44.jsx)(X, { size: 13, "aria-hidden": "true" }) })] }), (0, import_jsx_runtime44.jsxs)(_e.List, { ref: list, className: "tita-searchSelectList max-h-[min(340px,calc(var(--radix-popover-content-available-height)-48px))] overflow-y-auto overflow-x-hidden overscroll-contain p-0 outline-none [scrollbar-color:var(--tita-line-strong)_transparent] [scrollbar-width:thin]", children: [(0, import_jsx_runtime44.jsx)(_e.Empty, { className: "px-2 py-5 text-center text-[12px] text-tita-ink-muted", role: "status", children: loading ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u2026" : emptyLabel }), groups.map(([id, group]) => (0, import_jsx_runtime44.jsx)(_e.Group, { heading: group.label, className: "p-0 [&_[cmdk-group-heading]]:sticky [&_[cmdk-group-heading]]:top-0 [&_[cmdk-group-heading]]:z-10 [&_[cmdk-group-heading]]:bg-tita-surface [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-[11px] [&_[cmdk-group-heading]]:font-normal [&_[cmdk-group-heading]]:text-tita-ink-faint", children: group.options.map((option) => (0, import_jsx_runtime44.jsxs)(_e.Item, { value: option.value, keywords: [option.label, option.group?.label ?? "", ...option.keywords ?? []], disabled: option.disabled, onSelect: select, "aria-checked": option.value === value, className: "box-border flex min-h-9 cursor-pointer items-center gap-3 rounded-[9px] px-2 py-1 text-[13px] font-normal leading-5 text-tita-ink outline-none data-[selected=true]:bg-tita-surface-muted data-[disabled=true]:cursor-not-allowed data-[disabled=true]:text-tita-ink-faint", children: [(0, import_jsx_runtime44.jsx)("span", { className: "min-w-0 flex-1 break-words", children: option.label }), option.value === value && (0, import_jsx_runtime44.jsx)(Check, { size: 15, "aria-hidden": "true", className: "shrink-0" })] }, option.value)) }, id))] })] }) })] });
26820
+ }, children: (0, import_jsx_runtime44.jsx)(X, { size: 13, "aria-hidden": "true" }) })] }), (0, import_jsx_runtime44.jsxs)(_e.List, { ref: list2, className: "tita-searchSelectList max-h-[min(340px,calc(var(--radix-popover-content-available-height)-48px))] overflow-y-auto overflow-x-hidden overscroll-contain p-0 outline-none [scrollbar-color:var(--tita-line-strong)_transparent] [scrollbar-width:thin]", children: [(0, import_jsx_runtime44.jsx)(_e.Empty, { className: "px-2 py-5 text-center text-[12px] text-tita-ink-muted", role: "status", children: loading ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u2026" : emptyLabel }), groups.map(([id, group]) => (0, import_jsx_runtime44.jsx)(_e.Group, { heading: group.label, className: "p-0 [&_[cmdk-group-heading]]:sticky [&_[cmdk-group-heading]]:top-0 [&_[cmdk-group-heading]]:z-10 [&_[cmdk-group-heading]]:bg-tita-surface [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pb-1 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:text-[11px] [&_[cmdk-group-heading]]:font-normal [&_[cmdk-group-heading]]:text-tita-ink-faint", children: group.options.map((option) => (0, import_jsx_runtime44.jsxs)(_e.Item, { value: option.value, keywords: [option.label, option.group?.label ?? "", ...option.keywords ?? []], disabled: option.disabled, onSelect: select, "aria-checked": option.value === value, className: "box-border flex min-h-9 cursor-pointer items-center gap-3 rounded-[9px] px-2 py-1 text-[13px] font-normal leading-5 text-tita-ink outline-none data-[selected=true]:bg-tita-surface-muted data-[disabled=true]:cursor-not-allowed data-[disabled=true]:text-tita-ink-faint", children: [(0, import_jsx_runtime44.jsx)("span", { className: "min-w-0 flex-1 break-words", children: option.label }), option.value === value && (0, import_jsx_runtime44.jsx)(Check, { size: 15, "aria-hidden": "true", className: "shrink-0" })] }, option.value)) }, id))] })] }) })] });
24787
26821
  }
24788
26822
 
24789
26823
  // ../../packages/ui/lib/request-response.js
@@ -25698,9 +27732,9 @@ ${report.prompt.user}`;
25698
27732
  setLoading(true);
25699
27733
  void requestJson(`/knowledge/documents?${new URLSearchParams({ kb, limit: "200", offset: "0" })}`).then((result) => {
25700
27734
  if (cancelled) return;
25701
- const list = result.data?.documents ?? [];
25702
- setDocuments(list);
25703
- setDocId((current) => current || list[0]?.docId || "");
27735
+ const list2 = result.data?.documents ?? [];
27736
+ setDocuments(list2);
27737
+ setDocId((current) => current || list2[0]?.docId || "");
25704
27738
  }).catch((cause) => {
25705
27739
  if (!cancelled) setFailure(cause instanceof Error ? cause.message : String(cause));
25706
27740
  }).finally(() => {
@@ -25842,7 +27876,7 @@ ${report.prompt.user}`;
25842
27876
  }
25843
27877
 
25844
27878
  // src/client/FileImportView.tsx
25845
- var import_react19 = __toESM(require_react(), 1);
27879
+ var import_react18 = __toESM(require_react(), 1);
25846
27880
 
25847
27881
  // ../../packages/ui/lib/ui/progress.js
25848
27882
  var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
@@ -25858,46 +27892,34 @@ ${report.prompt.user}`;
25858
27892
  return `src_${globalThis.crypto.randomUUID()}`;
25859
27893
  }
25860
27894
 
25861
- // src/client/CompileDialogs.tsx
25862
- var import_react18 = __toESM(require_react(), 1);
25863
- var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
25864
-
25865
- // src/client/ImportFilesDialog.tsx
25866
- var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
25867
- var SOURCE_ORIGIN_OPTIONS = [
25868
- { value: "local", label: "\u672C\u5730\u6587\u4EF6" },
25869
- { value: "web", label: "\u7F51\u9875" },
25870
- { value: "feishu", label: "\u98DE\u4E66 / Lark" },
25871
- { value: "google_docs", label: "Google Docs" },
25872
- { value: "notion", label: "Notion" },
25873
- { value: "wechat", label: "\u5FAE\u4FE1\u516C\u4F17\u53F7" },
25874
- { value: "other", label: "\u5176\u4ED6\u6765\u6E90" }
25875
- ];
25876
- var EXT_TONE = {
25877
- pdf: styles.importExtPdf,
25878
- docx: styles.importExtOffice,
25879
- doc: styles.importExtOffice,
25880
- pptx: styles.importExtOffice,
25881
- xlsx: styles.importExtOffice,
25882
- xls: styles.importExtOffice,
25883
- md: styles.importExtText,
25884
- txt: styles.importExtText,
25885
- csv: styles.importExtText
25886
- };
25887
-
25888
27895
  // src/client/FileImportView.tsx
25889
- var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
27896
+ var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
27897
+ async function fileBase64(file) {
27898
+ const bytes = new Uint8Array(await file.arrayBuffer());
27899
+ let binary = "";
27900
+ const chunk = 32768;
27901
+ for (let index2 = 0; index2 < bytes.length; index2 += chunk) binary += String.fromCharCode(...bytes.subarray(index2, index2 + chunk));
27902
+ return btoa(binary);
27903
+ }
25890
27904
  function FileImportView({ kb, open, onClose, onComplete }) {
25891
- const input = (0, import_react19.useRef)(null);
25892
- const [files, setFiles] = (0, import_react19.useState)([]);
25893
- const [running, setRunning] = (0, import_react19.useState)(false);
25894
- const [error, setError] = (0, import_react19.useState)("");
27905
+ const input = (0, import_react18.useRef)(null);
27906
+ const [files, setFiles] = (0, import_react18.useState)([]);
27907
+ const [images, setImages] = (0, import_react18.useState)([]);
27908
+ const [running, setRunning] = (0, import_react18.useState)(false);
27909
+ const [error, setError] = (0, import_react18.useState)("");
25895
27910
  const update = (id, patch) => setFiles((rows) => rows.map((row) => row.id === id ? { ...row, ...patch } : row));
25896
27911
  const add2 = (items) => {
25897
27912
  if (running) return;
25898
- const valid = items.filter((file) => /\.(md|markdown)$/i.test(file.name));
25899
- setError(valid.length === items.length ? "" : "\u4EC5\u652F\u6301 Markdown \u6587\u4EF6\u3002");
25900
- setFiles((rows) => [...rows, ...valid.map((file) => ({ id: newSourceId(), file, origin: "", state: "pending" }))]);
27913
+ const markdown = items.filter((file) => /\.(md|markdown)$/i.test(file.name));
27914
+ const pictures = items.filter((file) => file.type.startsWith("image/") || /\.(png|jpe?g|gif|webp|avif|bmp|svg)$/i.test(file.name));
27915
+ const ignored = items.length - markdown.length - pictures.length;
27916
+ setError(ignored > 0 ? "\u53EA\u6536 Markdown \u548C\u56FE\u7247\uFF1B\u5176\u5B83\u6587\u4EF6\u5DF2\u5FFD\u7565\u3002" : "");
27917
+ if (markdown.length > 0) setFiles((rows) => [...rows, ...markdown.map((file) => ({ id: newSourceId(), file, state: "pending" }))]);
27918
+ if (markdown.length === 0 && pictures.length > 0) setError("\u56FE\u7247\u8981\u8DDF\u7740 Markdown \u4E00\u8D77\u9009\uFF1A\u56FE\u7247\u6309\u6587\u4EF6\u540D\u8865\u8FDB\u6B63\u6587\u3002");
27919
+ if (pictures.length > 0) setImages((current) => {
27920
+ const seen = new Set(current.map((file) => `${file.name}:${file.size}`));
27921
+ return [...current, ...pictures.filter((file) => !seen.has(`${file.name}:${file.size}`))];
27922
+ });
25901
27923
  };
25902
27924
  const drop = (event) => {
25903
27925
  event.preventDefault();
@@ -25905,7 +27927,7 @@ ${report.prompt.user}`;
25905
27927
  };
25906
27928
  const start = async () => {
25907
27929
  const pending = files.filter((file) => file.state === "pending" || file.state === "failed");
25908
- if (!pending.length || pending.some((file) => !file.origin)) return;
27930
+ if (!pending.length) return;
25909
27931
  setRunning(true);
25910
27932
  setError("");
25911
27933
  setFiles((rows) => rows.map((row) => row.state === "failed" ? { ...row, state: "pending", error: void 0 } : row));
@@ -25920,8 +27942,28 @@ ${report.prompt.user}`;
25920
27942
  try {
25921
27943
  const content = await item.file.text();
25922
27944
  if (!content.trim()) throw new Error("\u6587\u4EF6\u5185\u5BB9\u4E3A\u7A7A");
25923
- const result = await requestJson("/knowledge/sources", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ kb, source_id: item.id, title: item.file.name, external_id: `upload:${item.id}`, content, allow_duplicate_title: true, metadata: { original_filename: item.file.name, source_format: "markdown", source_origin: item.origin } }) });
25924
- const note2 = result.warnings?.join("\uFF1B") || void 0;
27945
+ const result = await requestJson("/knowledge/sources", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ kb, source_id: item.id, title: item.file.name, external_id: `upload:${item.id}`, content, allow_duplicate_title: true, metadata: { original_filename: item.file.name, source_format: "markdown" } }) });
27946
+ const notes = [...result.warnings ?? []];
27947
+ const sourceId = result.data?.sourceId ?? item.id;
27948
+ const referenced = new Set([...content.matchAll(/!\[[^\]]*\]\(\s*(?:<([^>]+)>|([^\s)]+))/g)].map((match) => (match[1] ?? match[2] ?? "").split("/").pop()).filter(Boolean));
27949
+ const matched = images.filter((image) => referenced.has(image.name));
27950
+ if (matched.length > 0) {
27951
+ try {
27952
+ const uploaded = await requestJson(`/knowledge/documents/${encodeURIComponent(sourceId)}/assets?${new URLSearchParams({ kb })}`, {
27953
+ method: "POST",
27954
+ headers: { "content-type": "application/json" },
27955
+ body: JSON.stringify({ files: await Promise.all(matched.map(async (image) => ({ name: image.name, data: await fileBase64(image) }))) })
27956
+ });
27957
+ const skipped = uploaded.data?.skipped ?? [];
27958
+ if (skipped.length > 0) notes.push(`${skipped.length} \u5F20\u56FE\u7247\u6CA1\u6709\u5199\u5165`);
27959
+ if (matched.length < images.length) notes.push(`\u53E6\u6709 ${images.length - matched.length} \u5F20\u56FE\u7247\u4E0E\u6B63\u6587\u5F15\u7528\u4E0D\u5339\u914D\uFF0C\u672A\u8BA1\u5165`);
27960
+ } catch (cause) {
27961
+ notes.push(`\u56FE\u7247\u672A\u5165\u5E93\uFF1A${cause instanceof Error ? cause.message : String(cause)}`);
27962
+ }
27963
+ } else if (images.length > 0) {
27964
+ notes.push("\u9009\u4E86\u56FE\u7247\uFF0C\u4F46\u6B63\u6587\u91CC\u6CA1\u6709\u540C\u540D\u5F15\u7528\uFF0C\u56FE\u7247\u672A\u5165\u5E93");
27965
+ }
27966
+ const note2 = notes.length > 0 ? notes.join("\uFF1B") : void 0;
25925
27967
  update(item.id, { state: "done", note: note2 });
25926
27968
  outcomes.push({ name: item.file.name, ext: item.file.name.split(".").pop()?.toLowerCase() ?? "", bytes: item.file.size, stage: "ingested", note: note2 });
25927
27969
  } catch (cause) {
@@ -25939,21 +27981,30 @@ ${report.prompt.user}`;
25939
27981
  }
25940
27982
  setRunning(false);
25941
27983
  onComplete();
27984
+ if (outcomes.every((item) => item.stage === "ingested")) {
27985
+ setFiles((rows) => rows.filter((file) => file.state !== "done"));
27986
+ setError("");
27987
+ onClose();
27988
+ }
25942
27989
  };
25943
27990
  const close = () => {
25944
27991
  if (running) return;
25945
- setFiles((rows) => rows.filter((file) => file.state !== "done"));
27992
+ setFiles((rows) => {
27993
+ const next = rows.filter((file) => file.state !== "done");
27994
+ if (next.length === 0) setImages([]);
27995
+ return next;
27996
+ });
25946
27997
  setError("");
25947
27998
  onClose();
25948
27999
  };
25949
28000
  const finished = files.filter((file) => file.state === "done" || file.state === "failed").length;
25950
28001
  const done = files.filter((file) => file.state === "done").length;
25951
28002
  const failed = files.filter((file) => file.state === "failed").length;
25952
- const canStart = !running && files.some((file) => file.state === "pending" || file.state === "failed") && files.every((file) => file.state === "done" || file.origin !== "");
25953
- const note = running ? `\u6B63\u5728\u5199\u5165\uFF1A${finished} / ${files.length} \u5DF2\u5904\u7406` : files.length === 0 ? "\u652F\u6301 .md / .markdown\uFF0C\u53EF\u6279\u91CF\u9009\u62E9\u3002" : failed > 0 ? `\u5DF2\u5165\u5E93 ${done} \u4EFD\uFF0C\u5931\u8D25 ${failed} \u4EFD\u3002\u53EF\u91CD\u8BD5\u5931\u8D25\u7684\u90A3\u4E9B\u3002` : done === files.length ? `\u5DF2\u5165\u5E93 ${done} \u4EFD\u3002\u62BD\u53D6\u4E0D\u4F1A\u81EA\u52A8\u5F00\u59CB\u3002` : "\u6BCF\u4EFD\u6587\u4EF6\u90FD\u8981\u9009\u5185\u5BB9\u6765\u6E90\u3002\u5BFC\u5165\u53EA\u5165\u5E93\uFF0C\u62BD\u53D6\u7531\u4F60\u53D1\u8D77\u3002";
25954
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Dialog2, { open, onOpenChange: (next) => {
28003
+ const canStart = !running && files.some((file) => file.state === "pending" || file.state === "failed");
28004
+ const note = running ? `\u6B63\u5728\u5199\u5165\uFF1A${finished} / ${files.length} \u5DF2\u5904\u7406` : files.length === 0 ? "\u652F\u6301 .md / .markdown + \u540C\u540D\u56FE\u7247\uFF0C\u53EF\u6279\u91CF\u9009\u62E9\u3002" : failed > 0 ? `\u5DF2\u5165\u5E93 ${done} \u4EFD\uFF0C\u5931\u8D25 ${failed} \u4EFD\u3002\u53EF\u91CD\u8BD5\u5931\u8D25\u7684\u90A3\u4E9B\u3002` : done === files.length ? `\u5DF2\u5165\u5E93 ${done} \u4EFD\u3002\u62BD\u53D6\u4E0D\u4F1A\u81EA\u52A8\u5F00\u59CB\u3002` : "\u5BFC\u5165\u53EA\u5165\u5E93\uFF0C\u62BD\u53D6\u7531\u4F60\u53D1\u8D77\u3002";
28005
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Dialog2, { open, onOpenChange: (next) => {
25955
28006
  if (!next) close();
25956
- }, children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
28007
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
25957
28008
  DialogContent3,
25958
28009
  {
25959
28010
  className: "kwImportDialog",
@@ -25964,63 +28015,68 @@ ${report.prompt.user}`;
25964
28015
  if (running) event.preventDefault();
25965
28016
  },
25966
28017
  children: [
25967
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(DialogHeader2, { children: [
25968
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(DialogTitle4, { children: "\u6DFB\u52A0\u6587\u4EF6" }),
25969
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(DialogDescription4, { children: "\u628A Markdown \u653E\u8FDB\u8FD9\u4E2A\u5E93\u3002\u5BFC\u5165\u53EA\u5165\u5E93\uFF0C\u62BD\u53D6\u7531\u4F60\u5728\u300C\u62BD\u53D6 Knowledge\u300D\u91CC\u53D1\u8D77\u3002" })
28018
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(DialogHeader2, { children: [
28019
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(DialogTitle4, { children: "\u6DFB\u52A0\u6587\u4EF6" }),
28020
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(DialogDescription4, { children: "\u628A Markdown \u653E\u8FDB\u8FD9\u4E2A\u5E93\u3002\u5BFC\u5165\u53EA\u5165\u5E93\uFF0C\u62BD\u53D6\u7531\u4F60\u5728\u300C\u62BD\u53D6 Knowledge\u300D\u91CC\u53D1\u8D77\u3002" })
25970
28021
  ] }),
25971
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwImportLayout", children: [
25972
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwDrop", onDragOver: (event) => event.preventDefault(), onDrop: drop, children: [
25973
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "kwDropIcon", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Upload, { size: 18, "aria-hidden": "true" }) }),
25974
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u628A Markdown \u62D6\u5230\u8FD9\u91CC" }),
25975
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { children: "\u4E5F\u53EF\u4EE5\u9009\u62E9\u6587\u4EF6\u3002\u652F\u6301\u6279\u91CF\uFF1B\u6BCF\u4EFD\u6587\u4EF6\u90FD\u8981\u5148\u6307\u5B9A\u5185\u5BB9\u6765\u6E90\u3002" }),
25976
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { variant: "outline", disabled: running, onClick: () => input.current?.click(), children: "\u9009\u62E9\u6587\u4EF6" }),
25977
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("input", { ref: input, hidden: true, type: "file", accept: ".md,.markdown,text/markdown", multiple: true, onChange: (event) => {
28022
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "kwImportLayout", children: [
28023
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "kwDrop", onDragOver: (event) => event.preventDefault(), onDrop: drop, children: [
28024
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "kwDropIcon", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Upload, { size: 18, "aria-hidden": "true" }) }),
28025
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("strong", { children: "\u628A Markdown \u548C\u56FE\u7247\u62D6\u5230\u8FD9\u91CC" }),
28026
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: "\u4E5F\u53EF\u4EE5\u9009\u62E9\u6587\u4EF6\u3002\u56FE\u7247\u6309\u6587\u4EF6\u540D\u5339\u914D\u6B63\u6587\u5F15\u7528\uFF1B\u5BFC\u5165\u53EA\u5165\u5E93\uFF0C\u62BD\u53D6\u7531\u4F60\u53D1\u8D77\u3002" }),
28027
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { variant: "outline", disabled: running, onClick: () => input.current?.click(), children: "\u9009\u62E9\u6587\u4EF6" }),
28028
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("input", { ref: input, hidden: true, type: "file", accept: ".md,.markdown,text/markdown,image/*", multiple: true, onChange: (event) => {
25978
28029
  add2(Array.from(event.target.files ?? []));
25979
28030
  event.target.value = "";
25980
28031
  } })
25981
28032
  ] }),
25982
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwQueuePanel", children: [
25983
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("header", { className: "kwQueuePanelHead", children: [
25984
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("h3", { children: "\u5F85\u5BFC\u5165" }),
25985
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { children: [
28033
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "kwQueuePanel", children: [
28034
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("header", { className: "kwQueuePanelHead", children: [
28035
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("h3", { children: "\u5F85\u5BFC\u5165" }),
28036
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { children: [
25986
28037
  files.length,
25987
- " \u4EFD"
28038
+ " \u4EFD",
28039
+ images.length > 0 ? ` \xB7 ${images.length} \u5F20\u56FE` : ""
25988
28040
  ] })
25989
28041
  ] }),
25990
- files.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwEmpty kwEmptyCompact", children: [
25991
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u8FD8\u6CA1\u6709\u9009\u6587\u4EF6" }),
25992
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { children: "\u9009\u597D\u6587\u4EF6\u540E\uFF0C\u5728\u8FD9\u91CC\u4E3A\u6BCF\u4EFD\u6587\u6863\u6307\u5B9A\u5185\u5BB9\u6765\u6E90\u3002" })
28042
+ files.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "kwEmpty kwEmptyCompact", children: [
28043
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("strong", { children: "\u8FD8\u6CA1\u6709\u9009\u6587\u4EF6" }),
28044
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { children: "\u9009\u597D Markdown \u548C\u540C\u540D\u56FE\u7247\uFF0C\u56FE\u7247\u4F1A\u6309\u6587\u4EF6\u540D\u8865\u8FDB\u8FD9\u4EFD\u6587\u6863\u3002" })
25993
28045
  ] }),
25994
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("ul", { className: "kwImportList", children: files.map((item) => /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("li", { className: "kwImportRow", children: [
25995
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(FileText, { size: 16, "aria-hidden": "true" }),
25996
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { className: "kwImportName", children: [
25997
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: item.file.name }),
25998
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("small", { children: item.file.size < 1024 ? `${item.file.size} B` : `${(item.file.size / 1024).toFixed(1)} KB` })
28046
+ images.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("p", { className: "kwImportImages", children: [
28047
+ "\u5DF2\u9644\u5E26 ",
28048
+ images.length,
28049
+ " \u5F20\u56FE\u7247 \xB7 \u53EA\u5339\u914D\u6B63\u6587\u91CC\u540C\u540D\u7684\u5F15\u7528"
28050
+ ] }),
28051
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("ul", { className: "kwImportList", children: files.map((item) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("li", { className: "kwImportRow", children: [
28052
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(FileText, { size: 16, "aria-hidden": "true" }),
28053
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "kwImportName", children: [
28054
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("strong", { children: item.file.name }),
28055
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("small", { children: item.file.size < 1024 ? `${item.file.size} B` : `${(item.file.size / 1024).toFixed(1)} KB` })
25999
28056
  ] }),
26000
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(SelectMenu, { size: "sm", "aria-label": `${item.file.name} \u7684\u5185\u5BB9\u6765\u6E90`, placeholder: "\u9009\u62E9\u5185\u5BB9\u6765\u6E90", value: item.origin, options: SOURCE_ORIGIN_OPTIONS, disabled: running || item.state === "done", onValueChange: (origin) => update(item.id, { origin }) }),
26001
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "kwImportState", children: item.state === "done" ? `\u5DF2\u5165\u5E93${item.note ? ` \xB7 ${item.note}` : ""}` : item.state === "failed" ? item.error : item.state === "running" ? "\u5904\u7406\u4E2D" : "" }),
26002
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { size: "icon", variant: "ghost", "aria-label": `\u79FB\u9664 ${item.file.name}`, disabled: running, onClick: () => setFiles((rows) => rows.filter((row) => row.id !== item.id)), children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Trash2, { size: 14 }) })
28057
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "kwImportState", children: item.state === "done" ? `\u5DF2\u5165\u5E93${item.note ? ` \xB7 ${item.note}` : ""}` : item.state === "failed" ? item.error : item.state === "running" ? "\u5904\u7406\u4E2D" : "" }),
28058
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { size: "icon", variant: "ghost", "aria-label": `\u79FB\u9664 ${item.file.name}`, disabled: running, onClick: () => setFiles((rows) => rows.filter((row) => row.id !== item.id)), children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Trash2, { size: 14 }) })
26003
28059
  ] }, item.id)) }),
26004
- error && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("p", { className: "kwNotice kwNotice-error", role: "alert", children: [
26005
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(CircleAlert, { size: 13 }),
26006
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { children: error })
28060
+ error && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("p", { className: "kwNotice kwNotice-error", role: "alert", children: [
28061
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(CircleAlert, { size: 13 }),
28062
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: error })
26007
28063
  ] }),
26008
- finished > 0 || running ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwImportProgress", children: [
26009
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { className: "kwImportState", children: [
28064
+ finished > 0 || running ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "kwImportProgress", children: [
28065
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "kwImportState", children: [
26010
28066
  finished,
26011
28067
  " / ",
26012
28068
  files.length,
26013
28069
  " \u5DF2\u5904\u7406"
26014
28070
  ] }),
26015
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Progress3, { max: files.length, value: finished, "aria-label": "\u6587\u4EF6\u5BFC\u5165\u8FDB\u5EA6" })
28071
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Progress3, { max: files.length, value: finished, "aria-label": "\u6587\u4EF6\u5BFC\u5165\u8FDB\u5EA6" })
26016
28072
  ] }) : null
26017
28073
  ] })
26018
28074
  ] }),
26019
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(DialogFooter2, { className: "kwImportFoot", children: [
26020
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "kwImportFootNote", children: note }),
26021
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwImportFootActions", children: [
26022
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { variant: "ghost", disabled: running, onClick: close, children: "\u5173\u95ED" }),
26023
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { variant: "default", disabled: !canStart, onClick: () => void start(), children: failed > 0 ? "\u91CD\u8BD5\u5931\u8D25\u6587\u4EF6" : "\u52A0\u5165\u77E5\u8BC6\u5E93" })
28075
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(DialogFooter2, { className: "kwImportFoot", children: [
28076
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { className: "kwImportFootNote", children: note }),
28077
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "kwImportFootActions", children: [
28078
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { variant: "ghost", disabled: running, onClick: close, children: "\u5173\u95ED" }),
28079
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button, { variant: "default", disabled: !canStart, onClick: () => void start(), children: failed > 0 ? "\u91CD\u8BD5\u5931\u8D25\u6587\u4EF6" : "\u52A0\u5165\u77E5\u8BC6\u5E93" })
26024
28080
  ] })
26025
28081
  ] })
26026
28082
  ]
@@ -26030,12 +28086,808 @@ ${report.prompt.user}`;
26030
28086
 
26031
28087
  // src/client/DocumentExtractionView.tsx
26032
28088
  var import_react20 = __toESM(require_react(), 1);
26033
- var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
28089
+
28090
+ // src/client/ReadingView.tsx
28091
+ var import_react19 = __toESM(require_react(), 1);
28092
+
28093
+ // src/reading-marks.ts
28094
+ var clamp3 = (value, max2) => Math.max(0, Math.min(max2, Math.trunc(value)));
28095
+ function itemRanges(item, body) {
28096
+ const ranges = [];
28097
+ for (const source of item.sources ?? []) {
28098
+ if (source.found === false) continue;
28099
+ let start = source.locator?.start;
28100
+ let end = source.locator?.end;
28101
+ if (start === void 0 || end === void 0) {
28102
+ const at2 = source.quote ? body.indexOf(source.quote) : -1;
28103
+ if (at2 < 0) continue;
28104
+ start = at2;
28105
+ end = at2 + source.quote.length;
28106
+ }
28107
+ start = clamp3(start, body.length);
28108
+ end = clamp3(end, body.length);
28109
+ if (end > start) ranges.push({ start, end });
28110
+ }
28111
+ return ranges;
28112
+ }
28113
+ function buildReadingMarks(body, items, gaps) {
28114
+ if (body.length === 0) return [];
28115
+ const ranges = [];
28116
+ for (const item of items) {
28117
+ for (const range of itemRanges(item, body)) ranges.push({ ...range, item });
28118
+ }
28119
+ const gapRanges = [];
28120
+ for (const gap of gaps) {
28121
+ const parts = gap.ranges !== void 0 && gap.ranges.length > 0 ? gap.ranges : [{ start: gap.start, end: gap.end }];
28122
+ for (const part of parts) {
28123
+ if (!Number.isFinite(part.start) || !Number.isFinite(part.end)) continue;
28124
+ const start = clamp3(part.start, body.length);
28125
+ const end = clamp3(part.end, body.length);
28126
+ if (end > start) gapRanges.push({ start, end, gap });
28127
+ }
28128
+ }
28129
+ const points = /* @__PURE__ */ new Set([0, body.length]);
28130
+ for (const range of ranges) {
28131
+ points.add(range.start);
28132
+ points.add(range.end);
28133
+ }
28134
+ for (const gap of gapRanges) {
28135
+ points.add(gap.start);
28136
+ points.add(gap.end);
28137
+ }
28138
+ const ordered = [...points].sort((a, b) => a - b);
28139
+ const marks = [];
28140
+ for (let index2 = 0; index2 < ordered.length - 1; index2 += 1) {
28141
+ const start = ordered[index2];
28142
+ const end = ordered[index2 + 1];
28143
+ if (end <= start) continue;
28144
+ const seen = /* @__PURE__ */ new Set();
28145
+ const covering = [];
28146
+ for (const range of ranges) {
28147
+ if (range.start <= start && range.end >= end && !seen.has(range.item.id)) {
28148
+ seen.add(range.item.id);
28149
+ covering.push(range.item);
28150
+ }
28151
+ }
28152
+ const gap = covering.length === 0 ? gapRanges.find((candidate) => candidate.start <= start && candidate.end >= end)?.gap : void 0;
28153
+ if (covering.length === 0 && gap === void 0) continue;
28154
+ const previous = marks.at(-1);
28155
+ const sameItems = previous !== void 0 && previous.gap === gap && previous.items.length === covering.length && previous.items.every((item, at2) => item.id === covering[at2]?.id);
28156
+ if (previous !== void 0 && previous.end === start && sameItems) previous.end = end;
28157
+ else marks.push({ id: marks.length, start, end, items: covering, ...gap ? { gap } : {} });
28158
+ }
28159
+ return marks;
28160
+ }
28161
+ function inlineTransform(raw) {
28162
+ let display = "";
28163
+ const map = [];
28164
+ const push = (value, at2) => {
28165
+ for (const char of value) {
28166
+ display += char;
28167
+ map.push(at2);
28168
+ }
28169
+ };
28170
+ let index2 = 0;
28171
+ while (index2 < raw.length) {
28172
+ const rest = raw.slice(index2);
28173
+ const image = /^!\[([^\]]*)\]\([^)]*\)/.exec(rest);
28174
+ if (image) {
28175
+ const label2 = image[1] && image[1].length <= 6 ? `[${image[1]}]` : "[\u56FE]";
28176
+ push(label2, index2);
28177
+ index2 += image[0].length;
28178
+ continue;
28179
+ }
28180
+ const link = /^\[([^\]]+)\]\([^)]*\)/.exec(rest);
28181
+ if (link) {
28182
+ const offset4 = link[0].indexOf(link[1]);
28183
+ push(link[1], index2 + offset4);
28184
+ index2 += link[0].length;
28185
+ continue;
28186
+ }
28187
+ const br = /^<br\s*\/?>/i.exec(rest);
28188
+ if (br) {
28189
+ push(" ", index2);
28190
+ index2 += br[0].length;
28191
+ continue;
28192
+ }
28193
+ const tag = /^<[^>]+>/.exec(rest);
28194
+ if (tag) {
28195
+ index2 += tag[0].length;
28196
+ continue;
28197
+ }
28198
+ if (rest.startsWith("**")) {
28199
+ index2 += 2;
28200
+ continue;
28201
+ }
28202
+ if (rest[0] === "*" || rest[0] === "`") {
28203
+ index2 += 1;
28204
+ continue;
28205
+ }
28206
+ if (rest[0] === "\\" && index2 + 1 < raw.length) {
28207
+ push(raw[index2 + 1], index2 + 1);
28208
+ index2 += 2;
28209
+ continue;
28210
+ }
28211
+ push(raw[index2], index2);
28212
+ index2 += 1;
28213
+ }
28214
+ return { display, map };
28215
+ }
28216
+
28217
+ // src/client/asset-images.ts
28218
+ function assetIndexOf(assets) {
28219
+ const byRel = /* @__PURE__ */ new Map();
28220
+ const byName = /* @__PURE__ */ new Map();
28221
+ for (const asset of assets) {
28222
+ byRel.set(asset.rel, asset);
28223
+ const name = asset.rel.split("/").pop() ?? "";
28224
+ if (name !== "" && !byName.has(name)) byName.set(name, asset);
28225
+ }
28226
+ return { byRel, byName };
28227
+ }
28228
+ function matchAsset(source, index2) {
28229
+ if (/^(?:https?:|data:)/i.test(source)) return void 0;
28230
+ const clean = source.replace(/^\.\//, "").replace(/^\/+/, "");
28231
+ const exact = index2.byRel.get(clean);
28232
+ if (exact !== void 0) return exact;
28233
+ for (const [rel, asset] of index2.byRel) if (rel.endsWith(`/${clean}`)) return asset;
28234
+ return index2.byName.get(clean.split("/").pop() ?? "");
28235
+ }
28236
+ function absoluteAssetUrl(url, origin, pageHref) {
28237
+ if (/^(?:https?:|data:|blob:|dsh-app:)/i.test(url)) return url;
28238
+ const base = origin ?? (typeof window === "undefined" ? void 0 : window.location.origin);
28239
+ if (base !== void 0 && /^https?:\/\//i.test(base)) {
28240
+ try {
28241
+ return new URL(url, base).href;
28242
+ } catch {
28243
+ return url;
28244
+ }
28245
+ }
28246
+ const href = pageHref ?? (typeof window === "undefined" ? void 0 : window.location.href);
28247
+ if (href !== void 0 && /^dsh-app:/i.test(href)) {
28248
+ try {
28249
+ return new URL(url, href).href;
28250
+ } catch {
28251
+ return url;
28252
+ }
28253
+ }
28254
+ return url;
28255
+ }
28256
+ function imageResolverOf(assets) {
28257
+ if (assets.length === 0) return void 0;
28258
+ const index2 = assetIndexOf(assets);
28259
+ return (source) => {
28260
+ if (/^(?:https?:|data:)/i.test(source)) return source;
28261
+ const asset = matchAsset(source, index2);
28262
+ return asset === void 0 ? null : absoluteAssetUrl(asset.url);
28263
+ };
28264
+ }
28265
+
28266
+ // src/client/ReadingView.tsx
28267
+ var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
28268
+ var KIND_LABEL3 = { fact: "FACT", procedure: "PROCEDURE", case: "CASE" };
28269
+ var GAP_LABEL = { section: "\u7AE0\u8282", table: "\u8868\u884C", block: "\u6BB5\u843D" };
28270
+ var MARK_PALETTE = ["#137d59", "#2d64be", "#634cc2", "#9a3f6e"];
28271
+ var gapKey = (gap) => `${gap.kind}:${gap.start}:${gap.end}:${gap.title}`;
28272
+ function ReadingView({ kb, docId, docTitle, currentVersion, sourceVersion, report, running, failed }) {
28273
+ const [body, setBody] = (0, import_react19.useState)("");
28274
+ const [assets, setAssets] = (0, import_react19.useState)([]);
28275
+ const [total, setTotal] = (0, import_react19.useState)(0);
28276
+ const [loading, setLoading] = (0, import_react19.useState)(true);
28277
+ const [loadError, setLoadError] = (0, import_react19.useState)("");
28278
+ const [reload, setReload] = (0, import_react19.useState)(0);
28279
+ const [uploading, setUploading] = (0, import_react19.useState)(false);
28280
+ const [uploadError, setUploadError] = (0, import_react19.useState)("");
28281
+ const [hover, setHover] = (0, import_react19.useState)(null);
28282
+ const [active2, setActive] = (0, import_react19.useState)(-1);
28283
+ const [scope, setScope] = (0, import_react19.useState)("all");
28284
+ const [query, setQuery] = (0, import_react19.useState)("");
28285
+ const [expanded, setExpanded] = (0, import_react19.useState)({ gap: false, item: false });
28286
+ const hoverTimer = (0, import_react19.useRef)(void 0);
28287
+ const uploadInput = (0, import_react19.useRef)(null);
28288
+ const popRef = (0, import_react19.useRef)(null);
28289
+ (0, import_react19.useEffect)(() => {
28290
+ let cancelled = false;
28291
+ setLoading(true);
28292
+ setLoadError("");
28293
+ setBody("");
28294
+ setHover(null);
28295
+ setActive(-1);
28296
+ void (async () => {
28297
+ try {
28298
+ void requestJson(`/knowledge/documents/${encodeURIComponent(docId)}?${new URLSearchParams({ kb })}`).then((meta) => {
28299
+ if (!cancelled) setAssets(meta.data?.document.assets ?? []);
28300
+ }).catch(() => {
28301
+ if (!cancelled) setAssets([]);
28302
+ });
28303
+ const result = await requestJson(`/knowledge/documents/${encodeURIComponent(docId)}/content?${new URLSearchParams({ kb, offset: "0", limit: "200000" })}`);
28304
+ if (cancelled) return;
28305
+ if (!result.data) throw new Error("\u539F\u6587\u5185\u5BB9\u4E3A\u7A7A");
28306
+ let text = result.data.text;
28307
+ let next = result.data.nextOffset;
28308
+ while (!result.data.eof && next > 0) {
28309
+ const page = await requestJson(`/knowledge/documents/${encodeURIComponent(docId)}/content?${new URLSearchParams({ kb, offset: String(next), limit: "200000" })}`);
28310
+ if (cancelled || !page.data) break;
28311
+ text += page.data.text;
28312
+ if (page.data.nextOffset <= next) break;
28313
+ next = page.data.nextOffset;
28314
+ if (page.data.eof) break;
28315
+ }
28316
+ setBody(text);
28317
+ setTotal(result.data.totalChars);
28318
+ } catch (cause) {
28319
+ if (!cancelled) setLoadError(cause instanceof Error ? cause.message : String(cause));
28320
+ } finally {
28321
+ if (!cancelled) setLoading(false);
28322
+ }
28323
+ })();
28324
+ return () => {
28325
+ cancelled = true;
28326
+ };
28327
+ }, [kb, docId, currentVersion, reload]);
28328
+ (0, import_react19.useEffect)(() => () => {
28329
+ if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
28330
+ }, []);
28331
+ const knowledgeCount = report?.knowledge?.length ?? 0;
28332
+ const caseCount = report?.events?.length ?? 0;
28333
+ const items = (0, import_react19.useMemo)(() => {
28334
+ const knowledge = (report?.knowledge ?? []).map((item) => ({
28335
+ id: item.id,
28336
+ kind: item.kind ?? "fact",
28337
+ text: item.text,
28338
+ object: item.object,
28339
+ action: item.action,
28340
+ scene: item.scene,
28341
+ sources: (item.sources ?? []).filter((source) => source.documentId === void 0 || source.documentId === docId)
28342
+ }));
28343
+ const events2 = (report?.events ?? []).map((item) => ({
28344
+ id: item.id,
28345
+ kind: "case",
28346
+ text: item.title,
28347
+ object: item.object,
28348
+ action: item.action,
28349
+ scene: item.scene,
28350
+ sources: (item.sources ?? []).filter((source) => source.documentId === void 0 || source.documentId === docId)
28351
+ }));
28352
+ return [...knowledge, ...events2];
28353
+ }, [report]);
28354
+ const resolveImage = (0, import_react19.useMemo)(() => imageResolverOf(assets), [assets]);
28355
+ const localImageNames = (0, import_react19.useMemo)(() => {
28356
+ const names = /* @__PURE__ */ new Set();
28357
+ for (const match of body.matchAll(/!\[[^\]]*\]\(\s*(?:<([^>]+)>|([^\s)]+))/g)) {
28358
+ const source = match[1] ?? match[2] ?? "";
28359
+ if (source === "" || /^(https?:|data:)/i.test(source)) continue;
28360
+ const name = source.split("/").pop();
28361
+ if (name) names.add(name);
28362
+ }
28363
+ return [...names];
28364
+ }, [body]);
28365
+ const missingImages = localImageNames.filter((name) => !assets.some((asset) => asset.rel === name || asset.rel.endsWith(`/${name}`)));
28366
+ const colorById = (0, import_react19.useMemo)(() => new Map(items.map((item, index2) => [item.id, MARK_PALETTE[index2 % MARK_PALETTE.length]])), [items]);
28367
+ const gaps = (0, import_react19.useMemo)(() => report?.coverage?.gaps ?? [], [report]);
28368
+ const segmentFailures = (0, import_react19.useMemo)(() => (report?.exceptions ?? []).filter((item) => item.step === "\u62BD\u53D6\u6BB5\u5931\u8D25"), [report]);
28369
+ const marks = (0, import_react19.useMemo)(() => buildReadingMarks(body, items, gaps), [body, items, gaps]);
28370
+ const charMark = (0, import_react19.useMemo)(() => {
28371
+ const marksByChar = new Int32Array(body.length).fill(-1);
28372
+ for (const mark of marks) for (let index2 = mark.start; index2 < mark.end; index2 += 1) marksByChar[index2] = mark.id;
28373
+ return marksByChar;
28374
+ }, [body, marks]);
28375
+ const firstMarkOfItem = (0, import_react19.useMemo)(() => {
28376
+ const map = /* @__PURE__ */ new Map();
28377
+ for (const mark of marks) for (const item of mark.items) if (!map.has(item.id)) map.set(item.id, mark.id);
28378
+ return map;
28379
+ }, [marks]);
28380
+ const firstMarkOfGap = (0, import_react19.useMemo)(() => {
28381
+ const map = /* @__PURE__ */ new Map();
28382
+ for (const mark of marks) if (mark.gap) map.set(gapKey(mark.gap), mark.id);
28383
+ return map;
28384
+ }, [marks]);
28385
+ const coverage = report?.coverage;
28386
+ const gapCount = coverage === void 0 ? 0 : gaps.length || coverage.sections.missing.length + (coverage.blocks?.missing ?? Math.max(0, (coverage.blocks?.total ?? 0) - (coverage.blocks?.covered ?? 0))) + Math.max(0, coverage.tables.rows - coverage.tables.coveredRows);
28387
+ const stats = coverage === void 0 ? void 0 : [
28388
+ { label: "\u8282", covered: coverage.sections.covered, total: coverage.sections.total },
28389
+ { label: "\u884C", covered: coverage.tables.coveredRows, total: coverage.tables.rows },
28390
+ { label: "\u6BB5", covered: coverage.blocks?.covered ?? 0, total: coverage.blocks?.total ?? 0 }
28391
+ ];
28392
+ const needle = query.trim().toLowerCase();
28393
+ const visibleGaps = gaps.filter((gap) => (scope === "all" || scope === "gap") && (needle === "" || `${gap.title} ${gap.detail} ${gap.excerpt}`.toLowerCase().includes(needle)));
28394
+ const visibleItems = items.filter((item) => (scope === "all" || scope === "covered") && (needle === "" || `${item.text} ${item.object ?? ""} ${item.action ?? ""} ${item.scene ?? ""}`.toLowerCase().includes(needle)));
28395
+ const shownGaps = scope === "all" && !expanded.gap ? visibleGaps.slice(0, 5) : visibleGaps;
28396
+ const shownItems = scope === "all" && !expanded.item ? visibleItems.slice(0, 6) : visibleItems;
28397
+ (0, import_react19.useEffect)(() => {
28398
+ setExpanded({ gap: false, item: false });
28399
+ }, [scope, query]);
28400
+ const show = (markId, rect) => {
28401
+ if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
28402
+ setHover({ id: markId, rect });
28403
+ setActive(markId);
28404
+ };
28405
+ const cancelHide = () => {
28406
+ if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
28407
+ };
28408
+ const hideSoon = () => {
28409
+ if (hoverTimer.current !== void 0) window.clearTimeout(hoverTimer.current);
28410
+ hoverTimer.current = window.setTimeout(() => setHover(null), 120);
28411
+ };
28412
+ const locate = (markId) => {
28413
+ if (markId === void 0) return;
28414
+ setActive(markId);
28415
+ window.requestAnimationFrame(() => {
28416
+ document.querySelectorAll(`[data-mark="${markId}"]`)[0]?.scrollIntoView({ block: "center", behavior: "smooth" });
28417
+ });
28418
+ };
28419
+ (0, import_react19.useEffect)(() => {
28420
+ if (hover === null) return;
28421
+ const close = (event) => {
28422
+ if (popRef.current?.contains(event.target)) return;
28423
+ setHover(null);
28424
+ };
28425
+ window.addEventListener("scroll", close, { capture: true, passive: true });
28426
+ window.addEventListener("resize", close);
28427
+ return () => {
28428
+ window.removeEventListener("scroll", close, { capture: true });
28429
+ window.removeEventListener("resize", close);
28430
+ };
28431
+ }, [hover]);
28432
+ const lines = useLines(body);
28433
+ const hoverMark = hover === null ? void 0 : marks[hover.id];
28434
+ const popStyle = (() => {
28435
+ const rect = hover?.rect;
28436
+ if (!rect) return { left: 12, top: 12 };
28437
+ const width = 380;
28438
+ const left = Math.max(12, Math.min(rect.left, window.innerWidth - width - 12));
28439
+ const above = rect.top > 330;
28440
+ const caret = Math.max(18, Math.min(rect.left + rect.width / 2 - left, width - 18));
28441
+ return {
28442
+ left,
28443
+ top: above ? rect.top - 10 : rect.bottom + 10,
28444
+ transform: above ? "translateY(-100%)" : "none",
28445
+ ["--kw-caret"]: `${caret}px`
28446
+ };
28447
+ })();
28448
+ const uploadImages = async (list2) => {
28449
+ if (list2 === null || list2.length === 0) return;
28450
+ setUploading(true);
28451
+ setUploadError("");
28452
+ try {
28453
+ const files = await Promise.all(Array.from(list2).map(async (file) => {
28454
+ const bytes = new Uint8Array(await file.arrayBuffer());
28455
+ let binary = "";
28456
+ const chunk = 32768;
28457
+ for (let index2 = 0; index2 < bytes.length; index2 += chunk) binary += String.fromCharCode(...bytes.subarray(index2, index2 + chunk));
28458
+ return { name: file.name, data: btoa(binary) };
28459
+ }));
28460
+ await requestJson(`/knowledge/documents/${encodeURIComponent(docId)}/assets?${new URLSearchParams({ kb })}`, {
28461
+ method: "POST",
28462
+ headers: { "content-type": "application/json" },
28463
+ body: JSON.stringify({ files })
28464
+ });
28465
+ const meta = await requestJson(`/knowledge/documents/${encodeURIComponent(docId)}?${new URLSearchParams({ kb })}`);
28466
+ setAssets(meta.data?.document.assets ?? []);
28467
+ } catch (cause) {
28468
+ setUploadError(cause instanceof Error ? cause.message : String(cause));
28469
+ } finally {
28470
+ setUploading(false);
28471
+ }
28472
+ };
28473
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwRead", children: [
28474
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadMain", children: [
28475
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadBar", children: [
28476
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("a", { className: "kwReadJump", href: "#kwReadList", children: [
28477
+ "\u6E05\u5355 ",
28478
+ items.length + gaps.length
28479
+ ] }),
28480
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "kwReadStats", children: stats === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "kwReadNoCoverage", children: [
28481
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TriangleAlert, { size: 12 }),
28482
+ "\u8FD9\u4E00\u7248\u6CA1\u6709\u8986\u76D6\u81EA\u68C0"
28483
+ ] }) : stats.map((stat) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { children: [
28484
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: stat.covered }),
28485
+ " / ",
28486
+ stat.total,
28487
+ " ",
28488
+ stat.label
28489
+ ] }, stat.label)) }),
28490
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadLegend", "aria-hidden": "true", children: [
28491
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { "data-tone": "covered", children: [
28492
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("i", {}),
28493
+ "\u5DF2\u62BD\u53D6 ",
28494
+ items.length
28495
+ ] }),
28496
+ gaps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { "data-tone": "gap", children: [
28497
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("i", {}),
28498
+ "\u672A\u8986\u76D6 ",
28499
+ gapCount
28500
+ ] })
28501
+ ] }),
28502
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadFilter", role: "group", "aria-label": "\u7B5B\u9009\u539F\u6587\u6807\u8BB0", children: [
28503
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", "aria-pressed": scope === "all", onClick: () => setScope("all"), children: [
28504
+ "\u5168\u90E8 ",
28505
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("i", { children: items.length + gaps.length })
28506
+ ] }),
28507
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", "aria-pressed": scope === "covered", onClick: () => setScope("covered"), children: [
28508
+ "\u5DF2\u62BD\u53D6 ",
28509
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("i", { children: items.length })
28510
+ ] }),
28511
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", "aria-pressed": scope === "gap", onClick: () => setScope("gap"), disabled: gaps.length === 0, children: [
28512
+ "\u672A\u8986\u76D6 ",
28513
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("i", { children: gaps.length })
28514
+ ] })
28515
+ ] }),
28516
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "kwReadSearch", children: [
28517
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Search, { size: 12, "aria-hidden": "true" }),
28518
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Input, { value: query, placeholder: "\u641C\u77E5\u8BC6\u3001\u5750\u6807\u6216\u7F3A\u53E3", "aria-label": "\u5728\u539F\u6587\u5BF9\u7167\u91CC\u641C\u7D22", onChange: (event) => setQuery(event.target.value) })
28519
+ ] })
28520
+ ] }),
28521
+ coverage !== void 0 && stats !== void 0 && (() => {
28522
+ const totalUnits = stats.reduce((sum, stat) => sum + stat.total, 0);
28523
+ const coveredUnits = stats.reduce((sum, stat) => sum + stat.covered, 0);
28524
+ const pct = totalUnits === 0 ? 0 : Math.round(coveredUnits / totalUnits * 100);
28525
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadMeter", "aria-hidden": "true", children: [
28526
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { "data-tone": "covered", style: { width: `${pct}%` } }),
28527
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { "data-tone": "gap" })
28528
+ ] });
28529
+ })(),
28530
+ running && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("p", { className: "kwNotice kwNotice-info", role: "status", children: [
28531
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(LoaderCircle, { size: 13, className: "motion-safe:animate-spin" }),
28532
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { children: "\u6B63\u5728\u62BD\u53D6\uFF1B\u4E0B\u65B9\u662F\u5DF2\u4FDD\u5B58\u7684\u4E0A\u4E00\u7248\u7ED3\u679C\u3002" })
28533
+ ] }),
28534
+ failed && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("p", { className: "kwNotice kwNotice-error", role: "status", children: [
28535
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TriangleAlert, { size: 13 }),
28536
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { children: "\u672C\u6B21\u62BD\u53D6\u5931\u8D25\uFF0C\u4E0B\u9762\u8FD9\u4EFD\u8FD4\u56DE\u5185\u5BB9\u672A\u751F\u6548\u3002" })
28537
+ ] }),
28538
+ segmentFailures.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwNotice kwNotice-warn", role: "status", children: [
28539
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TriangleAlert, { size: 13 }),
28540
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { children: [
28541
+ segmentFailures.length,
28542
+ " \u6BB5\u539F\u6587\u65E0\u6CD5\u63D0\u53D6\uFF0C\u5176\u4F59\u5206\u7247\u5DF2\u7EE7\u7EED\uFF1A",
28543
+ segmentFailures.slice(0, 2).map((item) => item.message).join("\uFF1B"),
28544
+ segmentFailures.length > 2 ? `\uFF1B\u53E6\u6709 ${segmentFailures.length - 2} \u6BB5` : ""
28545
+ ] })
28546
+ ] }),
28547
+ sourceVersion !== void 0 && sourceVersion !== currentVersion && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("p", { className: "kwNotice kwNotice-warn", role: "status", children: [
28548
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(TriangleAlert, { size: 13 }),
28549
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { children: [
28550
+ "\u8FD9\u6B21\u7ED3\u679C\u57FA\u4E8E\u539F\u6587 v",
28551
+ sourceVersion,
28552
+ "\uFF0C\u5F53\u524D\u539F\u6587\u662F v",
28553
+ currentVersion,
28554
+ "\uFF1B\u9AD8\u4EAE\u6309\u5F53\u524D\u539F\u6587\u5B9A\u4F4D\uFF0C\u53EF\u80FD\u504F\u79FB\u3002"
28555
+ ] })
28556
+ ] }),
28557
+ missingImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadUpload", children: [
28558
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { children: [
28559
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("strong", { children: [
28560
+ "\u539F\u6587\u6709 ",
28561
+ missingImages.length,
28562
+ " \u5F20\u56FE\u7247\u8FD8\u6CA1\u5165\u5E93"
28563
+ ] }),
28564
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { children: "\u6309\u6587\u4EF6\u540D\u8865\u9F50\uFF1B\u8865\u9F50\u540E\u5C31\u5730\u663E\u793A\uFF0C\u4E0D\u6539\u539F\u6587\u3002" }),
28565
+ uploadError !== "" && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("em", { children: uploadError })
28566
+ ] }),
28567
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("button", { type: "button", className: "kwReadUploadAction", disabled: uploading, onClick: () => uploadInput.current?.click(), children: uploading ? "\u6B63\u5728\u4E0A\u4F20\u2026" : "\u9009\u62E9\u56FE\u7247\u8865\u9F50" }),
28568
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("input", { ref: uploadInput, type: "file", accept: "image/*", multiple: true, hidden: true, disabled: uploading, onChange: (event) => {
28569
+ void uploadImages(event.target.files);
28570
+ event.target.value = "";
28571
+ } })
28572
+ ] }),
28573
+ loadError !== "" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadError", role: "alert", children: [
28574
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(CircleAlert, { size: 15 }),
28575
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { children: [
28576
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: "\u539F\u6587\u6CA1\u6709\u8BFB\u51FA\u6765" }),
28577
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { children: loadError })
28578
+ ] }),
28579
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Button, { size: "sm", variant: "outline", onClick: () => setReload((value) => value + 1), children: "\u91CD\u8BD5" })
28580
+ ] }) : loading ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadSkeleton", role: "status", "aria-label": "\u6B63\u5728\u8BFB\u53D6\u539F\u6587", children: [
28581
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", {}),
28582
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", {}),
28583
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", {}),
28584
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", {})
28585
+ ] }) : body === "" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwEmpty", children: [
28586
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwEmptyIcon", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Inbox, { size: 16 }) }),
28587
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: "\u539F\u6587\u4E3A\u7A7A" }),
28588
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { children: "\u8FD9\u4EFD\u6765\u6E90\u6CA1\u6709\u6B63\u6587\uFF0C\u65E0\u6CD5\u5BF9\u7167\u3002" })
28589
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("article", { className: "kwReadText", "data-scope": scope, "aria-label": "\u539F\u6587\u4E0E\u62BD\u53D6\u6807\u8BB0", children: [
28590
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Lines, { lines, marks, charMark, active: active2, docTitle, colorById, resolveImage, onHover: show, onLeave: hideSoon, onFocus: show }),
28591
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("p", { className: "kwReadEnd", children: [
28592
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Check, { size: 12 }),
28593
+ "\u5168\u6587 ",
28594
+ total.toLocaleString(),
28595
+ " \u5B57 \xB7 \u5F15\u6587\u7531\u539F\u6587\u5B9A\u4F4D\uFF0C\u672A\u627E\u5230\u7684\u4E0D\u753B\u7EBF"
28596
+ ] })
28597
+ ] })
28598
+ ] }),
28599
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("aside", { className: "kwReadRail", id: "kwReadList", "aria-label": "\u62BD\u53D6\u7ED3\u679C\u4E0E\u8986\u76D6\u7F3A\u53E3", children: [
28600
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("header", { className: "kwReadRailHead", children: [
28601
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: "\u6E05\u5355" }),
28602
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { children: [
28603
+ knowledgeCount,
28604
+ " \u6761\u77E5\u8BC6",
28605
+ caseCount > 0 ? ` \xB7 ${caseCount} \u6761\u6848\u4F8B` : "",
28606
+ " \xB7 ",
28607
+ gapCount,
28608
+ " \u5904\u7F3A\u53E3"
28609
+ ] })
28610
+ ] }),
28611
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadRailBody", children: [
28612
+ visibleGaps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("section", { className: "kwReadGroup", "aria-label": "\u8986\u76D6\u7F3A\u53E3", children: [
28613
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("h3", { children: [
28614
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadDot", "data-tone": "gap" }),
28615
+ "\u672A\u8986\u76D6 ",
28616
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("i", { children: visibleGaps.length })
28617
+ ] }),
28618
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("ul", { children: shownGaps.map((gap) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", className: "kwReadRow", "data-tone": "gap", "data-on": firstMarkOfGap.get(gapKey(gap)) === active2 || void 0, onClick: () => locate(firstMarkOfGap.get(gapKey(gap))), children: [
28619
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadRowKind", children: GAP_LABEL[gap.kind] }),
28620
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: gap.title }),
28621
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("small", { children: [
28622
+ gap.detail,
28623
+ gap.line > 0 ? ` \xB7 \u7B2C ${gap.line} \u884C` : ""
28624
+ ] })
28625
+ ] }) }, gapKey(gap))) }),
28626
+ scope === "all" && !expanded.gap && visibleGaps.length > shownGaps.length && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", className: "kwReadMore", onClick: () => setExpanded((value) => ({ ...value, gap: true })), children: [
28627
+ "\u5C55\u5F00\u5168\u90E8 ",
28628
+ visibleGaps.length,
28629
+ " \u5904\u7F3A\u53E3"
28630
+ ] })
28631
+ ] }),
28632
+ shownItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("section", { className: "kwReadGroup", "aria-label": "\u5DF2\u62BD\u53D6", children: [
28633
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("h3", { children: [
28634
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadDot", "data-tone": "covered" }),
28635
+ "\u5DF2\u62BD\u53D6 ",
28636
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("i", { children: visibleItems.length })
28637
+ ] }),
28638
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("ul", { children: shownItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", className: "kwReadRow", "data-on": firstMarkOfItem.get(item.id) === active2 || void 0, onClick: () => locate(firstMarkOfItem.get(item.id)), children: [
28639
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadRowKind", "data-kind": item.kind, children: KIND_LABEL3[item.kind] ?? item.kind }),
28640
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: item.text }),
28641
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("small", { children: [
28642
+ [item.object, item.action, item.scene].filter(Boolean).join(" \xB7 ") || "\u65E0\u5750\u6807",
28643
+ firstMarkOfItem.has(item.id) ? "" : " \xB7 \u5F15\u6587\u672A\u5B9A\u4F4D"
28644
+ ] })
28645
+ ] }) }, item.id)) }),
28646
+ scope === "all" && !expanded.item && visibleItems.length > shownItems.length && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", className: "kwReadMore", onClick: () => setExpanded((value) => ({ ...value, item: true })), children: [
28647
+ "\u5C55\u5F00\u5168\u90E8 ",
28648
+ visibleItems.length,
28649
+ " \u6761\u7ED3\u679C"
28650
+ ] })
28651
+ ] }),
28652
+ gaps.length === 0 && gapCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "kwReadRailNote", children: "\u8FD9\u4E00\u7248\u53EA\u8BB0\u4E86\u7F3A\u53E3\u6570\u91CF\uFF0C\u6CA1\u6709\u9010\u6761\u660E\u7EC6\uFF1B\u91CD\u62BD\u540E\u4F1A\u5217\u51FA\u3002" }),
28653
+ visibleGaps.length === 0 && visibleItems.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwEmpty kwEmptyCompact", children: [
28654
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: "\u6CA1\u6709\u5339\u914D\u9879" }),
28655
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { children: "\u6362\u4E2A\u5173\u952E\u8BCD\uFF0C\u6216\u628A\u7B5B\u9009\u5207\u56DE\u300C\u5168\u90E8\u300D\u3002" })
28656
+ ] })
28657
+ ] })
28658
+ ] }),
28659
+ hoverMark !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { ref: popRef, className: "kwReadPop", "data-above": hover !== null && hover.rect.top > 330 ? "true" : "false", style: popStyle, role: "status", onMouseEnter: cancelHide, onMouseLeave: hideSoon, children: hoverMark.gap !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
28660
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("header", { children: [
28661
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadDot", "data-tone": "gap" }),
28662
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: "\u672A\u8986\u76D6" }),
28663
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("em", { children: GAP_LABEL[hoverMark.gap.kind] }),
28664
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { children: [
28665
+ "\u7B2C ",
28666
+ hoverMark.gap.line,
28667
+ " \u884C"
28668
+ ] })
28669
+ ] }),
28670
+ hoverMark.gap.kind !== "block" && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "kwReadPopTitle", children: hoverMark.gap.title }),
28671
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "kwReadPopText", children: hoverMark.gap.detail }),
28672
+ hoverMark.gap.excerpt.trim() !== "" && hoverMark.gap.excerpt.trim() !== hoverMark.gap.title.trim() && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "kwReadPopQuote", children: hoverMark.gap.excerpt }),
28673
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("footer", { children: "\u8FD9\u6BB5\u539F\u6587\u6CA1\u6709\u4EFB\u4F55\u77E5\u8BC6\u5F15\u7528" })
28674
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
28675
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("header", { children: [
28676
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadDot", "data-tone": "covered", style: { background: hoverMark.items[0] ? colorById.get(hoverMark.items[0].id) : void 0 } }),
28677
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: "\u5DF2\u62BD\u53D6" }),
28678
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("em", { children: [
28679
+ hoverMark.items.length,
28680
+ " \u6761"
28681
+ ] }),
28682
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { children: STAGE_LABEL(hoverMark) })
28683
+ ] }),
28684
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadPopList", children: [
28685
+ hoverMark.items.slice(0, 4).map((item) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadPopItem", children: [
28686
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadRowKind", "data-kind": item.kind, children: KIND_LABEL3[item.kind] ?? item.kind }),
28687
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { children: item.text }),
28688
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("small", { children: [item.object, item.action, item.scene].filter(Boolean).join(" \xB7 ") || "\u65E0\u5750\u6807" })
28689
+ ] }, item.id)),
28690
+ hoverMark.items.length > 4 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("p", { className: "kwReadPopMore", children: [
28691
+ "\u53E6\u6709 ",
28692
+ hoverMark.items.length - 4,
28693
+ " \u6761"
28694
+ ] })
28695
+ ] }),
28696
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("footer", { children: "\u5F15\u6587\u5DF2\u6838\u9A8C \xB7 \u70B9\u51FB\u53F3\u4FA7\u6E05\u5355\u53EF\u5B9A\u4F4D" })
28697
+ ] }) })
28698
+ ] });
28699
+ }
28700
+ function STAGE_LABEL(mark) {
28701
+ const sources = mark.items.flatMap((item) => item.sources ?? []);
28702
+ return sources.some((source) => source.locator) ? "\u5DF2\u5B9A\u4F4D" : "\u6309\u539F\u6587\u67E5\u627E";
28703
+ }
28704
+ function useLines(body) {
28705
+ return (0, import_react19.useMemo)(() => {
28706
+ const lines = [];
28707
+ let start = 0;
28708
+ for (const text of body.split("\n")) {
28709
+ lines.push({ start, text });
28710
+ start += text.length + 1;
28711
+ }
28712
+ return lines;
28713
+ }, [body]);
28714
+ }
28715
+ function Lines({ lines, marks, charMark, active: active2, docTitle, colorById, resolveImage, onHover, onLeave, onFocus }) {
28716
+ const elements = [];
28717
+ let code = false;
28718
+ let codeLines = [];
28719
+ const flushCode = () => {
28720
+ if (codeLines.length === 0) return;
28721
+ const first = codeLines[0];
28722
+ const raw = codeLines.map((item) => item.text).join("\n");
28723
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("pre", { className: "kwReadCode", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(CodeText, { raw, base: first.start, charMark, marks, colorById, onHover, onLeave, onFocus }) }, `code-${first.start}`));
28724
+ codeLines = [];
28725
+ };
28726
+ let skipFront = false;
28727
+ let frontClosed = false;
28728
+ let skippedTitle = false;
28729
+ for (let index2 = 0; index2 < lines.length; index2 += 1) {
28730
+ const line = lines[index2];
28731
+ const text = line.text;
28732
+ const trimmed = text.trim();
28733
+ if (index2 === 0 && trimmed === "---") {
28734
+ skipFront = true;
28735
+ continue;
28736
+ }
28737
+ if (skipFront && !frontClosed) {
28738
+ if (trimmed === "---") {
28739
+ skipFront = false;
28740
+ frontClosed = true;
28741
+ }
28742
+ continue;
28743
+ }
28744
+ if (trimmed.startsWith("```")) {
28745
+ if (code) flushCode();
28746
+ code = !code;
28747
+ continue;
28748
+ }
28749
+ if (code) {
28750
+ codeLines.push(line);
28751
+ continue;
28752
+ }
28753
+ if (trimmed === "") {
28754
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "kwReadBlank", "aria-hidden": "true" }, line.start));
28755
+ continue;
28756
+ }
28757
+ const heading = /^(#{1,6})\s+(.*)$/.exec(text);
28758
+ if (heading) {
28759
+ const sameTitle = (value) => value.trim().replace(/\.(md|markdown)$/i, "") === docTitle.trim().replace(/\.(md|markdown)$/i, "");
28760
+ if (!skippedTitle && heading[1].length === 1 && sameTitle(heading[2])) {
28761
+ skippedTitle = true;
28762
+ continue;
28763
+ }
28764
+ const level = Math.min(3, heading[1].length);
28765
+ const raw = heading[2];
28766
+ const base = line.start + text.indexOf(raw);
28767
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("h3", { className: `kwReadH kwReadH${level}`, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(RichText, { raw, base, charMark, marks, active: active2, colorById, resolveImage, onHover, onLeave, onFocus }) }, line.start));
28768
+ continue;
28769
+ }
28770
+ if (/^\s*\|/.test(text)) {
28771
+ const next = lines[index2 + 1]?.text ?? "";
28772
+ const separator = /^\s*\|?[\s:|-]+\|?\s*$/.test(next) && next.includes("-");
28773
+ const cells = splitTableRow(text, line.start);
28774
+ if (cells.every((cell) => /^:?-{2,}:?$/.test(cell.text.trim()))) {
28775
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "kwReadTableRule", "aria-hidden": "true" }, line.start));
28776
+ continue;
28777
+ }
28778
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "kwReadTr", "data-head": separator || void 0, style: { gridTemplateColumns: `repeat(${Math.max(1, cells.length)}, minmax(0, 1fr))` }, children: cells.map((cell) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadTd", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(RichText, { raw: cell.text, base: cell.start, charMark, marks, active: active2, colorById, resolveImage, onHover, onLeave, onFocus }) }, `${line.start}-${cell.start}`)) }, line.start));
28779
+ continue;
28780
+ }
28781
+ if (trimmed === "---") {
28782
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "kwReadRule", "aria-hidden": "true" }, line.start));
28783
+ continue;
28784
+ }
28785
+ const list2 = /^(\s*)([-*+]|\d+\.)\s+(.*)$/.exec(text);
28786
+ if (list2) {
28787
+ const marker = /^\d/.test(list2[2]) ? list2[2] : "\xB7";
28788
+ const raw = list2[3];
28789
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "kwReadLi", children: [
28790
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadLiMark", "aria-hidden": "true", children: marker }),
28791
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(RichText, { raw, base: line.start + text.indexOf(raw), charMark, marks, active: active2, colorById, resolveImage, onHover, onLeave, onFocus }) })
28792
+ ] }, line.start));
28793
+ continue;
28794
+ }
28795
+ elements.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "kwReadP", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(RichText, { raw: text, base: line.start, charMark, marks, active: active2, colorById, resolveImage, onHover, onLeave, onFocus }) }, line.start));
28796
+ }
28797
+ flushCode();
28798
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_jsx_runtime51.Fragment, { children: elements });
28799
+ }
28800
+ function splitTableRow(text, start) {
28801
+ const cells = [];
28802
+ let cursor = 0;
28803
+ for (const part of text.split("|")) {
28804
+ const leading = part.length - part.trimStart().length;
28805
+ cells.push({ text: part.trim(), start: start + cursor + leading });
28806
+ cursor += part.length + 1;
28807
+ }
28808
+ if (text.trimStart().startsWith("|")) cells.shift();
28809
+ if (text.trimEnd().endsWith("|")) cells.pop();
28810
+ return cells;
28811
+ }
28812
+ var IMAGE_REF = new RegExp(`!\\[([^\\]]*)\\]\\(\\s*(?:<([^>]+)>|([^\\s)]+))\\s*\\)|<img[^>]*\\bsrc=["']([^"']+)["'][^>]*>`, "gi");
28813
+ function splitInlineImages(raw) {
28814
+ const parts = [];
28815
+ let cursor = 0;
28816
+ for (const match of raw.matchAll(IMAGE_REF)) {
28817
+ const at2 = match.index ?? 0;
28818
+ if (at2 > cursor) parts.push({ kind: "text", text: raw.slice(cursor, at2), start: cursor });
28819
+ const source = match[2] ?? match[3] ?? match[4] ?? "";
28820
+ if (source !== "") parts.push({ kind: "image", alt: match[1] ?? "", source, start: at2 });
28821
+ cursor = at2 + match[0].length;
28822
+ }
28823
+ if (cursor < raw.length) parts.push({ kind: "text", text: raw.slice(cursor), start: cursor });
28824
+ return parts;
28825
+ }
28826
+ function ReadImage({ alt, source, resolveImage }) {
28827
+ const [failed, setFailed] = (0, import_react19.useState)(false);
28828
+ const url = /^(https?:|data:)/i.test(source) ? source : resolveImage?.(source);
28829
+ if (url === null || url === void 0 || failed) {
28830
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "kwReadFigure", title: source, children: [
28831
+ alt.trim() !== "" ? alt.trim() : "\u56FE\u7247",
28832
+ " \xB7 \u672A\u5165\u5E93"
28833
+ ] });
28834
+ }
28835
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("img", { className: "kwReadImg", src: url, alt: alt.trim() !== "" ? alt.trim() : "\u539F\u6587\u56FE\u7247", loading: "lazy", onError: () => setFailed(true) });
28836
+ }
28837
+ function RichText({ raw, base, charMark, marks, active: active2, colorById, resolveImage, onHover, onLeave, onFocus }) {
28838
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_jsx_runtime51.Fragment, { children: splitInlineImages(raw).map((part, index2) => part.kind === "image" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ReadImage, { alt: part.alt, source: part.source, resolveImage }, `${base}-${index2}`) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Marked, { raw: part.text, base: base + part.start, charMark, marks, active: active2, colorById, onHover, onLeave, onFocus }, `${base}-${index2}`)) });
28839
+ }
28840
+ function CodeText({ raw, base, charMark, marks, colorById, onHover, onLeave, onFocus }) {
28841
+ const parts = [];
28842
+ let index2 = 0;
28843
+ while (index2 < raw.length) {
28844
+ const id = charMark[base + index2] ?? -1;
28845
+ let end = index2 + 1;
28846
+ while (end < raw.length && (charMark[base + end] ?? -1) === id) end += 1;
28847
+ const slice = raw.slice(index2, end);
28848
+ if (id >= 0) {
28849
+ const mark = marks[id];
28850
+ const color = mark?.gap ? void 0 : colorById.get(mark?.items[0]?.id ?? "");
28851
+ parts.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadMark", "data-mark": id, "data-tone": mark?.gap ? "gap" : "covered", style: color === void 0 ? void 0 : { "--kw-mark-color": color }, onMouseEnter: (event) => onHover(id, event.currentTarget.getBoundingClientRect()), onMouseLeave: onLeave, onFocus: (event) => onFocus(id, event.currentTarget.getBoundingClientRect()), onBlur: onLeave, children: slice }, `${base}-${index2}`));
28852
+ } else parts.push(slice);
28853
+ index2 = end;
28854
+ }
28855
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_jsx_runtime51.Fragment, { children: parts });
28856
+ }
28857
+ function Marked({ raw, base, charMark, marks, active: active2, colorById, onHover, onLeave, onFocus }) {
28858
+ const { display, map } = inlineTransform(raw);
28859
+ if (display === "") return null;
28860
+ const parts = [];
28861
+ let index2 = 0;
28862
+ while (index2 < display.length) {
28863
+ const mapped = map[index2];
28864
+ const rawAt = mapped === void 0 ? void 0 : base + mapped;
28865
+ const id = rawAt === void 0 ? -1 : charMark[rawAt] ?? -1;
28866
+ let end = index2 + 1;
28867
+ while (end < display.length) {
28868
+ const nextMapped = map[end];
28869
+ const nextRaw = nextMapped === void 0 ? void 0 : base + nextMapped;
28870
+ const next = nextRaw === void 0 ? -1 : charMark[nextRaw] ?? -1;
28871
+ if (next !== id) break;
28872
+ end += 1;
28873
+ }
28874
+ const slice = display.slice(index2, end);
28875
+ if (id >= 0) {
28876
+ const mark = marks[id];
28877
+ const tone2 = mark?.gap ? "gap" : "covered";
28878
+ const color = mark?.gap ? void 0 : colorById.get(mark?.items[0]?.id ?? "");
28879
+ parts.push(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "kwReadMark", "data-mark": id, "data-tone": tone2, "data-active": active2 === id || void 0, tabIndex: 0, title: tone2 === "gap" ? "\u672A\u8986\u76D6" : "\u5DF2\u62BD\u53D6", style: color === void 0 ? void 0 : { "--kw-mark-color": color }, onMouseEnter: (event) => onHover(id, event.currentTarget.getBoundingClientRect()), onMouseLeave: onLeave, onFocus: (event) => onFocus(id, event.currentTarget.getBoundingClientRect()), onBlur: onLeave, children: slice }, `${base}-${index2}`));
28880
+ } else parts.push(slice);
28881
+ index2 = end;
28882
+ }
28883
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_jsx_runtime51.Fragment, { children: parts });
28884
+ }
28885
+
28886
+ // src/client/DocumentExtractionView.tsx
28887
+ var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
26034
28888
  var STATUS_LABEL2 = { failed: "\u5931\u8D25", running: "\u62BD\u53D6\u4E2D", pending: "\u5F85\u62BD\u53D6", outdated: "\u539F\u6587\u5DF2\u53D8\u66F4", done: "\u5DF2\u62BD\u53D6" };
26035
28889
  var STATUS_TONE2 = { failed: "warning", running: "blue", pending: "neutral", outdated: "warning", done: "success" };
26036
- var KIND_ORDER = ["fact", "procedure", "case", "event"];
26037
- var KIND_LABEL3 = { fact: "Fact", procedure: "Procedure", case: "Case", event: "Event" };
26038
- function DocumentExtractionView({ kb, sources, initialSource, onRefresh, onLineage, onAddFile }) {
28890
+ function DocumentExtractionView({ kb, sources, initialSource, onRefresh, onLineage, onAddFile, startBlocked = false }) {
26039
28891
  const [doc, setDoc] = (0, import_react20.useState)(initialSource ?? "");
26040
28892
  const [query, setQuery] = (0, import_react20.useState)("");
26041
28893
  const [filter, setFilter] = (0, import_react20.useState)("all");
@@ -26045,13 +28897,10 @@ ${report.prompt.user}`;
26045
28897
  const [detail, setDetail] = (0, import_react20.useState)();
26046
28898
  const [report, setReport] = (0, import_react20.useState)();
26047
28899
  const [callPage, setCallPage] = (0, import_react20.useState)(0);
26048
- const [detailTab, setDetailTab] = (0, import_react20.useState)("result");
28900
+ const [detailTab, setDetailTab] = (0, import_react20.useState)("read");
26049
28901
  const [error, setError] = (0, import_react20.useState)("");
26050
28902
  const [busy, setBusy] = (0, import_react20.useState)(false);
26051
28903
  const [revision, setRevision] = (0, import_react20.useState)(0);
26052
- const [kindFilter, setKindFilter] = (0, import_react20.useState)("all");
26053
- const [resultQuery, setResultQuery] = (0, import_react20.useState)("");
26054
- const [copied, setCopied] = (0, import_react20.useState)(false);
26055
28904
  (0, import_react20.useEffect)(() => {
26056
28905
  if (!doc && sources.length) setDoc(sources[0].id);
26057
28906
  }, [doc, sources]);
@@ -26080,16 +28929,16 @@ ${report.prompt.user}`;
26080
28929
  setReport(void 0);
26081
28930
  const load = async () => {
26082
28931
  try {
26083
- const rows2 = [];
28932
+ const rows = [];
26084
28933
  for (; ; ) {
26085
- const result = await requestJson(`/knowledge/pipeline-versions?${new URLSearchParams({ kb, stage: "extract", source: doc, limit: "100", offset: String(rows2.length) })}`);
28934
+ const result = await requestJson(`/knowledge/pipeline-versions?${new URLSearchParams({ kb, stage: "extract", source: doc, limit: "100", offset: String(rows.length) })}`);
26086
28935
  const page = result.data?.versions ?? [];
26087
- rows2.push(...page);
28936
+ rows.push(...page);
26088
28937
  if (cancelled || page.length < 100) break;
26089
28938
  }
26090
28939
  if (!cancelled) {
26091
- setHistory(rows2);
26092
- setSelected((current2) => current2 && rows2.some((row) => row.id === current2) ? current2 : rows2[0]?.id ?? "");
28940
+ setHistory(rows);
28941
+ setSelected((current2) => current2 && rows.some((row) => row.id === current2) ? current2 : rows[0]?.id ?? "");
26093
28942
  }
26094
28943
  } catch (cause) {
26095
28944
  if (!cancelled) setError(cause instanceof Error ? cause.message : String(cause));
@@ -26131,10 +28980,6 @@ ${report.prompt.user}`;
26131
28980
  (0, import_react20.useEffect)(() => {
26132
28981
  setCallPage(0);
26133
28982
  }, [doc, selected]);
26134
- (0, import_react20.useEffect)(() => {
26135
- setKindFilter("all");
26136
- setResultQuery("");
26137
- }, [doc, selected]);
26138
28983
  const loadMoreLog = async () => {
26139
28984
  if (!detail || !doc) return;
26140
28985
  try {
@@ -26183,110 +29028,79 @@ ${report.prompt.user}`;
26183
29028
  const selectedVersion = history.find((row) => row.id === selected);
26184
29029
  const pendingCount = sources.filter((source) => source.state === "pending" || source.state === "outdated").length;
26185
29030
  const visibleSources = sources.filter((source) => source.title.toLowerCase().includes(query.toLowerCase()) && (filter === "all" || sourceStatus(source) === filter));
26186
- const knowledge = report?.knowledge ?? [];
26187
- const cases = report?.events ?? [];
26188
- const kindCounts = (0, import_react20.useMemo)(() => {
26189
- const counts = /* @__PURE__ */ new Map();
26190
- for (const item of knowledge) counts.set(item.kind ?? "fact", (counts.get(item.kind ?? "fact") ?? 0) + 1);
26191
- if (cases.length) counts.set("case", cases.length);
26192
- return counts;
26193
- }, [knowledge, cases]);
26194
- const coverageGaps = report?.coverage === void 0 ? { sections: 0, blocks: 0, rows: 0 } : {
26195
- sections: report.coverage.sections.missing.length,
26196
- blocks: report.coverage.blocks === void 0 ? 0 : report.coverage.blocks.missing ?? Math.max(0, report.coverage.blocks.total - report.coverage.blocks.covered),
26197
- rows: Math.max(0, report.coverage.tables.rows - report.coverage.tables.coveredRows)
26198
- };
26199
- const rows = (0, import_react20.useMemo)(() => {
26200
- const items = [
26201
- ...knowledge.map((item) => ({ id: item.id, kind: item.kind ?? "fact", text: item.text })),
26202
- ...cases.map((item) => ({ id: item.id, kind: "case", text: item.title }))
26203
- ];
26204
- const needle = resultQuery.trim().toLowerCase();
26205
- return items.filter((item) => (kindFilter === "all" || item.kind === kindFilter) && (needle === "" || item.text.toLowerCase().includes(needle)));
26206
- }, [knowledge, cases, kindFilter, resultQuery]);
26207
- const copyAll = async () => {
26208
- const text = rows.map((item) => `[${item.kind}] ${item.text}`).join("\n");
26209
- try {
26210
- await navigator.clipboard.writeText(text);
26211
- setCopied(true);
26212
- window.setTimeout(() => setCopied(false), 1600);
26213
- } catch {
26214
- setError("\u6D4F\u89C8\u5668\u6CA1\u6709\u5141\u8BB8\u5199\u526A\u8D34\u677F\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u6B63\u6587\u590D\u5236\u3002");
26215
- }
26216
- };
26217
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwBody", children: [
26218
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("aside", { className: "kwQueue", "aria-label": "\u6587\u6863\u961F\u5217", children: [
26219
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwQueueHead", children: [
26220
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwQueueTitle", children: [
26221
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: "\u6587\u6863" }),
26222
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { children: [
29031
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwBody", children: [
29032
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("aside", { className: "kwQueue", "aria-label": "\u6587\u6863\u961F\u5217", children: [
29033
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwQueueHead", children: [
29034
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwQueueTitle", children: [
29035
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u6587\u6863" }),
29036
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { children: [
26223
29037
  "\u5171 ",
26224
29038
  sources.length,
26225
29039
  " \u4EFD"
26226
29040
  ] }),
26227
- sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { className: "kwQueueAdd", size: "sm", variant: "default", onClick: onAddFile, children: [
26228
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Plus, { size: 12 }),
29041
+ sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Button, { className: "kwQueueAdd", size: "sm", variant: "default", onClick: onAddFile, children: [
29042
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Plus, { size: 12 }),
26229
29043
  "\u6DFB\u52A0\u6587\u4EF6"
26230
29044
  ] })
26231
29045
  ] }),
26232
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwQueueTools", children: [
26233
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "kwSearch", children: [
26234
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Search, { size: 12, "aria-hidden": "true" }),
26235
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Input, { value: query, placeholder: "\u641C\u7D22\u6587\u6863", "aria-label": "\u641C\u7D22\u6587\u6863", onChange: (event) => setQuery(event.target.value) })
29046
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwQueueTools", children: [
29047
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { className: "kwSearch", children: [
29048
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Search, { size: 12, "aria-hidden": "true" }),
29049
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Input, { value: query, placeholder: "\u641C\u7D22\u6587\u6863", "aria-label": "\u641C\u7D22\u6587\u6863", onChange: (event) => setQuery(event.target.value) })
26236
29050
  ] }),
26237
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(SelectMenu, { "aria-label": "\u6309\u62BD\u53D6\u72B6\u6001\u7B5B\u9009", value: filter, onValueChange: setFilter, options: [{ value: "all", label: "\u5168\u90E8\u72B6\u6001" }, ...Object.entries(STATUS_LABEL2).map(([value, label2]) => ({ value, label: label2 }))] })
29051
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(SelectMenu, { "aria-label": "\u6309\u62BD\u53D6\u72B6\u6001\u7B5B\u9009", value: filter, onValueChange: setFilter, options: [{ value: "all", label: "\u5168\u90E8\u72B6\u6001" }, ...Object.entries(STATUS_LABEL2).map(([value, label2]) => ({ value, label: label2 }))] })
26238
29052
  ] })
26239
29053
  ] }),
26240
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("ul", { className: "kwList", children: [
29054
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("ul", { className: "kwList", children: [
26241
29055
  visibleSources.map((source) => {
26242
29056
  const version = latest[source.id];
26243
29057
  const status = sourceStatus(source);
26244
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("button", { type: "button", className: "kwDoc", "data-on": doc === source.id || void 0, "aria-pressed": doc === source.id, onClick: () => setDoc(source.id), children: [
26245
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwDocTitle", children: source.title }),
26246
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "kwDocMeta", children: [
26247
- "\u539F\u6587 v",
26248
- source.version,
26249
- " \xB7 ",
26250
- version?.documentVersion ? `\u62BD\u53D6 v${version.documentVersion}` : "\u672A\u62BD\u53D6"
26251
- ] }),
26252
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "kwDocFoot", children: [
26253
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwDocCount", children: source.knowledgeCount !== void 0 ? `${source.knowledgeCount} \u6761\u77E5\u8BC6` : "\u6682\u65E0\u7ED3\u679C" }),
26254
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwState", "data-tone": STATUS_TONE2[status], children: STATUS_LABEL2[status] })
29058
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("button", { type: "button", className: "kwDoc", "data-on": doc === source.id || void 0, "aria-pressed": doc === source.id, onClick: () => setDoc(source.id), children: [
29059
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "kwDocTitle", children: source.title }),
29060
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { className: "kwDocMeta", children: [
29061
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { children: [
29062
+ "\u539F\u6587 v",
29063
+ source.version,
29064
+ " \xB7 ",
29065
+ version?.documentVersion ? `\u62BD\u53D6 v${version.documentVersion}` : "\u672A\u62BD\u53D6",
29066
+ source.knowledgeCount !== void 0 ? ` \xB7 ${source.knowledgeCount} \u6761` : ""
29067
+ ] }),
29068
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "kwState", "data-tone": STATUS_TONE2[status], children: STATUS_LABEL2[status] })
26255
29069
  ] })
26256
29070
  ] }) }, source.id);
26257
29071
  }),
26258
- visibleSources.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("li", { className: "kwEmpty kwEmptyList", children: sources.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
26259
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwEmptyIcon", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Inbox, { size: 16 }) }),
26260
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: "\u5E93\u91CC\u8FD8\u6CA1\u6709\u6587\u6863" }),
26261
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: "\u5148\u6DFB\u52A0\u4E00\u4EFD Markdown\u3002\u5BFC\u5165\u53EA\u5165\u5E93\uFF0C\u62BD\u53D6\u7531\u4F60\u53D1\u8D77\u3002" }),
26262
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { size: "sm", variant: "default", onClick: onAddFile, children: [
26263
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Plus, { size: 12 }),
29072
+ visibleSources.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("li", { className: "kwEmpty kwEmptyList", children: sources.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
29073
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "kwEmptyIcon", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Inbox, { size: 16 }) }),
29074
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u5E93\u91CC\u8FD8\u6CA1\u6709\u6587\u6863" }),
29075
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { children: "\u5148\u6DFB\u52A0\u4E00\u4EFD Markdown\u3002\u5BFC\u5165\u53EA\u5165\u5E93\uFF0C\u62BD\u53D6\u7531\u4F60\u53D1\u8D77\u3002" }),
29076
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Button, { size: "sm", variant: "default", onClick: onAddFile, children: [
29077
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Plus, { size: 12 }),
26264
29078
  "\u6DFB\u52A0\u6587\u4EF6"
26265
29079
  ] })
26266
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
26267
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: "\u6CA1\u6709\u5339\u914D\u7684\u6587\u6863" }),
26268
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: "\u6362\u4E2A\u5173\u952E\u8BCD\uFF0C\u6216\u628A\u72B6\u6001\u7B5B\u9009\u5207\u56DE\u300C\u5168\u90E8\u72B6\u6001\u300D\u3002" })
29080
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
29081
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u6CA1\u6709\u5339\u914D\u7684\u6587\u6863" }),
29082
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { children: "\u6362\u4E2A\u5173\u952E\u8BCD\uFF0C\u6216\u628A\u72B6\u6001\u7B5B\u9009\u5207\u56DE\u300C\u5168\u90E8\u72B6\u6001\u300D\u3002" })
26269
29083
  ] }) })
26270
29084
  ] }),
26271
- sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "kwQueueFoot", children: pendingCount === 0 ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwQueueAllDone", children: [
26272
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Check, { size: 12 }),
29085
+ sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "kwQueueFoot", children: pendingCount === 0 ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("p", { className: "kwQueueAllDone", children: [
29086
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Check, { size: 12 }),
26273
29087
  "\u5168\u90E8\u6587\u4EF6\u5DF2\u662F\u6700\u65B0"
26274
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { size: "sm", variant: "outline", className: "w-full", disabled: busy, onClick: () => void run(), children: [
26275
- busy ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(LoaderCircle, { size: 12, className: "motion-safe:animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Play, { size: 12 }),
29088
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Button, { size: "sm", variant: "outline", className: "w-full", disabled: busy || startBlocked, title: startBlocked ? "\u5DF2\u6709\u4EFB\u52A1\u5728\u8FD0\u884C\uFF0C\u7B49\u5B83\u7ED3\u675F\u540E\u518D\u8BD5" : void 0, onClick: () => void run(), children: [
29089
+ busy ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(LoaderCircle, { size: 12, className: "motion-safe:animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Play, { size: 12 }),
26276
29090
  "\u62BD\u53D6\u5F85\u5904\u7406 \xB7 ",
26277
29091
  pendingCount,
26278
29092
  " \u4EFD"
26279
29093
  ] }) })
26280
29094
  ] }),
26281
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("section", { className: "kwInspector", "aria-label": "\u6587\u6863\u62BD\u53D6\u8BE6\u60C5", children: !current ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwEmpty", children: [
26282
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwEmptyIcon", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Inbox, { size: 16 }) }),
26283
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: "\u5148\u9009\u4E00\u4EFD\u6587\u6863" }),
26284
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: "\u5DE6\u8FB9\u662F\u5E93\u91CC\u6240\u6709\u6587\u6863\u3002\u9009\u4E2D\u4E00\u4EFD\uFF0C\u8FD9\u91CC\u663E\u793A\u5B83\u6BCF\u4E00\u6B21\u62BD\u53D6\u7684\u7ED3\u679C\u3001\u65E5\u5FD7\u548C\u539F\u6587\u7248\u672C\u3002" })
26285
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
26286
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("header", { className: "kwInspectorHead", children: [
26287
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwInspectorTitle", children: [
26288
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h2", { children: current.title }),
26289
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { children: [
29095
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("section", { className: "kwInspector", "aria-label": "\u6587\u6863\u62BD\u53D6\u8BE6\u60C5", children: !current ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwEmpty", children: [
29096
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "kwEmptyIcon", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Inbox, { size: 16 }) }),
29097
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u5148\u9009\u4E00\u4EFD\u6587\u6863" }),
29098
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { children: "\u5DE6\u8FB9\u662F\u5E93\u91CC\u6240\u6709\u6587\u6863\u3002\u9009\u4E2D\u4E00\u4EFD\uFF0C\u8FD9\u91CC\u663E\u793A\u5B83\u6BCF\u4E00\u6B21\u62BD\u53D6\u7684\u7ED3\u679C\u3001\u65E5\u5FD7\u548C\u539F\u6587\u7248\u672C\u3002" })
29099
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
29100
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("header", { className: "kwInspectorHead", children: [
29101
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwInspectorTitle", children: [
29102
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("h2", { children: current.title }),
29103
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("p", { children: [
26290
29104
  "\u539F\u6587 v",
26291
29105
  current.version,
26292
29106
  " \xB7 ",
@@ -26295,160 +29109,100 @@ ${report.prompt.user}`;
26295
29109
  current.extractedSourceVersion !== void 0 && current.extractedSourceVersion !== current.version ? ` \xB7 \u7ED3\u679C\u57FA\u4E8E\u539F\u6587 v${current.extractedSourceVersion}` : ""
26296
29110
  ] })
26297
29111
  ] }),
26298
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwInspectorActions", children: [
26299
- selectedVersion && ["running", "paused"].includes(selectedVersion.state) && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
26300
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { size: "sm", variant: "outline", disabled: busy, onClick: () => void control(selectedVersion.state === "paused" ? "resume" : "pause"), children: [
26301
- selectedVersion.state === "paused" ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Play, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Pause, { size: 12 }),
29112
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwInspectorActions", children: [
29113
+ selectedVersion && ["running", "paused"].includes(selectedVersion.state) && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
29114
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Button, { size: "sm", variant: "outline", disabled: busy, onClick: () => void control(selectedVersion.state === "paused" ? "resume" : "pause"), children: [
29115
+ selectedVersion.state === "paused" ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Play, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Pause, { size: 12 }),
26302
29116
  selectedVersion.state === "paused" ? "\u7EE7\u7EED" : "\u6682\u505C"
26303
29117
  ] }),
26304
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { size: "sm", variant: "ghost", disabled: busy, onClick: () => void control("cancel"), children: [
26305
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(X, { size: 12 }),
29118
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Button, { size: "sm", variant: "ghost", disabled: busy, onClick: () => void control("cancel"), children: [
29119
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(X, { size: 12 }),
26306
29120
  "\u505C\u6B62"
26307
29121
  ] })
26308
29122
  ] }),
26309
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { size: "sm", variant: "ghost", onClick: () => onLineage(current.id), children: [
29123
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Button, { size: "sm", variant: "ghost", onClick: () => onLineage(current.id), children: [
26310
29124
  "\u6587\u6863\u94FE\u8DEF",
26311
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ExternalLink, { size: 12 })
29125
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ExternalLink, { size: 12 })
26312
29126
  ] }),
26313
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { size: "sm", variant: "outline", disabled: busy, onClick: () => void run(current.id), children: [
26314
- busy ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(LoaderCircle, { size: 12, className: "motion-safe:animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(RefreshCw, { size: 12 }),
26315
- latest[current.id] ? "\u91CD\u65B0\u62BD\u53D6" : "\u62BD\u53D6"
29127
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Button, { size: "sm", variant: "outline", disabled: busy || startBlocked, title: startBlocked ? "\u5DF2\u6709\u4EFB\u52A1\u5728\u8FD0\u884C\uFF0C\u7B49\u5B83\u7ED3\u675F\u540E\u518D\u8BD5" : void 0, onClick: () => void run(current.id), children: [
29128
+ busy ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(LoaderCircle, { size: 12, className: "motion-safe:animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(RefreshCw, { size: 12 }),
29129
+ selectedVersion?.items[current.id]?.state === "failed" ? "\u7EE7\u7EED\u672A\u5B8C\u6210\u5206\u7247" : latest[current.id] ? "\u91CD\u65B0\u62BD\u53D6" : "\u62BD\u53D6"
26316
29130
  ] })
26317
29131
  ] })
26318
29132
  ] }),
26319
- error && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwNotice kwNotice-error", role: "alert", children: [
26320
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(CircleAlert, { size: 13 }),
26321
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: error })
29133
+ error && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("p", { className: "kwNotice kwNotice-error", role: "alert", children: [
29134
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(CircleAlert, { size: 13 }),
29135
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { children: error })
26322
29136
  ] }),
26323
- !selectedVersion ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwEmpty", children: [
26324
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwEmptyIcon", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Inbox, { size: 16 }) }),
26325
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: "\u8FD9\u4EFD\u6587\u6863\u8FD8\u6CA1\u6709\u62BD\u53D6\u8BB0\u5F55" }),
26326
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: "\u70B9\u53F3\u4E0A\u89D2\u300C\u62BD\u53D6\u300D\u6309\u5F53\u524D\u539F\u6587\u8DD1\u4E00\u6B21\uFF1B\u8FD0\u884C\u7ED3\u675F\u540E\u7ED3\u679C\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002" })
26327
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
26328
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwVersionBar", children: [
26329
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: "\u62BD\u53D6\u7248\u672C" }),
26330
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "kwVersionPick", children: history.length <= 8 ? history.map((version) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("button", { type: "button", className: "kwVersionChip", "aria-pressed": version.id === selected, "aria-label": `\u62BD\u53D6\u7248\u672C v${version.documentVersion}`, title: `\u62BD\u53D6 v${version.documentVersion} \xB7 ${PIPELINE_STATE_LABEL[version.state]} \xB7 ${formatDateTime(version.createdAt)}`, onClick: () => setSelected(version.id), children: [
29137
+ !selectedVersion ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwEmpty", children: [
29138
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "kwEmptyIcon", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Inbox, { size: 16 }) }),
29139
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u8FD9\u4EFD\u6587\u6863\u8FD8\u6CA1\u6709\u62BD\u53D6\u8BB0\u5F55" }),
29140
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { children: "\u70B9\u53F3\u4E0A\u89D2\u300C\u62BD\u53D6\u300D\u6309\u5F53\u524D\u539F\u6587\u8DD1\u4E00\u6B21\uFF1B\u8FD0\u884C\u7ED3\u675F\u540E\u7ED3\u679C\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002" })
29141
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_jsx_runtime52.Fragment, { children: [
29142
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwVersionBar", children: [
29143
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("strong", { children: "\u62BD\u53D6\u7248\u672C" }),
29144
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "kwVersionPick", children: history.length <= 8 ? history.map((version) => /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("button", { type: "button", className: "kwVersionChip", "aria-pressed": version.id === selected, "aria-label": `\u62BD\u53D6\u7248\u672C v${version.documentVersion}`, title: `\u62BD\u53D6 v${version.documentVersion} \xB7 ${PIPELINE_STATE_LABEL[version.state]} \xB7 ${formatDateTime(version.createdAt)}`, onClick: () => setSelected(version.id), children: [
26331
29145
  "v",
26332
29146
  version.documentVersion
26333
- ] }, version.id)) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(SelectMenu, { size: "sm", "aria-label": "\u9009\u62E9\u6587\u6863\u62BD\u53D6\u7248\u672C", value: selected, onValueChange: setSelected, options: history.map((version) => ({ value: version.id, label: `\u62BD\u53D6 v${version.documentVersion} \xB7 ${PIPELINE_STATE_LABEL[version.state]} \xB7 ${formatDateTime(version.createdAt)}` })) }) }),
26334
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: formatDateTime(selectedVersion.createdAt) }),
26335
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { children: [
29147
+ ] }, version.id)) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(SelectMenu, { size: "sm", "aria-label": "\u9009\u62E9\u6587\u6863\u62BD\u53D6\u7248\u672C", value: selected, onValueChange: setSelected, options: history.map((version) => ({ value: version.id, label: `\u62BD\u53D6 v${version.documentVersion} \xB7 ${PIPELINE_STATE_LABEL[version.state]} \xB7 ${formatDateTime(version.createdAt)}` })) }) }),
29148
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { children: formatDateTime(selectedVersion.createdAt) }),
29149
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { children: [
26336
29150
  "\u539F\u6587 v",
26337
29151
  selectedVersion.sources.find((source) => source.id === current.id)?.version ?? "\u672A\u77E5"
26338
29152
  ] })
26339
29153
  ] }),
26340
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Tabs3, { value: detailTab, onValueChange: setDetailTab, children: [
26341
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "kwTabsRow", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(TabsList3, { "aria-label": "\u6587\u6863\u62BD\u53D6\u8BE6\u60C5", children: [
26342
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TabsTrigger3, { value: "result", children: "\u62BD\u53D6\u7ED3\u679C" }),
26343
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TabsTrigger3, { value: "logs", children: "\u7248\u672C\u4E0E\u65E5\u5FD7" }),
26344
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TabsTrigger3, { value: "source", children: "\u539F\u6587" })
29154
+ selectedVersion.items[current.id]?.state === "failed" && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwNotice kwNotice-error", role: "status", children: [
29155
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TriangleAlert, { size: 13 }),
29156
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { children: selectedVersion.items[current.id]?.summary ?? "\u4E0A\u4E00\u8F6E\u62BD\u53D6\u6CA1\u6709\u5B8C\u6210\uFF1B\u5DF2\u4FDD\u5B58\u7684\u5206\u7247\u4F1A\u590D\u7528\uFF0C\u7EE7\u7EED\u53EA\u8DD1\u672A\u5B8C\u6210\u90E8\u5206\u3002" }),
29157
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { className: "kwNoticeAction", size: "sm", variant: "ghost", disabled: busy || startBlocked, onClick: () => void run(current.id), children: "\u7EE7\u7EED\u672A\u5B8C\u6210\u5206\u7247" })
29158
+ ] }),
29159
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(Tabs3, { value: detailTab, onValueChange: setDetailTab, children: [
29160
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "kwTabsRow", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(TabsList3, { "aria-label": "\u6587\u6863\u62BD\u53D6\u8BE6\u60C5", children: [
29161
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TabsTrigger3, { value: "read", children: "\u539F\u6587\u5BF9\u7167" }),
29162
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TabsTrigger3, { value: "logs", children: "\u7248\u672C\u4E0E\u65E5\u5FD7" })
26345
29163
  ] }) }),
26346
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(TabsContent3, { value: "result", children: [
26347
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwResultBar", children: [
26348
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "kwResultSummary", children: [
26349
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: knowledge.length }),
26350
- " \u6761\u77E5\u8BC6 ",
26351
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: "\xB7" }),
26352
- " ",
26353
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: cases.length }),
26354
- " \u6761\u6848\u4F8B"
26355
- ] }),
26356
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwChips", children: [
26357
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("button", { type: "button", className: "kwChip", "aria-pressed": kindFilter === "all", onClick: () => setKindFilter("all"), children: [
26358
- "\u5168\u90E8 ",
26359
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("i", { children: knowledge.length + cases.length })
26360
- ] }),
26361
- KIND_ORDER.filter((kind) => (kindCounts.get(kind) ?? 0) > 0).map((kind) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("button", { type: "button", className: "kwChip", "aria-pressed": kindFilter === kind, onClick: () => setKindFilter(kind), children: [
26362
- KIND_LABEL3[kind],
26363
- " ",
26364
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("i", { children: kindCounts.get(kind) })
26365
- ] }, kind))
26366
- ] }),
26367
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "kwSearch", children: [
26368
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Search, { size: 12, "aria-hidden": "true" }),
26369
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Input, { value: resultQuery, placeholder: "\u5728\u7ED3\u679C\u91CC\u641C\u7D22", "aria-label": "\u5728\u7ED3\u679C\u91CC\u641C\u7D22", onChange: (event) => setResultQuery(event.target.value) })
26370
- ] }),
26371
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "icon", variant: "ghost", "aria-label": "\u590D\u5236\u5F53\u524D\u7ED3\u679C", title: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236\u5F53\u524D\u7ED3\u679C", disabled: rows.length === 0, onClick: () => void copyAll(), children: copied ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Check, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Copy, { size: 13 }) })
26372
- ] }),
26373
- selectedVersion.items[current.id]?.state === "failed" && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwNotice kwNotice-error", role: "status", children: [
26374
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TriangleAlert, { size: 13 }),
26375
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: "\u672C\u6B21\u62BD\u53D6\u5931\u8D25\uFF0C\u4E0B\u9762\u8FD9\u4EFD\u8FD4\u56DE\u5185\u5BB9\u672A\u751F\u6548\u3002" })
26376
- ] }),
26377
- coverageGaps.sections + coverageGaps.blocks + coverageGaps.rows > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwNotice kwNotice-warn", role: "status", children: [
26378
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TriangleAlert, { size: 13 }),
26379
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { children: [
26380
- "\u8986\u76D6\u81EA\u68C0\uFF1A",
26381
- [coverageGaps.sections > 0 ? `${coverageGaps.sections} \u4E2A\u4E8C\u7EA7\u6807\u9898` : "", coverageGaps.blocks > 0 ? `${coverageGaps.blocks} \u6BB5\u5185\u5BB9` : "", coverageGaps.rows > 0 ? `${coverageGaps.rows} \u884C\u8868\u683C` : ""].filter(Boolean).join("\u3001"),
26382
- "\u6CA1\u6709\u88AB\u4EFB\u4F55\u77E5\u8BC6\u5F15\u7528\u3002\u7F3A\u53E3\u5DF2\u5199\u5165\u65E5\u5FD7\u4E0E\u62A5\u544A\u4F8B\u5916\u3002"
26383
- ] })
26384
- ] }),
26385
- !detail && report === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwSkeleton", role: "status", "aria-label": "\u6B63\u5728\u8BFB\u53D6\u62BD\u53D6\u7ED3\u679C", children: [
26386
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwSkeletonRow" }),
26387
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwSkeletonRow" }),
26388
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwSkeletonRow" })
26389
- ] }) : rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwEmpty", children: [
26390
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwEmptyIcon", children: selectedVersion.state === "running" ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(LoaderCircle, { size: 16, className: "motion-safe:animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Inbox, { size: 16 }) }),
26391
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: knowledge.length + cases.length === 0 ? selectedVersion.state === "running" ? "\u6B63\u5728\u62BD\u53D6" : "\u8FD9\u4E00\u7248\u6CA1\u6709\u53EF\u5C55\u793A\u7684\u7ED3\u679C" : "\u6CA1\u6709\u5339\u914D\u7684\u7ED3\u679C" }),
26392
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: knowledge.length + cases.length === 0 ? selectedVersion.state === "running" ? "\u6A21\u578B\u8FD8\u5728\u8FD4\u56DE\u3002\u4FDD\u5B58\u4E0B\u6765\u7684\u5206\u7247\u4F1A\u5148\u51FA\u73B0\u5728\u300C\u7248\u672C\u4E0E\u65E5\u5FD7\u300D\u91CC\u3002" : "\u53EF\u80FD\u662F\u6A21\u578B\u6CA1\u6709\u62BD\u51FA\u5185\u5BB9\uFF0C\u6216\u5F15\u6587\u6838\u9A8C\u628A\u7ED3\u679C\u4E22\u6389\u4E86\u3002\u53BB\u300C\u7248\u672C\u4E0E\u65E5\u5FD7\u300D\u770B\u8FD9\u6B21\u8FD0\u884C\u7684\u539F\u56E0\u3002" : "\u6362\u4E2A\u5173\u952E\u8BCD\uFF0C\u6216\u628A\u7C7B\u578B\u5207\u56DE\u300C\u5168\u90E8\u300D\u3002" })
26393
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
26394
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("ol", { className: "kwResults", children: rows.map((row, index2) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("li", { className: "kwResult", children: [
26395
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwResultIndex", children: String(index2 + 1).padStart(3, "0") }),
26396
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwKind", "data-kind": row.kind, children: KIND_LABEL3[row.kind] ?? row.kind }),
26397
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwResultText", children: row.text })
26398
- ] }, row.id)) }),
26399
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwResultFoot", children: [
26400
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: rows.length === knowledge.length + cases.length ? `\u5171 ${rows.length} \u6761` : `\u7B5B\u9009\u51FA ${rows.length} \u6761\uFF0C\u5171 ${knowledge.length + cases.length} \u6761` }),
26401
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { children: [
26402
- "\u7B2C ",
26403
- selectedVersion.documentVersion,
26404
- " \u6B21\u62BD\u53D6 \xB7 ",
26405
- selectedVersion.reused > 0 ? `\u590D\u7528 ${selectedVersion.reused} \u6761` : "\u672C\u6B21\u65B0\u62BD"
26406
- ] })
26407
- ] })
26408
- ] })
26409
- ] }),
26410
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TabsContent3, { value: "logs", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwLog", children: [
26411
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h3", { children: "\u62BD\u53D6\u65E5\u5FD7" }),
26412
- detail?.log.events.filter((event) => event.kind !== "report").length ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("ol", { className: "kwTimeline", children: detail.log.events.filter((event) => event.kind !== "report").map((event) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("li", { "data-warn": event.kind === "warning" || void 0, children: [
26413
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("time", { children: formatDateTime(event.at) }),
26414
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: event.text })
26415
- ] }, event.seq)) }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwHint", children: selectedVersion.state === "running" ? "\u6B63\u5728\u8FD0\u884C\uFF0C\u4E8B\u4EF6\u4F1A\u9646\u7EED\u51FA\u73B0\u5728\u8FD9\u91CC\u3002" : "\u8FD9\u4E00\u7248\u6CA1\u6709\u9636\u6BB5\u4E8B\u4EF6\u3002" }),
26416
- detail?.log.hasMore && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "sm", variant: "outline", onClick: () => void loadMoreLog(), children: "\u52A0\u8F7D\u66F4\u591A\u65E5\u5FD7" }),
26417
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h3", { children: "\u539F\u59CB\u6A21\u578B\u8F93\u5165\u4E0E\u8F93\u51FA" }),
26418
- detail?.calls.length ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "kwCalls", children: detail.calls.map((call, index2) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("details", { className: "kwCall", children: [
26419
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("summary", { children: [
26420
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("strong", { children: [
29164
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TabsContent3, { value: "read", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
29165
+ ReadingView,
29166
+ {
29167
+ kb,
29168
+ docId: current.id,
29169
+ docTitle: current.title,
29170
+ currentVersion: current.version,
29171
+ sourceVersion: selectedVersion.sources.find((source) => source.id === current.id)?.version,
29172
+ report,
29173
+ running: selectedVersion.state === "running",
29174
+ failed: selectedVersion.items[current.id]?.state === "failed"
29175
+ }
29176
+ ) }),
29177
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TabsContent3, { value: "logs", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwLog", children: [
29178
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("h3", { children: "\u62BD\u53D6\u65E5\u5FD7" }),
29179
+ detail?.log.events.filter((event) => event.kind !== "report").length ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("ol", { className: "kwTimeline", children: detail.log.events.filter((event) => event.kind !== "report").map((event) => /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("li", { "data-warn": event.kind === "warning" || void 0, children: [
29180
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("time", { children: formatDateTime(event.at) }),
29181
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { children: event.text })
29182
+ ] }, event.seq)) }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "kwHint", children: selectedVersion.state === "running" ? "\u6B63\u5728\u8FD0\u884C\uFF0C\u4E8B\u4EF6\u4F1A\u9646\u7EED\u51FA\u73B0\u5728\u8FD9\u91CC\u3002" : "\u8FD9\u4E00\u7248\u6CA1\u6709\u9636\u6BB5\u4E8B\u4EF6\u3002" }),
29183
+ detail?.log.hasMore && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { size: "sm", variant: "outline", onClick: () => void loadMoreLog(), children: "\u52A0\u8F7D\u66F4\u591A\u65E5\u5FD7" }),
29184
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("h3", { children: "\u539F\u59CB\u6A21\u578B\u8F93\u5165\u4E0E\u8F93\u51FA" }),
29185
+ detail?.calls.length ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "kwCalls", children: detail.calls.map((call, index2) => /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("details", { className: "kwCall", children: [
29186
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("summary", { children: [
29187
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("strong", { children: [
26421
29188
  "\u8BF7\u6C42 ",
26422
29189
  callPage * 100 + index2 + 1,
26423
29190
  call.objectTitle ? ` \xB7 ${call.objectTitle}` : ""
26424
29191
  ] }),
26425
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Badge, { tone: call.state === "failed" ? "warning" : call.state === "running" ? "blue" : "success", children: call.state === "running" ? "\u8BF7\u6C42\u4E2D" : call.state === "failed" ? "\u5931\u8D25" : "\u5DF2\u8FD4\u56DE" }),
26426
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("small", { children: formatDateTime(call.at) })
29192
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Badge, { tone: call.state === "failed" ? "warning" : call.state === "running" ? "blue" : "success", children: call.state === "running" ? "\u8BF7\u6C42\u4E2D" : call.state === "failed" ? "\u5931\u8D25" : "\u5DF2\u8FD4\u56DE" }),
29193
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("small", { children: formatDateTime(call.at) })
26427
29194
  ] }),
26428
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "kwCallBody", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(RequestResponse, { request: call.request, response: call.response, error: call.error, pending: call.state === "running" }) })
26429
- ] }, call.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwHint", children: !detail ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u8BB0\u5F55\u2026" : selectedVersion.reused > 0 ? "\u8FD9\u4E00\u7248\u590D\u7528\u4E0A\u6B21\u7ED3\u679C\uFF0C\u6CA1\u6709\u65B0\u7684\u6A21\u578B\u8BF7\u6C42\u3002" : selectedVersion.state === "running" ? "\u7B49\u5F85\u7B2C\u4E00\u4E2A\u6A21\u578B\u8BF7\u6C42\u3002" : "\u8FD9\u4E00\u7248\u6CA1\u6709\u8BB0\u5F55\u6A21\u578B\u8BF7\u6C42\u3002" }),
26430
- detail && detail.total > 100 && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwPager", children: [
26431
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "sm", variant: "outline", disabled: callPage === 0, onClick: () => setCallPage((page) => page - 1), children: "\u4E0A\u4E00\u9875" }),
26432
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { children: [
29195
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "kwCallBody", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(RequestResponse, { request: call.request, response: call.response, error: call.error, pending: call.state === "running" }) })
29196
+ ] }, call.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "kwHint", children: !detail ? "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u8BB0\u5F55\u2026" : selectedVersion.reused > 0 ? "\u8FD9\u4E00\u7248\u590D\u7528\u4E0A\u6B21\u7ED3\u679C\uFF0C\u6CA1\u6709\u65B0\u7684\u6A21\u578B\u8BF7\u6C42\u3002" : selectedVersion.state === "running" ? "\u7B49\u5F85\u7B2C\u4E00\u4E2A\u6A21\u578B\u8BF7\u6C42\u3002" : "\u8FD9\u4E00\u7248\u6CA1\u6709\u8BB0\u5F55\u6A21\u578B\u8BF7\u6C42\u3002" }),
29197
+ detail && detail.total > 100 && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "kwPager", children: [
29198
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { size: "sm", variant: "outline", disabled: callPage === 0, onClick: () => setCallPage((page) => page - 1), children: "\u4E0A\u4E00\u9875" }),
29199
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("span", { children: [
26433
29200
  callPage + 1,
26434
29201
  " / ",
26435
29202
  Math.ceil(detail.total / 100)
26436
29203
  ] }),
26437
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "sm", variant: "outline", disabled: (callPage + 1) * 100 >= detail.total, onClick: () => setCallPage((page) => page + 1), children: "\u4E0B\u4E00\u9875" })
29204
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Button, { size: "sm", variant: "outline", disabled: (callPage + 1) * 100 >= detail.total, onClick: () => setCallPage((page) => page + 1), children: "\u4E0B\u4E00\u9875" })
26438
29205
  ] })
26439
- ] }) }),
26440
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TabsContent3, { value: "source", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwLog", children: [
26441
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h3", { children: "\u8FD9\u6B21\u62BD\u53D6\u8BFB\u7684\u662F\u54EA\u4E00\u7248\u539F\u6587" }),
26442
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwHint", children: [
26443
- "\u672C\u6B21\u4F7F\u7528\u539F\u6587 v",
26444
- selectedVersion.sources.find((source) => source.id === current.id)?.version ?? "\u672A\u77E5",
26445
- "\u3002",
26446
- selectedVersion.sources.find((source) => source.id === current.id)?.version === current.version ? "\u4E0E\u5F53\u524D\u539F\u6587\u4E00\u81F4\u3002" : `\u5F53\u524D\u539F\u6587\u5DF2\u662F v${current.version}\uFF0C\u91CD\u8DD1\u540E\u7ED3\u679C\u624D\u4F1A\u8DDF\u4E0A\u3002`
26447
- ] }),
26448
- selectedVersion.sources.find((source) => source.id === current.id)?.version === current.version ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwHint", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("a", { href: `/knowledge/documents/${encodeURIComponent(current.id)}/view?${new URLSearchParams({ kb })}`, target: "_blank", rel: "noreferrer", children: [
26449
- "\u6253\u5F00\u539F\u6587",
26450
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(ExternalLink, { size: 11 })
26451
- ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwHint", children: "\u5386\u53F2\u539F\u6587\u8BF7\u4ECE\u6765\u6E90\u7684\u7248\u672C\u8BB0\u5F55\u67E5\u770B\u3002" })
26452
29206
  ] }) })
26453
29207
  ] })
26454
29208
  ] })
@@ -26456,6 +29210,172 @@ ${report.prompt.user}`;
26456
29210
  ] });
26457
29211
  }
26458
29212
 
29213
+ // src/client/NormalizeAxesPanel.tsx
29214
+ var import_react21 = __toESM(require_react(), 1);
29215
+ var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
29216
+ var KIND_LABEL4 = { object: "\u5BF9\u8C61", action: "\u52A8\u4F5C", scene: "\u573A\u666F" };
29217
+ var OUTCOME_LABEL2 = {
29218
+ matched: "\u5DF2\u5339\u914D",
29219
+ new: "\u65B0\u5EFA\u5019\u9009",
29220
+ ambiguous: "\u4ECD\u6709\u6B67\u4E49",
29221
+ "no-registry": "\u672A\u67E5\u6CE8\u518C\u8868"
29222
+ };
29223
+ var OUTCOME_TONE = {
29224
+ matched: "success",
29225
+ new: "blue",
29226
+ ambiguous: "warning",
29227
+ "no-registry": "neutral"
29228
+ };
29229
+ function NormalizeAxesPanel({ kb, sources, initialSource, version, onOpenSettings }) {
29230
+ const [source, setSource] = (0, import_react21.useState)(initialSource ?? sources[0]?.id ?? "");
29231
+ const [view, setView] = (0, import_react21.useState)(null);
29232
+ const [loading, setLoading] = (0, import_react21.useState)(false);
29233
+ const [error, setError] = (0, import_react21.useState)("");
29234
+ (0, import_react21.useEffect)(() => {
29235
+ if (source === "" && sources.length > 0) setSource(sources[0].id);
29236
+ }, [source, sources]);
29237
+ (0, import_react21.useEffect)(() => {
29238
+ if (source === "") return;
29239
+ let cancelled = false;
29240
+ setLoading(true);
29241
+ setError("");
29242
+ void requestJson(`/knowledge/normalize-axes?${new URLSearchParams({ kb, source })}`).then((result) => {
29243
+ if (!cancelled) setView(result.data ?? null);
29244
+ }).catch((cause) => {
29245
+ if (!cancelled) {
29246
+ setView(null);
29247
+ setError(cause instanceof Error ? cause.message : String(cause));
29248
+ }
29249
+ }).finally(() => {
29250
+ if (!cancelled) setLoading(false);
29251
+ });
29252
+ return () => {
29253
+ cancelled = true;
29254
+ };
29255
+ }, [kb, source, version]);
29256
+ const axes = (0, import_react21.useMemo)(() => view === null ? [] : [
29257
+ ...view.objects.map((axis) => ({ kind: "object", axis })),
29258
+ ...view.actions.map((axis) => ({ kind: "action", axis })),
29259
+ ...view.scenes.map((axis) => ({ kind: "scene", axis }))
29260
+ ], [view]);
29261
+ const counts = (0, import_react21.useMemo)(() => {
29262
+ const map = /* @__PURE__ */ new Map();
29263
+ for (const { axis } of axes) map.set(axis.outcome, (map.get(axis.outcome) ?? 0) + 1);
29264
+ return map;
29265
+ }, [axes]);
29266
+ const groups = (0, import_react21.useMemo)(() => {
29267
+ const map = /* @__PURE__ */ new Map();
29268
+ for (const { kind, axis } of axes) {
29269
+ const target = axis.outcome === "matched" && axis.existing ? axis.existing : axis.name;
29270
+ const key = `${kind}\0${target}`;
29271
+ if (!map.has(key)) map.set(key, { kind, target, axes: [] });
29272
+ map.get(key).axes.push(axis);
29273
+ }
29274
+ return [...map.values()].map((group) => ({ ...group, names: [...new Set(group.axes.map((axis) => axis.name))] })).filter((group) => group.names.length > 1 || group.names[0] !== void 0 && group.names[0] !== group.target);
29275
+ }, [axes]);
29276
+ const newAxes = (0, import_react21.useMemo)(() => axes.filter((entry) => entry.axis.outcome === "new"), [axes]);
29277
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("section", { className: "kwAxes", "aria-label": "\u5F52\u4E00\u5750\u6807\u660E\u7EC6", children: [
29278
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("header", { className: "kwAxesHead", children: [
29279
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { children: [
29280
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h3", { children: "\u5750\u6807\u5F52\u4E00\u660E\u7EC6" }),
29281
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: "\u8FD9\u4E00\u7248\u628A\u539F\u6587\u91CC\u7684\u53EB\u6CD5\u7ED1\u5230\u54EA\u4E9B\u5750\u6807\uFF1B\u6B67\u4E49\u9879\u4FDD\u7559\u539F\u56E0\u4E0E\u5019\u9009\u3002" })
29282
+ ] }),
29283
+ sources.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(SelectMenu, { size: "sm", "aria-label": "\u9009\u62E9\u8981\u67E5\u770B\u7684\u6587\u6863", value: source, onValueChange: setSource, options: sources.map((item) => ({ value: item.id, label: item.title })) })
29284
+ ] }),
29285
+ loading && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwAxesState", children: [
29286
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(LoaderCircle, { size: 13, className: "motion-safe:animate-spin" }),
29287
+ "\u6B63\u5728\u8BFB\u5F52\u4E00\u7ED3\u679C\u2026"
29288
+ ] }),
29289
+ error !== "" && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwAxesState", "data-tone": "error", children: [
29290
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(CircleAlert, { size: 13 }),
29291
+ error
29292
+ ] }),
29293
+ !loading && error === "" && view === null && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwAxesState", children: "\u8FD9\u4EFD\u6587\u6863\u8FD8\u6CA1\u6709\u5F52\u4E00\u7ED3\u679C\u3002\u5148\u8FD0\u884C\u4E00\u6B21\u5F52\u4E00\u3002" }),
29294
+ view !== null && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
29295
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwAxesSummary", children: [
29296
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { children: [
29297
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: axes.length }),
29298
+ " \u4E2A\u5750\u6807 mention"
29299
+ ] }),
29300
+ ["matched", "new", "ambiguous", "no-registry"].filter((outcome) => (counts.get(outcome) ?? 0) > 0).map((outcome) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { "data-tone": OUTCOME_TONE[outcome], children: [
29301
+ OUTCOME_LABEL2[outcome],
29302
+ " ",
29303
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: counts.get(outcome) })
29304
+ ] }, outcome)),
29305
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "kwAxesSource", children: [
29306
+ "\u539F\u6587 v",
29307
+ view.source.version ?? "?",
29308
+ " \xB7 ",
29309
+ view.source.title
29310
+ ] })
29311
+ ] }),
29312
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwAxesTip", children: [
29313
+ "\u6B67\u4E49\u9879\u4F1A\u5217\u51FA\u5019\u9009\u4E0E\u539F\u56E0\uFF1B\u786E\u8BA4\u6216\u5408\u5E76\u5B9E\u4F53\u540E\u91CD\u8DD1\u5F52\u4E00\u3002",
29314
+ onOpenSettings !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("button", { type: "button", className: "kwAxesLink", onClick: onOpenSettings, children: "\u6253\u5F00\u5750\u6807\u5B9E\u4F53" })
29315
+ ] }),
29316
+ groups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwAxesNone", children: "\u672C\u6B21\u6CA1\u6709\u9700\u8981\u5408\u5E76\u7684\u522B\u540D\uFF1B\u65B0\u5EFA\u5019\u9009\u89C1\u4E0B\u3002" }),
29317
+ groups.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwAxesGroup", children: [
29318
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("h4", { children: [
29319
+ "\u672C\u6B21\u8981\u5408\u5E76\u7684\u5750\u6807 ",
29320
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: groups.length })
29321
+ ] }),
29322
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("ul", { children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("li", { children: [
29323
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwAxesKind", children: KIND_LABEL4[group.kind] }),
29324
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: group.target }),
29325
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwAxesArrow", "aria-hidden": "true", children: "\u2190" }),
29326
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwAxesMentions", children: group.names.join("\u3001") })
29327
+ ] }, `${group.kind}-${group.target}`)) })
29328
+ ] }),
29329
+ newAxes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwAxesGroup", children: [
29330
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("h4", { children: [
29331
+ "\u672C\u6B21\u65B0\u5EFA\u7684\u5750\u6807 ",
29332
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: newAxes.length })
29333
+ ] }),
29334
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("ul", { children: newAxes.map(({ kind, axis }) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("li", { children: [
29335
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwAxesKind", children: KIND_LABEL4[kind] }),
29336
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: axis.name }),
29337
+ axis.definition !== void 0 && axis.definition !== "" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "kwAxesMentions", children: axis.definition })
29338
+ ] }, `new-${kind}-${axis.name}`)) })
29339
+ ] }),
29340
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "kwAxesScroll", children: ["object", "action", "scene"].map((kind) => {
29341
+ const rows = axes.filter((entry) => entry.kind === kind);
29342
+ if (rows.length === 0) return null;
29343
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwAxesGroup", children: [
29344
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("h4", { children: [
29345
+ KIND_LABEL4[kind],
29346
+ " ",
29347
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children: rows.length })
29348
+ ] }),
29349
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("ul", { children: rows.map(({ axis }) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("li", { className: "kwAxesRow", children: [
29350
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "kwAxesRowHead", children: [
29351
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("strong", { children: axis.name }),
29352
+ axis.outcome === "matched" && axis.existing && axis.existing !== axis.name && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "kwAxesTarget", children: [
29353
+ "\u2192 ",
29354
+ axis.existing
29355
+ ] }),
29356
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Badge, { tone: OUTCOME_TONE[axis.outcome] ?? "neutral", children: OUTCOME_LABEL2[axis.outcome] ?? axis.outcome })
29357
+ ] }),
29358
+ axis.definition !== void 0 && axis.definition !== "" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { children: axis.definition }),
29359
+ axis.evidence !== void 0 && axis.evidence !== "" && !/^q\d+(\s+q\d+)*$/.test(axis.evidence.trim()) && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwAxesEvidence", children: [
29360
+ "\u8BC1\u636E\uFF1A",
29361
+ axis.evidence.replace(/\s+/g, " ").slice(0, 240)
29362
+ ] }),
29363
+ axis.context !== void 0 && axis.context !== "" && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwAxesEvidence", children: [
29364
+ "\u539F\u6587\u4E0A\u4E0B\u6587\uFF1A",
29365
+ axis.context.replace(/\s+/g, " ").slice(0, 260)
29366
+ ] }),
29367
+ axis.outcome !== "matched" && axis.how !== "" && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "kwAxesWhy", children: axis.how })
29368
+ ] }, `${kind}-${axis.name}`)) })
29369
+ ] }, kind);
29370
+ }) }),
29371
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("p", { className: "kwAxesHint", children: [
29372
+ "\u4ECD\u6709\u6B67\u4E49\u65F6\uFF1A\u5148\u5728\u300C\u7F16\u8BD1\u8BBE\u7F6E \u2192 \u5750\u6807\u5B9E\u4F53\u300D\u786E\u8BA4\u6216\u5408\u5E76\u5B9E\u4F53\uFF0C\u518D\u56DE\u6765\u91CD\u8DD1\u5F52\u4E00\u3002\u5750\u6807\u662F\u5F52\u4E00\u9636\u6BB5\u5199\u5B9A\u7684\uFF0C\u7269\u5316\u53EA\u8BFB\u8FD9\u4EFD\u7ED3\u679C\u3002",
29373
+ onOpenSettings !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("button", { type: "button", className: "kwAxesLink", onClick: onOpenSettings, children: "\u6253\u5F00\u5750\u6807\u5B9E\u4F53" })
29374
+ ] })
29375
+ ] })
29376
+ ] });
29377
+ }
29378
+
26459
29379
  // src/client/ExtractionTasksPage.tsx
26460
29380
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
26461
29381
  var INPUT_TITLE = {
@@ -26492,37 +29412,37 @@ ${report.prompt.user}`;
26492
29412
  var label = (value) => value.stale && !active(value) ? "\u5F85\u91CD\u8DD1" : PIPELINE_STATE_LABEL[value.state];
26493
29413
  function ExtractionTasksPage({ kb }) {
26494
29414
  const params = new URLSearchParams(typeof window === "undefined" ? "" : window.location.search);
26495
- const [view, setView] = (0, import_react21.useState)(() => {
29415
+ const [view, setView] = (0, import_react22.useState)(() => {
26496
29416
  const wanted = params.get("view");
26497
29417
  return wanted === "settings" ? "settings" : wanted === "lineage" ? "lineage" : "run";
26498
29418
  });
26499
- const [stage, setStage] = (0, import_react21.useState)("extract");
26500
- const [adding, setAdding] = (0, import_react21.useState)(params.get("node") === "add");
26501
- const [focusDocument, setFocusDocument] = (0, import_react21.useState)(params.get("source") ?? "");
26502
- const [kbName, setKbName] = (0, import_react21.useState)("");
26503
- const [status, setStatus] = (0, import_react21.useState)();
26504
- const [heads, setHeads] = (0, import_react21.useState)([]);
26505
- const [versions, setVersions] = (0, import_react21.useState)([]);
26506
- const [selectedId, setSelectedId] = (0, import_react21.useState)("");
26507
- const [selectedDoc, setSelectedDoc] = (0, import_react21.useState)("");
26508
- const [sourceIds, setSourceIds] = (0, import_react21.useState)([]);
26509
- const [tasks, setTasks] = (0, import_react21.useState)([]);
26510
- const [calls, setCalls] = (0, import_react21.useState)([]);
26511
- const [events2, setEvents] = (0, import_react21.useState)([]);
26512
- const [logAfter, setLogAfter] = (0, import_react21.useState)(0);
26513
- const [logNext, setLogNext] = (0, import_react21.useState)(0);
26514
- const [logMore, setLogMore] = (0, import_react21.useState)(false);
26515
- const [callTotal, setCallTotal] = (0, import_react21.useState)(0);
26516
- const [callPage, setCallPage] = (0, import_react21.useState)(0);
26517
- const [versionPage, setVersionPage] = (0, import_react21.useState)(0);
26518
- const [busy, setBusy] = (0, import_react21.useState)(false);
26519
- const [notice, setNotice] = (0, import_react21.useState)(null);
26520
- const [settingsKey, setSettingsKey] = (0, import_react21.useState)(0);
26521
- const [loading, setLoading] = (0, import_react21.useState)(true);
26522
- const [callsLoading, setCallsLoading] = (0, import_react21.useState)(false);
26523
- const [callsError, setCallsError] = (0, import_react21.useState)("");
26524
- const [selectedDetail, setSelectedDetail] = (0, import_react21.useState)();
26525
- const sequence = (0, import_react21.useRef)(0);
29419
+ const [stage, setStage] = (0, import_react22.useState)("extract");
29420
+ const [adding, setAdding] = (0, import_react22.useState)(params.get("node") === "add");
29421
+ const [focusDocument, setFocusDocument] = (0, import_react22.useState)(params.get("source") ?? "");
29422
+ const [kbName, setKbName] = (0, import_react22.useState)("");
29423
+ const [status, setStatus] = (0, import_react22.useState)();
29424
+ const [heads, setHeads] = (0, import_react22.useState)([]);
29425
+ const [versions, setVersions] = (0, import_react22.useState)([]);
29426
+ const [selectedId, setSelectedId] = (0, import_react22.useState)("");
29427
+ const [selectedDoc, setSelectedDoc] = (0, import_react22.useState)("");
29428
+ const [sourceIds, setSourceIds] = (0, import_react22.useState)([]);
29429
+ const [tasks, setTasks] = (0, import_react22.useState)([]);
29430
+ const [calls, setCalls] = (0, import_react22.useState)([]);
29431
+ const [events2, setEvents] = (0, import_react22.useState)([]);
29432
+ const [logAfter, setLogAfter] = (0, import_react22.useState)(0);
29433
+ const [logNext, setLogNext] = (0, import_react22.useState)(0);
29434
+ const [logMore, setLogMore] = (0, import_react22.useState)(false);
29435
+ const [callTotal, setCallTotal] = (0, import_react22.useState)(0);
29436
+ const [callPage, setCallPage] = (0, import_react22.useState)(0);
29437
+ const [versionPage, setVersionPage] = (0, import_react22.useState)(0);
29438
+ const [busy, setBusy] = (0, import_react22.useState)(false);
29439
+ const [notice, setNotice] = (0, import_react22.useState)(null);
29440
+ const [settingsKey, setSettingsKey] = (0, import_react22.useState)(0);
29441
+ const [loading, setLoading] = (0, import_react22.useState)(true);
29442
+ const [callsLoading, setCallsLoading] = (0, import_react22.useState)(false);
29443
+ const [callsError, setCallsError] = (0, import_react22.useState)("");
29444
+ const [selectedDetail, setSelectedDetail] = (0, import_react22.useState)();
29445
+ const sequence = (0, import_react22.useRef)(0);
26526
29446
  const selected = versions.find((row) => row.id === selectedId) ?? (selectedDetail?.id === selectedId ? selectedDetail : void 0) ?? versions[0];
26527
29447
  const inputRows = stage === "materialize" ? (status?.groups ?? []).map((group) => ({
26528
29448
  id: group.key,
@@ -26540,7 +29460,7 @@ ${report.prompt.user}`;
26540
29460
  ...source.state === "pending" || source.state === "outdated" ? { waiting: true } : {}
26541
29461
  }));
26542
29462
  const head = heads.find((row) => row.stage === stage);
26543
- (0, import_react21.useEffect)(() => {
29463
+ (0, import_react22.useEffect)(() => {
26544
29464
  let cancelled = false;
26545
29465
  void requestJson("/knowledge/bases").then((result) => {
26546
29466
  if (!cancelled) setKbName(result.data?.bases.find((base) => base.id === kb)?.name ?? "");
@@ -26550,7 +29470,7 @@ ${report.prompt.user}`;
26550
29470
  cancelled = true;
26551
29471
  };
26552
29472
  }, [kb]);
26553
- const refresh = (0, import_react21.useCallback)(async () => {
29473
+ const refresh = (0, import_react22.useCallback)(async () => {
26554
29474
  if (!kb) {
26555
29475
  setLoading(false);
26556
29476
  return;
@@ -26576,7 +29496,7 @@ ${report.prompt.user}`;
26576
29496
  }
26577
29497
  }
26578
29498
  }, [kb, stage, versionPage]);
26579
- (0, import_react21.useEffect)(() => {
29499
+ (0, import_react22.useEffect)(() => {
26580
29500
  void refresh();
26581
29501
  const timer = window.setInterval(() => {
26582
29502
  void refresh();
@@ -26588,17 +29508,17 @@ ${report.prompt.user}`;
26588
29508
  window.removeEventListener("focus", refresh);
26589
29509
  };
26590
29510
  }, [refresh]);
26591
- (0, import_react21.useEffect)(() => {
29511
+ (0, import_react22.useEffect)(() => {
26592
29512
  setCallPage(0);
26593
29513
  setSelectedDoc("");
26594
29514
  setCalls([]);
26595
29515
  setEvents([]);
26596
29516
  setLogAfter(0);
26597
29517
  }, [selected?.id]);
26598
- (0, import_react21.useEffect)(() => {
29518
+ (0, import_react22.useEffect)(() => {
26599
29519
  setCalls([]);
26600
29520
  }, [selectedDoc, callPage]);
26601
- (0, import_react21.useEffect)(() => {
29521
+ (0, import_react22.useEffect)(() => {
26602
29522
  if (!selected) return;
26603
29523
  let cancelled = false;
26604
29524
  const read = async () => {
@@ -26692,6 +29612,7 @@ ${report.prompt.user}`;
26692
29612
  ] })
26693
29613
  ] });
26694
29614
  };
29615
+ const activeTask = tasks[0];
26695
29616
  const sources = status?.sources ?? [];
26696
29617
  const groups = status?.groups ?? [];
26697
29618
  const pendingSources = sources.filter((source) => source.state === "pending" || source.state === "outdated").length;
@@ -26789,7 +29710,7 @@ ${report.prompt.user}`;
26789
29710
  const Icon2 = STAGE_META[id].icon;
26790
29711
  const percentage = value?.total ? Math.round(value.done / value.total * 100) : value?.state === "succeeded" ? 100 : 0;
26791
29712
  const stageTone = value ? tone(value) : "neutral";
26792
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_react21.Fragment, { children: [
29713
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_react22.Fragment, { children: [
26793
29714
  index2 > 0 && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "kwBandArrow", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(ArrowRight, { size: 14 }) }),
26794
29715
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "kwGate", "data-on": stage === id || void 0, "data-tone": stageTone, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("button", { type: "button", className: "kwGateBtn", "aria-current": stage === id ? "step" : void 0, onClick: () => chooseStage(id), children: [
26795
29716
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { className: "kwGateTop", children: [
@@ -26812,6 +29733,16 @@ ${report.prompt.user}`;
26812
29733
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "kwScopeNow", children: scope.now }),
26813
29734
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "kwScopeKey", children: scope.key })
26814
29735
  ] }),
29736
+ activeTask && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("p", { className: "kwRunBusy", role: "status", children: [
29737
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(LoaderCircle, { size: 12, className: "motion-safe:animate-spin", "aria-hidden": "true" }),
29738
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { children: [
29739
+ "\u5DF2\u6709\u4EFB\u52A1\u5728\u8FD0\u884C\uFF1A",
29740
+ PIPELINE_STAGE_LABEL[activeTask.stage],
29741
+ "\uFF08",
29742
+ PIPELINE_STATE_LABEL[activeTask.state],
29743
+ "\uFF09\u3002\u7B49\u5B83\u7ED3\u675F\u540E\u624D\u80FD\u5F00\u59CB\u4E0B\u4E00\u6BB5\u3002"
29744
+ ] })
29745
+ ] }),
26815
29746
  stage === "extract" ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DocumentExtractionView, { kb, sources, initialSource: focusDocument || void 0, onRefresh: () => {
26816
29747
  void refresh();
26817
29748
  }, onLineage: (id) => {
@@ -26820,7 +29751,7 @@ ${report.prompt.user}`;
26820
29751
  }, onAddFile: () => {
26821
29752
  setAdding(true);
26822
29753
  setView("run");
26823
- } }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("section", { className: "kwStage", "aria-label": `${PIPELINE_STAGE_LABEL[stage]}\u8FD0\u884C\u8BBE\u7F6E`, children: [
29754
+ }, startBlocked: activeTask !== void 0 }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("section", { className: "kwStage", "aria-label": `${PIPELINE_STAGE_LABEL[stage]}\u8FD0\u884C\u8BBE\u7F6E`, children: [
26824
29755
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("header", { className: "kwStageHead", children: [
26825
29756
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "kwStageCopy", children: [
26826
29757
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("h2", { children: PIPELINE_STAGE_LABEL[stage] }),
@@ -26832,7 +29763,7 @@ ${report.prompt.user}`;
26832
29763
  " \xB7 v",
26833
29764
  head.version
26834
29765
  ] }),
26835
- /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Button, { size: "sm", disabled: busy || !status || !sources.length, onClick: () => {
29766
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(Button, { size: "sm", disabled: busy || !status || !sources.length || activeTask !== void 0, title: activeTask ? "\u5DF2\u6709\u4EFB\u52A1\u5728\u8FD0\u884C\uFF0C\u7B49\u5B83\u7ED3\u675F\u540E\u518D\u8BD5" : void 0, onClick: () => {
26836
29767
  void start(stage, true);
26837
29768
  }, children: [
26838
29769
  busy ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(LoaderCircle, { size: 12, className: "motion-safe:animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Play, { size: 12 }),
@@ -26844,6 +29775,7 @@ ${report.prompt.user}`;
26844
29775
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(CircleAlert, { size: 13 }),
26845
29776
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children: "\u4E0A\u6E38\u5DF2\u66F4\u65B0\u3002\u6B64\u8282\u70B9\u53CA\u540E\u7EED\u8282\u70B9\u9700\u8981\u91CD\u8DD1\uFF0C\u5386\u53F2\u7248\u672C\u7EE7\u7EED\u4FDD\u7559\u3002" })
26846
29777
  ] }),
29778
+ stage === "normalize" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(NormalizeAxesPanel, { kb, sources, initialSource: selected?.sources[0]?.id, version: head?.version, onOpenSettings: () => setView("settings") }),
26847
29779
  stage === "derive" && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("section", { className: "kwInput", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "kwInputHead", children: [
26848
29780
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("strong", { children: "\u672C\u6B65\u5BF9\u8C61\uFF1ACase" }),
26849
29781
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children: head ? `\u4E0A\u6B21 ${head.done} \u4E2A Case \xB7 \u590D\u7528 ${head.reused}` : "\u5C1A\u672A\u8FD0\u884C" })
@@ -26957,12 +29889,48 @@ ${report.prompt.user}`;
26957
29889
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("strong", { children: [
26958
29890
  "\u8BF7\u6C42 ",
26959
29891
  callPage * 10 + index2 + 1,
26960
- call.objectTitle ? ` \xB7 ${call.objectTitle}` : ""
29892
+ call.label ? ` \xB7 ${call.label}` : call.objectTitle ? ` \xB7 ${call.objectTitle}` : ""
26961
29893
  ] }),
26962
29894
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Badge, { tone: call.state === "failed" ? "warning" : call.state === "running" ? "blue" : "success", children: call.state === "running" ? "\u8BF7\u6C42\u4E2D" : call.state === "failed" ? "\u5931\u8D25" : "\u5DF2\u8FD4\u56DE" }),
26963
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("small", { children: formatDateTime(call.at) })
29895
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("small", { children: formatDateTime(call.at) }),
29896
+ call.usage !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("small", { className: "kwCallUsage", children: [
29897
+ "\u8F93\u5165 ",
29898
+ (call.usage.inputTokens ?? 0).toLocaleString("zh-CN"),
29899
+ " \xB7 \u8F93\u51FA ",
29900
+ (call.usage.outputTokens ?? 0).toLocaleString("zh-CN"),
29901
+ " \xB7 \u7F13\u5B58\u547D\u4E2D ",
29902
+ (call.usage.cacheReadTokens ?? 0).toLocaleString("zh-CN")
29903
+ ] })
26964
29904
  ] }),
26965
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "kwCallBody", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(RequestResponse, { request: call.request, response: call.response, error: call.error, pending: call.state === "running" }) })
29905
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "kwCallBody", children: [
29906
+ call.usage !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("dl", { className: "kwUsage", "aria-label": "\u672C\u6B21\u6A21\u578B token \u7528\u91CF", children: [
29907
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { children: [
29908
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dt", { children: "\u5408\u8BA1" }),
29909
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dd", { children: (call.usage.totalTokens ?? (call.usage.inputTokens ?? 0) + (call.usage.outputTokens ?? 0)).toLocaleString("zh-CN") })
29910
+ ] }),
29911
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { children: [
29912
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dt", { children: "\u8F93\u5165" }),
29913
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dd", { children: (call.usage.inputTokens ?? 0).toLocaleString("zh-CN") })
29914
+ ] }),
29915
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { children: [
29916
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dt", { children: "\u8F93\u51FA" }),
29917
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dd", { children: (call.usage.outputTokens ?? 0).toLocaleString("zh-CN") })
29918
+ ] }),
29919
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { children: [
29920
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dt", { children: "\u7F13\u5B58\u547D\u4E2D" }),
29921
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dd", { children: (call.usage.cacheReadTokens ?? 0).toLocaleString("zh-CN") })
29922
+ ] }),
29923
+ (call.usage.cacheWriteTokens ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { children: [
29924
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dt", { children: "\u7F13\u5B58\u5199\u5165" }),
29925
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dd", { children: (call.usage.cacheWriteTokens ?? 0).toLocaleString("zh-CN") })
29926
+ ] }),
29927
+ (call.usage.reasoningTokens ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { children: [
29928
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dt", { children: "\u63A8\u7406" }),
29929
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("dd", { children: (call.usage.reasoningTokens ?? 0).toLocaleString("zh-CN") })
29930
+ ] })
29931
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "kwUsageMissing", children: "\u8FD9\u6B21\u6CA1\u6709\u8FD4\u56DE token \u7528\u91CF\u3002" }),
29932
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(RequestResponse, { request: call.request, response: call.response, error: call.error, pending: call.state === "running" })
29933
+ ] })
26966
29934
  ] }, call.id)),
26967
29935
  callTotal > 10 && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "kwPager", children: [
26968
29936
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Button, { size: "sm", variant: "outline", disabled: callPage === 0, onClick: () => setCallPage((page) => page - 1), children: "\u4E0A\u4E00\u9875\u8BF7\u6C42" }),
@@ -27046,19 +30014,19 @@ ${report.prompt.user}`;
27046
30014
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PageShell, { title, column: "help", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "page-state", children }) });
27047
30015
  }
27048
30016
  function TrialPage({ kb }) {
27049
- const [documents, setDocuments] = (0, import_react22.useState)(null);
27050
- const [kbName, setKbName] = (0, import_react22.useState)("");
27051
- const [failure, setFailure] = (0, import_react22.useState)("");
27052
- (0, import_react22.useEffect)(() => {
30017
+ const [documents, setDocuments] = (0, import_react23.useState)(null);
30018
+ const [kbName, setKbName] = (0, import_react23.useState)("");
30019
+ const [failure, setFailure] = (0, import_react23.useState)("");
30020
+ (0, import_react23.useEffect)(() => {
27053
30021
  let cancelled = false;
27054
30022
  void (async () => {
27055
30023
  try {
27056
- const [list, bases] = await Promise.all([
30024
+ const [list2, bases] = await Promise.all([
27057
30025
  getJson(`/knowledge/documents?kb=${encodeURIComponent(kb)}&limit=200`),
27058
30026
  getJson("/knowledge/bases")
27059
30027
  ]);
27060
30028
  if (cancelled) return;
27061
- setDocuments((list.documents ?? []).map((item) => ({ docId: item.docId, title: item.title })));
30029
+ setDocuments((list2.documents ?? []).map((item) => ({ docId: item.docId, title: item.title })));
27062
30030
  setKbName(bases.bases?.find((base) => base.id === kb)?.name ?? kb);
27063
30031
  } catch (cause) {
27064
30032
  if (cancelled) return;
@@ -27091,13 +30059,13 @@ ${report.prompt.user}`;
27091
30059
  ] });
27092
30060
  }
27093
30061
  function RunPage({ kb, runId }) {
27094
- const [run, setRun] = (0, import_react22.useState)(null);
27095
- const [failure, setFailure] = (0, import_react22.useState)("");
27096
- (0, import_react22.useEffect)(() => {
30062
+ const [run, setRun] = (0, import_react23.useState)(null);
30063
+ const [failure, setFailure] = (0, import_react23.useState)("");
30064
+ (0, import_react23.useEffect)(() => {
27097
30065
  if (kb === "" || runId === "") return void 0;
27098
30066
  let cancelled = false;
27099
- void requestExtractionRun({ kb, id: runId }).then((record) => {
27100
- if (!cancelled) setRun(record);
30067
+ void requestExtractionRun({ kb, id: runId }).then((record2) => {
30068
+ if (!cancelled) setRun(record2);
27101
30069
  }).catch((cause) => {
27102
30070
  if (!cancelled) setFailure(cause instanceof Error ? cause.message : String(cause));
27103
30071
  });
@@ -27185,7 +30153,7 @@ ${report.prompt.user}`;
27185
30153
  ] });
27186
30154
  }
27187
30155
  var container = document.getElementById("tita-page-root");
27188
- if (container !== null) (0, import_client.createRoot)(container).render(/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react22.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(App, {}) }));
30156
+ if (container !== null) (0, import_client.createRoot)(container).render(/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react23.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(App, {}) }));
27189
30157
  })();
27190
30158
  /*! Bundled license information:
27191
30159