@jingyi0605/codingns 0.9.0 → 0.9.5

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 (224) hide show
  1. package/dist/public/assets/{AdaptiveButlerPage-B17QiMyT.js → AdaptiveButlerPage-kkJDsnCO.js} +2 -2
  2. package/dist/public/assets/{App-CFBwDUNA.js → App-DrNI9lWA.js} +6 -6
  3. package/dist/public/assets/{BootstrapPage-W5wU3BPh.js → BootstrapPage-QgVH5Mps.js} +1 -1
  4. package/dist/public/assets/{ConversationPage-DQLX1bUh.js → ConversationPage-DVk8VfIj.js} +1 -1
  5. package/dist/public/assets/{DesktopDetachPreviewPage-DTPeuAW-.js → DesktopDetachPreviewPage-BhfP0TpH.js} +1 -1
  6. package/dist/public/assets/{DesktopModal-6ii53_Y9.js → DesktopModal-DRmDrv0S.js} +1 -1
  7. package/dist/public/assets/DesktopWindowPage-DNbJXnSs.js +2 -0
  8. package/dist/public/assets/FileContextPanel---fLO4ve.js +1 -0
  9. package/dist/public/assets/GitSidebar-sXUE0TqT.js +6 -0
  10. package/dist/public/assets/MobileCreateSessionSheet-BftZ5pvb.js +1 -0
  11. package/dist/public/assets/{MobileSheet-opTWyRe1.js → MobileSheet-nw5SCa3N.js} +1 -1
  12. package/dist/public/assets/{MobileTopHeaderFrame-BbNON3Y4.js → MobileTopHeaderFrame-DH_D02Wy.js} +1 -1
  13. package/dist/public/assets/{MobileWorkspaceSwitcherHeader-BZEzPeMj.js → MobileWorkspaceSwitcherHeader-2K406G5p.js} +1 -1
  14. package/dist/public/assets/{PluginAccessOverview-mQDmAljp.js → PluginAccessOverview-BVJihw3D.js} +1 -1
  15. package/dist/public/assets/{PluginContainerPage-CcxUJpM4.js → PluginContainerPage-CR4vStvr.js} +1 -1
  16. package/dist/public/assets/{PluginDetailPage-D5--ACIt.js → PluginDetailPage-CrMX0Mnm.js} +1 -1
  17. package/dist/public/assets/{PluginsListPage-D_oJxYXT.js → PluginsListPage-FtIL71Yg.js} +1 -1
  18. package/dist/public/assets/{RelayConnectEntryPage-DROxpnkv.js → RelayConnectEntryPage-Bt1apX53.js} +1 -1
  19. package/dist/public/assets/{ServerSettingsModal-CUUOPqSe.js → ServerSettingsModal-D-guzPrI.js} +1 -1
  20. package/dist/public/assets/{SessionIndexPage-C2Jxh6Gp.js → SessionIndexPage-CX2FppcJ.js} +1 -1
  21. package/dist/public/assets/SettingsPage-BI2Olcvr.js +2 -0
  22. package/dist/public/assets/TerminalManagerPanel-B5MKGPy-.js +1 -0
  23. package/dist/public/assets/{TerminalPage-CwWyFDj8.js → TerminalPage-C2dTNGHK.js} +1 -1
  24. package/dist/public/assets/{TerminalRuntimeFallbackModal-CSVVbO8r.js → TerminalRuntimeFallbackModal-DAqOxFD8.js} +1 -1
  25. package/dist/public/assets/{ToolFilesPage-QBEY8oCf.js → ToolFilesPage-IsNwyE6T.js} +1 -1
  26. package/dist/public/assets/{ToolGitPage-BKoZ2l9v.js → ToolGitPage-BK1JBERN.js} +1 -1
  27. package/dist/public/assets/{ToolProcessesPage-BOH0ib4G.js → ToolProcessesPage-DwTYUQCK.js} +1 -1
  28. package/dist/public/assets/{ToolsHomePage-BcMZ3BCQ.js → ToolsHomePage-BLOy7lPg.js} +1 -1
  29. package/dist/public/assets/{WorkbenchLandingPage-B5zoppEl.js → WorkbenchLandingPage-CqZKR6EA.js} +1 -1
  30. package/dist/public/assets/WorkbenchLayout-CJHQtwuL.js +1022 -0
  31. package/dist/public/assets/{WorkbenchModal-NGmPgqaE.js → WorkbenchModal-BM-OeW-b.js} +1 -1
  32. package/dist/public/assets/WorkbenchShellRoute-2bKI6Q9k.js +1 -0
  33. package/dist/public/assets/WorkbenchShellRoute-BjuZD101.css +1 -0
  34. package/dist/public/assets/WorkspaceDebugDetailPage-BMsEN5iG.js +1 -0
  35. package/dist/public/assets/WorkspaceDetailPage-5H9Gosx2.js +1 -0
  36. package/dist/public/assets/WorkspaceHomePage-DQiXKgiP.js +1 -0
  37. package/dist/public/assets/{client-runtime-manager-DXbI9K1K.js → client-runtime-manager-CgPJq21V.js} +1 -1
  38. package/dist/public/assets/index-BARqMVSw.css +1 -0
  39. package/dist/public/assets/index-BUoNjVrY.js +50 -0
  40. package/dist/public/assets/{login-direct-candidate-resolver-DkKyFtQJ.js → login-direct-candidate-resolver-CGaxAXV8.js} +1 -1
  41. package/dist/public/assets/{plugin-permission-copy-CzN269Bk.js → plugin-permission-copy-BR9gWy8b.js} +1 -1
  42. package/dist/public/assets/{plugins-api-Bv9DHpLF.js → plugins-api-CdCsrG2e.js} +1 -1
  43. package/dist/public/assets/{preferences-service-D2ISL2Zz.js → preferences-service-lOhnlxzP.js} +1 -1
  44. package/dist/public/assets/{relay-entry-Bg0OisQy.js → relay-entry-CQpxTS8y.js} +1 -1
  45. package/dist/public/assets/{terminal-runtime-meta-C8t-CIDF.js → terminal-runtime-meta-oteTx66X.js} +1 -1
  46. package/dist/public/assets/useRegisteredDebugTemplates-Bu2ykZ6s.js +1 -0
  47. package/dist/public/assets/workbench-navigation-DlgXuFW2.js +1 -0
  48. package/dist/public/index.html +2 -2
  49. package/dist/server/config/env.d.ts +1 -0
  50. package/dist/server/config/env.js +3 -0
  51. package/dist/server/config/env.js.map +1 -1
  52. package/dist/server/modules/affairs-indexer/core/src/parser/parser-skip-repository.js.map +1 -1
  53. package/dist/server/modules/affairs-indexer/core/src/repositories/catalog-write-repository.js.map +1 -1
  54. package/dist/server/modules/affairs-indexer/core/src/sqlite/detect-catalog-schema.js +2 -2
  55. package/dist/server/modules/affairs-indexer/core/src/sqlite/detect-catalog-schema.js.map +1 -1
  56. package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.d.ts +20 -3
  57. package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.js +3 -3
  58. package/dist/server/modules/affairs-indexer/core/src/sqlite/open-database.js.map +1 -1
  59. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.d.ts +32 -0
  60. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js +93 -0
  61. package/dist/server/modules/butler/assistant-sandbox-cleanup-scheduler.js.map +1 -0
  62. package/dist/server/modules/butler/assistant-sandbox-service.d.ts +69 -0
  63. package/dist/server/modules/butler/assistant-sandbox-service.js +399 -0
  64. package/dist/server/modules/butler/assistant-sandbox-service.js.map +1 -0
  65. package/dist/server/modules/butler/butler-follow-up-service.d.ts +3 -0
  66. package/dist/server/modules/butler/butler-follow-up-service.js +11 -1
  67. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
  68. package/dist/server/modules/butler/butler-inbox-service.d.ts +3 -0
  69. package/dist/server/modules/butler/butler-inbox-service.js +14 -2
  70. package/dist/server/modules/butler/butler-inbox-service.js.map +1 -1
  71. package/dist/server/modules/butler/butler-session-service.d.ts +3 -0
  72. package/dist/server/modules/butler/butler-session-service.js +18 -0
  73. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  74. package/dist/server/modules/channels/wechat-claw-client.d.ts +51 -0
  75. package/dist/server/modules/channels/wechat-claw-client.js +245 -0
  76. package/dist/server/modules/channels/wechat-claw-client.js.map +1 -0
  77. package/dist/server/modules/file/file-controller.d.ts +11 -2
  78. package/dist/server/modules/file/file-controller.js +404 -17
  79. package/dist/server/modules/file/file-controller.js.map +1 -1
  80. package/dist/server/modules/file/file-search-service.js +200 -12
  81. package/dist/server/modules/file/file-search-service.js.map +1 -1
  82. package/dist/server/modules/file/runtime/codingns-workspace-bridge.js +18 -5
  83. package/dist/server/modules/file/workspace-file-bridge-service.d.ts +9 -0
  84. package/dist/server/modules/file/workspace-file-bridge-service.js +3 -0
  85. package/dist/server/modules/file/workspace-file-bridge-service.js.map +1 -1
  86. package/dist/server/modules/file/workspace-file-bridge-watch-service.d.ts +9 -0
  87. package/dist/server/modules/file/workspace-file-bridge-watch-service.js +28 -0
  88. package/dist/server/modules/file/workspace-file-bridge-watch-service.js.map +1 -1
  89. package/dist/server/modules/tasks/task-types.d.ts +1 -0
  90. package/dist/server/modules/tasks/task-types.js +1 -0
  91. package/dist/server/modules/tasks/task-types.js.map +1 -1
  92. package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.d.ts +1 -1
  93. package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.js +22 -5
  94. package/dist/server/modules/workbench/affairs-assistant-session-snapshot-service.js.map +1 -1
  95. package/dist/server/modules/workbench/workbench-controller.d.ts +5 -0
  96. package/dist/server/modules/workbench/workbench-controller.js +20 -0
  97. package/dist/server/modules/workbench/workbench-controller.js.map +1 -1
  98. package/dist/server/modules/workbench/workbench-service.d.ts +6 -6
  99. package/dist/server/modules/workbench/workbench-service.js +33 -36
  100. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  101. package/dist/server/modules/workspace/affairs-library-controller.d.ts +8 -0
  102. package/dist/server/modules/workspace/affairs-library-controller.js +11 -0
  103. package/dist/server/modules/workspace/affairs-library-controller.js.map +1 -1
  104. package/dist/server/modules/workspace/affairs-library-preview-link-service.d.ts +6 -0
  105. package/dist/server/modules/workspace/affairs-library-preview-link-service.js +12 -2
  106. package/dist/server/modules/workspace/affairs-library-preview-link-service.js.map +1 -1
  107. package/dist/server/modules/workspace/affairs-library-service.d.ts +9 -0
  108. package/dist/server/modules/workspace/affairs-library-service.js +182 -42
  109. package/dist/server/modules/workspace/affairs-library-service.js.map +1 -1
  110. package/dist/server/modules/workspace/affairs-lightweight-session-controller.d.ts +8 -0
  111. package/dist/server/modules/workspace/affairs-lightweight-session-controller.js +55 -8
  112. package/dist/server/modules/workspace/affairs-lightweight-session-controller.js.map +1 -1
  113. package/dist/server/modules/workspace/affairs-lightweight-session-service.d.ts +13 -0
  114. package/dist/server/modules/workspace/affairs-lightweight-session-service.js +167 -21
  115. package/dist/server/modules/workspace/affairs-lightweight-session-service.js.map +1 -1
  116. package/dist/server/modules/workspace/affairs-tag-controller.d.ts +3 -0
  117. package/dist/server/modules/workspace/affairs-tag-controller.js +5 -0
  118. package/dist/server/modules/workspace/affairs-tag-controller.js.map +1 -1
  119. package/dist/server/modules/workspace/affairs-tag-service.d.ts +22 -1
  120. package/dist/server/modules/workspace/affairs-tag-service.js +41 -2
  121. package/dist/server/modules/workspace/affairs-tag-service.js.map +1 -1
  122. package/dist/server/modules/workspace/teable-api-client.d.ts +118 -0
  123. package/dist/server/modules/workspace/teable-api-client.js +142 -0
  124. package/dist/server/modules/workspace/teable-api-client.js.map +1 -0
  125. package/dist/server/modules/workspace/teable-catalog-controller.d.ts +18 -0
  126. package/dist/server/modules/workspace/teable-catalog-controller.js +17 -0
  127. package/dist/server/modules/workspace/teable-catalog-controller.js.map +1 -0
  128. package/dist/server/modules/workspace/teable-catalog-service.d.ts +36 -0
  129. package/dist/server/modules/workspace/teable-catalog-service.js +124 -0
  130. package/dist/server/modules/workspace/teable-catalog-service.js.map +1 -0
  131. package/dist/server/modules/workspace/teable-credential-service.d.ts +8 -0
  132. package/dist/server/modules/workspace/teable-credential-service.js +37 -0
  133. package/dist/server/modules/workspace/teable-credential-service.js.map +1 -0
  134. package/dist/server/modules/workspace/teable-field-mapping-controller.d.ts +25 -0
  135. package/dist/server/modules/workspace/teable-field-mapping-controller.js +31 -0
  136. package/dist/server/modules/workspace/teable-field-mapping-controller.js.map +1 -0
  137. package/dist/server/modules/workspace/teable-field-mapping-service.d.ts +38 -0
  138. package/dist/server/modules/workspace/teable-field-mapping-service.js +215 -0
  139. package/dist/server/modules/workspace/teable-field-mapping-service.js.map +1 -0
  140. package/dist/server/modules/workspace/teable-global-binding-controller.d.ts +22 -0
  141. package/dist/server/modules/workspace/teable-global-binding-controller.js +25 -0
  142. package/dist/server/modules/workspace/teable-global-binding-controller.js.map +1 -0
  143. package/dist/server/modules/workspace/teable-global-binding-service.d.ts +35 -0
  144. package/dist/server/modules/workspace/teable-global-binding-service.js +151 -0
  145. package/dist/server/modules/workspace/teable-global-binding-service.js.map +1 -0
  146. package/dist/server/modules/workspace/teable-mirror-sync-controller.d.ts +29 -0
  147. package/dist/server/modules/workspace/teable-mirror-sync-controller.js +50 -0
  148. package/dist/server/modules/workspace/teable-mirror-sync-controller.js.map +1 -0
  149. package/dist/server/modules/workspace/teable-mirror-sync-service.d.ts +157 -0
  150. package/dist/server/modules/workspace/teable-mirror-sync-service.js +917 -0
  151. package/dist/server/modules/workspace/teable-mirror-sync-service.js.map +1 -0
  152. package/dist/server/modules/workspace/teable-runtime-controller.d.ts +58 -0
  153. package/dist/server/modules/workspace/teable-runtime-controller.js +60 -0
  154. package/dist/server/modules/workspace/teable-runtime-controller.js.map +1 -0
  155. package/dist/server/modules/workspace/teable-runtime-service.d.ts +96 -0
  156. package/dist/server/modules/workspace/teable-runtime-service.js +362 -0
  157. package/dist/server/modules/workspace/teable-runtime-service.js.map +1 -0
  158. package/dist/server/modules/workspace/teable-workbench-sync-config-controller.d.ts +22 -0
  159. package/dist/server/modules/workspace/teable-workbench-sync-config-controller.js +20 -0
  160. package/dist/server/modules/workspace/teable-workbench-sync-config-controller.js.map +1 -0
  161. package/dist/server/modules/workspace/teable-workbench-sync-config-service.d.ts +22 -0
  162. package/dist/server/modules/workspace/teable-workbench-sync-config-service.js +159 -0
  163. package/dist/server/modules/workspace/teable-workbench-sync-config-service.js.map +1 -0
  164. package/dist/server/routes/affairs.d.ts +9 -1
  165. package/dist/server/routes/affairs.js +120 -1
  166. package/dist/server/routes/affairs.js.map +1 -1
  167. package/dist/server/routes/workbench.js +15 -0
  168. package/dist/server/routes/workbench.js.map +1 -1
  169. package/dist/server/routes/workspaces.js +51 -41
  170. package/dist/server/routes/workspaces.js.map +1 -1
  171. package/dist/server/server/create-server.d.ts +14 -0
  172. package/dist/server/server/create-server.js +73 -7
  173. package/dist/server/server/create-server.js.map +1 -1
  174. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.d.ts +18 -0
  175. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js +191 -0
  176. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js.map +1 -0
  177. package/dist/server/storage/repositories/user-affairs-library-setting-repository.js +8 -5
  178. package/dist/server/storage/repositories/user-affairs-library-setting-repository.js.map +1 -1
  179. package/dist/server/storage/repositories/user-teable-credential-repository.d.ts +9 -0
  180. package/dist/server/storage/repositories/user-teable-credential-repository.js +45 -0
  181. package/dist/server/storage/repositories/user-teable-credential-repository.js.map +1 -0
  182. package/dist/server/storage/repositories/user-teable-field-mapping-repository.d.ts +10 -0
  183. package/dist/server/storage/repositories/user-teable-field-mapping-repository.js +69 -0
  184. package/dist/server/storage/repositories/user-teable-field-mapping-repository.js.map +1 -0
  185. package/dist/server/storage/repositories/user-teable-global-setting-repository.d.ts +8 -0
  186. package/dist/server/storage/repositories/user-teable-global-setting-repository.js +52 -0
  187. package/dist/server/storage/repositories/user-teable-global-setting-repository.js.map +1 -0
  188. package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.d.ts +9 -0
  189. package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.js +66 -0
  190. package/dist/server/storage/repositories/user-teable-mirror-record-mapping-repository.js.map +1 -0
  191. package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.d.ts +9 -0
  192. package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.js +67 -0
  193. package/dist/server/storage/repositories/user-teable-mirror-table-binding-repository.js.map +1 -0
  194. package/dist/server/storage/repositories/user-teable-sync-log-repository.d.ts +14 -0
  195. package/dist/server/storage/repositories/user-teable-sync-log-repository.js +97 -0
  196. package/dist/server/storage/repositories/user-teable-sync-log-repository.js.map +1 -0
  197. package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.d.ts +8 -0
  198. package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.js +55 -0
  199. package/dist/server/storage/repositories/user-teable-workbench-sync-config-repository.js.map +1 -0
  200. package/dist/server/storage/sqlite/client.js +404 -1
  201. package/dist/server/storage/sqlite/client.js.map +1 -1
  202. package/dist/server/storage/sqlite/schema.sql +167 -1
  203. package/dist/server/types/domain.d.ts +106 -0
  204. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.d.ts +22 -3
  205. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js +29 -2
  206. package/node_modules/@codingns/session-sync-core/dist/sqlite/node-sqlite.js.map +1 -1
  207. package/node_modules/@codingns/session-sync-core/package.json +3 -1
  208. package/package.json +1 -1
  209. package/dist/public/assets/DesktopWindowPage-D0blSuKd.js +0 -2
  210. package/dist/public/assets/FileContextPanel-BrKO8Xt6.js +0 -1
  211. package/dist/public/assets/GitSidebar-BdwiDtOr.js +0 -6
  212. package/dist/public/assets/MobileCreateSessionSheet-Cx_dBiBb.js +0 -1
  213. package/dist/public/assets/SettingsPage-BlAZCHsy.js +0 -2
  214. package/dist/public/assets/TerminalManagerPanel-CjzbiWjl.js +0 -1
  215. package/dist/public/assets/WorkbenchLayout-CikJBS62.js +0 -1019
  216. package/dist/public/assets/WorkbenchShellRoute-BbbSOiZw.js +0 -1
  217. package/dist/public/assets/WorkbenchShellRoute-DT3VMjWD.css +0 -1
  218. package/dist/public/assets/WorkspaceDebugDetailPage-CVivdPx5.js +0 -1
  219. package/dist/public/assets/WorkspaceDetailPage-DgOSjscR.js +0 -1
  220. package/dist/public/assets/WorkspaceHomePage-HPa7M_Vh.js +0 -1
  221. package/dist/public/assets/index-BxJPQpFM.css +0 -1
  222. package/dist/public/assets/index-CeXGOT_T.js +0 -50
  223. package/dist/public/assets/useRegisteredDebugTemplates-Bol3NVfN.js +0 -1
  224. package/dist/public/assets/workbench-navigation-B7IjRQd8.js +0 -1
@@ -0,0 +1,50 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/App-DrNI9lWA.js","assets/App-CcDXqFl1.css"])))=>i.map(i=>d[i]);
2
+ var Gm=Object.defineProperty;var Km=(i,r,o)=>r in i?Gm(i,r,{enumerable:!0,configurable:!0,writable:!0,value:o}):i[r]=o;var A=(i,r,o)=>Km(i,typeof r!="symbol"?r+"":r,o);function Qm(i,r){for(var o=0;o<r.length;o++){const c=r[o];if(typeof c!="string"&&!Array.isArray(c)){for(const u in c)if(u!=="default"&&!(u in i)){const p=Object.getOwnPropertyDescriptor(c,u);p&&Object.defineProperty(i,u,p.get?p:{enumerable:!0,get:()=>c[u]})}}}return Object.freeze(Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}))}(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))c(u);new MutationObserver(u=>{for(const p of u)if(p.type==="childList")for(const y of p.addedNodes)y.tagName==="LINK"&&y.rel==="modulepreload"&&c(y)}).observe(document,{childList:!0,subtree:!0});function o(u){const p={};return u.integrity&&(p.integrity=u.integrity),u.referrerPolicy&&(p.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?p.credentials="include":u.crossOrigin==="anonymous"?p.credentials="omit":p.credentials="same-origin",p}function c(u){if(u.ep)return;u.ep=!0;const p=o(u);fetch(u.href,p)}})();function Bd(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var Ll={exports:{}},qi={},Al={exports:{}},G={};/**
3
+ * @license React
4
+ * react.production.min.js
5
+ *
6
+ * Copyright (c) Facebook, Inc. and its affiliates.
7
+ *
8
+ * This source code is licensed under the MIT license found in the
9
+ * LICENSE file in the root directory of this source tree.
10
+ */var Xu;function Ym(){if(Xu)return G;Xu=1;var i=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),c=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),p=Symbol.for("react.provider"),y=Symbol.for("react.context"),k=Symbol.for("react.forward_ref"),L=Symbol.for("react.suspense"),O=Symbol.for("react.memo"),E=Symbol.for("react.lazy"),B=Symbol.iterator;function j(g){return g===null||typeof g!="object"?null:(g=B&&g[B]||g["@@iterator"],typeof g=="function"?g:null)}var Z={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},ce=Object.assign,ae={};function ie(g,v,q){this.props=g,this.context=v,this.refs=ae,this.updater=q||Z}ie.prototype.isReactComponent={},ie.prototype.setState=function(g,v){if(typeof g!="object"&&typeof g!="function"&&g!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,g,v,"setState")},ie.prototype.forceUpdate=function(g){this.updater.enqueueForceUpdate(this,g,"forceUpdate")};function Ft(){}Ft.prototype=ie.prototype;function Tt(g,v,q){this.props=g,this.context=v,this.refs=ae,this.updater=q||Z}var ut=Tt.prototype=new Ft;ut.constructor=Tt,ce(ut,ie.prototype),ut.isPureReactComponent=!0;var Le=Array.isArray,dt=Object.prototype.hasOwnProperty,Ie={current:null},Ue={key:!0,ref:!0,__self:!0,__source:!0};function at(g,v,q){var K,Y={},$=null,re=null;if(v!=null)for(K in v.ref!==void 0&&(re=v.ref),v.key!==void 0&&($=""+v.key),v)dt.call(v,K)&&!Ue.hasOwnProperty(K)&&(Y[K]=v[K]);var ee=arguments.length-2;if(ee===1)Y.children=q;else if(1<ee){for(var ue=Array(ee),Ye=0;Ye<ee;Ye++)ue[Ye]=arguments[Ye+2];Y.children=ue}if(g&&g.defaultProps)for(K in ee=g.defaultProps,ee)Y[K]===void 0&&(Y[K]=ee[K]);return{$$typeof:i,type:g,key:$,ref:re,props:Y,_owner:Ie.current}}function Ut(g,v){return{$$typeof:i,type:g.type,key:v,ref:g.ref,props:g.props,_owner:g._owner}}function Et(g){return typeof g=="object"&&g!==null&&g.$$typeof===i}function ua(g){var v={"=":"=0",":":"=2"};return"$"+g.replace(/[=:]/g,function(q){return v[q]})}var wt=/\/+/g;function Qe(g,v){return typeof g=="object"&&g!==null&&g.key!=null?ua(""+g.key):v.toString(36)}function pt(g,v,q,K,Y){var $=typeof g;($==="undefined"||$==="boolean")&&(g=null);var re=!1;if(g===null)re=!0;else switch($){case"string":case"number":re=!0;break;case"object":switch(g.$$typeof){case i:case r:re=!0}}if(re)return re=g,Y=Y(re),g=K===""?"."+Qe(re,0):K,Le(Y)?(q="",g!=null&&(q=g.replace(wt,"$&/")+"/"),pt(Y,v,q,"",function(Ye){return Ye})):Y!=null&&(Et(Y)&&(Y=Ut(Y,q+(!Y.key||re&&re.key===Y.key?"":(""+Y.key).replace(wt,"$&/")+"/")+g)),v.push(Y)),1;if(re=0,K=K===""?".":K+":",Le(g))for(var ee=0;ee<g.length;ee++){$=g[ee];var ue=K+Qe($,ee);re+=pt($,v,q,ue,Y)}else if(ue=j(g),typeof ue=="function")for(g=ue.call(g),ee=0;!($=g.next()).done;)$=$.value,ue=K+Qe($,ee++),re+=pt($,v,q,ue,Y);else if($==="object")throw v=String(g),Error("Objects are not valid as a React child (found: "+(v==="[object Object]"?"object with keys {"+Object.keys(g).join(", ")+"}":v)+"). If you meant to render a collection of children, use an array instead.");return re}function vt(g,v,q){if(g==null)return g;var K=[],Y=0;return pt(g,K,"","",function($){return v.call(q,$,Y++)}),K}function _e(g){if(g._status===-1){var v=g._result;v=v(),v.then(function(q){(g._status===0||g._status===-1)&&(g._status=1,g._result=q)},function(q){(g._status===0||g._status===-1)&&(g._status=2,g._result=q)}),g._status===-1&&(g._status=0,g._result=v)}if(g._status===1)return g._result.default;throw g._result}var me={current:null},R={transition:null},V={ReactCurrentDispatcher:me,ReactCurrentBatchConfig:R,ReactCurrentOwner:Ie};function I(){throw Error("act(...) is not supported in production builds of React.")}return G.Children={map:vt,forEach:function(g,v,q){vt(g,function(){v.apply(this,arguments)},q)},count:function(g){var v=0;return vt(g,function(){v++}),v},toArray:function(g){return vt(g,function(v){return v})||[]},only:function(g){if(!Et(g))throw Error("React.Children.only expected to receive a single React element child.");return g}},G.Component=ie,G.Fragment=o,G.Profiler=u,G.PureComponent=Tt,G.StrictMode=c,G.Suspense=L,G.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=V,G.act=I,G.cloneElement=function(g,v,q){if(g==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+g+".");var K=ce({},g.props),Y=g.key,$=g.ref,re=g._owner;if(v!=null){if(v.ref!==void 0&&($=v.ref,re=Ie.current),v.key!==void 0&&(Y=""+v.key),g.type&&g.type.defaultProps)var ee=g.type.defaultProps;for(ue in v)dt.call(v,ue)&&!Ue.hasOwnProperty(ue)&&(K[ue]=v[ue]===void 0&&ee!==void 0?ee[ue]:v[ue])}var ue=arguments.length-2;if(ue===1)K.children=q;else if(1<ue){ee=Array(ue);for(var Ye=0;Ye<ue;Ye++)ee[Ye]=arguments[Ye+2];K.children=ee}return{$$typeof:i,type:g.type,key:Y,ref:$,props:K,_owner:re}},G.createContext=function(g){return g={$$typeof:y,_currentValue:g,_currentValue2:g,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},g.Provider={$$typeof:p,_context:g},g.Consumer=g},G.createElement=at,G.createFactory=function(g){var v=at.bind(null,g);return v.type=g,v},G.createRef=function(){return{current:null}},G.forwardRef=function(g){return{$$typeof:k,render:g}},G.isValidElement=Et,G.lazy=function(g){return{$$typeof:E,_payload:{_status:-1,_result:g},_init:_e}},G.memo=function(g,v){return{$$typeof:O,type:g,compare:v===void 0?null:v}},G.startTransition=function(g){var v=R.transition;R.transition={};try{g()}finally{R.transition=v}},G.unstable_act=I,G.useCallback=function(g,v){return me.current.useCallback(g,v)},G.useContext=function(g){return me.current.useContext(g)},G.useDebugValue=function(){},G.useDeferredValue=function(g){return me.current.useDeferredValue(g)},G.useEffect=function(g,v){return me.current.useEffect(g,v)},G.useId=function(){return me.current.useId()},G.useImperativeHandle=function(g,v,q){return me.current.useImperativeHandle(g,v,q)},G.useInsertionEffect=function(g,v){return me.current.useInsertionEffect(g,v)},G.useLayoutEffect=function(g,v){return me.current.useLayoutEffect(g,v)},G.useMemo=function(g,v){return me.current.useMemo(g,v)},G.useReducer=function(g,v,q){return me.current.useReducer(g,v,q)},G.useRef=function(g){return me.current.useRef(g)},G.useState=function(g){return me.current.useState(g)},G.useSyncExternalStore=function(g,v,q){return me.current.useSyncExternalStore(g,v,q)},G.useTransition=function(){return me.current.useTransition()},G.version="18.3.1",G}var Zu;function ql(){return Zu||(Zu=1,Al.exports=Ym()),Al.exports}/**
11
+ * @license React
12
+ * react-jsx-runtime.production.min.js
13
+ *
14
+ * Copyright (c) Facebook, Inc. and its affiliates.
15
+ *
16
+ * This source code is licensed under the MIT license found in the
17
+ * LICENSE file in the root directory of this source tree.
18
+ */var ed;function $m(){if(ed)return qi;ed=1;var i=ql(),r=Symbol.for("react.element"),o=Symbol.for("react.fragment"),c=Object.prototype.hasOwnProperty,u=i.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};function y(k,L,O){var E,B={},j=null,Z=null;O!==void 0&&(j=""+O),L.key!==void 0&&(j=""+L.key),L.ref!==void 0&&(Z=L.ref);for(E in L)c.call(L,E)&&!p.hasOwnProperty(E)&&(B[E]=L[E]);if(k&&k.defaultProps)for(E in L=k.defaultProps,L)B[E]===void 0&&(B[E]=L[E]);return{$$typeof:r,type:k,key:j,ref:Z,props:B,_owner:u.current}}return qi.Fragment=o,qi.jsx=y,qi.jsxs=y,qi}var td;function Jm(){return td||(td=1,Ll.exports=$m()),Ll.exports}var la=Jm(),un={},Rl={exports:{}},Ke={},Fl={exports:{}},El={};/**
19
+ * @license React
20
+ * scheduler.production.min.js
21
+ *
22
+ * Copyright (c) Facebook, Inc. and its affiliates.
23
+ *
24
+ * This source code is licensed under the MIT license found in the
25
+ * LICENSE file in the root directory of this source tree.
26
+ */var ad;function Xm(){return ad||(ad=1,(function(i){function r(R,V){var I=R.length;R.push(V);e:for(;0<I;){var g=I-1>>>1,v=R[g];if(0<u(v,V))R[g]=V,R[I]=v,I=g;else break e}}function o(R){return R.length===0?null:R[0]}function c(R){if(R.length===0)return null;var V=R[0],I=R.pop();if(I!==V){R[0]=I;e:for(var g=0,v=R.length,q=v>>>1;g<q;){var K=2*(g+1)-1,Y=R[K],$=K+1,re=R[$];if(0>u(Y,I))$<v&&0>u(re,Y)?(R[g]=re,R[$]=I,g=$):(R[g]=Y,R[K]=I,g=K);else if($<v&&0>u(re,I))R[g]=re,R[$]=I,g=$;else break e}}return V}function u(R,V){var I=R.sortIndex-V.sortIndex;return I!==0?I:R.id-V.id}if(typeof performance=="object"&&typeof performance.now=="function"){var p=performance;i.unstable_now=function(){return p.now()}}else{var y=Date,k=y.now();i.unstable_now=function(){return y.now()-k}}var L=[],O=[],E=1,B=null,j=3,Z=!1,ce=!1,ae=!1,ie=typeof setTimeout=="function"?setTimeout:null,Ft=typeof clearTimeout=="function"?clearTimeout:null,Tt=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function ut(R){for(var V=o(O);V!==null;){if(V.callback===null)c(O);else if(V.startTime<=R)c(O),V.sortIndex=V.expirationTime,r(L,V);else break;V=o(O)}}function Le(R){if(ae=!1,ut(R),!ce)if(o(L)!==null)ce=!0,_e(dt);else{var V=o(O);V!==null&&me(Le,V.startTime-R)}}function dt(R,V){ce=!1,ae&&(ae=!1,Ft(at),at=-1),Z=!0;var I=j;try{for(ut(V),B=o(L);B!==null&&(!(B.expirationTime>V)||R&&!ua());){var g=B.callback;if(typeof g=="function"){B.callback=null,j=B.priorityLevel;var v=g(B.expirationTime<=V);V=i.unstable_now(),typeof v=="function"?B.callback=v:B===o(L)&&c(L),ut(V)}else c(L);B=o(L)}if(B!==null)var q=!0;else{var K=o(O);K!==null&&me(Le,K.startTime-V),q=!1}return q}finally{B=null,j=I,Z=!1}}var Ie=!1,Ue=null,at=-1,Ut=5,Et=-1;function ua(){return!(i.unstable_now()-Et<Ut)}function wt(){if(Ue!==null){var R=i.unstable_now();Et=R;var V=!0;try{V=Ue(!0,R)}finally{V?Qe():(Ie=!1,Ue=null)}}else Ie=!1}var Qe;if(typeof Tt=="function")Qe=function(){Tt(wt)};else if(typeof MessageChannel<"u"){var pt=new MessageChannel,vt=pt.port2;pt.port1.onmessage=wt,Qe=function(){vt.postMessage(null)}}else Qe=function(){ie(wt,0)};function _e(R){Ue=R,Ie||(Ie=!0,Qe())}function me(R,V){at=ie(function(){R(i.unstable_now())},V)}i.unstable_IdlePriority=5,i.unstable_ImmediatePriority=1,i.unstable_LowPriority=4,i.unstable_NormalPriority=3,i.unstable_Profiling=null,i.unstable_UserBlockingPriority=2,i.unstable_cancelCallback=function(R){R.callback=null},i.unstable_continueExecution=function(){ce||Z||(ce=!0,_e(dt))},i.unstable_forceFrameRate=function(R){0>R||125<R?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):Ut=0<R?Math.floor(1e3/R):5},i.unstable_getCurrentPriorityLevel=function(){return j},i.unstable_getFirstCallbackNode=function(){return o(L)},i.unstable_next=function(R){switch(j){case 1:case 2:case 3:var V=3;break;default:V=j}var I=j;j=V;try{return R()}finally{j=I}},i.unstable_pauseExecution=function(){},i.unstable_requestPaint=function(){},i.unstable_runWithPriority=function(R,V){switch(R){case 1:case 2:case 3:case 4:case 5:break;default:R=3}var I=j;j=R;try{return V()}finally{j=I}},i.unstable_scheduleCallback=function(R,V,I){var g=i.unstable_now();switch(typeof I=="object"&&I!==null?(I=I.delay,I=typeof I=="number"&&0<I?g+I:g):I=g,R){case 1:var v=-1;break;case 2:v=250;break;case 5:v=1073741823;break;case 4:v=1e4;break;default:v=5e3}return v=I+v,R={id:E++,callback:V,priorityLevel:R,startTime:I,expirationTime:v,sortIndex:-1},I>g?(R.sortIndex=I,r(O,R),o(L)===null&&R===o(O)&&(ae?(Ft(at),at=-1):ae=!0,me(Le,I-g))):(R.sortIndex=v,r(L,R),ce||Z||(ce=!0,_e(dt))),R},i.unstable_shouldYield=ua,i.unstable_wrapCallback=function(R){var V=j;return function(){var I=j;j=V;try{return R.apply(this,arguments)}finally{j=I}}}})(El)),El}var id;function Zm(){return id||(id=1,Fl.exports=Xm()),Fl.exports}/**
27
+ * @license React
28
+ * react-dom.production.min.js
29
+ *
30
+ * Copyright (c) Facebook, Inc. and its affiliates.
31
+ *
32
+ * This source code is licensed under the MIT license found in the
33
+ * LICENSE file in the root directory of this source tree.
34
+ */var rd;function eh(){if(rd)return Ke;rd=1;var i=ql(),r=Zm();function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,a=1;a<arguments.length;a++)t+="&args[]="+encodeURIComponent(arguments[a]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var c=new Set,u={};function p(e,t){y(e,t),y(e+"Capture",t)}function y(e,t){for(u[e]=t,e=0;e<t.length;e++)c.add(t[e])}var k=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),L=Object.prototype.hasOwnProperty,O=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,E={},B={};function j(e){return L.call(B,e)?!0:L.call(E,e)?!1:O.test(e)?B[e]=!0:(E[e]=!0,!1)}function Z(e,t,a,n){if(a!==null&&a.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return n?!1:a!==null?!a.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function ce(e,t,a,n){if(t===null||typeof t>"u"||Z(e,t,a,n))return!0;if(n)return!1;if(a!==null)switch(a.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function ae(e,t,a,n,l,s,d){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=n,this.attributeNamespace=l,this.mustUseProperty=a,this.propertyName=e,this.type=t,this.sanitizeURL=s,this.removeEmptyString=d}var ie={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){ie[e]=new ae(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];ie[t]=new ae(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){ie[e]=new ae(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){ie[e]=new ae(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){ie[e]=new ae(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){ie[e]=new ae(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){ie[e]=new ae(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){ie[e]=new ae(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){ie[e]=new ae(e,5,!1,e.toLowerCase(),null,!1,!1)});var Ft=/[\-:]([a-z])/g;function Tt(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Ft,Tt);ie[t]=new ae(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Ft,Tt);ie[t]=new ae(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Ft,Tt);ie[t]=new ae(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){ie[e]=new ae(e,1,!1,e.toLowerCase(),null,!1,!1)}),ie.xlinkHref=new ae("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){ie[e]=new ae(e,1,!1,e.toLowerCase(),null,!0,!0)});function ut(e,t,a,n){var l=ie.hasOwnProperty(t)?ie[t]:null;(l!==null?l.type!==0:n||!(2<t.length)||t[0]!=="o"&&t[0]!=="O"||t[1]!=="n"&&t[1]!=="N")&&(ce(t,a,l,n)&&(a=null),n||l===null?j(t)&&(a===null?e.removeAttribute(t):e.setAttribute(t,""+a)):l.mustUseProperty?e[l.propertyName]=a===null?l.type===3?!1:"":a:(t=l.attributeName,n=l.attributeNamespace,a===null?e.removeAttribute(t):(l=l.type,a=l===3||l===4&&a===!0?"":""+a,n?e.setAttributeNS(n,t,a):e.setAttribute(t,a))))}var Le=i.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,dt=Symbol.for("react.element"),Ie=Symbol.for("react.portal"),Ue=Symbol.for("react.fragment"),at=Symbol.for("react.strict_mode"),Ut=Symbol.for("react.profiler"),Et=Symbol.for("react.provider"),ua=Symbol.for("react.context"),wt=Symbol.for("react.forward_ref"),Qe=Symbol.for("react.suspense"),pt=Symbol.for("react.suspense_list"),vt=Symbol.for("react.memo"),_e=Symbol.for("react.lazy"),me=Symbol.for("react.offscreen"),R=Symbol.iterator;function V(e){return e===null||typeof e!="object"?null:(e=R&&e[R]||e["@@iterator"],typeof e=="function"?e:null)}var I=Object.assign,g;function v(e){if(g===void 0)try{throw Error()}catch(a){var t=a.stack.trim().match(/\n( *(at )?)/);g=t&&t[1]||""}return`
35
+ `+g+e}var q=!1;function K(e,t){if(!e||q)return"";q=!0;var a=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(t,[])}catch(T){var n=T}Reflect.construct(e,[],t)}else{try{t.call()}catch(T){n=T}e.call(t.prototype)}else{try{throw Error()}catch(T){n=T}e()}}catch(T){if(T&&n&&typeof T.stack=="string"){for(var l=T.stack.split(`
36
+ `),s=n.stack.split(`
37
+ `),d=l.length-1,f=s.length-1;1<=d&&0<=f&&l[d]!==s[f];)f--;for(;1<=d&&0<=f;d--,f--)if(l[d]!==s[f]){if(d!==1||f!==1)do if(d--,f--,0>f||l[d]!==s[f]){var m=`
38
+ `+l[d].replace(" at new "," at ");return e.displayName&&m.includes("<anonymous>")&&(m=m.replace("<anonymous>",e.displayName)),m}while(1<=d&&0<=f);break}}}finally{q=!1,Error.prepareStackTrace=a}return(e=e?e.displayName||e.name:"")?v(e):""}function Y(e){switch(e.tag){case 5:return v(e.type);case 16:return v("Lazy");case 13:return v("Suspense");case 19:return v("SuspenseList");case 0:case 2:case 15:return e=K(e.type,!1),e;case 11:return e=K(e.type.render,!1),e;case 1:return e=K(e.type,!0),e;default:return""}}function $(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Ue:return"Fragment";case Ie:return"Portal";case Ut:return"Profiler";case at:return"StrictMode";case Qe:return"Suspense";case pt:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case ua:return(e.displayName||"Context")+".Consumer";case Et:return(e._context.displayName||"Context")+".Provider";case wt:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case vt:return t=e.displayName||null,t!==null?t:$(e.type)||"Memo";case _e:t=e._payload,e=e._init;try{return $(e(t))}catch{}}return null}function re(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return $(t);case 8:return t===at?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function ee(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ue(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Ye(e){var t=ue(e)?"checked":"value",a=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),n=""+e[t];if(!e.hasOwnProperty(t)&&typeof a<"u"&&typeof a.get=="function"&&typeof a.set=="function"){var l=a.get,s=a.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return l.call(this)},set:function(d){n=""+d,s.call(this,d)}}),Object.defineProperty(e,t,{enumerable:a.enumerable}),{getValue:function(){return n},setValue:function(d){n=""+d},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function Zi(e){e._valueTracker||(e._valueTracker=Ye(e))}function rs(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var a=t.getValue(),n="";return e&&(n=ue(e)?e.checked?"true":"false":e.value),e=n,e!==a?(t.setValue(e),!0):!1}function er(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function In(e,t){var a=t.checked;return I({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:a??e._wrapperState.initialChecked})}function ns(e,t){var a=t.defaultValue==null?"":t.defaultValue,n=t.checked!=null?t.checked:t.defaultChecked;a=ee(t.value!=null?t.value:a),e._wrapperState={initialChecked:n,initialValue:a,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function os(e,t){t=t.checked,t!=null&&ut(e,"checked",t,!1)}function xn(e,t){os(e,t);var a=ee(t.value),n=t.type;if(a!=null)n==="number"?(a===0&&e.value===""||e.value!=a)&&(e.value=""+a):e.value!==""+a&&(e.value=""+a);else if(n==="submit"||n==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?On(e,t.type,a):t.hasOwnProperty("defaultValue")&&On(e,t.type,ee(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function ls(e,t,a){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var n=t.type;if(!(n!=="submit"&&n!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,a||t===e.value||(e.value=t),e.defaultValue=t}a=e.name,a!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,a!==""&&(e.name=a)}function On(e,t,a){(t!=="number"||er(e.ownerDocument)!==e)&&(a==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+a&&(e.defaultValue=""+a))}var oi=Array.isArray;function Ra(e,t,a,n){if(e=e.options,t){t={};for(var l=0;l<a.length;l++)t["$"+a[l]]=!0;for(a=0;a<e.length;a++)l=t.hasOwnProperty("$"+e[a].value),e[a].selected!==l&&(e[a].selected=l),l&&n&&(e[a].defaultSelected=!0)}else{for(a=""+ee(a),t=null,l=0;l<e.length;l++){if(e[l].value===a){e[l].selected=!0,n&&(e[l].defaultSelected=!0);return}t!==null||e[l].disabled||(t=e[l])}t!==null&&(t.selected=!0)}}function Hn(e,t){if(t.dangerouslySetInnerHTML!=null)throw Error(o(91));return I({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function ss(e,t){var a=t.value;if(a==null){if(a=t.children,t=t.defaultValue,a!=null){if(t!=null)throw Error(o(92));if(oi(a)){if(1<a.length)throw Error(o(93));a=a[0]}t=a}t==null&&(t=""),a=t}e._wrapperState={initialValue:ee(a)}}function cs(e,t){var a=ee(t.value),n=ee(t.defaultValue);a!=null&&(a=""+a,a!==e.value&&(e.value=a),t.defaultValue==null&&e.defaultValue!==a&&(e.defaultValue=a)),n!=null&&(e.defaultValue=""+n)}function us(e){var t=e.textContent;t===e._wrapperState.initialValue&&t!==""&&t!==null&&(e.value=t)}function ds(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function Nn(e,t){return e==null||e==="http://www.w3.org/1999/xhtml"?ds(t):e==="http://www.w3.org/2000/svg"&&t==="foreignObject"?"http://www.w3.org/1999/xhtml":e}var tr,ps=(function(e){return typeof MSApp<"u"&&MSApp.execUnsafeLocalFunction?function(t,a,n,l){MSApp.execUnsafeLocalFunction(function(){return e(t,a,n,l)})}:e})(function(e,t){if(e.namespaceURI!=="http://www.w3.org/2000/svg"||"innerHTML"in e)e.innerHTML=t;else{for(tr=tr||document.createElement("div"),tr.innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=tr.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function li(e,t){if(t){var a=e.firstChild;if(a&&a===e.lastChild&&a.nodeType===3){a.nodeValue=t;return}}e.textContent=t}var si={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Yp=["Webkit","ms","Moz","O"];Object.keys(si).forEach(function(e){Yp.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),si[t]=si[e]})});function fs(e,t,a){return t==null||typeof t=="boolean"||t===""?"":a||typeof t!="number"||t===0||si.hasOwnProperty(e)&&si[e]?(""+t).trim():t+"px"}function ms(e,t){e=e.style;for(var a in t)if(t.hasOwnProperty(a)){var n=a.indexOf("--")===0,l=fs(a,t[a],n);a==="float"&&(a="cssFloat"),n?e.setProperty(a,l):e[a]=l}}var $p=I({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Bn(e,t){if(t){if($p[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(o(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(o(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(o(61))}if(t.style!=null&&typeof t.style!="object")throw Error(o(62))}}function Wn(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Un=null;function _n(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Vn=null,Fa=null,Ea=null;function hs(e){if(e=Fi(e)){if(typeof Vn!="function")throw Error(o(280));var t=e.stateNode;t&&(t=Cr(t),Vn(e.stateNode,e.type,t))}}function gs(e){Fa?Ea?Ea.push(e):Ea=[e]:Fa=e}function bs(){if(Fa){var e=Fa,t=Ea;if(Ea=Fa=null,hs(e),t)for(e=0;e<t.length;e++)hs(t[e])}}function ys(e,t){return e(t)}function Ss(){}var zn=!1;function ks(e,t,a){if(zn)return e(t,a);zn=!0;try{return ys(e,t,a)}finally{zn=!1,(Fa!==null||Ea!==null)&&(Ss(),bs())}}function ci(e,t){var a=e.stateNode;if(a===null)return null;var n=Cr(a);if(n===null)return null;a=n[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(n=!n.disabled)||(e=e.type,n=!(e==="button"||e==="input"||e==="select"||e==="textarea")),e=!n;break e;default:e=!1}if(e)return null;if(a&&typeof a!="function")throw Error(o(231,t,typeof a));return a}var jn=!1;if(k)try{var ui={};Object.defineProperty(ui,"passive",{get:function(){jn=!0}}),window.addEventListener("test",ui,ui),window.removeEventListener("test",ui,ui)}catch{jn=!1}function Jp(e,t,a,n,l,s,d,f,m){var T=Array.prototype.slice.call(arguments,3);try{t.apply(a,T)}catch(C){this.onError(C)}}var di=!1,ar=null,ir=!1,qn=null,Xp={onError:function(e){di=!0,ar=e}};function Zp(e,t,a,n,l,s,d,f,m){di=!1,ar=null,Jp.apply(Xp,arguments)}function ef(e,t,a,n,l,s,d,f,m){if(Zp.apply(this,arguments),di){if(di){var T=ar;di=!1,ar=null}else throw Error(o(198));ir||(ir=!0,qn=T)}}function da(e){var t=e,a=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do t=e,(t.flags&4098)!==0&&(a=t.return),e=t.return;while(e)}return t.tag===3?a:null}function Ts(e){if(e.tag===13){var t=e.memoizedState;if(t===null&&(e=e.alternate,e!==null&&(t=e.memoizedState)),t!==null)return t.dehydrated}return null}function ws(e){if(da(e)!==e)throw Error(o(188))}function tf(e){var t=e.alternate;if(!t){if(t=da(e),t===null)throw Error(o(188));return t!==e?null:e}for(var a=e,n=t;;){var l=a.return;if(l===null)break;var s=l.alternate;if(s===null){if(n=l.return,n!==null){a=n;continue}break}if(l.child===s.child){for(s=l.child;s;){if(s===a)return ws(l),e;if(s===n)return ws(l),t;s=s.sibling}throw Error(o(188))}if(a.return!==n.return)a=l,n=s;else{for(var d=!1,f=l.child;f;){if(f===a){d=!0,a=l,n=s;break}if(f===n){d=!0,n=l,a=s;break}f=f.sibling}if(!d){for(f=s.child;f;){if(f===a){d=!0,a=s,n=l;break}if(f===n){d=!0,n=s,a=l;break}f=f.sibling}if(!d)throw Error(o(189))}}if(a.alternate!==n)throw Error(o(190))}if(a.tag!==3)throw Error(o(188));return a.stateNode.current===a?e:t}function vs(e){return e=tf(e),e!==null?Cs(e):null}function Cs(e){if(e.tag===5||e.tag===6)return e;for(e=e.child;e!==null;){var t=Cs(e);if(t!==null)return t;e=e.sibling}return null}var Ds=r.unstable_scheduleCallback,Ps=r.unstable_cancelCallback,af=r.unstable_shouldYield,rf=r.unstable_requestPaint,ge=r.unstable_now,nf=r.unstable_getCurrentPriorityLevel,Gn=r.unstable_ImmediatePriority,Ls=r.unstable_UserBlockingPriority,rr=r.unstable_NormalPriority,of=r.unstable_LowPriority,As=r.unstable_IdlePriority,nr=null,Ct=null;function lf(e){if(Ct&&typeof Ct.onCommitFiberRoot=="function")try{Ct.onCommitFiberRoot(nr,e,void 0,(e.current.flags&128)===128)}catch{}}var ft=Math.clz32?Math.clz32:uf,sf=Math.log,cf=Math.LN2;function uf(e){return e>>>=0,e===0?32:31-(sf(e)/cf|0)|0}var or=64,lr=4194304;function pi(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function sr(e,t){var a=e.pendingLanes;if(a===0)return 0;var n=0,l=e.suspendedLanes,s=e.pingedLanes,d=a&268435455;if(d!==0){var f=d&~l;f!==0?n=pi(f):(s&=d,s!==0&&(n=pi(s)))}else d=a&~l,d!==0?n=pi(d):s!==0&&(n=pi(s));if(n===0)return 0;if(t!==0&&t!==n&&(t&l)===0&&(l=n&-n,s=t&-t,l>=s||l===16&&(s&4194240)!==0))return t;if((n&4)!==0&&(n|=a&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=n;0<t;)a=31-ft(t),l=1<<a,n|=e[a],t&=~l;return n}function df(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function pf(e,t){for(var a=e.suspendedLanes,n=e.pingedLanes,l=e.expirationTimes,s=e.pendingLanes;0<s;){var d=31-ft(s),f=1<<d,m=l[d];m===-1?((f&a)===0||(f&n)!==0)&&(l[d]=df(f,t)):m<=t&&(e.expiredLanes|=f),s&=~f}}function Kn(e){return e=e.pendingLanes&-1073741825,e!==0?e:e&1073741824?1073741824:0}function Rs(){var e=or;return or<<=1,(or&4194240)===0&&(or=64),e}function Qn(e){for(var t=[],a=0;31>a;a++)t.push(e);return t}function fi(e,t,a){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-ft(t),e[t]=a}function ff(e,t){var a=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var n=e.eventTimes;for(e=e.expirationTimes;0<a;){var l=31-ft(a),s=1<<l;t[l]=0,n[l]=-1,e[l]=-1,a&=~s}}function Yn(e,t){var a=e.entangledLanes|=t;for(e=e.entanglements;a;){var n=31-ft(a),l=1<<n;l&t|e[n]&t&&(e[n]|=t),a&=~l}}var te=0;function Fs(e){return e&=-e,1<e?4<e?(e&268435455)!==0?16:536870912:4:1}var Es,$n,Ms,Is,xs,Jn=!1,cr=[],_t=null,Vt=null,zt=null,mi=new Map,hi=new Map,jt=[],mf="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function Os(e,t){switch(e){case"focusin":case"focusout":_t=null;break;case"dragenter":case"dragleave":Vt=null;break;case"mouseover":case"mouseout":zt=null;break;case"pointerover":case"pointerout":mi.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":hi.delete(t.pointerId)}}function gi(e,t,a,n,l,s){return e===null||e.nativeEvent!==s?(e={blockedOn:t,domEventName:a,eventSystemFlags:n,nativeEvent:s,targetContainers:[l]},t!==null&&(t=Fi(t),t!==null&&$n(t)),e):(e.eventSystemFlags|=n,t=e.targetContainers,l!==null&&t.indexOf(l)===-1&&t.push(l),e)}function hf(e,t,a,n,l){switch(t){case"focusin":return _t=gi(_t,e,t,a,n,l),!0;case"dragenter":return Vt=gi(Vt,e,t,a,n,l),!0;case"mouseover":return zt=gi(zt,e,t,a,n,l),!0;case"pointerover":var s=l.pointerId;return mi.set(s,gi(mi.get(s)||null,e,t,a,n,l)),!0;case"gotpointercapture":return s=l.pointerId,hi.set(s,gi(hi.get(s)||null,e,t,a,n,l)),!0}return!1}function Hs(e){var t=pa(e.target);if(t!==null){var a=da(t);if(a!==null){if(t=a.tag,t===13){if(t=Ts(a),t!==null){e.blockedOn=t,xs(e.priority,function(){Ms(a)});return}}else if(t===3&&a.stateNode.current.memoizedState.isDehydrated){e.blockedOn=a.tag===3?a.stateNode.containerInfo:null;return}}}e.blockedOn=null}function ur(e){if(e.blockedOn!==null)return!1;for(var t=e.targetContainers;0<t.length;){var a=Zn(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(a===null){a=e.nativeEvent;var n=new a.constructor(a.type,a);Un=n,a.target.dispatchEvent(n),Un=null}else return t=Fi(a),t!==null&&$n(t),e.blockedOn=a,!1;t.shift()}return!0}function Ns(e,t,a){ur(e)&&a.delete(t)}function gf(){Jn=!1,_t!==null&&ur(_t)&&(_t=null),Vt!==null&&ur(Vt)&&(Vt=null),zt!==null&&ur(zt)&&(zt=null),mi.forEach(Ns),hi.forEach(Ns)}function bi(e,t){e.blockedOn===t&&(e.blockedOn=null,Jn||(Jn=!0,r.unstable_scheduleCallback(r.unstable_NormalPriority,gf)))}function yi(e){function t(l){return bi(l,e)}if(0<cr.length){bi(cr[0],e);for(var a=1;a<cr.length;a++){var n=cr[a];n.blockedOn===e&&(n.blockedOn=null)}}for(_t!==null&&bi(_t,e),Vt!==null&&bi(Vt,e),zt!==null&&bi(zt,e),mi.forEach(t),hi.forEach(t),a=0;a<jt.length;a++)n=jt[a],n.blockedOn===e&&(n.blockedOn=null);for(;0<jt.length&&(a=jt[0],a.blockedOn===null);)Hs(a),a.blockedOn===null&&jt.shift()}var Ma=Le.ReactCurrentBatchConfig,dr=!0;function bf(e,t,a,n){var l=te,s=Ma.transition;Ma.transition=null;try{te=1,Xn(e,t,a,n)}finally{te=l,Ma.transition=s}}function yf(e,t,a,n){var l=te,s=Ma.transition;Ma.transition=null;try{te=4,Xn(e,t,a,n)}finally{te=l,Ma.transition=s}}function Xn(e,t,a,n){if(dr){var l=Zn(e,t,a,n);if(l===null)bo(e,t,n,pr,a),Os(e,n);else if(hf(l,e,t,a,n))n.stopPropagation();else if(Os(e,n),t&4&&-1<mf.indexOf(e)){for(;l!==null;){var s=Fi(l);if(s!==null&&Es(s),s=Zn(e,t,a,n),s===null&&bo(e,t,n,pr,a),s===l)break;l=s}l!==null&&n.stopPropagation()}else bo(e,t,n,null,a)}}var pr=null;function Zn(e,t,a,n){if(pr=null,e=_n(n),e=pa(e),e!==null)if(t=da(e),t===null)e=null;else if(a=t.tag,a===13){if(e=Ts(t),e!==null)return e;e=null}else if(a===3){if(t.stateNode.current.memoizedState.isDehydrated)return t.tag===3?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return pr=e,null}function Bs(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(nf()){case Gn:return 1;case Ls:return 4;case rr:case of:return 16;case As:return 536870912;default:return 16}default:return 16}}var qt=null,eo=null,fr=null;function Ws(){if(fr)return fr;var e,t=eo,a=t.length,n,l="value"in qt?qt.value:qt.textContent,s=l.length;for(e=0;e<a&&t[e]===l[e];e++);var d=a-e;for(n=1;n<=d&&t[a-n]===l[s-n];n++);return fr=l.slice(e,1<n?1-n:void 0)}function mr(e){var t=e.keyCode;return"charCode"in e?(e=e.charCode,e===0&&t===13&&(e=13)):e=t,e===10&&(e=13),32<=e||e===13?e:0}function hr(){return!0}function Us(){return!1}function $e(e){function t(a,n,l,s,d){this._reactName=a,this._targetInst=l,this.type=n,this.nativeEvent=s,this.target=d,this.currentTarget=null;for(var f in e)e.hasOwnProperty(f)&&(a=e[f],this[f]=a?a(s):s[f]);return this.isDefaultPrevented=(s.defaultPrevented!=null?s.defaultPrevented:s.returnValue===!1)?hr:Us,this.isPropagationStopped=Us,this}return I(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():typeof a.returnValue!="unknown"&&(a.returnValue=!1),this.isDefaultPrevented=hr)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():typeof a.cancelBubble!="unknown"&&(a.cancelBubble=!0),this.isPropagationStopped=hr)},persist:function(){},isPersistent:hr}),t}var Ia={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},to=$e(Ia),Si=I({},Ia,{view:0,detail:0}),Sf=$e(Si),ao,io,ki,gr=I({},Si,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:no,button:0,buttons:0,relatedTarget:function(e){return e.relatedTarget===void 0?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==ki&&(ki&&e.type==="mousemove"?(ao=e.screenX-ki.screenX,io=e.screenY-ki.screenY):io=ao=0,ki=e),ao)},movementY:function(e){return"movementY"in e?e.movementY:io}}),_s=$e(gr),kf=I({},gr,{dataTransfer:0}),Tf=$e(kf),wf=I({},Si,{relatedTarget:0}),ro=$e(wf),vf=I({},Ia,{animationName:0,elapsedTime:0,pseudoElement:0}),Cf=$e(vf),Df=I({},Ia,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),Pf=$e(Df),Lf=I({},Ia,{data:0}),Vs=$e(Lf),Af={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Rf={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Ff={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Ef(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):(e=Ff[e])?!!t[e]:!1}function no(){return Ef}var Mf=I({},Si,{key:function(e){if(e.key){var t=Af[e.key]||e.key;if(t!=="Unidentified")return t}return e.type==="keypress"?(e=mr(e),e===13?"Enter":String.fromCharCode(e)):e.type==="keydown"||e.type==="keyup"?Rf[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:no,charCode:function(e){return e.type==="keypress"?mr(e):0},keyCode:function(e){return e.type==="keydown"||e.type==="keyup"?e.keyCode:0},which:function(e){return e.type==="keypress"?mr(e):e.type==="keydown"||e.type==="keyup"?e.keyCode:0}}),If=$e(Mf),xf=I({},gr,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),zs=$e(xf),Of=I({},Si,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:no}),Hf=$e(Of),Nf=I({},Ia,{propertyName:0,elapsedTime:0,pseudoElement:0}),Bf=$e(Nf),Wf=I({},gr,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Uf=$e(Wf),_f=[9,13,27,32],oo=k&&"CompositionEvent"in window,Ti=null;k&&"documentMode"in document&&(Ti=document.documentMode);var Vf=k&&"TextEvent"in window&&!Ti,js=k&&(!oo||Ti&&8<Ti&&11>=Ti),qs=" ",Gs=!1;function Ks(e,t){switch(e){case"keyup":return _f.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Qs(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var xa=!1;function zf(e,t){switch(e){case"compositionend":return Qs(t);case"keypress":return t.which!==32?null:(Gs=!0,qs);case"textInput":return e=t.data,e===qs&&Gs?null:e;default:return null}}function jf(e,t){if(xa)return e==="compositionend"||!oo&&Ks(e,t)?(e=Ws(),fr=eo=qt=null,xa=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return js&&t.locale!=="ko"?null:t.data;default:return null}}var qf={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Ys(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t==="input"?!!qf[e.type]:t==="textarea"}function $s(e,t,a,n){gs(n),t=Tr(t,"onChange"),0<t.length&&(a=new to("onChange","change",null,a,n),e.push({event:a,listeners:t}))}var wi=null,vi=null;function Gf(e){mc(e,0)}function br(e){var t=Wa(e);if(rs(t))return e}function Kf(e,t){if(e==="change")return t}var Js=!1;if(k){var lo;if(k){var so="oninput"in document;if(!so){var Xs=document.createElement("div");Xs.setAttribute("oninput","return;"),so=typeof Xs.oninput=="function"}lo=so}else lo=!1;Js=lo&&(!document.documentMode||9<document.documentMode)}function Zs(){wi&&(wi.detachEvent("onpropertychange",ec),vi=wi=null)}function ec(e){if(e.propertyName==="value"&&br(vi)){var t=[];$s(t,vi,e,_n(e)),ks(Gf,t)}}function Qf(e,t,a){e==="focusin"?(Zs(),wi=t,vi=a,wi.attachEvent("onpropertychange",ec)):e==="focusout"&&Zs()}function Yf(e){if(e==="selectionchange"||e==="keyup"||e==="keydown")return br(vi)}function $f(e,t){if(e==="click")return br(t)}function Jf(e,t){if(e==="input"||e==="change")return br(t)}function Xf(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var mt=typeof Object.is=="function"?Object.is:Xf;function Ci(e,t){if(mt(e,t))return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;var a=Object.keys(e),n=Object.keys(t);if(a.length!==n.length)return!1;for(n=0;n<a.length;n++){var l=a[n];if(!L.call(t,l)||!mt(e[l],t[l]))return!1}return!0}function tc(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function ac(e,t){var a=tc(e);e=0;for(var n;a;){if(a.nodeType===3){if(n=e+a.textContent.length,e<=t&&n>=t)return{node:a,offset:t-e};e=n}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=tc(a)}}function ic(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?ic(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function rc(){for(var e=window,t=er();t instanceof e.HTMLIFrameElement;){try{var a=typeof t.contentWindow.location.href=="string"}catch{a=!1}if(a)e=t.contentWindow;else break;t=er(e.document)}return t}function co(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Zf(e){var t=rc(),a=e.focusedElem,n=e.selectionRange;if(t!==a&&a&&a.ownerDocument&&ic(a.ownerDocument.documentElement,a)){if(n!==null&&co(a)){if(t=n.start,e=n.end,e===void 0&&(e=t),"selectionStart"in a)a.selectionStart=t,a.selectionEnd=Math.min(e,a.value.length);else if(e=(t=a.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var l=a.textContent.length,s=Math.min(n.start,l);n=n.end===void 0?s:Math.min(n.end,l),!e.extend&&s>n&&(l=n,n=s,s=l),l=ac(a,s);var d=ac(a,n);l&&d&&(e.rangeCount!==1||e.anchorNode!==l.node||e.anchorOffset!==l.offset||e.focusNode!==d.node||e.focusOffset!==d.offset)&&(t=t.createRange(),t.setStart(l.node,l.offset),e.removeAllRanges(),s>n?(e.addRange(t),e.extend(d.node,d.offset)):(t.setEnd(d.node,d.offset),e.addRange(t)))}}for(t=[],e=a;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof a.focus=="function"&&a.focus(),a=0;a<t.length;a++)e=t[a],e.element.scrollLeft=e.left,e.element.scrollTop=e.top}}var em=k&&"documentMode"in document&&11>=document.documentMode,Oa=null,uo=null,Di=null,po=!1;function nc(e,t,a){var n=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;po||Oa==null||Oa!==er(n)||(n=Oa,"selectionStart"in n&&co(n)?n={start:n.selectionStart,end:n.selectionEnd}:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset}),Di&&Ci(Di,n)||(Di=n,n=Tr(uo,"onSelect"),0<n.length&&(t=new to("onSelect","select",null,t,a),e.push({event:t,listeners:n}),t.target=Oa)))}function yr(e,t){var a={};return a[e.toLowerCase()]=t.toLowerCase(),a["Webkit"+e]="webkit"+t,a["Moz"+e]="moz"+t,a}var Ha={animationend:yr("Animation","AnimationEnd"),animationiteration:yr("Animation","AnimationIteration"),animationstart:yr("Animation","AnimationStart"),transitionend:yr("Transition","TransitionEnd")},fo={},oc={};k&&(oc=document.createElement("div").style,"AnimationEvent"in window||(delete Ha.animationend.animation,delete Ha.animationiteration.animation,delete Ha.animationstart.animation),"TransitionEvent"in window||delete Ha.transitionend.transition);function Sr(e){if(fo[e])return fo[e];if(!Ha[e])return e;var t=Ha[e],a;for(a in t)if(t.hasOwnProperty(a)&&a in oc)return fo[e]=t[a];return e}var lc=Sr("animationend"),sc=Sr("animationiteration"),cc=Sr("animationstart"),uc=Sr("transitionend"),dc=new Map,pc="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Gt(e,t){dc.set(e,t),p(t,[e])}for(var mo=0;mo<pc.length;mo++){var ho=pc[mo],tm=ho.toLowerCase(),am=ho[0].toUpperCase()+ho.slice(1);Gt(tm,"on"+am)}Gt(lc,"onAnimationEnd"),Gt(sc,"onAnimationIteration"),Gt(cc,"onAnimationStart"),Gt("dblclick","onDoubleClick"),Gt("focusin","onFocus"),Gt("focusout","onBlur"),Gt(uc,"onTransitionEnd"),y("onMouseEnter",["mouseout","mouseover"]),y("onMouseLeave",["mouseout","mouseover"]),y("onPointerEnter",["pointerout","pointerover"]),y("onPointerLeave",["pointerout","pointerover"]),p("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),p("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),p("onBeforeInput",["compositionend","keypress","textInput","paste"]),p("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),p("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),p("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Pi="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),im=new Set("cancel close invalid load scroll toggle".split(" ").concat(Pi));function fc(e,t,a){var n=e.type||"unknown-event";e.currentTarget=a,ef(n,t,void 0,e),e.currentTarget=null}function mc(e,t){t=(t&4)!==0;for(var a=0;a<e.length;a++){var n=e[a],l=n.event;n=n.listeners;e:{var s=void 0;if(t)for(var d=n.length-1;0<=d;d--){var f=n[d],m=f.instance,T=f.currentTarget;if(f=f.listener,m!==s&&l.isPropagationStopped())break e;fc(l,f,T),s=m}else for(d=0;d<n.length;d++){if(f=n[d],m=f.instance,T=f.currentTarget,f=f.listener,m!==s&&l.isPropagationStopped())break e;fc(l,f,T),s=m}}}if(ir)throw e=qn,ir=!1,qn=null,e}function oe(e,t){var a=t[vo];a===void 0&&(a=t[vo]=new Set);var n=e+"__bubble";a.has(n)||(hc(t,e,2,!1),a.add(n))}function go(e,t,a){var n=0;t&&(n|=4),hc(a,e,n,t)}var kr="_reactListening"+Math.random().toString(36).slice(2);function Li(e){if(!e[kr]){e[kr]=!0,c.forEach(function(a){a!=="selectionchange"&&(im.has(a)||go(a,!1,e),go(a,!0,e))});var t=e.nodeType===9?e:e.ownerDocument;t===null||t[kr]||(t[kr]=!0,go("selectionchange",!1,t))}}function hc(e,t,a,n){switch(Bs(t)){case 1:var l=bf;break;case 4:l=yf;break;default:l=Xn}a=l.bind(null,t,a,e),l=void 0,!jn||t!=="touchstart"&&t!=="touchmove"&&t!=="wheel"||(l=!0),n?l!==void 0?e.addEventListener(t,a,{capture:!0,passive:l}):e.addEventListener(t,a,!0):l!==void 0?e.addEventListener(t,a,{passive:l}):e.addEventListener(t,a,!1)}function bo(e,t,a,n,l){var s=n;if((t&1)===0&&(t&2)===0&&n!==null)e:for(;;){if(n===null)return;var d=n.tag;if(d===3||d===4){var f=n.stateNode.containerInfo;if(f===l||f.nodeType===8&&f.parentNode===l)break;if(d===4)for(d=n.return;d!==null;){var m=d.tag;if((m===3||m===4)&&(m=d.stateNode.containerInfo,m===l||m.nodeType===8&&m.parentNode===l))return;d=d.return}for(;f!==null;){if(d=pa(f),d===null)return;if(m=d.tag,m===5||m===6){n=s=d;continue e}f=f.parentNode}}n=n.return}ks(function(){var T=s,C=_n(a),D=[];e:{var w=dc.get(e);if(w!==void 0){var F=to,x=e;switch(e){case"keypress":if(mr(a)===0)break e;case"keydown":case"keyup":F=If;break;case"focusin":x="focus",F=ro;break;case"focusout":x="blur",F=ro;break;case"beforeblur":case"afterblur":F=ro;break;case"click":if(a.button===2)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":F=_s;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":F=Tf;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":F=Hf;break;case lc:case sc:case cc:F=Cf;break;case uc:F=Bf;break;case"scroll":F=Sf;break;case"wheel":F=Uf;break;case"copy":case"cut":case"paste":F=Pf;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":F=zs}var H=(t&4)!==0,be=!H&&e==="scroll",b=H?w!==null?w+"Capture":null:w;H=[];for(var h=T,S;h!==null;){S=h;var P=S.stateNode;if(S.tag===5&&P!==null&&(S=P,b!==null&&(P=ci(h,b),P!=null&&H.push(Ai(h,P,S)))),be)break;h=h.return}0<H.length&&(w=new F(w,x,null,a,C),D.push({event:w,listeners:H}))}}if((t&7)===0){e:{if(w=e==="mouseover"||e==="pointerover",F=e==="mouseout"||e==="pointerout",w&&a!==Un&&(x=a.relatedTarget||a.fromElement)&&(pa(x)||x[Mt]))break e;if((F||w)&&(w=C.window===C?C:(w=C.ownerDocument)?w.defaultView||w.parentWindow:window,F?(x=a.relatedTarget||a.toElement,F=T,x=x?pa(x):null,x!==null&&(be=da(x),x!==be||x.tag!==5&&x.tag!==6)&&(x=null)):(F=null,x=T),F!==x)){if(H=_s,P="onMouseLeave",b="onMouseEnter",h="mouse",(e==="pointerout"||e==="pointerover")&&(H=zs,P="onPointerLeave",b="onPointerEnter",h="pointer"),be=F==null?w:Wa(F),S=x==null?w:Wa(x),w=new H(P,h+"leave",F,a,C),w.target=be,w.relatedTarget=S,P=null,pa(C)===T&&(H=new H(b,h+"enter",x,a,C),H.target=S,H.relatedTarget=be,P=H),be=P,F&&x)t:{for(H=F,b=x,h=0,S=H;S;S=Na(S))h++;for(S=0,P=b;P;P=Na(P))S++;for(;0<h-S;)H=Na(H),h--;for(;0<S-h;)b=Na(b),S--;for(;h--;){if(H===b||b!==null&&H===b.alternate)break t;H=Na(H),b=Na(b)}H=null}else H=null;F!==null&&gc(D,w,F,H,!1),x!==null&&be!==null&&gc(D,be,x,H,!0)}}e:{if(w=T?Wa(T):window,F=w.nodeName&&w.nodeName.toLowerCase(),F==="select"||F==="input"&&w.type==="file")var N=Kf;else if(Ys(w))if(Js)N=Jf;else{N=Yf;var W=Qf}else(F=w.nodeName)&&F.toLowerCase()==="input"&&(w.type==="checkbox"||w.type==="radio")&&(N=$f);if(N&&(N=N(e,T))){$s(D,N,a,C);break e}W&&W(e,w,T),e==="focusout"&&(W=w._wrapperState)&&W.controlled&&w.type==="number"&&On(w,"number",w.value)}switch(W=T?Wa(T):window,e){case"focusin":(Ys(W)||W.contentEditable==="true")&&(Oa=W,uo=T,Di=null);break;case"focusout":Di=uo=Oa=null;break;case"mousedown":po=!0;break;case"contextmenu":case"mouseup":case"dragend":po=!1,nc(D,a,C);break;case"selectionchange":if(em)break;case"keydown":case"keyup":nc(D,a,C)}var U;if(oo)e:{switch(e){case"compositionstart":var z="onCompositionStart";break e;case"compositionend":z="onCompositionEnd";break e;case"compositionupdate":z="onCompositionUpdate";break e}z=void 0}else xa?Ks(e,a)&&(z="onCompositionEnd"):e==="keydown"&&a.keyCode===229&&(z="onCompositionStart");z&&(js&&a.locale!=="ko"&&(xa||z!=="onCompositionStart"?z==="onCompositionEnd"&&xa&&(U=Ws()):(qt=C,eo="value"in qt?qt.value:qt.textContent,xa=!0)),W=Tr(T,z),0<W.length&&(z=new Vs(z,e,null,a,C),D.push({event:z,listeners:W}),U?z.data=U:(U=Qs(a),U!==null&&(z.data=U)))),(U=Vf?zf(e,a):jf(e,a))&&(T=Tr(T,"onBeforeInput"),0<T.length&&(C=new Vs("onBeforeInput","beforeinput",null,a,C),D.push({event:C,listeners:T}),C.data=U))}mc(D,t)})}function Ai(e,t,a){return{instance:e,listener:t,currentTarget:a}}function Tr(e,t){for(var a=t+"Capture",n=[];e!==null;){var l=e,s=l.stateNode;l.tag===5&&s!==null&&(l=s,s=ci(e,a),s!=null&&n.unshift(Ai(e,s,l)),s=ci(e,t),s!=null&&n.push(Ai(e,s,l))),e=e.return}return n}function Na(e){if(e===null)return null;do e=e.return;while(e&&e.tag!==5);return e||null}function gc(e,t,a,n,l){for(var s=t._reactName,d=[];a!==null&&a!==n;){var f=a,m=f.alternate,T=f.stateNode;if(m!==null&&m===n)break;f.tag===5&&T!==null&&(f=T,l?(m=ci(a,s),m!=null&&d.unshift(Ai(a,m,f))):l||(m=ci(a,s),m!=null&&d.push(Ai(a,m,f)))),a=a.return}d.length!==0&&e.push({event:t,listeners:d})}var rm=/\r\n?/g,nm=/\u0000|\uFFFD/g;function bc(e){return(typeof e=="string"?e:""+e).replace(rm,`
39
+ `).replace(nm,"")}function wr(e,t,a){if(t=bc(t),bc(e)!==t&&a)throw Error(o(425))}function vr(){}var yo=null,So=null;function ko(e,t){return e==="textarea"||e==="noscript"||typeof t.children=="string"||typeof t.children=="number"||typeof t.dangerouslySetInnerHTML=="object"&&t.dangerouslySetInnerHTML!==null&&t.dangerouslySetInnerHTML.__html!=null}var To=typeof setTimeout=="function"?setTimeout:void 0,om=typeof clearTimeout=="function"?clearTimeout:void 0,yc=typeof Promise=="function"?Promise:void 0,lm=typeof queueMicrotask=="function"?queueMicrotask:typeof yc<"u"?function(e){return yc.resolve(null).then(e).catch(sm)}:To;function sm(e){setTimeout(function(){throw e})}function wo(e,t){var a=t,n=0;do{var l=a.nextSibling;if(e.removeChild(a),l&&l.nodeType===8)if(a=l.data,a==="/$"){if(n===0){e.removeChild(l),yi(t);return}n--}else a!=="$"&&a!=="$?"&&a!=="$!"||n++;a=l}while(a);yi(t)}function Kt(e){for(;e!=null;e=e.nextSibling){var t=e.nodeType;if(t===1||t===3)break;if(t===8){if(t=e.data,t==="$"||t==="$!"||t==="$?")break;if(t==="/$")return null}}return e}function Sc(e){e=e.previousSibling;for(var t=0;e;){if(e.nodeType===8){var a=e.data;if(a==="$"||a==="$!"||a==="$?"){if(t===0)return e;t--}else a==="/$"&&t++}e=e.previousSibling}return null}var Ba=Math.random().toString(36).slice(2),Dt="__reactFiber$"+Ba,Ri="__reactProps$"+Ba,Mt="__reactContainer$"+Ba,vo="__reactEvents$"+Ba,cm="__reactListeners$"+Ba,um="__reactHandles$"+Ba;function pa(e){var t=e[Dt];if(t)return t;for(var a=e.parentNode;a;){if(t=a[Mt]||a[Dt]){if(a=t.alternate,t.child!==null||a!==null&&a.child!==null)for(e=Sc(e);e!==null;){if(a=e[Dt])return a;e=Sc(e)}return t}e=a,a=e.parentNode}return null}function Fi(e){return e=e[Dt]||e[Mt],!e||e.tag!==5&&e.tag!==6&&e.tag!==13&&e.tag!==3?null:e}function Wa(e){if(e.tag===5||e.tag===6)return e.stateNode;throw Error(o(33))}function Cr(e){return e[Ri]||null}var Co=[],Ua=-1;function Qt(e){return{current:e}}function le(e){0>Ua||(e.current=Co[Ua],Co[Ua]=null,Ua--)}function ne(e,t){Ua++,Co[Ua]=e.current,e.current=t}var Yt={},Ae=Qt(Yt),Ve=Qt(!1),fa=Yt;function _a(e,t){var a=e.type.contextTypes;if(!a)return Yt;var n=e.stateNode;if(n&&n.__reactInternalMemoizedUnmaskedChildContext===t)return n.__reactInternalMemoizedMaskedChildContext;var l={},s;for(s in a)l[s]=t[s];return n&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=l),l}function ze(e){return e=e.childContextTypes,e!=null}function Dr(){le(Ve),le(Ae)}function kc(e,t,a){if(Ae.current!==Yt)throw Error(o(168));ne(Ae,t),ne(Ve,a)}function Tc(e,t,a){var n=e.stateNode;if(t=t.childContextTypes,typeof n.getChildContext!="function")return a;n=n.getChildContext();for(var l in n)if(!(l in t))throw Error(o(108,re(e)||"Unknown",l));return I({},a,n)}function Pr(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Yt,fa=Ae.current,ne(Ae,e),ne(Ve,Ve.current),!0}function wc(e,t,a){var n=e.stateNode;if(!n)throw Error(o(169));a?(e=Tc(e,t,fa),n.__reactInternalMemoizedMergedChildContext=e,le(Ve),le(Ae),ne(Ae,e)):le(Ve),ne(Ve,a)}var It=null,Lr=!1,Do=!1;function vc(e){It===null?It=[e]:It.push(e)}function dm(e){Lr=!0,vc(e)}function $t(){if(!Do&&It!==null){Do=!0;var e=0,t=te;try{var a=It;for(te=1;e<a.length;e++){var n=a[e];do n=n(!0);while(n!==null)}It=null,Lr=!1}catch(l){throw It!==null&&(It=It.slice(e+1)),Ds(Gn,$t),l}finally{te=t,Do=!1}}return null}var Va=[],za=0,Ar=null,Rr=0,it=[],rt=0,ma=null,xt=1,Ot="";function ha(e,t){Va[za++]=Rr,Va[za++]=Ar,Ar=e,Rr=t}function Cc(e,t,a){it[rt++]=xt,it[rt++]=Ot,it[rt++]=ma,ma=e;var n=xt;e=Ot;var l=32-ft(n)-1;n&=~(1<<l),a+=1;var s=32-ft(t)+l;if(30<s){var d=l-l%5;s=(n&(1<<d)-1).toString(32),n>>=d,l-=d,xt=1<<32-ft(t)+l|a<<l|n,Ot=s+e}else xt=1<<s|a<<l|n,Ot=e}function Po(e){e.return!==null&&(ha(e,1),Cc(e,1,0))}function Lo(e){for(;e===Ar;)Ar=Va[--za],Va[za]=null,Rr=Va[--za],Va[za]=null;for(;e===ma;)ma=it[--rt],it[rt]=null,Ot=it[--rt],it[rt]=null,xt=it[--rt],it[rt]=null}var Je=null,Xe=null,de=!1,ht=null;function Dc(e,t){var a=st(5,null,null,0);a.elementType="DELETED",a.stateNode=t,a.return=e,t=e.deletions,t===null?(e.deletions=[a],e.flags|=16):t.push(a)}function Pc(e,t){switch(e.tag){case 5:var a=e.type;return t=t.nodeType!==1||a.toLowerCase()!==t.nodeName.toLowerCase()?null:t,t!==null?(e.stateNode=t,Je=e,Xe=Kt(t.firstChild),!0):!1;case 6:return t=e.pendingProps===""||t.nodeType!==3?null:t,t!==null?(e.stateNode=t,Je=e,Xe=null,!0):!1;case 13:return t=t.nodeType!==8?null:t,t!==null?(a=ma!==null?{id:xt,overflow:Ot}:null,e.memoizedState={dehydrated:t,treeContext:a,retryLane:1073741824},a=st(18,null,null,0),a.stateNode=t,a.return=e,e.child=a,Je=e,Xe=null,!0):!1;default:return!1}}function Ao(e){return(e.mode&1)!==0&&(e.flags&128)===0}function Ro(e){if(de){var t=Xe;if(t){var a=t;if(!Pc(e,t)){if(Ao(e))throw Error(o(418));t=Kt(a.nextSibling);var n=Je;t&&Pc(e,t)?Dc(n,a):(e.flags=e.flags&-4097|2,de=!1,Je=e)}}else{if(Ao(e))throw Error(o(418));e.flags=e.flags&-4097|2,de=!1,Je=e}}}function Lc(e){for(e=e.return;e!==null&&e.tag!==5&&e.tag!==3&&e.tag!==13;)e=e.return;Je=e}function Fr(e){if(e!==Je)return!1;if(!de)return Lc(e),de=!0,!1;var t;if((t=e.tag!==3)&&!(t=e.tag!==5)&&(t=e.type,t=t!=="head"&&t!=="body"&&!ko(e.type,e.memoizedProps)),t&&(t=Xe)){if(Ao(e))throw Ac(),Error(o(418));for(;t;)Dc(e,t),t=Kt(t.nextSibling)}if(Lc(e),e.tag===13){if(e=e.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(o(317));e:{for(e=e.nextSibling,t=0;e;){if(e.nodeType===8){var a=e.data;if(a==="/$"){if(t===0){Xe=Kt(e.nextSibling);break e}t--}else a!=="$"&&a!=="$!"&&a!=="$?"||t++}e=e.nextSibling}Xe=null}}else Xe=Je?Kt(e.stateNode.nextSibling):null;return!0}function Ac(){for(var e=Xe;e;)e=Kt(e.nextSibling)}function ja(){Xe=Je=null,de=!1}function Fo(e){ht===null?ht=[e]:ht.push(e)}var pm=Le.ReactCurrentBatchConfig;function Ei(e,t,a){if(e=a.ref,e!==null&&typeof e!="function"&&typeof e!="object"){if(a._owner){if(a=a._owner,a){if(a.tag!==1)throw Error(o(309));var n=a.stateNode}if(!n)throw Error(o(147,e));var l=n,s=""+e;return t!==null&&t.ref!==null&&typeof t.ref=="function"&&t.ref._stringRef===s?t.ref:(t=function(d){var f=l.refs;d===null?delete f[s]:f[s]=d},t._stringRef=s,t)}if(typeof e!="string")throw Error(o(284));if(!a._owner)throw Error(o(290,e))}return e}function Er(e,t){throw e=Object.prototype.toString.call(t),Error(o(31,e==="[object Object]"?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function Rc(e){var t=e._init;return t(e._payload)}function Fc(e){function t(b,h){if(e){var S=b.deletions;S===null?(b.deletions=[h],b.flags|=16):S.push(h)}}function a(b,h){if(!e)return null;for(;h!==null;)t(b,h),h=h.sibling;return null}function n(b,h){for(b=new Map;h!==null;)h.key!==null?b.set(h.key,h):b.set(h.index,h),h=h.sibling;return b}function l(b,h){return b=ra(b,h),b.index=0,b.sibling=null,b}function s(b,h,S){return b.index=S,e?(S=b.alternate,S!==null?(S=S.index,S<h?(b.flags|=2,h):S):(b.flags|=2,h)):(b.flags|=1048576,h)}function d(b){return e&&b.alternate===null&&(b.flags|=2),b}function f(b,h,S,P){return h===null||h.tag!==6?(h=Tl(S,b.mode,P),h.return=b,h):(h=l(h,S),h.return=b,h)}function m(b,h,S,P){var N=S.type;return N===Ue?C(b,h,S.props.children,P,S.key):h!==null&&(h.elementType===N||typeof N=="object"&&N!==null&&N.$$typeof===_e&&Rc(N)===h.type)?(P=l(h,S.props),P.ref=Ei(b,h,S),P.return=b,P):(P=tn(S.type,S.key,S.props,null,b.mode,P),P.ref=Ei(b,h,S),P.return=b,P)}function T(b,h,S,P){return h===null||h.tag!==4||h.stateNode.containerInfo!==S.containerInfo||h.stateNode.implementation!==S.implementation?(h=wl(S,b.mode,P),h.return=b,h):(h=l(h,S.children||[]),h.return=b,h)}function C(b,h,S,P,N){return h===null||h.tag!==7?(h=va(S,b.mode,P,N),h.return=b,h):(h=l(h,S),h.return=b,h)}function D(b,h,S){if(typeof h=="string"&&h!==""||typeof h=="number")return h=Tl(""+h,b.mode,S),h.return=b,h;if(typeof h=="object"&&h!==null){switch(h.$$typeof){case dt:return S=tn(h.type,h.key,h.props,null,b.mode,S),S.ref=Ei(b,null,h),S.return=b,S;case Ie:return h=wl(h,b.mode,S),h.return=b,h;case _e:var P=h._init;return D(b,P(h._payload),S)}if(oi(h)||V(h))return h=va(h,b.mode,S,null),h.return=b,h;Er(b,h)}return null}function w(b,h,S,P){var N=h!==null?h.key:null;if(typeof S=="string"&&S!==""||typeof S=="number")return N!==null?null:f(b,h,""+S,P);if(typeof S=="object"&&S!==null){switch(S.$$typeof){case dt:return S.key===N?m(b,h,S,P):null;case Ie:return S.key===N?T(b,h,S,P):null;case _e:return N=S._init,w(b,h,N(S._payload),P)}if(oi(S)||V(S))return N!==null?null:C(b,h,S,P,null);Er(b,S)}return null}function F(b,h,S,P,N){if(typeof P=="string"&&P!==""||typeof P=="number")return b=b.get(S)||null,f(h,b,""+P,N);if(typeof P=="object"&&P!==null){switch(P.$$typeof){case dt:return b=b.get(P.key===null?S:P.key)||null,m(h,b,P,N);case Ie:return b=b.get(P.key===null?S:P.key)||null,T(h,b,P,N);case _e:var W=P._init;return F(b,h,S,W(P._payload),N)}if(oi(P)||V(P))return b=b.get(S)||null,C(h,b,P,N,null);Er(h,P)}return null}function x(b,h,S,P){for(var N=null,W=null,U=h,z=h=0,ve=null;U!==null&&z<S.length;z++){U.index>z?(ve=U,U=null):ve=U.sibling;var J=w(b,U,S[z],P);if(J===null){U===null&&(U=ve);break}e&&U&&J.alternate===null&&t(b,U),h=s(J,h,z),W===null?N=J:W.sibling=J,W=J,U=ve}if(z===S.length)return a(b,U),de&&ha(b,z),N;if(U===null){for(;z<S.length;z++)U=D(b,S[z],P),U!==null&&(h=s(U,h,z),W===null?N=U:W.sibling=U,W=U);return de&&ha(b,z),N}for(U=n(b,U);z<S.length;z++)ve=F(U,b,z,S[z],P),ve!==null&&(e&&ve.alternate!==null&&U.delete(ve.key===null?z:ve.key),h=s(ve,h,z),W===null?N=ve:W.sibling=ve,W=ve);return e&&U.forEach(function(na){return t(b,na)}),de&&ha(b,z),N}function H(b,h,S,P){var N=V(S);if(typeof N!="function")throw Error(o(150));if(S=N.call(S),S==null)throw Error(o(151));for(var W=N=null,U=h,z=h=0,ve=null,J=S.next();U!==null&&!J.done;z++,J=S.next()){U.index>z?(ve=U,U=null):ve=U.sibling;var na=w(b,U,J.value,P);if(na===null){U===null&&(U=ve);break}e&&U&&na.alternate===null&&t(b,U),h=s(na,h,z),W===null?N=na:W.sibling=na,W=na,U=ve}if(J.done)return a(b,U),de&&ha(b,z),N;if(U===null){for(;!J.done;z++,J=S.next())J=D(b,J.value,P),J!==null&&(h=s(J,h,z),W===null?N=J:W.sibling=J,W=J);return de&&ha(b,z),N}for(U=n(b,U);!J.done;z++,J=S.next())J=F(U,b,z,J.value,P),J!==null&&(e&&J.alternate!==null&&U.delete(J.key===null?z:J.key),h=s(J,h,z),W===null?N=J:W.sibling=J,W=J);return e&&U.forEach(function(qm){return t(b,qm)}),de&&ha(b,z),N}function be(b,h,S,P){if(typeof S=="object"&&S!==null&&S.type===Ue&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case dt:e:{for(var N=S.key,W=h;W!==null;){if(W.key===N){if(N=S.type,N===Ue){if(W.tag===7){a(b,W.sibling),h=l(W,S.props.children),h.return=b,b=h;break e}}else if(W.elementType===N||typeof N=="object"&&N!==null&&N.$$typeof===_e&&Rc(N)===W.type){a(b,W.sibling),h=l(W,S.props),h.ref=Ei(b,W,S),h.return=b,b=h;break e}a(b,W);break}else t(b,W);W=W.sibling}S.type===Ue?(h=va(S.props.children,b.mode,P,S.key),h.return=b,b=h):(P=tn(S.type,S.key,S.props,null,b.mode,P),P.ref=Ei(b,h,S),P.return=b,b=P)}return d(b);case Ie:e:{for(W=S.key;h!==null;){if(h.key===W)if(h.tag===4&&h.stateNode.containerInfo===S.containerInfo&&h.stateNode.implementation===S.implementation){a(b,h.sibling),h=l(h,S.children||[]),h.return=b,b=h;break e}else{a(b,h);break}else t(b,h);h=h.sibling}h=wl(S,b.mode,P),h.return=b,b=h}return d(b);case _e:return W=S._init,be(b,h,W(S._payload),P)}if(oi(S))return x(b,h,S,P);if(V(S))return H(b,h,S,P);Er(b,S)}return typeof S=="string"&&S!==""||typeof S=="number"?(S=""+S,h!==null&&h.tag===6?(a(b,h.sibling),h=l(h,S),h.return=b,b=h):(a(b,h),h=Tl(S,b.mode,P),h.return=b,b=h),d(b)):a(b,h)}return be}var qa=Fc(!0),Ec=Fc(!1),Mr=Qt(null),Ir=null,Ga=null,Eo=null;function Mo(){Eo=Ga=Ir=null}function Io(e){var t=Mr.current;le(Mr),e._currentValue=t}function xo(e,t,a){for(;e!==null;){var n=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,n!==null&&(n.childLanes|=t)):n!==null&&(n.childLanes&t)!==t&&(n.childLanes|=t),e===a)break;e=e.return}}function Ka(e,t){Ir=e,Eo=Ga=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(je=!0),e.firstContext=null)}function nt(e){var t=e._currentValue;if(Eo!==e)if(e={context:e,memoizedValue:t,next:null},Ga===null){if(Ir===null)throw Error(o(308));Ga=e,Ir.dependencies={lanes:0,firstContext:e}}else Ga=Ga.next=e;return t}var ga=null;function Oo(e){ga===null?ga=[e]:ga.push(e)}function Mc(e,t,a,n){var l=t.interleaved;return l===null?(a.next=a,Oo(t)):(a.next=l.next,l.next=a),t.interleaved=a,Ht(e,n)}function Ht(e,t){e.lanes|=t;var a=e.alternate;for(a!==null&&(a.lanes|=t),a=e,e=e.return;e!==null;)e.childLanes|=t,a=e.alternate,a!==null&&(a.childLanes|=t),a=e,e=e.return;return a.tag===3?a.stateNode:null}var Jt=!1;function Ho(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ic(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Nt(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Xt(e,t,a){var n=e.updateQueue;if(n===null)return null;if(n=n.shared,(Q&2)!==0){var l=n.pending;return l===null?t.next=t:(t.next=l.next,l.next=t),n.pending=t,Ht(e,a)}return l=n.interleaved,l===null?(t.next=t,Oo(n)):(t.next=l.next,l.next=t),n.interleaved=t,Ht(e,a)}function xr(e,t,a){if(t=t.updateQueue,t!==null&&(t=t.shared,(a&4194240)!==0)){var n=t.lanes;n&=e.pendingLanes,a|=n,t.lanes=a,Yn(e,a)}}function xc(e,t){var a=e.updateQueue,n=e.alternate;if(n!==null&&(n=n.updateQueue,a===n)){var l=null,s=null;if(a=a.firstBaseUpdate,a!==null){do{var d={eventTime:a.eventTime,lane:a.lane,tag:a.tag,payload:a.payload,callback:a.callback,next:null};s===null?l=s=d:s=s.next=d,a=a.next}while(a!==null);s===null?l=s=t:s=s.next=t}else l=s=t;a={baseState:n.baseState,firstBaseUpdate:l,lastBaseUpdate:s,shared:n.shared,effects:n.effects},e.updateQueue=a;return}e=a.lastBaseUpdate,e===null?a.firstBaseUpdate=t:e.next=t,a.lastBaseUpdate=t}function Or(e,t,a,n){var l=e.updateQueue;Jt=!1;var s=l.firstBaseUpdate,d=l.lastBaseUpdate,f=l.shared.pending;if(f!==null){l.shared.pending=null;var m=f,T=m.next;m.next=null,d===null?s=T:d.next=T,d=m;var C=e.alternate;C!==null&&(C=C.updateQueue,f=C.lastBaseUpdate,f!==d&&(f===null?C.firstBaseUpdate=T:f.next=T,C.lastBaseUpdate=m))}if(s!==null){var D=l.baseState;d=0,C=T=m=null,f=s;do{var w=f.lane,F=f.eventTime;if((n&w)===w){C!==null&&(C=C.next={eventTime:F,lane:0,tag:f.tag,payload:f.payload,callback:f.callback,next:null});e:{var x=e,H=f;switch(w=t,F=a,H.tag){case 1:if(x=H.payload,typeof x=="function"){D=x.call(F,D,w);break e}D=x;break e;case 3:x.flags=x.flags&-65537|128;case 0:if(x=H.payload,w=typeof x=="function"?x.call(F,D,w):x,w==null)break e;D=I({},D,w);break e;case 2:Jt=!0}}f.callback!==null&&f.lane!==0&&(e.flags|=64,w=l.effects,w===null?l.effects=[f]:w.push(f))}else F={eventTime:F,lane:w,tag:f.tag,payload:f.payload,callback:f.callback,next:null},C===null?(T=C=F,m=D):C=C.next=F,d|=w;if(f=f.next,f===null){if(f=l.shared.pending,f===null)break;w=f,f=w.next,w.next=null,l.lastBaseUpdate=w,l.shared.pending=null}}while(!0);if(C===null&&(m=D),l.baseState=m,l.firstBaseUpdate=T,l.lastBaseUpdate=C,t=l.shared.interleaved,t!==null){l=t;do d|=l.lane,l=l.next;while(l!==t)}else s===null&&(l.shared.lanes=0);Sa|=d,e.lanes=d,e.memoizedState=D}}function Oc(e,t,a){if(e=t.effects,t.effects=null,e!==null)for(t=0;t<e.length;t++){var n=e[t],l=n.callback;if(l!==null){if(n.callback=null,n=a,typeof l!="function")throw Error(o(191,l));l.call(n)}}}var Mi={},Pt=Qt(Mi),Ii=Qt(Mi),xi=Qt(Mi);function ba(e){if(e===Mi)throw Error(o(174));return e}function No(e,t){switch(ne(xi,t),ne(Ii,e),ne(Pt,Mi),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:Nn(null,"");break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=Nn(t,e)}le(Pt),ne(Pt,t)}function Qa(){le(Pt),le(Ii),le(xi)}function Hc(e){ba(xi.current);var t=ba(Pt.current),a=Nn(t,e.type);t!==a&&(ne(Ii,e),ne(Pt,a))}function Bo(e){Ii.current===e&&(le(Pt),le(Ii))}var pe=Qt(0);function Hr(e){for(var t=e;t!==null;){if(t.tag===13){var a=t.memoizedState;if(a!==null&&(a=a.dehydrated,a===null||a.data==="$?"||a.data==="$!"))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if((t.flags&128)!==0)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Wo=[];function Uo(){for(var e=0;e<Wo.length;e++)Wo[e]._workInProgressVersionPrimary=null;Wo.length=0}var Nr=Le.ReactCurrentDispatcher,_o=Le.ReactCurrentBatchConfig,ya=0,fe=null,Se=null,Te=null,Br=!1,Oi=!1,Hi=0,fm=0;function Re(){throw Error(o(321))}function Vo(e,t){if(t===null)return!1;for(var a=0;a<t.length&&a<e.length;a++)if(!mt(e[a],t[a]))return!1;return!0}function zo(e,t,a,n,l,s){if(ya=s,fe=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Nr.current=e===null||e.memoizedState===null?bm:ym,e=a(n,l),Oi){s=0;do{if(Oi=!1,Hi=0,25<=s)throw Error(o(301));s+=1,Te=Se=null,t.updateQueue=null,Nr.current=Sm,e=a(n,l)}while(Oi)}if(Nr.current=_r,t=Se!==null&&Se.next!==null,ya=0,Te=Se=fe=null,Br=!1,t)throw Error(o(300));return e}function jo(){var e=Hi!==0;return Hi=0,e}function Lt(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return Te===null?fe.memoizedState=Te=e:Te=Te.next=e,Te}function ot(){if(Se===null){var e=fe.alternate;e=e!==null?e.memoizedState:null}else e=Se.next;var t=Te===null?fe.memoizedState:Te.next;if(t!==null)Te=t,Se=e;else{if(e===null)throw Error(o(310));Se=e,e={memoizedState:Se.memoizedState,baseState:Se.baseState,baseQueue:Se.baseQueue,queue:Se.queue,next:null},Te===null?fe.memoizedState=Te=e:Te=Te.next=e}return Te}function Ni(e,t){return typeof t=="function"?t(e):t}function qo(e){var t=ot(),a=t.queue;if(a===null)throw Error(o(311));a.lastRenderedReducer=e;var n=Se,l=n.baseQueue,s=a.pending;if(s!==null){if(l!==null){var d=l.next;l.next=s.next,s.next=d}n.baseQueue=l=s,a.pending=null}if(l!==null){s=l.next,n=n.baseState;var f=d=null,m=null,T=s;do{var C=T.lane;if((ya&C)===C)m!==null&&(m=m.next={lane:0,action:T.action,hasEagerState:T.hasEagerState,eagerState:T.eagerState,next:null}),n=T.hasEagerState?T.eagerState:e(n,T.action);else{var D={lane:C,action:T.action,hasEagerState:T.hasEagerState,eagerState:T.eagerState,next:null};m===null?(f=m=D,d=n):m=m.next=D,fe.lanes|=C,Sa|=C}T=T.next}while(T!==null&&T!==s);m===null?d=n:m.next=f,mt(n,t.memoizedState)||(je=!0),t.memoizedState=n,t.baseState=d,t.baseQueue=m,a.lastRenderedState=n}if(e=a.interleaved,e!==null){l=e;do s=l.lane,fe.lanes|=s,Sa|=s,l=l.next;while(l!==e)}else l===null&&(a.lanes=0);return[t.memoizedState,a.dispatch]}function Go(e){var t=ot(),a=t.queue;if(a===null)throw Error(o(311));a.lastRenderedReducer=e;var n=a.dispatch,l=a.pending,s=t.memoizedState;if(l!==null){a.pending=null;var d=l=l.next;do s=e(s,d.action),d=d.next;while(d!==l);mt(s,t.memoizedState)||(je=!0),t.memoizedState=s,t.baseQueue===null&&(t.baseState=s),a.lastRenderedState=s}return[s,n]}function Nc(){}function Bc(e,t){var a=fe,n=ot(),l=t(),s=!mt(n.memoizedState,l);if(s&&(n.memoizedState=l,je=!0),n=n.queue,Ko(_c.bind(null,a,n,e),[e]),n.getSnapshot!==t||s||Te!==null&&Te.memoizedState.tag&1){if(a.flags|=2048,Bi(9,Uc.bind(null,a,n,l,t),void 0,null),we===null)throw Error(o(349));(ya&30)!==0||Wc(a,t,l)}return l}function Wc(e,t,a){e.flags|=16384,e={getSnapshot:t,value:a},t=fe.updateQueue,t===null?(t={lastEffect:null,stores:null},fe.updateQueue=t,t.stores=[e]):(a=t.stores,a===null?t.stores=[e]:a.push(e))}function Uc(e,t,a,n){t.value=a,t.getSnapshot=n,Vc(t)&&zc(e)}function _c(e,t,a){return a(function(){Vc(t)&&zc(e)})}function Vc(e){var t=e.getSnapshot;e=e.value;try{var a=t();return!mt(e,a)}catch{return!0}}function zc(e){var t=Ht(e,1);t!==null&&St(t,e,1,-1)}function jc(e){var t=Lt();return typeof e=="function"&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Ni,lastRenderedState:e},t.queue=e,e=e.dispatch=gm.bind(null,fe,e),[t.memoizedState,e]}function Bi(e,t,a,n){return e={tag:e,create:t,destroy:a,deps:n,next:null},t=fe.updateQueue,t===null?(t={lastEffect:null,stores:null},fe.updateQueue=t,t.lastEffect=e.next=e):(a=t.lastEffect,a===null?t.lastEffect=e.next=e:(n=a.next,a.next=e,e.next=n,t.lastEffect=e)),e}function qc(){return ot().memoizedState}function Wr(e,t,a,n){var l=Lt();fe.flags|=e,l.memoizedState=Bi(1|t,a,void 0,n===void 0?null:n)}function Ur(e,t,a,n){var l=ot();n=n===void 0?null:n;var s=void 0;if(Se!==null){var d=Se.memoizedState;if(s=d.destroy,n!==null&&Vo(n,d.deps)){l.memoizedState=Bi(t,a,s,n);return}}fe.flags|=e,l.memoizedState=Bi(1|t,a,s,n)}function Gc(e,t){return Wr(8390656,8,e,t)}function Ko(e,t){return Ur(2048,8,e,t)}function Kc(e,t){return Ur(4,2,e,t)}function Qc(e,t){return Ur(4,4,e,t)}function Yc(e,t){if(typeof t=="function")return e=e(),t(e),function(){t(null)};if(t!=null)return e=e(),t.current=e,function(){t.current=null}}function $c(e,t,a){return a=a!=null?a.concat([e]):null,Ur(4,4,Yc.bind(null,t,e),a)}function Qo(){}function Jc(e,t){var a=ot();t=t===void 0?null:t;var n=a.memoizedState;return n!==null&&t!==null&&Vo(t,n[1])?n[0]:(a.memoizedState=[e,t],e)}function Xc(e,t){var a=ot();t=t===void 0?null:t;var n=a.memoizedState;return n!==null&&t!==null&&Vo(t,n[1])?n[0]:(e=e(),a.memoizedState=[e,t],e)}function Zc(e,t,a){return(ya&21)===0?(e.baseState&&(e.baseState=!1,je=!0),e.memoizedState=a):(mt(a,t)||(a=Rs(),fe.lanes|=a,Sa|=a,e.baseState=!0),t)}function mm(e,t){var a=te;te=a!==0&&4>a?a:4,e(!0);var n=_o.transition;_o.transition={};try{e(!1),t()}finally{te=a,_o.transition=n}}function eu(){return ot().memoizedState}function hm(e,t,a){var n=aa(e);if(a={lane:n,action:a,hasEagerState:!1,eagerState:null,next:null},tu(e))au(t,a);else if(a=Mc(e,t,a,n),a!==null){var l=Oe();St(a,e,n,l),iu(a,t,n)}}function gm(e,t,a){var n=aa(e),l={lane:n,action:a,hasEagerState:!1,eagerState:null,next:null};if(tu(e))au(t,l);else{var s=e.alternate;if(e.lanes===0&&(s===null||s.lanes===0)&&(s=t.lastRenderedReducer,s!==null))try{var d=t.lastRenderedState,f=s(d,a);if(l.hasEagerState=!0,l.eagerState=f,mt(f,d)){var m=t.interleaved;m===null?(l.next=l,Oo(t)):(l.next=m.next,m.next=l),t.interleaved=l;return}}catch{}finally{}a=Mc(e,t,l,n),a!==null&&(l=Oe(),St(a,e,n,l),iu(a,t,n))}}function tu(e){var t=e.alternate;return e===fe||t!==null&&t===fe}function au(e,t){Oi=Br=!0;var a=e.pending;a===null?t.next=t:(t.next=a.next,a.next=t),e.pending=t}function iu(e,t,a){if((a&4194240)!==0){var n=t.lanes;n&=e.pendingLanes,a|=n,t.lanes=a,Yn(e,a)}}var _r={readContext:nt,useCallback:Re,useContext:Re,useEffect:Re,useImperativeHandle:Re,useInsertionEffect:Re,useLayoutEffect:Re,useMemo:Re,useReducer:Re,useRef:Re,useState:Re,useDebugValue:Re,useDeferredValue:Re,useTransition:Re,useMutableSource:Re,useSyncExternalStore:Re,useId:Re,unstable_isNewReconciler:!1},bm={readContext:nt,useCallback:function(e,t){return Lt().memoizedState=[e,t===void 0?null:t],e},useContext:nt,useEffect:Gc,useImperativeHandle:function(e,t,a){return a=a!=null?a.concat([e]):null,Wr(4194308,4,Yc.bind(null,t,e),a)},useLayoutEffect:function(e,t){return Wr(4194308,4,e,t)},useInsertionEffect:function(e,t){return Wr(4,2,e,t)},useMemo:function(e,t){var a=Lt();return t=t===void 0?null:t,e=e(),a.memoizedState=[e,t],e},useReducer:function(e,t,a){var n=Lt();return t=a!==void 0?a(t):t,n.memoizedState=n.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},n.queue=e,e=e.dispatch=hm.bind(null,fe,e),[n.memoizedState,e]},useRef:function(e){var t=Lt();return e={current:e},t.memoizedState=e},useState:jc,useDebugValue:Qo,useDeferredValue:function(e){return Lt().memoizedState=e},useTransition:function(){var e=jc(!1),t=e[0];return e=mm.bind(null,e[1]),Lt().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,a){var n=fe,l=Lt();if(de){if(a===void 0)throw Error(o(407));a=a()}else{if(a=t(),we===null)throw Error(o(349));(ya&30)!==0||Wc(n,t,a)}l.memoizedState=a;var s={value:a,getSnapshot:t};return l.queue=s,Gc(_c.bind(null,n,s,e),[e]),n.flags|=2048,Bi(9,Uc.bind(null,n,s,a,t),void 0,null),a},useId:function(){var e=Lt(),t=we.identifierPrefix;if(de){var a=Ot,n=xt;a=(n&~(1<<32-ft(n)-1)).toString(32)+a,t=":"+t+"R"+a,a=Hi++,0<a&&(t+="H"+a.toString(32)),t+=":"}else a=fm++,t=":"+t+"r"+a.toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},ym={readContext:nt,useCallback:Jc,useContext:nt,useEffect:Ko,useImperativeHandle:$c,useInsertionEffect:Kc,useLayoutEffect:Qc,useMemo:Xc,useReducer:qo,useRef:qc,useState:function(){return qo(Ni)},useDebugValue:Qo,useDeferredValue:function(e){var t=ot();return Zc(t,Se.memoizedState,e)},useTransition:function(){var e=qo(Ni)[0],t=ot().memoizedState;return[e,t]},useMutableSource:Nc,useSyncExternalStore:Bc,useId:eu,unstable_isNewReconciler:!1},Sm={readContext:nt,useCallback:Jc,useContext:nt,useEffect:Ko,useImperativeHandle:$c,useInsertionEffect:Kc,useLayoutEffect:Qc,useMemo:Xc,useReducer:Go,useRef:qc,useState:function(){return Go(Ni)},useDebugValue:Qo,useDeferredValue:function(e){var t=ot();return Se===null?t.memoizedState=e:Zc(t,Se.memoizedState,e)},useTransition:function(){var e=Go(Ni)[0],t=ot().memoizedState;return[e,t]},useMutableSource:Nc,useSyncExternalStore:Bc,useId:eu,unstable_isNewReconciler:!1};function gt(e,t){if(e&&e.defaultProps){t=I({},t),e=e.defaultProps;for(var a in e)t[a]===void 0&&(t[a]=e[a]);return t}return t}function Yo(e,t,a,n){t=e.memoizedState,a=a(n,t),a=a==null?t:I({},t,a),e.memoizedState=a,e.lanes===0&&(e.updateQueue.baseState=a)}var Vr={isMounted:function(e){return(e=e._reactInternals)?da(e)===e:!1},enqueueSetState:function(e,t,a){e=e._reactInternals;var n=Oe(),l=aa(e),s=Nt(n,l);s.payload=t,a!=null&&(s.callback=a),t=Xt(e,s,l),t!==null&&(St(t,e,l,n),xr(t,e,l))},enqueueReplaceState:function(e,t,a){e=e._reactInternals;var n=Oe(),l=aa(e),s=Nt(n,l);s.tag=1,s.payload=t,a!=null&&(s.callback=a),t=Xt(e,s,l),t!==null&&(St(t,e,l,n),xr(t,e,l))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var a=Oe(),n=aa(e),l=Nt(a,n);l.tag=2,t!=null&&(l.callback=t),t=Xt(e,l,n),t!==null&&(St(t,e,n,a),xr(t,e,n))}};function ru(e,t,a,n,l,s,d){return e=e.stateNode,typeof e.shouldComponentUpdate=="function"?e.shouldComponentUpdate(n,s,d):t.prototype&&t.prototype.isPureReactComponent?!Ci(a,n)||!Ci(l,s):!0}function nu(e,t,a){var n=!1,l=Yt,s=t.contextType;return typeof s=="object"&&s!==null?s=nt(s):(l=ze(t)?fa:Ae.current,n=t.contextTypes,s=(n=n!=null)?_a(e,l):Yt),t=new t(a,s),e.memoizedState=t.state!==null&&t.state!==void 0?t.state:null,t.updater=Vr,e.stateNode=t,t._reactInternals=e,n&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=l,e.__reactInternalMemoizedMaskedChildContext=s),t}function ou(e,t,a,n){e=t.state,typeof t.componentWillReceiveProps=="function"&&t.componentWillReceiveProps(a,n),typeof t.UNSAFE_componentWillReceiveProps=="function"&&t.UNSAFE_componentWillReceiveProps(a,n),t.state!==e&&Vr.enqueueReplaceState(t,t.state,null)}function $o(e,t,a,n){var l=e.stateNode;l.props=a,l.state=e.memoizedState,l.refs={},Ho(e);var s=t.contextType;typeof s=="object"&&s!==null?l.context=nt(s):(s=ze(t)?fa:Ae.current,l.context=_a(e,s)),l.state=e.memoizedState,s=t.getDerivedStateFromProps,typeof s=="function"&&(Yo(e,t,s,a),l.state=e.memoizedState),typeof t.getDerivedStateFromProps=="function"||typeof l.getSnapshotBeforeUpdate=="function"||typeof l.UNSAFE_componentWillMount!="function"&&typeof l.componentWillMount!="function"||(t=l.state,typeof l.componentWillMount=="function"&&l.componentWillMount(),typeof l.UNSAFE_componentWillMount=="function"&&l.UNSAFE_componentWillMount(),t!==l.state&&Vr.enqueueReplaceState(l,l.state,null),Or(e,a,l,n),l.state=e.memoizedState),typeof l.componentDidMount=="function"&&(e.flags|=4194308)}function Ya(e,t){try{var a="",n=t;do a+=Y(n),n=n.return;while(n);var l=a}catch(s){l=`
40
+ Error generating stack: `+s.message+`
41
+ `+s.stack}return{value:e,source:t,stack:l,digest:null}}function Jo(e,t,a){return{value:e,source:null,stack:a??null,digest:t??null}}function Xo(e,t){try{console.error(t.value)}catch(a){setTimeout(function(){throw a})}}var km=typeof WeakMap=="function"?WeakMap:Map;function lu(e,t,a){a=Nt(-1,a),a.tag=3,a.payload={element:null};var n=t.value;return a.callback=function(){Yr||(Yr=!0,fl=n),Xo(e,t)},a}function su(e,t,a){a=Nt(-1,a),a.tag=3;var n=e.type.getDerivedStateFromError;if(typeof n=="function"){var l=t.value;a.payload=function(){return n(l)},a.callback=function(){Xo(e,t)}}var s=e.stateNode;return s!==null&&typeof s.componentDidCatch=="function"&&(a.callback=function(){Xo(e,t),typeof n!="function"&&(ea===null?ea=new Set([this]):ea.add(this));var d=t.stack;this.componentDidCatch(t.value,{componentStack:d!==null?d:""})}),a}function cu(e,t,a){var n=e.pingCache;if(n===null){n=e.pingCache=new km;var l=new Set;n.set(t,l)}else l=n.get(t),l===void 0&&(l=new Set,n.set(t,l));l.has(a)||(l.add(a),e=xm.bind(null,e,t,a),t.then(e,e))}function uu(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t!==null?t.dehydrated!==null:!0),t)return e;e=e.return}while(e!==null);return null}function du(e,t,a,n,l){return(e.mode&1)===0?(e===t?e.flags|=65536:(e.flags|=128,a.flags|=131072,a.flags&=-52805,a.tag===1&&(a.alternate===null?a.tag=17:(t=Nt(-1,1),t.tag=2,Xt(a,t,1))),a.lanes|=1),e):(e.flags|=65536,e.lanes=l,e)}var Tm=Le.ReactCurrentOwner,je=!1;function xe(e,t,a,n){t.child=e===null?Ec(t,null,a,n):qa(t,e.child,a,n)}function pu(e,t,a,n,l){a=a.render;var s=t.ref;return Ka(t,l),n=zo(e,t,a,n,s,l),a=jo(),e!==null&&!je?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~l,Bt(e,t,l)):(de&&a&&Po(t),t.flags|=1,xe(e,t,n,l),t.child)}function fu(e,t,a,n,l){if(e===null){var s=a.type;return typeof s=="function"&&!kl(s)&&s.defaultProps===void 0&&a.compare===null&&a.defaultProps===void 0?(t.tag=15,t.type=s,mu(e,t,s,n,l)):(e=tn(a.type,null,n,t,t.mode,l),e.ref=t.ref,e.return=t,t.child=e)}if(s=e.child,(e.lanes&l)===0){var d=s.memoizedProps;if(a=a.compare,a=a!==null?a:Ci,a(d,n)&&e.ref===t.ref)return Bt(e,t,l)}return t.flags|=1,e=ra(s,n),e.ref=t.ref,e.return=t,t.child=e}function mu(e,t,a,n,l){if(e!==null){var s=e.memoizedProps;if(Ci(s,n)&&e.ref===t.ref)if(je=!1,t.pendingProps=n=s,(e.lanes&l)!==0)(e.flags&131072)!==0&&(je=!0);else return t.lanes=e.lanes,Bt(e,t,l)}return Zo(e,t,a,n,l)}function hu(e,t,a){var n=t.pendingProps,l=n.children,s=e!==null?e.memoizedState:null;if(n.mode==="hidden")if((t.mode&1)===0)t.memoizedState={baseLanes:0,cachePool:null,transitions:null},ne(Ja,Ze),Ze|=a;else{if((a&1073741824)===0)return e=s!==null?s.baseLanes|a:a,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,ne(Ja,Ze),Ze|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},n=s!==null?s.baseLanes:a,ne(Ja,Ze),Ze|=n}else s!==null?(n=s.baseLanes|a,t.memoizedState=null):n=a,ne(Ja,Ze),Ze|=n;return xe(e,t,l,a),t.child}function gu(e,t){var a=t.ref;(e===null&&a!==null||e!==null&&e.ref!==a)&&(t.flags|=512,t.flags|=2097152)}function Zo(e,t,a,n,l){var s=ze(a)?fa:Ae.current;return s=_a(t,s),Ka(t,l),a=zo(e,t,a,n,s,l),n=jo(),e!==null&&!je?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~l,Bt(e,t,l)):(de&&n&&Po(t),t.flags|=1,xe(e,t,a,l),t.child)}function bu(e,t,a,n,l){if(ze(a)){var s=!0;Pr(t)}else s=!1;if(Ka(t,l),t.stateNode===null)jr(e,t),nu(t,a,n),$o(t,a,n,l),n=!0;else if(e===null){var d=t.stateNode,f=t.memoizedProps;d.props=f;var m=d.context,T=a.contextType;typeof T=="object"&&T!==null?T=nt(T):(T=ze(a)?fa:Ae.current,T=_a(t,T));var C=a.getDerivedStateFromProps,D=typeof C=="function"||typeof d.getSnapshotBeforeUpdate=="function";D||typeof d.UNSAFE_componentWillReceiveProps!="function"&&typeof d.componentWillReceiveProps!="function"||(f!==n||m!==T)&&ou(t,d,n,T),Jt=!1;var w=t.memoizedState;d.state=w,Or(t,n,d,l),m=t.memoizedState,f!==n||w!==m||Ve.current||Jt?(typeof C=="function"&&(Yo(t,a,C,n),m=t.memoizedState),(f=Jt||ru(t,a,f,n,w,m,T))?(D||typeof d.UNSAFE_componentWillMount!="function"&&typeof d.componentWillMount!="function"||(typeof d.componentWillMount=="function"&&d.componentWillMount(),typeof d.UNSAFE_componentWillMount=="function"&&d.UNSAFE_componentWillMount()),typeof d.componentDidMount=="function"&&(t.flags|=4194308)):(typeof d.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=n,t.memoizedState=m),d.props=n,d.state=m,d.context=T,n=f):(typeof d.componentDidMount=="function"&&(t.flags|=4194308),n=!1)}else{d=t.stateNode,Ic(e,t),f=t.memoizedProps,T=t.type===t.elementType?f:gt(t.type,f),d.props=T,D=t.pendingProps,w=d.context,m=a.contextType,typeof m=="object"&&m!==null?m=nt(m):(m=ze(a)?fa:Ae.current,m=_a(t,m));var F=a.getDerivedStateFromProps;(C=typeof F=="function"||typeof d.getSnapshotBeforeUpdate=="function")||typeof d.UNSAFE_componentWillReceiveProps!="function"&&typeof d.componentWillReceiveProps!="function"||(f!==D||w!==m)&&ou(t,d,n,m),Jt=!1,w=t.memoizedState,d.state=w,Or(t,n,d,l);var x=t.memoizedState;f!==D||w!==x||Ve.current||Jt?(typeof F=="function"&&(Yo(t,a,F,n),x=t.memoizedState),(T=Jt||ru(t,a,T,n,w,x,m)||!1)?(C||typeof d.UNSAFE_componentWillUpdate!="function"&&typeof d.componentWillUpdate!="function"||(typeof d.componentWillUpdate=="function"&&d.componentWillUpdate(n,x,m),typeof d.UNSAFE_componentWillUpdate=="function"&&d.UNSAFE_componentWillUpdate(n,x,m)),typeof d.componentDidUpdate=="function"&&(t.flags|=4),typeof d.getSnapshotBeforeUpdate=="function"&&(t.flags|=1024)):(typeof d.componentDidUpdate!="function"||f===e.memoizedProps&&w===e.memoizedState||(t.flags|=4),typeof d.getSnapshotBeforeUpdate!="function"||f===e.memoizedProps&&w===e.memoizedState||(t.flags|=1024),t.memoizedProps=n,t.memoizedState=x),d.props=n,d.state=x,d.context=m,n=T):(typeof d.componentDidUpdate!="function"||f===e.memoizedProps&&w===e.memoizedState||(t.flags|=4),typeof d.getSnapshotBeforeUpdate!="function"||f===e.memoizedProps&&w===e.memoizedState||(t.flags|=1024),n=!1)}return el(e,t,a,n,s,l)}function el(e,t,a,n,l,s){gu(e,t);var d=(t.flags&128)!==0;if(!n&&!d)return l&&wc(t,a,!1),Bt(e,t,s);n=t.stateNode,Tm.current=t;var f=d&&typeof a.getDerivedStateFromError!="function"?null:n.render();return t.flags|=1,e!==null&&d?(t.child=qa(t,e.child,null,s),t.child=qa(t,null,f,s)):xe(e,t,f,s),t.memoizedState=n.state,l&&wc(t,a,!0),t.child}function yu(e){var t=e.stateNode;t.pendingContext?kc(e,t.pendingContext,t.pendingContext!==t.context):t.context&&kc(e,t.context,!1),No(e,t.containerInfo)}function Su(e,t,a,n,l){return ja(),Fo(l),t.flags|=256,xe(e,t,a,n),t.child}var tl={dehydrated:null,treeContext:null,retryLane:0};function al(e){return{baseLanes:e,cachePool:null,transitions:null}}function ku(e,t,a){var n=t.pendingProps,l=pe.current,s=!1,d=(t.flags&128)!==0,f;if((f=d)||(f=e!==null&&e.memoizedState===null?!1:(l&2)!==0),f?(s=!0,t.flags&=-129):(e===null||e.memoizedState!==null)&&(l|=1),ne(pe,l&1),e===null)return Ro(t),e=t.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?((t.mode&1)===0?t.lanes=1:e.data==="$!"?t.lanes=8:t.lanes=1073741824,null):(d=n.children,e=n.fallback,s?(n=t.mode,s=t.child,d={mode:"hidden",children:d},(n&1)===0&&s!==null?(s.childLanes=0,s.pendingProps=d):s=an(d,n,0,null),e=va(e,n,a,null),s.return=t,e.return=t,s.sibling=e,t.child=s,t.child.memoizedState=al(a),t.memoizedState=tl,e):il(t,d));if(l=e.memoizedState,l!==null&&(f=l.dehydrated,f!==null))return wm(e,t,d,n,f,l,a);if(s){s=n.fallback,d=t.mode,l=e.child,f=l.sibling;var m={mode:"hidden",children:n.children};return(d&1)===0&&t.child!==l?(n=t.child,n.childLanes=0,n.pendingProps=m,t.deletions=null):(n=ra(l,m),n.subtreeFlags=l.subtreeFlags&14680064),f!==null?s=ra(f,s):(s=va(s,d,a,null),s.flags|=2),s.return=t,n.return=t,n.sibling=s,t.child=n,n=s,s=t.child,d=e.child.memoizedState,d=d===null?al(a):{baseLanes:d.baseLanes|a,cachePool:null,transitions:d.transitions},s.memoizedState=d,s.childLanes=e.childLanes&~a,t.memoizedState=tl,n}return s=e.child,e=s.sibling,n=ra(s,{mode:"visible",children:n.children}),(t.mode&1)===0&&(n.lanes=a),n.return=t,n.sibling=null,e!==null&&(a=t.deletions,a===null?(t.deletions=[e],t.flags|=16):a.push(e)),t.child=n,t.memoizedState=null,n}function il(e,t){return t=an({mode:"visible",children:t},e.mode,0,null),t.return=e,e.child=t}function zr(e,t,a,n){return n!==null&&Fo(n),qa(t,e.child,null,a),e=il(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function wm(e,t,a,n,l,s,d){if(a)return t.flags&256?(t.flags&=-257,n=Jo(Error(o(422))),zr(e,t,d,n)):t.memoizedState!==null?(t.child=e.child,t.flags|=128,null):(s=n.fallback,l=t.mode,n=an({mode:"visible",children:n.children},l,0,null),s=va(s,l,d,null),s.flags|=2,n.return=t,s.return=t,n.sibling=s,t.child=n,(t.mode&1)!==0&&qa(t,e.child,null,d),t.child.memoizedState=al(d),t.memoizedState=tl,s);if((t.mode&1)===0)return zr(e,t,d,null);if(l.data==="$!"){if(n=l.nextSibling&&l.nextSibling.dataset,n)var f=n.dgst;return n=f,s=Error(o(419)),n=Jo(s,n,void 0),zr(e,t,d,n)}if(f=(d&e.childLanes)!==0,je||f){if(n=we,n!==null){switch(d&-d){case 4:l=2;break;case 16:l=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:l=32;break;case 536870912:l=268435456;break;default:l=0}l=(l&(n.suspendedLanes|d))!==0?0:l,l!==0&&l!==s.retryLane&&(s.retryLane=l,Ht(e,l),St(n,e,l,-1))}return Sl(),n=Jo(Error(o(421))),zr(e,t,d,n)}return l.data==="$?"?(t.flags|=128,t.child=e.child,t=Om.bind(null,e),l._reactRetry=t,null):(e=s.treeContext,Xe=Kt(l.nextSibling),Je=t,de=!0,ht=null,e!==null&&(it[rt++]=xt,it[rt++]=Ot,it[rt++]=ma,xt=e.id,Ot=e.overflow,ma=t),t=il(t,n.children),t.flags|=4096,t)}function Tu(e,t,a){e.lanes|=t;var n=e.alternate;n!==null&&(n.lanes|=t),xo(e.return,t,a)}function rl(e,t,a,n,l){var s=e.memoizedState;s===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:n,tail:a,tailMode:l}:(s.isBackwards=t,s.rendering=null,s.renderingStartTime=0,s.last=n,s.tail=a,s.tailMode=l)}function wu(e,t,a){var n=t.pendingProps,l=n.revealOrder,s=n.tail;if(xe(e,t,n.children,a),n=pe.current,(n&2)!==0)n=n&1|2,t.flags|=128;else{if(e!==null&&(e.flags&128)!==0)e:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Tu(e,a,t);else if(e.tag===19)Tu(e,a,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;e.sibling===null;){if(e.return===null||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}n&=1}if(ne(pe,n),(t.mode&1)===0)t.memoizedState=null;else switch(l){case"forwards":for(a=t.child,l=null;a!==null;)e=a.alternate,e!==null&&Hr(e)===null&&(l=a),a=a.sibling;a=l,a===null?(l=t.child,t.child=null):(l=a.sibling,a.sibling=null),rl(t,!1,l,a,s);break;case"backwards":for(a=null,l=t.child,t.child=null;l!==null;){if(e=l.alternate,e!==null&&Hr(e)===null){t.child=l;break}e=l.sibling,l.sibling=a,a=l,l=e}rl(t,!0,a,null,s);break;case"together":rl(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function jr(e,t){(t.mode&1)===0&&e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Bt(e,t,a){if(e!==null&&(t.dependencies=e.dependencies),Sa|=t.lanes,(a&t.childLanes)===0)return null;if(e!==null&&t.child!==e.child)throw Error(o(153));if(t.child!==null){for(e=t.child,a=ra(e,e.pendingProps),t.child=a,a.return=t;e.sibling!==null;)e=e.sibling,a=a.sibling=ra(e,e.pendingProps),a.return=t;a.sibling=null}return t.child}function vm(e,t,a){switch(t.tag){case 3:yu(t),ja();break;case 5:Hc(t);break;case 1:ze(t.type)&&Pr(t);break;case 4:No(t,t.stateNode.containerInfo);break;case 10:var n=t.type._context,l=t.memoizedProps.value;ne(Mr,n._currentValue),n._currentValue=l;break;case 13:if(n=t.memoizedState,n!==null)return n.dehydrated!==null?(ne(pe,pe.current&1),t.flags|=128,null):(a&t.child.childLanes)!==0?ku(e,t,a):(ne(pe,pe.current&1),e=Bt(e,t,a),e!==null?e.sibling:null);ne(pe,pe.current&1);break;case 19:if(n=(a&t.childLanes)!==0,(e.flags&128)!==0){if(n)return wu(e,t,a);t.flags|=128}if(l=t.memoizedState,l!==null&&(l.rendering=null,l.tail=null,l.lastEffect=null),ne(pe,pe.current),n)break;return null;case 22:case 23:return t.lanes=0,hu(e,t,a)}return Bt(e,t,a)}var vu,nl,Cu,Du;vu=function(e,t){for(var a=t.child;a!==null;){if(a.tag===5||a.tag===6)e.appendChild(a.stateNode);else if(a.tag!==4&&a.child!==null){a.child.return=a,a=a.child;continue}if(a===t)break;for(;a.sibling===null;){if(a.return===null||a.return===t)return;a=a.return}a.sibling.return=a.return,a=a.sibling}},nl=function(){},Cu=function(e,t,a,n){var l=e.memoizedProps;if(l!==n){e=t.stateNode,ba(Pt.current);var s=null;switch(a){case"input":l=In(e,l),n=In(e,n),s=[];break;case"select":l=I({},l,{value:void 0}),n=I({},n,{value:void 0}),s=[];break;case"textarea":l=Hn(e,l),n=Hn(e,n),s=[];break;default:typeof l.onClick!="function"&&typeof n.onClick=="function"&&(e.onclick=vr)}Bn(a,n);var d;a=null;for(T in l)if(!n.hasOwnProperty(T)&&l.hasOwnProperty(T)&&l[T]!=null)if(T==="style"){var f=l[T];for(d in f)f.hasOwnProperty(d)&&(a||(a={}),a[d]="")}else T!=="dangerouslySetInnerHTML"&&T!=="children"&&T!=="suppressContentEditableWarning"&&T!=="suppressHydrationWarning"&&T!=="autoFocus"&&(u.hasOwnProperty(T)?s||(s=[]):(s=s||[]).push(T,null));for(T in n){var m=n[T];if(f=l!=null?l[T]:void 0,n.hasOwnProperty(T)&&m!==f&&(m!=null||f!=null))if(T==="style")if(f){for(d in f)!f.hasOwnProperty(d)||m&&m.hasOwnProperty(d)||(a||(a={}),a[d]="");for(d in m)m.hasOwnProperty(d)&&f[d]!==m[d]&&(a||(a={}),a[d]=m[d])}else a||(s||(s=[]),s.push(T,a)),a=m;else T==="dangerouslySetInnerHTML"?(m=m?m.__html:void 0,f=f?f.__html:void 0,m!=null&&f!==m&&(s=s||[]).push(T,m)):T==="children"?typeof m!="string"&&typeof m!="number"||(s=s||[]).push(T,""+m):T!=="suppressContentEditableWarning"&&T!=="suppressHydrationWarning"&&(u.hasOwnProperty(T)?(m!=null&&T==="onScroll"&&oe("scroll",e),s||f===m||(s=[])):(s=s||[]).push(T,m))}a&&(s=s||[]).push("style",a);var T=s;(t.updateQueue=T)&&(t.flags|=4)}},Du=function(e,t,a,n){a!==n&&(t.flags|=4)};function Wi(e,t){if(!de)switch(e.tailMode){case"hidden":t=e.tail;for(var a=null;t!==null;)t.alternate!==null&&(a=t),t=t.sibling;a===null?e.tail=null:a.sibling=null;break;case"collapsed":a=e.tail;for(var n=null;a!==null;)a.alternate!==null&&(n=a),a=a.sibling;n===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:n.sibling=null}}function Fe(e){var t=e.alternate!==null&&e.alternate.child===e.child,a=0,n=0;if(t)for(var l=e.child;l!==null;)a|=l.lanes|l.childLanes,n|=l.subtreeFlags&14680064,n|=l.flags&14680064,l.return=e,l=l.sibling;else for(l=e.child;l!==null;)a|=l.lanes|l.childLanes,n|=l.subtreeFlags,n|=l.flags,l.return=e,l=l.sibling;return e.subtreeFlags|=n,e.childLanes=a,t}function Cm(e,t,a){var n=t.pendingProps;switch(Lo(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Fe(t),null;case 1:return ze(t.type)&&Dr(),Fe(t),null;case 3:return n=t.stateNode,Qa(),le(Ve),le(Ae),Uo(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),(e===null||e.child===null)&&(Fr(t)?t.flags|=4:e===null||e.memoizedState.isDehydrated&&(t.flags&256)===0||(t.flags|=1024,ht!==null&&(gl(ht),ht=null))),nl(e,t),Fe(t),null;case 5:Bo(t);var l=ba(xi.current);if(a=t.type,e!==null&&t.stateNode!=null)Cu(e,t,a,n,l),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!n){if(t.stateNode===null)throw Error(o(166));return Fe(t),null}if(e=ba(Pt.current),Fr(t)){n=t.stateNode,a=t.type;var s=t.memoizedProps;switch(n[Dt]=t,n[Ri]=s,e=(t.mode&1)!==0,a){case"dialog":oe("cancel",n),oe("close",n);break;case"iframe":case"object":case"embed":oe("load",n);break;case"video":case"audio":for(l=0;l<Pi.length;l++)oe(Pi[l],n);break;case"source":oe("error",n);break;case"img":case"image":case"link":oe("error",n),oe("load",n);break;case"details":oe("toggle",n);break;case"input":ns(n,s),oe("invalid",n);break;case"select":n._wrapperState={wasMultiple:!!s.multiple},oe("invalid",n);break;case"textarea":ss(n,s),oe("invalid",n)}Bn(a,s),l=null;for(var d in s)if(s.hasOwnProperty(d)){var f=s[d];d==="children"?typeof f=="string"?n.textContent!==f&&(s.suppressHydrationWarning!==!0&&wr(n.textContent,f,e),l=["children",f]):typeof f=="number"&&n.textContent!==""+f&&(s.suppressHydrationWarning!==!0&&wr(n.textContent,f,e),l=["children",""+f]):u.hasOwnProperty(d)&&f!=null&&d==="onScroll"&&oe("scroll",n)}switch(a){case"input":Zi(n),ls(n,s,!0);break;case"textarea":Zi(n),us(n);break;case"select":case"option":break;default:typeof s.onClick=="function"&&(n.onclick=vr)}n=l,t.updateQueue=n,n!==null&&(t.flags|=4)}else{d=l.nodeType===9?l:l.ownerDocument,e==="http://www.w3.org/1999/xhtml"&&(e=ds(a)),e==="http://www.w3.org/1999/xhtml"?a==="script"?(e=d.createElement("div"),e.innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):typeof n.is=="string"?e=d.createElement(a,{is:n.is}):(e=d.createElement(a),a==="select"&&(d=e,n.multiple?d.multiple=!0:n.size&&(d.size=n.size))):e=d.createElementNS(e,a),e[Dt]=t,e[Ri]=n,vu(e,t,!1,!1),t.stateNode=e;e:{switch(d=Wn(a,n),a){case"dialog":oe("cancel",e),oe("close",e),l=n;break;case"iframe":case"object":case"embed":oe("load",e),l=n;break;case"video":case"audio":for(l=0;l<Pi.length;l++)oe(Pi[l],e);l=n;break;case"source":oe("error",e),l=n;break;case"img":case"image":case"link":oe("error",e),oe("load",e),l=n;break;case"details":oe("toggle",e),l=n;break;case"input":ns(e,n),l=In(e,n),oe("invalid",e);break;case"option":l=n;break;case"select":e._wrapperState={wasMultiple:!!n.multiple},l=I({},n,{value:void 0}),oe("invalid",e);break;case"textarea":ss(e,n),l=Hn(e,n),oe("invalid",e);break;default:l=n}Bn(a,l),f=l;for(s in f)if(f.hasOwnProperty(s)){var m=f[s];s==="style"?ms(e,m):s==="dangerouslySetInnerHTML"?(m=m?m.__html:void 0,m!=null&&ps(e,m)):s==="children"?typeof m=="string"?(a!=="textarea"||m!=="")&&li(e,m):typeof m=="number"&&li(e,""+m):s!=="suppressContentEditableWarning"&&s!=="suppressHydrationWarning"&&s!=="autoFocus"&&(u.hasOwnProperty(s)?m!=null&&s==="onScroll"&&oe("scroll",e):m!=null&&ut(e,s,m,d))}switch(a){case"input":Zi(e),ls(e,n,!1);break;case"textarea":Zi(e),us(e);break;case"option":n.value!=null&&e.setAttribute("value",""+ee(n.value));break;case"select":e.multiple=!!n.multiple,s=n.value,s!=null?Ra(e,!!n.multiple,s,!1):n.defaultValue!=null&&Ra(e,!!n.multiple,n.defaultValue,!0);break;default:typeof l.onClick=="function"&&(e.onclick=vr)}switch(a){case"button":case"input":case"select":case"textarea":n=!!n.autoFocus;break e;case"img":n=!0;break e;default:n=!1}}n&&(t.flags|=4)}t.ref!==null&&(t.flags|=512,t.flags|=2097152)}return Fe(t),null;case 6:if(e&&t.stateNode!=null)Du(e,t,e.memoizedProps,n);else{if(typeof n!="string"&&t.stateNode===null)throw Error(o(166));if(a=ba(xi.current),ba(Pt.current),Fr(t)){if(n=t.stateNode,a=t.memoizedProps,n[Dt]=t,(s=n.nodeValue!==a)&&(e=Je,e!==null))switch(e.tag){case 3:wr(n.nodeValue,a,(e.mode&1)!==0);break;case 5:e.memoizedProps.suppressHydrationWarning!==!0&&wr(n.nodeValue,a,(e.mode&1)!==0)}s&&(t.flags|=4)}else n=(a.nodeType===9?a:a.ownerDocument).createTextNode(n),n[Dt]=t,t.stateNode=n}return Fe(t),null;case 13:if(le(pe),n=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(de&&Xe!==null&&(t.mode&1)!==0&&(t.flags&128)===0)Ac(),ja(),t.flags|=98560,s=!1;else if(s=Fr(t),n!==null&&n.dehydrated!==null){if(e===null){if(!s)throw Error(o(318));if(s=t.memoizedState,s=s!==null?s.dehydrated:null,!s)throw Error(o(317));s[Dt]=t}else ja(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;Fe(t),s=!1}else ht!==null&&(gl(ht),ht=null),s=!0;if(!s)return t.flags&65536?t:null}return(t.flags&128)!==0?(t.lanes=a,t):(n=n!==null,n!==(e!==null&&e.memoizedState!==null)&&n&&(t.child.flags|=8192,(t.mode&1)!==0&&(e===null||(pe.current&1)!==0?ke===0&&(ke=3):Sl())),t.updateQueue!==null&&(t.flags|=4),Fe(t),null);case 4:return Qa(),nl(e,t),e===null&&Li(t.stateNode.containerInfo),Fe(t),null;case 10:return Io(t.type._context),Fe(t),null;case 17:return ze(t.type)&&Dr(),Fe(t),null;case 19:if(le(pe),s=t.memoizedState,s===null)return Fe(t),null;if(n=(t.flags&128)!==0,d=s.rendering,d===null)if(n)Wi(s,!1);else{if(ke!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(d=Hr(e),d!==null){for(t.flags|=128,Wi(s,!1),n=d.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),t.subtreeFlags=0,n=a,a=t.child;a!==null;)s=a,e=n,s.flags&=14680066,d=s.alternate,d===null?(s.childLanes=0,s.lanes=e,s.child=null,s.subtreeFlags=0,s.memoizedProps=null,s.memoizedState=null,s.updateQueue=null,s.dependencies=null,s.stateNode=null):(s.childLanes=d.childLanes,s.lanes=d.lanes,s.child=d.child,s.subtreeFlags=0,s.deletions=null,s.memoizedProps=d.memoizedProps,s.memoizedState=d.memoizedState,s.updateQueue=d.updateQueue,s.type=d.type,e=d.dependencies,s.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),a=a.sibling;return ne(pe,pe.current&1|2),t.child}e=e.sibling}s.tail!==null&&ge()>Xa&&(t.flags|=128,n=!0,Wi(s,!1),t.lanes=4194304)}else{if(!n)if(e=Hr(d),e!==null){if(t.flags|=128,n=!0,a=e.updateQueue,a!==null&&(t.updateQueue=a,t.flags|=4),Wi(s,!0),s.tail===null&&s.tailMode==="hidden"&&!d.alternate&&!de)return Fe(t),null}else 2*ge()-s.renderingStartTime>Xa&&a!==1073741824&&(t.flags|=128,n=!0,Wi(s,!1),t.lanes=4194304);s.isBackwards?(d.sibling=t.child,t.child=d):(a=s.last,a!==null?a.sibling=d:t.child=d,s.last=d)}return s.tail!==null?(t=s.tail,s.rendering=t,s.tail=t.sibling,s.renderingStartTime=ge(),t.sibling=null,a=pe.current,ne(pe,n?a&1|2:a&1),t):(Fe(t),null);case 22:case 23:return yl(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&(t.mode&1)!==0?(Ze&1073741824)!==0&&(Fe(t),t.subtreeFlags&6&&(t.flags|=8192)):Fe(t),null;case 24:return null;case 25:return null}throw Error(o(156,t.tag))}function Dm(e,t){switch(Lo(t),t.tag){case 1:return ze(t.type)&&Dr(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Qa(),le(Ve),le(Ae),Uo(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return Bo(t),null;case 13:if(le(pe),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(o(340));ja()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return le(pe),null;case 4:return Qa(),null;case 10:return Io(t.type._context),null;case 22:case 23:return yl(),null;case 24:return null;default:return null}}var qr=!1,Ee=!1,Pm=typeof WeakSet=="function"?WeakSet:Set,M=null;function $a(e,t){var a=e.ref;if(a!==null)if(typeof a=="function")try{a(null)}catch(n){he(e,t,n)}else a.current=null}function ol(e,t,a){try{a()}catch(n){he(e,t,n)}}var Pu=!1;function Lm(e,t){if(yo=dr,e=rc(),co(e)){if("selectionStart"in e)var a={start:e.selectionStart,end:e.selectionEnd};else e:{a=(a=e.ownerDocument)&&a.defaultView||window;var n=a.getSelection&&a.getSelection();if(n&&n.rangeCount!==0){a=n.anchorNode;var l=n.anchorOffset,s=n.focusNode;n=n.focusOffset;try{a.nodeType,s.nodeType}catch{a=null;break e}var d=0,f=-1,m=-1,T=0,C=0,D=e,w=null;t:for(;;){for(var F;D!==a||l!==0&&D.nodeType!==3||(f=d+l),D!==s||n!==0&&D.nodeType!==3||(m=d+n),D.nodeType===3&&(d+=D.nodeValue.length),(F=D.firstChild)!==null;)w=D,D=F;for(;;){if(D===e)break t;if(w===a&&++T===l&&(f=d),w===s&&++C===n&&(m=d),(F=D.nextSibling)!==null)break;D=w,w=D.parentNode}D=F}a=f===-1||m===-1?null:{start:f,end:m}}else a=null}a=a||{start:0,end:0}}else a=null;for(So={focusedElem:e,selectionRange:a},dr=!1,M=t;M!==null;)if(t=M,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,M=e;else for(;M!==null;){t=M;try{var x=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(x!==null){var H=x.memoizedProps,be=x.memoizedState,b=t.stateNode,h=b.getSnapshotBeforeUpdate(t.elementType===t.type?H:gt(t.type,H),be);b.__reactInternalSnapshotBeforeUpdate=h}break;case 3:var S=t.stateNode.containerInfo;S.nodeType===1?S.textContent="":S.nodeType===9&&S.documentElement&&S.removeChild(S.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(o(163))}}catch(P){he(t,t.return,P)}if(e=t.sibling,e!==null){e.return=t.return,M=e;break}M=t.return}return x=Pu,Pu=!1,x}function Ui(e,t,a){var n=t.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var l=n=n.next;do{if((l.tag&e)===e){var s=l.destroy;l.destroy=void 0,s!==void 0&&ol(t,a,s)}l=l.next}while(l!==n)}}function Gr(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var a=t=t.next;do{if((a.tag&e)===e){var n=a.create;a.destroy=n()}a=a.next}while(a!==t)}}function ll(e){var t=e.ref;if(t!==null){var a=e.stateNode;switch(e.tag){case 5:e=a;break;default:e=a}typeof t=="function"?t(e):t.current=e}}function Lu(e){var t=e.alternate;t!==null&&(e.alternate=null,Lu(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Dt],delete t[Ri],delete t[vo],delete t[cm],delete t[um])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Au(e){return e.tag===5||e.tag===3||e.tag===4}function Ru(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Au(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function sl(e,t,a){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?a.nodeType===8?a.parentNode.insertBefore(e,t):a.insertBefore(e,t):(a.nodeType===8?(t=a.parentNode,t.insertBefore(e,a)):(t=a,t.appendChild(e)),a=a._reactRootContainer,a!=null||t.onclick!==null||(t.onclick=vr));else if(n!==4&&(e=e.child,e!==null))for(sl(e,t,a),e=e.sibling;e!==null;)sl(e,t,a),e=e.sibling}function cl(e,t,a){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?a.insertBefore(e,t):a.appendChild(e);else if(n!==4&&(e=e.child,e!==null))for(cl(e,t,a),e=e.sibling;e!==null;)cl(e,t,a),e=e.sibling}var De=null,bt=!1;function Zt(e,t,a){for(a=a.child;a!==null;)Fu(e,t,a),a=a.sibling}function Fu(e,t,a){if(Ct&&typeof Ct.onCommitFiberUnmount=="function")try{Ct.onCommitFiberUnmount(nr,a)}catch{}switch(a.tag){case 5:Ee||$a(a,t);case 6:var n=De,l=bt;De=null,Zt(e,t,a),De=n,bt=l,De!==null&&(bt?(e=De,a=a.stateNode,e.nodeType===8?e.parentNode.removeChild(a):e.removeChild(a)):De.removeChild(a.stateNode));break;case 18:De!==null&&(bt?(e=De,a=a.stateNode,e.nodeType===8?wo(e.parentNode,a):e.nodeType===1&&wo(e,a),yi(e)):wo(De,a.stateNode));break;case 4:n=De,l=bt,De=a.stateNode.containerInfo,bt=!0,Zt(e,t,a),De=n,bt=l;break;case 0:case 11:case 14:case 15:if(!Ee&&(n=a.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){l=n=n.next;do{var s=l,d=s.destroy;s=s.tag,d!==void 0&&((s&2)!==0||(s&4)!==0)&&ol(a,t,d),l=l.next}while(l!==n)}Zt(e,t,a);break;case 1:if(!Ee&&($a(a,t),n=a.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=a.memoizedProps,n.state=a.memoizedState,n.componentWillUnmount()}catch(f){he(a,t,f)}Zt(e,t,a);break;case 21:Zt(e,t,a);break;case 22:a.mode&1?(Ee=(n=Ee)||a.memoizedState!==null,Zt(e,t,a),Ee=n):Zt(e,t,a);break;default:Zt(e,t,a)}}function Eu(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var a=e.stateNode;a===null&&(a=e.stateNode=new Pm),t.forEach(function(n){var l=Hm.bind(null,e,n);a.has(n)||(a.add(n),n.then(l,l))})}}function yt(e,t){var a=t.deletions;if(a!==null)for(var n=0;n<a.length;n++){var l=a[n];try{var s=e,d=t,f=d;e:for(;f!==null;){switch(f.tag){case 5:De=f.stateNode,bt=!1;break e;case 3:De=f.stateNode.containerInfo,bt=!0;break e;case 4:De=f.stateNode.containerInfo,bt=!0;break e}f=f.return}if(De===null)throw Error(o(160));Fu(s,d,l),De=null,bt=!1;var m=l.alternate;m!==null&&(m.return=null),l.return=null}catch(T){he(l,t,T)}}if(t.subtreeFlags&12854)for(t=t.child;t!==null;)Mu(t,e),t=t.sibling}function Mu(e,t){var a=e.alternate,n=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(yt(t,e),At(e),n&4){try{Ui(3,e,e.return),Gr(3,e)}catch(H){he(e,e.return,H)}try{Ui(5,e,e.return)}catch(H){he(e,e.return,H)}}break;case 1:yt(t,e),At(e),n&512&&a!==null&&$a(a,a.return);break;case 5:if(yt(t,e),At(e),n&512&&a!==null&&$a(a,a.return),e.flags&32){var l=e.stateNode;try{li(l,"")}catch(H){he(e,e.return,H)}}if(n&4&&(l=e.stateNode,l!=null)){var s=e.memoizedProps,d=a!==null?a.memoizedProps:s,f=e.type,m=e.updateQueue;if(e.updateQueue=null,m!==null)try{f==="input"&&s.type==="radio"&&s.name!=null&&os(l,s),Wn(f,d);var T=Wn(f,s);for(d=0;d<m.length;d+=2){var C=m[d],D=m[d+1];C==="style"?ms(l,D):C==="dangerouslySetInnerHTML"?ps(l,D):C==="children"?li(l,D):ut(l,C,D,T)}switch(f){case"input":xn(l,s);break;case"textarea":cs(l,s);break;case"select":var w=l._wrapperState.wasMultiple;l._wrapperState.wasMultiple=!!s.multiple;var F=s.value;F!=null?Ra(l,!!s.multiple,F,!1):w!==!!s.multiple&&(s.defaultValue!=null?Ra(l,!!s.multiple,s.defaultValue,!0):Ra(l,!!s.multiple,s.multiple?[]:"",!1))}l[Ri]=s}catch(H){he(e,e.return,H)}}break;case 6:if(yt(t,e),At(e),n&4){if(e.stateNode===null)throw Error(o(162));l=e.stateNode,s=e.memoizedProps;try{l.nodeValue=s}catch(H){he(e,e.return,H)}}break;case 3:if(yt(t,e),At(e),n&4&&a!==null&&a.memoizedState.isDehydrated)try{yi(t.containerInfo)}catch(H){he(e,e.return,H)}break;case 4:yt(t,e),At(e);break;case 13:yt(t,e),At(e),l=e.child,l.flags&8192&&(s=l.memoizedState!==null,l.stateNode.isHidden=s,!s||l.alternate!==null&&l.alternate.memoizedState!==null||(pl=ge())),n&4&&Eu(e);break;case 22:if(C=a!==null&&a.memoizedState!==null,e.mode&1?(Ee=(T=Ee)||C,yt(t,e),Ee=T):yt(t,e),At(e),n&8192){if(T=e.memoizedState!==null,(e.stateNode.isHidden=T)&&!C&&(e.mode&1)!==0)for(M=e,C=e.child;C!==null;){for(D=M=C;M!==null;){switch(w=M,F=w.child,w.tag){case 0:case 11:case 14:case 15:Ui(4,w,w.return);break;case 1:$a(w,w.return);var x=w.stateNode;if(typeof x.componentWillUnmount=="function"){n=w,a=w.return;try{t=n,x.props=t.memoizedProps,x.state=t.memoizedState,x.componentWillUnmount()}catch(H){he(n,a,H)}}break;case 5:$a(w,w.return);break;case 22:if(w.memoizedState!==null){Ou(D);continue}}F!==null?(F.return=w,M=F):Ou(D)}C=C.sibling}e:for(C=null,D=e;;){if(D.tag===5){if(C===null){C=D;try{l=D.stateNode,T?(s=l.style,typeof s.setProperty=="function"?s.setProperty("display","none","important"):s.display="none"):(f=D.stateNode,m=D.memoizedProps.style,d=m!=null&&m.hasOwnProperty("display")?m.display:null,f.style.display=fs("display",d))}catch(H){he(e,e.return,H)}}}else if(D.tag===6){if(C===null)try{D.stateNode.nodeValue=T?"":D.memoizedProps}catch(H){he(e,e.return,H)}}else if((D.tag!==22&&D.tag!==23||D.memoizedState===null||D===e)&&D.child!==null){D.child.return=D,D=D.child;continue}if(D===e)break e;for(;D.sibling===null;){if(D.return===null||D.return===e)break e;C===D&&(C=null),D=D.return}C===D&&(C=null),D.sibling.return=D.return,D=D.sibling}}break;case 19:yt(t,e),At(e),n&4&&Eu(e);break;case 21:break;default:yt(t,e),At(e)}}function At(e){var t=e.flags;if(t&2){try{e:{for(var a=e.return;a!==null;){if(Au(a)){var n=a;break e}a=a.return}throw Error(o(160))}switch(n.tag){case 5:var l=n.stateNode;n.flags&32&&(li(l,""),n.flags&=-33);var s=Ru(e);cl(e,s,l);break;case 3:case 4:var d=n.stateNode.containerInfo,f=Ru(e);sl(e,f,d);break;default:throw Error(o(161))}}catch(m){he(e,e.return,m)}e.flags&=-3}t&4096&&(e.flags&=-4097)}function Am(e,t,a){M=e,Iu(e)}function Iu(e,t,a){for(var n=(e.mode&1)!==0;M!==null;){var l=M,s=l.child;if(l.tag===22&&n){var d=l.memoizedState!==null||qr;if(!d){var f=l.alternate,m=f!==null&&f.memoizedState!==null||Ee;f=qr;var T=Ee;if(qr=d,(Ee=m)&&!T)for(M=l;M!==null;)d=M,m=d.child,d.tag===22&&d.memoizedState!==null?Hu(l):m!==null?(m.return=d,M=m):Hu(l);for(;s!==null;)M=s,Iu(s),s=s.sibling;M=l,qr=f,Ee=T}xu(e)}else(l.subtreeFlags&8772)!==0&&s!==null?(s.return=l,M=s):xu(e)}}function xu(e){for(;M!==null;){var t=M;if((t.flags&8772)!==0){var a=t.alternate;try{if((t.flags&8772)!==0)switch(t.tag){case 0:case 11:case 15:Ee||Gr(5,t);break;case 1:var n=t.stateNode;if(t.flags&4&&!Ee)if(a===null)n.componentDidMount();else{var l=t.elementType===t.type?a.memoizedProps:gt(t.type,a.memoizedProps);n.componentDidUpdate(l,a.memoizedState,n.__reactInternalSnapshotBeforeUpdate)}var s=t.updateQueue;s!==null&&Oc(t,s,n);break;case 3:var d=t.updateQueue;if(d!==null){if(a=null,t.child!==null)switch(t.child.tag){case 5:a=t.child.stateNode;break;case 1:a=t.child.stateNode}Oc(t,d,a)}break;case 5:var f=t.stateNode;if(a===null&&t.flags&4){a=f;var m=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":m.autoFocus&&a.focus();break;case"img":m.src&&(a.src=m.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(t.memoizedState===null){var T=t.alternate;if(T!==null){var C=T.memoizedState;if(C!==null){var D=C.dehydrated;D!==null&&yi(D)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(o(163))}Ee||t.flags&512&&ll(t)}catch(w){he(t,t.return,w)}}if(t===e){M=null;break}if(a=t.sibling,a!==null){a.return=t.return,M=a;break}M=t.return}}function Ou(e){for(;M!==null;){var t=M;if(t===e){M=null;break}var a=t.sibling;if(a!==null){a.return=t.return,M=a;break}M=t.return}}function Hu(e){for(;M!==null;){var t=M;try{switch(t.tag){case 0:case 11:case 15:var a=t.return;try{Gr(4,t)}catch(m){he(t,a,m)}break;case 1:var n=t.stateNode;if(typeof n.componentDidMount=="function"){var l=t.return;try{n.componentDidMount()}catch(m){he(t,l,m)}}var s=t.return;try{ll(t)}catch(m){he(t,s,m)}break;case 5:var d=t.return;try{ll(t)}catch(m){he(t,d,m)}}}catch(m){he(t,t.return,m)}if(t===e){M=null;break}var f=t.sibling;if(f!==null){f.return=t.return,M=f;break}M=t.return}}var Rm=Math.ceil,Kr=Le.ReactCurrentDispatcher,ul=Le.ReactCurrentOwner,lt=Le.ReactCurrentBatchConfig,Q=0,we=null,ye=null,Pe=0,Ze=0,Ja=Qt(0),ke=0,_i=null,Sa=0,Qr=0,dl=0,Vi=null,qe=null,pl=0,Xa=1/0,Wt=null,Yr=!1,fl=null,ea=null,$r=!1,ta=null,Jr=0,zi=0,ml=null,Xr=-1,Zr=0;function Oe(){return(Q&6)!==0?ge():Xr!==-1?Xr:Xr=ge()}function aa(e){return(e.mode&1)===0?1:(Q&2)!==0&&Pe!==0?Pe&-Pe:pm.transition!==null?(Zr===0&&(Zr=Rs()),Zr):(e=te,e!==0||(e=window.event,e=e===void 0?16:Bs(e.type)),e)}function St(e,t,a,n){if(50<zi)throw zi=0,ml=null,Error(o(185));fi(e,a,n),((Q&2)===0||e!==we)&&(e===we&&((Q&2)===0&&(Qr|=a),ke===4&&ia(e,Pe)),Ge(e,n),a===1&&Q===0&&(t.mode&1)===0&&(Xa=ge()+500,Lr&&$t()))}function Ge(e,t){var a=e.callbackNode;pf(e,t);var n=sr(e,e===we?Pe:0);if(n===0)a!==null&&Ps(a),e.callbackNode=null,e.callbackPriority=0;else if(t=n&-n,e.callbackPriority!==t){if(a!=null&&Ps(a),t===1)e.tag===0?dm(Bu.bind(null,e)):vc(Bu.bind(null,e)),lm(function(){(Q&6)===0&&$t()}),a=null;else{switch(Fs(n)){case 1:a=Gn;break;case 4:a=Ls;break;case 16:a=rr;break;case 536870912:a=As;break;default:a=rr}a=Gu(a,Nu.bind(null,e))}e.callbackPriority=t,e.callbackNode=a}}function Nu(e,t){if(Xr=-1,Zr=0,(Q&6)!==0)throw Error(o(327));var a=e.callbackNode;if(Za()&&e.callbackNode!==a)return null;var n=sr(e,e===we?Pe:0);if(n===0)return null;if((n&30)!==0||(n&e.expiredLanes)!==0||t)t=en(e,n);else{t=n;var l=Q;Q|=2;var s=Uu();(we!==e||Pe!==t)&&(Wt=null,Xa=ge()+500,Ta(e,t));do try{Mm();break}catch(f){Wu(e,f)}while(!0);Mo(),Kr.current=s,Q=l,ye!==null?t=0:(we=null,Pe=0,t=ke)}if(t!==0){if(t===2&&(l=Kn(e),l!==0&&(n=l,t=hl(e,l))),t===1)throw a=_i,Ta(e,0),ia(e,n),Ge(e,ge()),a;if(t===6)ia(e,n);else{if(l=e.current.alternate,(n&30)===0&&!Fm(l)&&(t=en(e,n),t===2&&(s=Kn(e),s!==0&&(n=s,t=hl(e,s))),t===1))throw a=_i,Ta(e,0),ia(e,n),Ge(e,ge()),a;switch(e.finishedWork=l,e.finishedLanes=n,t){case 0:case 1:throw Error(o(345));case 2:wa(e,qe,Wt);break;case 3:if(ia(e,n),(n&130023424)===n&&(t=pl+500-ge(),10<t)){if(sr(e,0)!==0)break;if(l=e.suspendedLanes,(l&n)!==n){Oe(),e.pingedLanes|=e.suspendedLanes&l;break}e.timeoutHandle=To(wa.bind(null,e,qe,Wt),t);break}wa(e,qe,Wt);break;case 4:if(ia(e,n),(n&4194240)===n)break;for(t=e.eventTimes,l=-1;0<n;){var d=31-ft(n);s=1<<d,d=t[d],d>l&&(l=d),n&=~s}if(n=l,n=ge()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Rm(n/1960))-n,10<n){e.timeoutHandle=To(wa.bind(null,e,qe,Wt),n);break}wa(e,qe,Wt);break;case 5:wa(e,qe,Wt);break;default:throw Error(o(329))}}}return Ge(e,ge()),e.callbackNode===a?Nu.bind(null,e):null}function hl(e,t){var a=Vi;return e.current.memoizedState.isDehydrated&&(Ta(e,t).flags|=256),e=en(e,t),e!==2&&(t=qe,qe=a,t!==null&&gl(t)),e}function gl(e){qe===null?qe=e:qe.push.apply(qe,e)}function Fm(e){for(var t=e;;){if(t.flags&16384){var a=t.updateQueue;if(a!==null&&(a=a.stores,a!==null))for(var n=0;n<a.length;n++){var l=a[n],s=l.getSnapshot;l=l.value;try{if(!mt(s(),l))return!1}catch{return!1}}}if(a=t.child,t.subtreeFlags&16384&&a!==null)a.return=t,t=a;else{if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function ia(e,t){for(t&=~dl,t&=~Qr,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var a=31-ft(t),n=1<<a;e[a]=-1,t&=~n}}function Bu(e){if((Q&6)!==0)throw Error(o(327));Za();var t=sr(e,0);if((t&1)===0)return Ge(e,ge()),null;var a=en(e,t);if(e.tag!==0&&a===2){var n=Kn(e);n!==0&&(t=n,a=hl(e,n))}if(a===1)throw a=_i,Ta(e,0),ia(e,t),Ge(e,ge()),a;if(a===6)throw Error(o(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,wa(e,qe,Wt),Ge(e,ge()),null}function bl(e,t){var a=Q;Q|=1;try{return e(t)}finally{Q=a,Q===0&&(Xa=ge()+500,Lr&&$t())}}function ka(e){ta!==null&&ta.tag===0&&(Q&6)===0&&Za();var t=Q;Q|=1;var a=lt.transition,n=te;try{if(lt.transition=null,te=1,e)return e()}finally{te=n,lt.transition=a,Q=t,(Q&6)===0&&$t()}}function yl(){Ze=Ja.current,le(Ja)}function Ta(e,t){e.finishedWork=null,e.finishedLanes=0;var a=e.timeoutHandle;if(a!==-1&&(e.timeoutHandle=-1,om(a)),ye!==null)for(a=ye.return;a!==null;){var n=a;switch(Lo(n),n.tag){case 1:n=n.type.childContextTypes,n!=null&&Dr();break;case 3:Qa(),le(Ve),le(Ae),Uo();break;case 5:Bo(n);break;case 4:Qa();break;case 13:le(pe);break;case 19:le(pe);break;case 10:Io(n.type._context);break;case 22:case 23:yl()}a=a.return}if(we=e,ye=e=ra(e.current,null),Pe=Ze=t,ke=0,_i=null,dl=Qr=Sa=0,qe=Vi=null,ga!==null){for(t=0;t<ga.length;t++)if(a=ga[t],n=a.interleaved,n!==null){a.interleaved=null;var l=n.next,s=a.pending;if(s!==null){var d=s.next;s.next=l,n.next=d}a.pending=n}ga=null}return e}function Wu(e,t){do{var a=ye;try{if(Mo(),Nr.current=_r,Br){for(var n=fe.memoizedState;n!==null;){var l=n.queue;l!==null&&(l.pending=null),n=n.next}Br=!1}if(ya=0,Te=Se=fe=null,Oi=!1,Hi=0,ul.current=null,a===null||a.return===null){ke=1,_i=t,ye=null;break}e:{var s=e,d=a.return,f=a,m=t;if(t=Pe,f.flags|=32768,m!==null&&typeof m=="object"&&typeof m.then=="function"){var T=m,C=f,D=C.tag;if((C.mode&1)===0&&(D===0||D===11||D===15)){var w=C.alternate;w?(C.updateQueue=w.updateQueue,C.memoizedState=w.memoizedState,C.lanes=w.lanes):(C.updateQueue=null,C.memoizedState=null)}var F=uu(d);if(F!==null){F.flags&=-257,du(F,d,f,s,t),F.mode&1&&cu(s,T,t),t=F,m=T;var x=t.updateQueue;if(x===null){var H=new Set;H.add(m),t.updateQueue=H}else x.add(m);break e}else{if((t&1)===0){cu(s,T,t),Sl();break e}m=Error(o(426))}}else if(de&&f.mode&1){var be=uu(d);if(be!==null){(be.flags&65536)===0&&(be.flags|=256),du(be,d,f,s,t),Fo(Ya(m,f));break e}}s=m=Ya(m,f),ke!==4&&(ke=2),Vi===null?Vi=[s]:Vi.push(s),s=d;do{switch(s.tag){case 3:s.flags|=65536,t&=-t,s.lanes|=t;var b=lu(s,m,t);xc(s,b);break e;case 1:f=m;var h=s.type,S=s.stateNode;if((s.flags&128)===0&&(typeof h.getDerivedStateFromError=="function"||S!==null&&typeof S.componentDidCatch=="function"&&(ea===null||!ea.has(S)))){s.flags|=65536,t&=-t,s.lanes|=t;var P=su(s,f,t);xc(s,P);break e}}s=s.return}while(s!==null)}Vu(a)}catch(N){t=N,ye===a&&a!==null&&(ye=a=a.return);continue}break}while(!0)}function Uu(){var e=Kr.current;return Kr.current=_r,e===null?_r:e}function Sl(){(ke===0||ke===3||ke===2)&&(ke=4),we===null||(Sa&268435455)===0&&(Qr&268435455)===0||ia(we,Pe)}function en(e,t){var a=Q;Q|=2;var n=Uu();(we!==e||Pe!==t)&&(Wt=null,Ta(e,t));do try{Em();break}catch(l){Wu(e,l)}while(!0);if(Mo(),Q=a,Kr.current=n,ye!==null)throw Error(o(261));return we=null,Pe=0,ke}function Em(){for(;ye!==null;)_u(ye)}function Mm(){for(;ye!==null&&!af();)_u(ye)}function _u(e){var t=qu(e.alternate,e,Ze);e.memoizedProps=e.pendingProps,t===null?Vu(e):ye=t,ul.current=null}function Vu(e){var t=e;do{var a=t.alternate;if(e=t.return,(t.flags&32768)===0){if(a=Cm(a,t,Ze),a!==null){ye=a;return}}else{if(a=Dm(a,t),a!==null){a.flags&=32767,ye=a;return}if(e!==null)e.flags|=32768,e.subtreeFlags=0,e.deletions=null;else{ke=6,ye=null;return}}if(t=t.sibling,t!==null){ye=t;return}ye=t=e}while(t!==null);ke===0&&(ke=5)}function wa(e,t,a){var n=te,l=lt.transition;try{lt.transition=null,te=1,Im(e,t,a,n)}finally{lt.transition=l,te=n}return null}function Im(e,t,a,n){do Za();while(ta!==null);if((Q&6)!==0)throw Error(o(327));a=e.finishedWork;var l=e.finishedLanes;if(a===null)return null;if(e.finishedWork=null,e.finishedLanes=0,a===e.current)throw Error(o(177));e.callbackNode=null,e.callbackPriority=0;var s=a.lanes|a.childLanes;if(ff(e,s),e===we&&(ye=we=null,Pe=0),(a.subtreeFlags&2064)===0&&(a.flags&2064)===0||$r||($r=!0,Gu(rr,function(){return Za(),null})),s=(a.flags&15990)!==0,(a.subtreeFlags&15990)!==0||s){s=lt.transition,lt.transition=null;var d=te;te=1;var f=Q;Q|=4,ul.current=null,Lm(e,a),Mu(a,e),Zf(So),dr=!!yo,So=yo=null,e.current=a,Am(a),rf(),Q=f,te=d,lt.transition=s}else e.current=a;if($r&&($r=!1,ta=e,Jr=l),s=e.pendingLanes,s===0&&(ea=null),lf(a.stateNode),Ge(e,ge()),t!==null)for(n=e.onRecoverableError,a=0;a<t.length;a++)l=t[a],n(l.value,{componentStack:l.stack,digest:l.digest});if(Yr)throw Yr=!1,e=fl,fl=null,e;return(Jr&1)!==0&&e.tag!==0&&Za(),s=e.pendingLanes,(s&1)!==0?e===ml?zi++:(zi=0,ml=e):zi=0,$t(),null}function Za(){if(ta!==null){var e=Fs(Jr),t=lt.transition,a=te;try{if(lt.transition=null,te=16>e?16:e,ta===null)var n=!1;else{if(e=ta,ta=null,Jr=0,(Q&6)!==0)throw Error(o(331));var l=Q;for(Q|=4,M=e.current;M!==null;){var s=M,d=s.child;if((M.flags&16)!==0){var f=s.deletions;if(f!==null){for(var m=0;m<f.length;m++){var T=f[m];for(M=T;M!==null;){var C=M;switch(C.tag){case 0:case 11:case 15:Ui(8,C,s)}var D=C.child;if(D!==null)D.return=C,M=D;else for(;M!==null;){C=M;var w=C.sibling,F=C.return;if(Lu(C),C===T){M=null;break}if(w!==null){w.return=F,M=w;break}M=F}}}var x=s.alternate;if(x!==null){var H=x.child;if(H!==null){x.child=null;do{var be=H.sibling;H.sibling=null,H=be}while(H!==null)}}M=s}}if((s.subtreeFlags&2064)!==0&&d!==null)d.return=s,M=d;else e:for(;M!==null;){if(s=M,(s.flags&2048)!==0)switch(s.tag){case 0:case 11:case 15:Ui(9,s,s.return)}var b=s.sibling;if(b!==null){b.return=s.return,M=b;break e}M=s.return}}var h=e.current;for(M=h;M!==null;){d=M;var S=d.child;if((d.subtreeFlags&2064)!==0&&S!==null)S.return=d,M=S;else e:for(d=h;M!==null;){if(f=M,(f.flags&2048)!==0)try{switch(f.tag){case 0:case 11:case 15:Gr(9,f)}}catch(N){he(f,f.return,N)}if(f===d){M=null;break e}var P=f.sibling;if(P!==null){P.return=f.return,M=P;break e}M=f.return}}if(Q=l,$t(),Ct&&typeof Ct.onPostCommitFiberRoot=="function")try{Ct.onPostCommitFiberRoot(nr,e)}catch{}n=!0}return n}finally{te=a,lt.transition=t}}return!1}function zu(e,t,a){t=Ya(a,t),t=lu(e,t,1),e=Xt(e,t,1),t=Oe(),e!==null&&(fi(e,1,t),Ge(e,t))}function he(e,t,a){if(e.tag===3)zu(e,e,a);else for(;t!==null;){if(t.tag===3){zu(t,e,a);break}else if(t.tag===1){var n=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof n.componentDidCatch=="function"&&(ea===null||!ea.has(n))){e=Ya(a,e),e=su(t,e,1),t=Xt(t,e,1),e=Oe(),t!==null&&(fi(t,1,e),Ge(t,e));break}}t=t.return}}function xm(e,t,a){var n=e.pingCache;n!==null&&n.delete(t),t=Oe(),e.pingedLanes|=e.suspendedLanes&a,we===e&&(Pe&a)===a&&(ke===4||ke===3&&(Pe&130023424)===Pe&&500>ge()-pl?Ta(e,0):dl|=a),Ge(e,t)}function ju(e,t){t===0&&((e.mode&1)===0?t=1:(t=lr,lr<<=1,(lr&130023424)===0&&(lr=4194304)));var a=Oe();e=Ht(e,t),e!==null&&(fi(e,t,a),Ge(e,a))}function Om(e){var t=e.memoizedState,a=0;t!==null&&(a=t.retryLane),ju(e,a)}function Hm(e,t){var a=0;switch(e.tag){case 13:var n=e.stateNode,l=e.memoizedState;l!==null&&(a=l.retryLane);break;case 19:n=e.stateNode;break;default:throw Error(o(314))}n!==null&&n.delete(t),ju(e,a)}var qu;qu=function(e,t,a){if(e!==null)if(e.memoizedProps!==t.pendingProps||Ve.current)je=!0;else{if((e.lanes&a)===0&&(t.flags&128)===0)return je=!1,vm(e,t,a);je=(e.flags&131072)!==0}else je=!1,de&&(t.flags&1048576)!==0&&Cc(t,Rr,t.index);switch(t.lanes=0,t.tag){case 2:var n=t.type;jr(e,t),e=t.pendingProps;var l=_a(t,Ae.current);Ka(t,a),l=zo(null,t,n,e,l,a);var s=jo();return t.flags|=1,typeof l=="object"&&l!==null&&typeof l.render=="function"&&l.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,ze(n)?(s=!0,Pr(t)):s=!1,t.memoizedState=l.state!==null&&l.state!==void 0?l.state:null,Ho(t),l.updater=Vr,t.stateNode=l,l._reactInternals=t,$o(t,n,e,a),t=el(null,t,n,!0,s,a)):(t.tag=0,de&&s&&Po(t),xe(null,t,l,a),t=t.child),t;case 16:n=t.elementType;e:{switch(jr(e,t),e=t.pendingProps,l=n._init,n=l(n._payload),t.type=n,l=t.tag=Bm(n),e=gt(n,e),l){case 0:t=Zo(null,t,n,e,a);break e;case 1:t=bu(null,t,n,e,a);break e;case 11:t=pu(null,t,n,e,a);break e;case 14:t=fu(null,t,n,gt(n.type,e),a);break e}throw Error(o(306,n,""))}return t;case 0:return n=t.type,l=t.pendingProps,l=t.elementType===n?l:gt(n,l),Zo(e,t,n,l,a);case 1:return n=t.type,l=t.pendingProps,l=t.elementType===n?l:gt(n,l),bu(e,t,n,l,a);case 3:e:{if(yu(t),e===null)throw Error(o(387));n=t.pendingProps,s=t.memoizedState,l=s.element,Ic(e,t),Or(t,n,null,a);var d=t.memoizedState;if(n=d.element,s.isDehydrated)if(s={element:n,isDehydrated:!1,cache:d.cache,pendingSuspenseBoundaries:d.pendingSuspenseBoundaries,transitions:d.transitions},t.updateQueue.baseState=s,t.memoizedState=s,t.flags&256){l=Ya(Error(o(423)),t),t=Su(e,t,n,a,l);break e}else if(n!==l){l=Ya(Error(o(424)),t),t=Su(e,t,n,a,l);break e}else for(Xe=Kt(t.stateNode.containerInfo.firstChild),Je=t,de=!0,ht=null,a=Ec(t,null,n,a),t.child=a;a;)a.flags=a.flags&-3|4096,a=a.sibling;else{if(ja(),n===l){t=Bt(e,t,a);break e}xe(e,t,n,a)}t=t.child}return t;case 5:return Hc(t),e===null&&Ro(t),n=t.type,l=t.pendingProps,s=e!==null?e.memoizedProps:null,d=l.children,ko(n,l)?d=null:s!==null&&ko(n,s)&&(t.flags|=32),gu(e,t),xe(e,t,d,a),t.child;case 6:return e===null&&Ro(t),null;case 13:return ku(e,t,a);case 4:return No(t,t.stateNode.containerInfo),n=t.pendingProps,e===null?t.child=qa(t,null,n,a):xe(e,t,n,a),t.child;case 11:return n=t.type,l=t.pendingProps,l=t.elementType===n?l:gt(n,l),pu(e,t,n,l,a);case 7:return xe(e,t,t.pendingProps,a),t.child;case 8:return xe(e,t,t.pendingProps.children,a),t.child;case 12:return xe(e,t,t.pendingProps.children,a),t.child;case 10:e:{if(n=t.type._context,l=t.pendingProps,s=t.memoizedProps,d=l.value,ne(Mr,n._currentValue),n._currentValue=d,s!==null)if(mt(s.value,d)){if(s.children===l.children&&!Ve.current){t=Bt(e,t,a);break e}}else for(s=t.child,s!==null&&(s.return=t);s!==null;){var f=s.dependencies;if(f!==null){d=s.child;for(var m=f.firstContext;m!==null;){if(m.context===n){if(s.tag===1){m=Nt(-1,a&-a),m.tag=2;var T=s.updateQueue;if(T!==null){T=T.shared;var C=T.pending;C===null?m.next=m:(m.next=C.next,C.next=m),T.pending=m}}s.lanes|=a,m=s.alternate,m!==null&&(m.lanes|=a),xo(s.return,a,t),f.lanes|=a;break}m=m.next}}else if(s.tag===10)d=s.type===t.type?null:s.child;else if(s.tag===18){if(d=s.return,d===null)throw Error(o(341));d.lanes|=a,f=d.alternate,f!==null&&(f.lanes|=a),xo(d,a,t),d=s.sibling}else d=s.child;if(d!==null)d.return=s;else for(d=s;d!==null;){if(d===t){d=null;break}if(s=d.sibling,s!==null){s.return=d.return,d=s;break}d=d.return}s=d}xe(e,t,l.children,a),t=t.child}return t;case 9:return l=t.type,n=t.pendingProps.children,Ka(t,a),l=nt(l),n=n(l),t.flags|=1,xe(e,t,n,a),t.child;case 14:return n=t.type,l=gt(n,t.pendingProps),l=gt(n.type,l),fu(e,t,n,l,a);case 15:return mu(e,t,t.type,t.pendingProps,a);case 17:return n=t.type,l=t.pendingProps,l=t.elementType===n?l:gt(n,l),jr(e,t),t.tag=1,ze(n)?(e=!0,Pr(t)):e=!1,Ka(t,a),nu(t,n,l),$o(t,n,l,a),el(null,t,n,!0,e,a);case 19:return wu(e,t,a);case 22:return hu(e,t,a)}throw Error(o(156,t.tag))};function Gu(e,t){return Ds(e,t)}function Nm(e,t,a,n){this.tag=e,this.key=a,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function st(e,t,a,n){return new Nm(e,t,a,n)}function kl(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Bm(e){if(typeof e=="function")return kl(e)?1:0;if(e!=null){if(e=e.$$typeof,e===wt)return 11;if(e===vt)return 14}return 2}function ra(e,t){var a=e.alternate;return a===null?(a=st(e.tag,t,e.key,e.mode),a.elementType=e.elementType,a.type=e.type,a.stateNode=e.stateNode,a.alternate=e,e.alternate=a):(a.pendingProps=t,a.type=e.type,a.flags=0,a.subtreeFlags=0,a.deletions=null),a.flags=e.flags&14680064,a.childLanes=e.childLanes,a.lanes=e.lanes,a.child=e.child,a.memoizedProps=e.memoizedProps,a.memoizedState=e.memoizedState,a.updateQueue=e.updateQueue,t=e.dependencies,a.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},a.sibling=e.sibling,a.index=e.index,a.ref=e.ref,a}function tn(e,t,a,n,l,s){var d=2;if(n=e,typeof e=="function")kl(e)&&(d=1);else if(typeof e=="string")d=5;else e:switch(e){case Ue:return va(a.children,l,s,t);case at:d=8,l|=8;break;case Ut:return e=st(12,a,t,l|2),e.elementType=Ut,e.lanes=s,e;case Qe:return e=st(13,a,t,l),e.elementType=Qe,e.lanes=s,e;case pt:return e=st(19,a,t,l),e.elementType=pt,e.lanes=s,e;case me:return an(a,l,s,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case Et:d=10;break e;case ua:d=9;break e;case wt:d=11;break e;case vt:d=14;break e;case _e:d=16,n=null;break e}throw Error(o(130,e==null?e:typeof e,""))}return t=st(d,a,t,l),t.elementType=e,t.type=n,t.lanes=s,t}function va(e,t,a,n){return e=st(7,e,n,t),e.lanes=a,e}function an(e,t,a,n){return e=st(22,e,n,t),e.elementType=me,e.lanes=a,e.stateNode={isHidden:!1},e}function Tl(e,t,a){return e=st(6,e,null,t),e.lanes=a,e}function wl(e,t,a){return t=st(4,e.children!==null?e.children:[],e.key,t),t.lanes=a,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Wm(e,t,a,n,l){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Qn(0),this.expirationTimes=Qn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Qn(0),this.identifierPrefix=n,this.onRecoverableError=l,this.mutableSourceEagerHydrationData=null}function vl(e,t,a,n,l,s,d,f,m){return e=new Wm(e,t,a,f,m),t===1?(t=1,s===!0&&(t|=8)):t=0,s=st(3,null,null,t),e.current=s,s.stateNode=e,s.memoizedState={element:n,isDehydrated:a,cache:null,transitions:null,pendingSuspenseBoundaries:null},Ho(s),e}function Um(e,t,a){var n=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:Ie,key:n==null?null:""+n,children:e,containerInfo:t,implementation:a}}function Ku(e){if(!e)return Yt;e=e._reactInternals;e:{if(da(e)!==e||e.tag!==1)throw Error(o(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(ze(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(t!==null);throw Error(o(171))}if(e.tag===1){var a=e.type;if(ze(a))return Tc(e,a,t)}return t}function Qu(e,t,a,n,l,s,d,f,m){return e=vl(a,n,!0,e,l,s,d,f,m),e.context=Ku(null),a=e.current,n=Oe(),l=aa(a),s=Nt(n,l),s.callback=t??null,Xt(a,s,l),e.current.lanes=l,fi(e,l,n),Ge(e,n),e}function rn(e,t,a,n){var l=t.current,s=Oe(),d=aa(l);return a=Ku(a),t.context===null?t.context=a:t.pendingContext=a,t=Nt(s,d),t.payload={element:e},n=n===void 0?null:n,n!==null&&(t.callback=n),e=Xt(l,t,d),e!==null&&(St(e,l,d,s),xr(e,l,d)),d}function nn(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return e.child.stateNode;default:return e.child.stateNode}}function Yu(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var a=e.retryLane;e.retryLane=a!==0&&a<t?a:t}}function Cl(e,t){Yu(e,t),(e=e.alternate)&&Yu(e,t)}function _m(){return null}var $u=typeof reportError=="function"?reportError:function(e){console.error(e)};function Dl(e){this._internalRoot=e}on.prototype.render=Dl.prototype.render=function(e){var t=this._internalRoot;if(t===null)throw Error(o(409));rn(e,t,null,null)},on.prototype.unmount=Dl.prototype.unmount=function(){var e=this._internalRoot;if(e!==null){this._internalRoot=null;var t=e.containerInfo;ka(function(){rn(null,e,null,null)}),t[Mt]=null}};function on(e){this._internalRoot=e}on.prototype.unstable_scheduleHydration=function(e){if(e){var t=Is();e={blockedOn:null,target:e,priority:t};for(var a=0;a<jt.length&&t!==0&&t<jt[a].priority;a++);jt.splice(a,0,e),a===0&&Hs(e)}};function Pl(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function ln(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11&&(e.nodeType!==8||e.nodeValue!==" react-mount-point-unstable "))}function Ju(){}function Vm(e,t,a,n,l){if(l){if(typeof n=="function"){var s=n;n=function(){var T=nn(d);s.call(T)}}var d=Qu(t,n,e,0,null,!1,!1,"",Ju);return e._reactRootContainer=d,e[Mt]=d.current,Li(e.nodeType===8?e.parentNode:e),ka(),d}for(;l=e.lastChild;)e.removeChild(l);if(typeof n=="function"){var f=n;n=function(){var T=nn(m);f.call(T)}}var m=vl(e,0,!1,null,null,!1,!1,"",Ju);return e._reactRootContainer=m,e[Mt]=m.current,Li(e.nodeType===8?e.parentNode:e),ka(function(){rn(t,m,a,n)}),m}function sn(e,t,a,n,l){var s=a._reactRootContainer;if(s){var d=s;if(typeof l=="function"){var f=l;l=function(){var m=nn(d);f.call(m)}}rn(t,d,e,l)}else d=Vm(a,t,e,l,n);return nn(d)}Es=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var a=pi(t.pendingLanes);a!==0&&(Yn(t,a|1),Ge(t,ge()),(Q&6)===0&&(Xa=ge()+500,$t()))}break;case 13:ka(function(){var n=Ht(e,1);if(n!==null){var l=Oe();St(n,e,1,l)}}),Cl(e,1)}},$n=function(e){if(e.tag===13){var t=Ht(e,134217728);if(t!==null){var a=Oe();St(t,e,134217728,a)}Cl(e,134217728)}},Ms=function(e){if(e.tag===13){var t=aa(e),a=Ht(e,t);if(a!==null){var n=Oe();St(a,e,t,n)}Cl(e,t)}},Is=function(){return te},xs=function(e,t){var a=te;try{return te=e,t()}finally{te=a}},Vn=function(e,t,a){switch(t){case"input":if(xn(e,a),t=a.name,a.type==="radio"&&t!=null){for(a=e;a.parentNode;)a=a.parentNode;for(a=a.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<a.length;t++){var n=a[t];if(n!==e&&n.form===e.form){var l=Cr(n);if(!l)throw Error(o(90));rs(n),xn(n,l)}}}break;case"textarea":cs(e,a);break;case"select":t=a.value,t!=null&&Ra(e,!!a.multiple,t,!1)}},ys=bl,Ss=ka;var zm={usingClientEntryPoint:!1,Events:[Fi,Wa,Cr,gs,bs,bl]},ji={findFiberByHostInstance:pa,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},jm={bundleType:ji.bundleType,version:ji.version,rendererPackageName:ji.rendererPackageName,rendererConfig:ji.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Le.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return e=vs(e),e===null?null:e.stateNode},findFiberByHostInstance:ji.findFiberByHostInstance||_m,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){var cn=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!cn.isDisabled&&cn.supportsFiber)try{nr=cn.inject(jm),Ct=cn}catch{}}return Ke.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=zm,Ke.createPortal=function(e,t){var a=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!Pl(t))throw Error(o(200));return Um(e,t,null,a)},Ke.createRoot=function(e,t){if(!Pl(e))throw Error(o(299));var a=!1,n="",l=$u;return t!=null&&(t.unstable_strictMode===!0&&(a=!0),t.identifierPrefix!==void 0&&(n=t.identifierPrefix),t.onRecoverableError!==void 0&&(l=t.onRecoverableError)),t=vl(e,1,!1,null,null,a,!1,n,l),e[Mt]=t.current,Li(e.nodeType===8?e.parentNode:e),new Dl(t)},Ke.findDOMNode=function(e){if(e==null)return null;if(e.nodeType===1)return e;var t=e._reactInternals;if(t===void 0)throw typeof e.render=="function"?Error(o(188)):(e=Object.keys(e).join(","),Error(o(268,e)));return e=vs(t),e=e===null?null:e.stateNode,e},Ke.flushSync=function(e){return ka(e)},Ke.hydrate=function(e,t,a){if(!ln(t))throw Error(o(200));return sn(null,e,t,!0,a)},Ke.hydrateRoot=function(e,t,a){if(!Pl(e))throw Error(o(405));var n=a!=null&&a.hydratedSources||null,l=!1,s="",d=$u;if(a!=null&&(a.unstable_strictMode===!0&&(l=!0),a.identifierPrefix!==void 0&&(s=a.identifierPrefix),a.onRecoverableError!==void 0&&(d=a.onRecoverableError)),t=Qu(t,null,e,1,a??null,l,!1,s,d),e[Mt]=t.current,Li(e),n)for(e=0;e<n.length;e++)a=n[e],l=a._getVersion,l=l(a._source),t.mutableSourceEagerHydrationData==null?t.mutableSourceEagerHydrationData=[a,l]:t.mutableSourceEagerHydrationData.push(a,l);return new on(t)},Ke.render=function(e,t,a){if(!ln(t))throw Error(o(200));return sn(null,e,t,!1,a)},Ke.unmountComponentAtNode=function(e){if(!ln(e))throw Error(o(40));return e._reactRootContainer?(ka(function(){sn(null,null,e,!1,function(){e._reactRootContainer=null,e[Mt]=null})}),!0):!1},Ke.unstable_batchedUpdates=bl,Ke.unstable_renderSubtreeIntoContainer=function(e,t,a,n){if(!ln(a))throw Error(o(200));if(e==null||e._reactInternals===void 0)throw Error(o(38));return sn(e,t,a,!1,n)},Ke.version="18.3.1-next-f1338f8080-20240426",Ke}var nd;function th(){if(nd)return Rl.exports;nd=1;function i(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(r){console.error(r)}}return i(),Rl.exports=eh(),Rl.exports}var od;function ah(){if(od)return un;od=1;var i=th();return un.createRoot=i.createRoot,un.hydrateRoot=i.hydrateRoot,un}var ih=ah();const rh=Bd(ih),nh="modulepreload",oh=function(i){return"/"+i},ld={},sa=function(r,o,c){let u=Promise.resolve();if(o&&o.length>0){let y=function(O){return Promise.all(O.map(E=>Promise.resolve(E).then(B=>({status:"fulfilled",value:B}),B=>({status:"rejected",reason:B}))))};document.getElementsByTagName("link");const k=document.querySelector("meta[property=csp-nonce]"),L=(k==null?void 0:k.nonce)||(k==null?void 0:k.getAttribute("nonce"));u=y(o.map(O=>{if(O=oh(O),O in ld)return;ld[O]=!0;const E=O.endsWith(".css"),B=E?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${O}"]${B}`))return;const j=document.createElement("link");if(j.rel=E?"stylesheet":nh,E||(j.as="script"),j.crossOrigin="",j.href=O,L&&j.setAttribute("nonce",L),document.head.appendChild(j),E)return new Promise((Z,ce)=>{j.addEventListener("load",Z),j.addEventListener("error",()=>ce(new Error(`Unable to preload CSS for ${O}`)))})}))}function p(y){const k=new Event("vite:preloadError",{cancelable:!0});if(k.payload=y,window.dispatchEvent(k),!k.defaultPrevented)throw y}return u.then(y=>{for(const k of y||[])k.status==="rejected"&&p(k.reason);return r().catch(p)})};var He=ql();const lh=Bd(He),Gy=Qm({__proto__:null,default:lh},[He]),sh={common:{appName:"CodingNS",loading:"Loading...",retry:"Retry",back:"Back",save:"Save",connectionRouteRelay:"CodingNS Connect",connectionRouteLan:"LAN Direct",connectionRouteLoopback:"Local Direct",connectionRouteTailscale:"Tailscale Direct",connectionRouteDirect:"Direct Connection",logout:"Log out",unknown:"Unknown session",close:"Close",cancel:"Cancel",language:"Language"},auth:{loginTitle:"Resume your coding session",loginSubtitle:"INITIALIZING DEVELOPMENT ENVIRONMENT...",serverPreset:"Server Preset",serverCustomOption:"Use custom server",serverAddress:"Server Address",serverPlaceholder:"For example: http://127.0.0.1:3002",serverHint:"Login, realtime messages, and terminals all connect through this host. Point the client at the Host API endpoint such as http://127.0.0.1:3002; frontend dev ports like 4174 or 5173 are not meant for packaged clients and only work for temporary debugging when proxying and CORS are configured correctly.",serverInvalid:"Invalid server address. Check it and try again.",serverDiscoveredTag:"Auto-discovered",serverCurrent:"Current Server",bootstrapTitle:"Complete the first-time bootstrap",bootstrapSubtitle:"This Host does not have an admin account yet. Create the minimal login entry first.",username:"Username",password:"Password",rememberPassword:"Remember Password",confirmPassword:"Confirm Password",submitLogin:"Enter Workspace",submitBootstrap:"Create Admin Account",bootstrapSuccess:"Bootstrap completed. You can log in now.",bootstrapMismatch:"The two passwords do not match.",authUnavailable:"Host is unreachable right now. Check the server and try again.",logoutSuccess:"The current login state has been cleared.",demoBanner:"Demo environment — all account data is public and cleared on logout",demoSessionExpired:"Demo session expired. Please log in again.",captcha:"Captcha",captchaPlaceholder:"Enter the characters in the image",captchaHint:"After three failed attempts, complete the captcha before trying again.",captchaImageAlt:"Login captcha image",serverSettings:"Server Settings",serverSettingsTitle:"Server Configuration",saveServerSettings:"Save Settings",relayEntryTitle:"Connecting To Remote Host",relayEntryDescription:"Switching to this Host's trusted remote entry. You will be returned to the login page automatically.",relayEntryInvalid:"The remote access entry parameters are incomplete. Open the access URL again.",trustedEntryOnlyTitle:"Open This Through Your Remote Access URL",trustedEntryOnlyDescription:"This trusted frontend only loads the connection UI. It is not the Host API entry itself. Open the device's remote access URL again.",trustedEntryOnlyHintTitle:"How to enter",trustedEntryOnlyHint:"Use a remote access URL like https://xxxx.channel.codingns.com:1443. The tunnel domain will redirect you to the correct trusted entry automatically."},plugins:{listTitle:"Plugins",listDescription:"Review the plugins available to this workspace and decide whether to open or disable them.",loading:"Loading plugins...",listLoadFailed:"Failed to load the plugin list.",emptyTitle:"No plugins are available yet",emptyDescription:"Valid plugins will appear here automatically after Host scans them.",enabled:"Enabled",disabled:"Disabled",frontendTag:"Frontend",backendTag:"Action",detailLoadFailed:"Failed to load the plugin details.",detailMissingTitle:"This plugin could not be found",detailMissingDescription:"The plugin directory may have been removed, or Host has not scanned it again yet.",backToList:"Back to plugins",backToDetail:"Back to details",summaryTitle:"Summary",summaryDescription:"Confirm what this plugin is, where it is installed, and whether it is usable.",pluginIdLabel:"Plugin ID",installRootLabel:"Install directory",runtimeLabel:"Runtime",frontendOnly:"Frontend only, without backend actions",permissionTitle:"Permissions",permissionDescription:"Only explicitly declared permissions are listed here. Anything undeclared stays blocked by default.",workspaceReadAllowed:"Can read the current workspace",workspaceReadDenied:"Workspace read is not declared",networkAllowed:"Network access allowed",networkDenied:"Network access blocked by default",noDesktopPermission:"No desktop permission",actionTitle:"Available actions",actionDescription:"Every action goes through the unified plugin gateway instead of private command entry points.",runHistoryTitle:"Recent runs",runHistoryDescription:"Show the latest 10 runs first so it is easy to see whether actions actually ran.",runHistoryEmptyTitle:"No runs yet",runHistoryEmptyDescription:"A formal run record will appear here after the first action execution.",unknownAction:"Unknown action",openPlugin:"Open plugin",enableAction:"Enable plugin",disableAction:"Disable plugin",permissionNameReadFile:"Read files",permissionNameListDirectory:"List directory contents",permissionNameWriteFile:"Write files",permissionNameOpenFile:"Open files on desktop",permissionNameRevealInFileManager:"Reveal files in the file manager",permissionScopeWorkspace:"The whole current workspace",permissionScopeDirectory:"Directory: {scopePath}",permissionScopeFile:"File: {scopePath}",permissionScopeUnknown:"The target scope is not clear yet",permissionGrantModeOnce:"This time only",permissionGrantModeSession:"While this page stays open",permissionGrantModePersistent:"Keep it long term",permissionPromptTitle:"This plugin needs your approval first",permissionPromptDescription:"Review what it wants to do, then decide how long and how far the permission should go.",permissionPromptSummaryTitle:"What this request is asking for",permissionPromptSummaryDescription:"{pluginName} asked for a controlled capability. Nothing continues until you approve it.",permissionPromptPermissionLabel:"Requested capability",permissionPromptTargetLabel:"Applies to",permissionPromptPendingTag:"Waiting for you",permissionPromptOptionsTitle:"How you can allow it",permissionPromptOptionsDescription:"Start with the smallest scope instead of opening too much by default.",permissionPromptOptionOnce:"Allow only this target once",permissionPromptOptionOnceDescription:"Only continue this request. The plugin must ask again next time.",permissionPromptOptionSession:"Allow for this open session",permissionPromptOptionSessionDescription:"Keep it only while this plugin page stays open, then expire it automatically.",permissionPromptOptionDirectory:"Allow this directory long term",permissionPromptOptionDirectoryDescription:"Future access to {scopePath} and its children will not ask again each time.",permissionPromptDenyAction:"Not now",permissionPromptNoOptionTitle:"No valid approval choice is available",permissionPromptNoOptionDescription:"This request does not provide a safe scope yet. Go back to the plugin details first.",grantedPermissionTitle:"Permissions already allowed in this workspace",grantedPermissionDescription:"This shows only what has already been allowed for the current workspace, so you can pull it back at any time.",grantedPermissionEmptyTitle:"No permission has been granted yet",grantedPermissionEmptyDescription:"A formal grant record appears here after the plugin asks for access and you approve it.",permissionGrantLoading:"Loading permission grants...",permissionGrantLoadFailed:"Failed to load plugin permission grants.",revokeGrantAction:"Revoke",revokeGrantSuccess:"The plugin permission was revoked.",revokeGrantFailed:"Failed to revoke the plugin permission.",permissionAuditTitle:"Recent permission activity",permissionAuditDescription:"Grant, deny, and revoke records stay here so you can trace who opened what later.",permissionAuditEmptyTitle:"No permission activity yet",permissionAuditEmptyDescription:"Grant, deny, or revoke activity will appear here automatically.",permissionEventGranted:"Granted: {permission}",permissionEventRevoked:"Revoked: {permission}",permissionEventDenied:"Denied: {permission}",permissionEventUnknown:"Unknown permission",permissionEventReasonDeclarationMissing:"Denied because the plugin never declared it",permissionEventReasonGrantRequired:"Needs your approval first",enableSuccess:"Plugin enabled.",disableSuccess:"Plugin disabled.",saveFailed:"Failed to save the plugin state.",disabledByUserReason:"Disabled by the user from the plugin detail page",containerDescription:"The plugin frontend runs in an isolated container and does not receive the host desktop bridge directly.",containerLoadFailed:"Failed to load the plugin runtime page.",containerMissingTitle:"This plugin has no runnable page",containerMissingDescription:"This plugin may be backend-only or already disabled."},settings:{title:"Settings",appearance:"Appearance",appearanceSectionSummary:"Language, theme, and interface colors",language:"Language",languageDescription:"Choose the display language used by the interface.",theme:"Theme",themeDescription:"Choose the color theme that fits the way you work.",autoTheme:"Follow system theme automatically",autoThemeDescription:"When enabled, switch between day and night mode based on the system or browser color scheme.",fileManager:"File Manager",workspaceSessionSortMode:"Workspace session sort order",teableEntryTitle:"Teable Forms",teableEntryDescription:"Manage the Teable connection and how CodingNS data syncs into Teable tables.",teableOpenSettingsAction:"Open settings",teableModalTitle:"Teable form settings",teableModalDescription:"Manage the Teable connection, synced tables, and field mappings between CodingNS data and Teable tables.",teableTabConnection:"Connection",teableTabForms:"Forms",teableTabMirrors:"Mirrors",teableTabFieldMappings:"Field mappings",teableTabConnectionSettings:"Connection settings",teableTabFormSettings:"Form settings",teableTabTableSyncSettings:"Table sync settings",teableTabSyncLogs:"Sync logs",teableTestConnectionAction:"Test connection",teableConnectionTestSuccess:"Connection works. Read {tableCount} tables.",teableLoadFailed:"Failed to load Teable settings.",teableStatusUnknown:"Status unavailable",teableStatusIdleHint:"No mirror sync has been triggered yet.",teableStatusBindingLabel:"Connection",teableStatusSourceLabel:"Enabled sources",teableStatusSourceDetail:"{count} source types are currently enabled for Teable sync.",teableStatusMirrorLabel:"Mirror tables",teableStatusMirrorDetail:"{count} mirror table bindings are currently recorded.",teableStatusTaskLabel:"Latest sync",teableBindingSectionTitle:"Connection settings",teableBindingSectionDescription:"Fill in the Teable site, space, base, and access token first, then decide whether to enable sync.",teableEnabledLabel:"Enable Teable sync",teableBaseUrlLabel:"Teable site URL",teableBaseUrlDescription:"Both http:// and https:// are supported. Use a plain http address when Teable is on the same LAN as Host.",teableBaseUrlPlaceholder:"For example: http://192.168.1.20:3000",teableSpaceIdLabel:"Space ID",teableSpaceIdPlaceholder:"Enter the target Space ID",teableBaseIdLabel:"Base ID",teableBaseIdPlaceholder:"Enter the target Base ID",teableAuthRefLabel:"Auth reference",teableAuthRefPlaceholder:"For example: secret://teable/main",teableAuthTokenLabel:"Access token",teableAuthTokenDescription:"Leave this blank if the Host already has a saved token you want to keep using.",teableAuthTokenPlaceholder:"Leave blank to keep the saved token",teableMirrorModeLabel:"Sync mode",teableBindingSaved:"Teable connection settings saved.",teableSyncConfigSectionTitle:"Workbench push scope",teableSyncConfigSectionDescription:"Choose which tags, sessions, and todos are pushed to Teable, and which table each type should use.",teableSyncEnabledLabel:"Allow syncing this source type",teableTargetTableLabel:"Target table",teableTargetTablePlaceholder:"Choose an existing Teable table",teableTagRootsLabel:"Tag trees to sync",teableSessionScopeModeLabel:"Session sync scope",teableSessionScopeAll:"Sync sessions from every workspace",teableSessionScopeSelected:"Sync sessions only from selected workspaces",teableWorkspaceMultiSelectLabel:"Choose workspaces",teableTodoSourceLabel:"Todo sources",teableTodoWorkspaceSource:"Sync workspace todos",teableTodoAffairsSource:"Sync affairs todos",teableTodoWorkspaceHint:"If you choose workspaces here, only todos from those workspaces are included. Leave it empty to avoid extra workspace filtering.",teableTargetTableIdLabel:"Target table ID",teableTargetTableHint:"Leave this blank and Host will create the default mirror table automatically.",teableTargetTableBoundHint:'Currently bound to table "{table}".',teableTargetTableIdPlaceholder:"Optional: reuse an existing table ID",teableScopeJsonLabel:"Sync scope (JSON)",teableScopeJsonPlaceholder:"Enter the sync scope JSON for this source type.",teableScopeJsonInvalid:"The sync scope must be a valid JSON object.",teableSyncConfigSaved:"Teable push scope saved.",teableFormsCatalogTitle:"Existing Teable forms",teableFormsCatalogDescription:"This list shows the form views that already exist in Teable.",teableFormsCatalogEmptyTitle:"No forms are available yet",teableFormsCatalogEmptyDescription:"Create at least one form view in Teable first.",teableFormSettingsLeftTitle:"Legacy form settings",teableFormSettingsLeftDescription:"The settings page no longer configures mirror sync by forms. Mirror sync is configured by Teable tables.",teableFormMappingPanelTitle:"Legacy sync content settings",teableFormMappingPanelDescription:"The settings page no longer configures mirror sync by forms. Mirror sync is configured by Teable tables.",teableAddSyncFormAction:"Add sync form",teableRemoveSyncFormAction:"Remove",teableSyncFormAddedTag:"Added",teableSyncFormAdded:"Sync form added.",teableSyncFormRemoved:"Sync form removed.",teableFormShareReady:"Sharing enabled",teableFormShareMissing:"Sharing disabled",teableSelectSyncFormTitle:"Select a form first",teableSelectSyncFormDescription:"After you select a Teable form on the left, sync content, workspace scope, and field mappings appear here.",teableSelectedFormLabel:"Selected form",teableSyncSourceLabel:"Information to sync",teableSyncSource:{sessions:"Session records",todos:"Todos",tags:"Document library tags"},teableWorkspaceScopeLabel:"Workspace scope",teableWorkspaceScopeAll:"All workspaces",teableWorkspaceScopeSelected:"Selected workspaces",teableWorkspaceScopeEmpty:"No workspace is available yet.",teableDocumentTagRootsLabel:"Document library root tags",teableDocumentTagRootsDescription:"Only the selected root tags and all child tags are synced. This is not a workspace-form binding.",teableDocumentTagRootsEmpty:"No document library root tag is available yet.",teableFieldMappingTitle:"Field mapping",teableFieldMappingInlineDescription:"CodingNS fields are on the left. Choose target fields from the Teable table on the right.",teableSourceFieldsEmpty:"This sync content has no mappable fields.",teableSaveFormSyncSettingsAction:"Save table sync settings",teableFormSyncSettingsSaved:"Table sync settings saved.",teableTableSyncAvailableTitle:"Teable table catalog",teableTableSyncAvailableDescription:"This does not list forms. Choose an existing table from the current Base, then add it to the sync table list on the left.",teableTableSyncListTitle:"Synced tables",teableTableSyncListDescription:"Tables added as mirror sync targets appear here. Select one table, then configure content, scope, and field mappings on the right.",teableTableSyncConfigTitle:"Current table settings",teableTableSyncConfigDescription:"Only the selected table from the left is configured here. The sync table list is not duplicated on this side.",teableTableToAddLabel:"Table to add",teableAllTablesAdded:"All tables have been added",teableAddSyncTableAction:"Add sync table",teableRemoveSyncTableAction:"Remove",teableSyncTableAddedTag:"Added",teableSelectSyncTableTitle:"Add a sync table first",teableSelectSyncTableDescription:"After you add a table from the Teable table catalog on the left, sync content, workspace scope, and field mappings appear here.",teableSelectedSyncTableLabel:"Current sync table",teableTableAssignedDescription:"Configured to sync {source}",teableTableUnassignedDescription:"No sync content configured yet",teableSaveTableSyncSettingsAction:"Save table sync settings",teableTableSyncSettingsSaved:"Table sync settings saved.",teableFieldAutoCreateAction:"Add fields and auto-map",teableFieldAutoCreateModalTitle:"Add Teable fields",teableFieldAutoCreateModalDescription:"Choose CodingNS fields to add to the current Teable table.",teableFieldAutoCreateModalSectionTitle:"Choose fields",teableFieldAutoCreateModalSectionDescription:'These fields will be added to "{table}" and mapped automatically. Existing fields with the same name are reused.',teableFieldAutoCreateConfirmAction:"Add and auto-map",teableFieldAutoCreateSuccess:"Added and mapped {count} fields.",teableFieldAutoCreateEmptyError:"Choose at least one field to add.",teableFieldAlreadyMappedDescription:'Mapped to "{field}".',teableTablesCatalogTitle:"Existing Teable tables",teableTablesCatalogDescription:"This list shows the tables in the current Base so you can choose sync targets and field mappings by table.",teableTablesCatalogEmptyTitle:"No table is available in the current Base",teableTablesCatalogEmptyDescription:"Create a table in Teable first, then come back to configure sync.",teableTableInspectAction:"Inspect table",teableTableCollapseAction:"Collapse details",teableTableFieldsLabel:"Fields in this table",teableTableFieldsEmpty:"This table has no field yet.",teableTableFormViewsLabel:"Form views under this table",teableTableFormViewsEmpty:"This table does not have a form view yet.",teableTableFormReadyTag:"Ready for workbench",teableTableFormShareMissingTag:"Share disabled",teableTableFormCountTag:"{count} forms",teableTableFieldCountPending:"Field count pending",teableTableFieldCountValue:"{count} fields",teableTableFormCountValue:"{count} form views",teableTablesUsageTitle:"What this page is for",teableTablesUsageDescription:"Settings are for sync and field mapping. The Teable block on the workbench is where you choose which form to display.",teableTablesUsageMirrorTitle:"Sync configuration uses tables",teableTablesUsageMirrorDescription:"Tags, sessions, and todos are mapped to Teable tables here.",teableTablesUsageFormTitle:"Workbench blocks use forms",teableTablesUsageFormDescription:"Actual user-facing forms are chosen inside the Teable block on the workbench.",teableSyncActionSectionTitle:"Sync status and actions",teableSyncActionSectionDescription:"Review the latest task result here, or trigger mirror sync manually.",teableLatestTaskTitle:"Latest mirror sync",teableLatestTaskEmpty:"There is no mirror sync record yet.",teableSyncLogsTitle:"Sync logs",teableSyncLogsDescription:"Manual syncs and local-change sync tasks are recorded here so you can confirm whether data has been pushed to Teable.",teableSyncLogsRefreshAction:"Refresh logs",teableSyncLogsEmptyTitle:"No sync log yet",teableSyncLogsEmptyDescription:"Logs will appear here after a manual sync or a local data change triggers sync.",teableSyncLogDescription:"{trigger} · {source} · {time}",teableSyncLogCounts:"Created {created}, updated {updated}, deleted {deleted}, skipped {skipped}",teableSyncLogTrigger:{manual:"Manual",local_change:"Local change",retry:"Retry"},teableFieldMappingSectionTitle:"Field mappings",teableFieldMappingSectionDescription:"Map CodingNS source fields to Teable target fields manually. Sync only writes using the mapping defined here.",teableFieldMappingTargetMissingTitle:"Choose a target table first",teableFieldMappingTargetMissingDescription:"Go to the Mirrors tab, assign a target table for this source type, then come back and map its fields.",teableFieldMappingSaveAction:"Save field mappings",teableFieldMappingSaved:"Field mappings saved.",teableFieldTargetPlaceholder:"Choose a target field",teableFieldRequired:"Required",teableFieldOptional:"Optional",teableMirrorBindingReady:'The mirror table is already bound to "{table}".',teableMirrorBindingMissing:"This source type has not created a mirror table yet.",teableMirrorBindingReadyTag:"Bound",teableMirrorBindingPendingTag:"Pending",teableRefreshAction:"Refresh status",teableSaveBindingAction:"Save connection",teableSaveSyncConfigAction:"Save push scope",teableSyncNowAction:"Sync now",teableBindingStatus:{unbound:"Not bound",ready:"Ready",disabled:"Disabled",config_invalid:"Incomplete"},teableTaskState:{idle:"Not started",queued:"Queued",running:"Running",succeeded:"Succeeded",partial_failed:"Partial failure",failed:"Failed"},teableMirrorMode:{manual:"Manual trigger",scheduled:"Scheduled sync (not available yet)",event_driven:"Auto-sync on local changes"},teableSource:{tags:{title:"Tag mirror",description:"Sync affair tags into a Teable mirror table so business forms can use Link and Lookup.",scopeHint:"Examples include includePaths or manually selected paths. This round only stores the config."},sessions:{title:"Session mirror",description:"Sync lightweight session summaries into Teable so forms can reference recent context.",scopeHint:"Examples include recent and limit. This round only stores the config."},todos:{title:"Todo mirror",description:"Sync workbench todos into Teable so forms can reference current tasks directly.",scopeHint:"Examples include open_only or status filters. This round only stores the config."}},pluginManagement:"Plugin management",pluginManagementDescription:"Review the plugins Host has scanned, then decide whether to enable, disable, or open them.",pluginManagementAction:"Manage plugins",pluginManagementModalTitle:"Plugin management",pluginManagementModalDescription:"See plugin status, permission boundaries, and recent runs here without manually building plugin URLs.",pluginManagementModalListTitle:"Plugin list",pluginManagementModalListDescription:"Select a plugin first, then review its current status and recent runs.",pluginManagementModalDetailTitle:"Plugin details",pluginManagementModalDetailDescription:"Only officially registered Host plugin data and runs are shown here.",pluginManagementSelectPluginTitle:"Select a plugin first",pluginManagementSelectPluginDescription:"After you pick a plugin on the left, its permissions, actions, and recent runs appear here.",pluginManagementWorkspaceRequired:"A current workspace is required before opening a plugin frontend page.",workspaceSessionSortModeDescription:"Controls the default sort order for session lists across the workspace. This setting only applies to the current device.",sessionSortModeCreatedAt:"By session created time",sessionSortModeUpdatedAt:"By session updated time",sessionSortModeTitle:"By session name",showSystemFiles:"Show system files",showSystemFilesDescription:"Display common macOS and Windows system files in the file manager, such as .DS_Store and Thumbs.db. This setting only applies to the current device.",serverConnection:"Server Connection",serverConnectionSectionSummary:"Server address and reconnection behavior",remoteAccess:"Remote Access",remoteAccessSectionSummary:"Connect to this Host from outside through CodingNS Connect or Tailscale.",remoteAccessNavValue:"CodingNS Connect / Tailscale",remoteAccessManageTitle:"Remote Access",remoteAccessManageDescription:"Choose and configure how external devices connect to this Host.",remoteAccessManageAction:"Manage Remote Access",remoteAccessModalTitle:"Access Method Management",remoteAccessModalDescription:"Choose and configure the remote access method you want to use.",remoteAccessTabsLabel:"Remote access method tabs",remoteAccessTunnelTab:"CodingNS Connect",remoteAccessTailscaleTab:"Tailscale Access",remoteAccessFeatureDisabledValue:"Off",abilityManagement:"Capability Management",abilityManagementSectionSummary:"Manage which CLI providers stay available and switch model profile presets from one place.",abilityManagementNavValue:"Providers / Profiles",modelManagement:"Model Management",modelManagementNavValue:"Quick switch",modelManagementSectionTitle:"Model Profile Management",providerManagement:"CLI Providers",providerManagementSectionSummary:"Control which CLIs appear in session, fork, assistant, and Skill entry points.",providerManagementNavValue:"Availability",providerManagementDescription:"Control which CLIs this Host is allowed to expose. Open the dialog to review the matrix, status, and enable switches.",providerManagementManageAction:"Manage CLI Providers",providerManagementModalTitle:"CLI Provider Management",providerManagementModalDescription:"Review what each CLI can do in the product, its current state, and whether it stays visible.",providerManagementRefresh:"Refresh list",providerManagementRefreshSuccess:"CLI provider list refreshed.",providerManagementLoading:"Loading available CLI providers...",providerManagementEmpty:"No CLI providers are available to manage yet.",providerManagementEmptyDescription:"This list will appear automatically once the Host reports available CLI providers.",providerManagementLoginRequired:"Sign in before managing CLI providers.",providerManagementLoadFailed:"Failed to load the CLI provider list.",providerManagementSaveFailed:"Failed to save the CLI provider status.",providerManagementSummaryTitle:"Provider Overview",providerManagementSummaryDescription:"Check the totals first, then decide which CLI should stay enabled.",providerManagementSummaryEnabled:"Enabled",providerManagementSummaryDisabled:"Disabled",providerManagementSummaryTotal:"Total",providerManagementMatrixTitle:"Capability Matrix",providerManagementMatrixDescription:"Rows are CLI providers and columns are product capabilities. Turning a provider off hides it across related entry points.",providerManagementTableProvider:"CLI Provider",providerManagementTableStatus:"Status",providerManagementTableEnabled:"Enabled",providerManagementStatusEnabled:"Enabled",providerManagementStatusDisabled:"Disabled",providerManagementInstallReady:"Installed",providerManagementInstallMissing:"Not detected",providerManagementInstallUnknown:"Unknown",providerManagementStateEnabled:"This CLI is currently shown in new session, fork, assistant, and Skill-related entry points.",providerManagementStateDisabled:"This CLI is hidden from new entry points, and its old sessions are also hidden from normal lists.",providerManagementStateMissing:"This CLI is allowed, but the local runtime is not ready yet, so it cannot be used until installation is complete.",providerManagementToggleLabel:"Toggle {provider}",providerManagementEnableSuccess:"{provider} has been enabled again.",providerManagementDisableSuccess:"{provider} has been disabled.",providerManagementCapabilityStreaming:"Streaming output",providerManagementCapabilityToolCalls:"Tool calls",providerManagementCapabilityAssistant:"Assistant service",providerManagementCapabilityFork:"Session fork",providerManagementCapabilitySkill:"Skill usage",providerManagementCapabilityAvailable:"Available",providerManagementCapabilityUnavailable:"Unavailable",providerManagementImpactSessionStart:"new session start",providerManagementImpactFork:"session fork",providerManagementImpactAssistant:"assistant follow-up",providerManagementImpactSkill:"new Skill targets",providerManagementImpactEnabled:"If you turn it off now, old sessions will be hidden and {actions} will be blocked.",providerManagementImpactDisabled:"It is currently blocking {actions}; once re-enabled, those entry points will show up again.",providerManagementImpactEnabledFallback:"If you turn it off now, this CLI will disappear from new entry points across the product.",providerManagementImpactDisabledFallback:"Once re-enabled, this CLI will return to the normal entry points across the product.",channelsManagement:"Messaging Channels",channelsManagementSectionSummary:"Manage external channels, polling accounts, and recent inbound or outbound records in one place.",channelsManagementNavValue:"Accounts / Records",channelsManagementDescription:"Manage channel accounts here and review recent messages and delivery records.",channelsManageAction:"Manage Channel Accounts",channelsModalTitle:"Messaging Channel Accounts",channelsAddAccountAction:"Add Channel Account",channelsModalDescription:"This first phase uses a shared account model. Text messages, fixed provider selection, polling, and Butler control session bridging are the main scope.",channelsActionPending:"Working...",channelsRefresh:"Refresh data",channelsRefreshSuccess:"Channel data refreshed.",channelsLoading:"Loading channel data...",channelsLoadingDetails:"Loading recent threads and messages...",channelsLoadFailed:"Failed to load channel data.",channelsLoadDetailsFailed:"Failed to load recent threads and messages.",channelsSaveFailed:"Failed to save the channel account.",channelsProbeFailed:"Failed to probe the channel account.",channelsPollFailed:"Failed to trigger manual polling.",channelsRemoveFailed:"Failed to remove the channel account.",channelsCreateSuccess:"{account} created.",channelsUpdateSuccess:"{account} saved.",channelsRemoveSuccess:"Removed channel account “{account}”.",channelsSelectAccountFirst:"Select an existing account first, or create a new one.",channelsSummaryTitle:"Channel Overview",channelsSummaryAccounts:"Accounts",channelsSummaryActive:"Healthy",channelsSummaryPlatforms:"Platforms",channelsWizardTitle:"Setup Wizard",channelsWizardCreateDescription:"Choose a channel first, fill that channel's own config form, then bind the account to a fixed assistant engine.",channelsWizardEditDescription:"You are editing an existing account. The platform stays fixed here, and changing the assistant engine only affects new sessions.",channelsWizardStepsTitle:"Channel account setup steps",channelsWizardStepPlatform:"Choose channel",channelsWizardStepConfig:"Channel config",channelsWizardStepBinding:"Bind account",channelsWizardNextToConfig:"Continue to config",channelsWizardNextToBinding:"Continue to binding",channelsWizardBackToPlatform:"Back to channel selection",channelsWizardBackToConfig:"Back to channel config",channelsWizardSelectPlatformHint:"Pick a channel first so the matching platform-specific form can be shown below.",channelsWizardBindingSummary:"Multi-session support",channelsPlatformsTitle:"Platform Catalog",channelsPlatformsDescription:"Channel cards show the phase-one polling model, multi-session support, and the current limits.",channelsPlatformsEmpty:"No platform capabilities are available yet.",channelsPlatformsEmptyDescription:"This list will appear automatically once the Host reports the platform catalog.",channelsPlatformSummary:"Modes: {modes}; multi-session: {multiSession}",channelsAccountsTitle:"Channel Accounts",channelsAccountsDescription:"Each account is fixed to one assistant engine and always uses polling in phase one. New sessions follow the account config, while old sessions keep their original context.",channelsAccountsEmpty:"No channel accounts yet.",channelsAccountsEmptyDescription:"Add one channel account first. Thread mappings and delivery records will appear after real traffic arrives.",channelsAccountRowDescription:"{platform} · {provider} · {mode}",channelsCreateAction:"Create account",channelsSaveAction:"Save account",channelsResetToCreate:"New account form",channelsCreateFormTitle:"Create Channel Account",channelsCreateFormDescription:"Build the shared account fields first. Platform-specific differences stay in the extra JSON config for this phase.",channelsEditFormTitle:"Edit Channel Account",channelsEditFormDescription:"Changing the provider only affects new sessions. Existing sessions keep their original context.",channelsFieldDisplayName:"Account name",channelsFieldDisplayNamePlaceholder:"For example: Feishu Duty Bot",channelsFieldPlatform:"Platform",channelsFieldPlatformDescription:"Choose the platform first, then pick the connection mode and extra config.",channelsFieldProvider:"Assistant engine",channelsFieldProviderDescription:"Phase one only allows Codex or Claude Code, and you cannot switch providers inside the same external thread.",channelsFieldConnectionMode:"Connection mode",channelsFieldConnectionModeDescription:"All six platforms use polling in phase one. You do not switch to another mode here.",channelsFieldStatus:"Account status",channelsFieldStatusDescription:"Use healthy, disabled, or degraded to control whether this account should keep serving traffic.",channelsFieldConfig:"Extra platform config (JSON)",channelsFieldConfigDescription:"Use this only for fields that the dedicated form does not cover yet. The dedicated form stays the primary source.",channelsAdvancedConfigTitle:"Extra fields (advanced)",channelsAdvancedConfigDescription:"Only put fields here when the dedicated form does not cover them yet, such as outbound URLs, temporary switches, or experiment flags.",channelsValidationDisplayName:"Enter an account name first.",channelsValidationPlatform:"Choose a platform first.",channelsValidationConnectionMode:"Choose a connection mode first.",channelsValidationConfigJson:"The extra config is not valid JSON.",channelsValidationConfigObject:"The extra config must be a JSON object.",channelsValidationRequiredField:"Fill in “{field}” first.",channelsValidationFeishuCredential:"Feishu still needs one working credential set: either a Tenant Access Token, or both App ID and App Secret.",channelsConfigWechatUnavailableTitle:"WeChat (claw) does not need manual protocol fields",channelsConfigWechatUnavailableDescription:"QR binding, login state, polling, and outbound delivery are handled by the Host helper, so this step does not require private protocol fields.",channelsDetailTitle:"Selected Account Overview",channelsDetailDescription:"Review the current account state, recent traffic, and whether the account needs manual follow-up.",channelsDetailPlatform:"Platform",channelsDetailProvider:"Assistant engine",channelsDetailConnectionMode:"Connection mode",channelsDetailStatus:"Account status",channelsDetailLastInbound:"Last inbound",channelsDetailLastOutbound:"Last outbound",channelsDetailLastError:"Last error",channelsProbeAction:"Probe account",channelsPollAction:"Run polling",channelsRemoveAction:"Remove account",channelsRemoveConfirmAction:"Confirm removal",channelsRemoveConfirmDescription:"Removing this account also clears its thread mappings, inbound events, and delivery records. This action cannot be undone.",channelsWebhookHint:"This account uses webhook mode, so manual polling is not needed.",channelsConnectionModeFixedHint:"Phase one always models these channels as polling. If a different mode is needed later, the account rules will be upgraded separately.",channelsThreadsTitle:"Thread Mappings",channelsThreadsDescription:"Recent {count} thread mappings between external conversation keys and Butler control sessions.",channelsThreadsEmpty:"No thread mappings yet.",channelsThreadsEmptyDescription:"This list appears automatically after the first external message is received.",channelsEventsTitle:"Inbound Events",channelsEventsDescription:"Recent {count} inbound events so you can verify whether the Host received and dispatched them.",channelsEventsEmpty:"No inbound events yet.",channelsEventsEmptyDescription:"Records will appear here after the channel starts pulling real text messages.",channelsDeliveriesTitle:"Deliveries",channelsDeliveriesDescription:"Recent {count} outbound deliveries so you can confirm whether Butler's first text reached the external platform.",channelsDeliveriesEmpty:"No deliveries yet.",channelsDeliveriesEmptyDescription:"Records will appear here after Butler produces the first outbound text.",channelsConnectionModeWebhook:"Webhook",channelsConnectionModePolling:"Polling",channelsConnectionModeBridge:"Bridge",channelsMultiSessionSupported:"Multi-session ready",channelsMultiSessionLimited:"Limited multi-session",channelsStatusActive:"Healthy",channelsStatusDisabled:"Disabled",channelsStatusDegraded:"Degraded",channelsThreadStatusActive:"Active",channelsThreadStatusClosed:"Closed",channelsThreadStatusFailed:"Failed",channelsEventStatusReceived:"Received",channelsEventStatusDispatched:"Dispatched",channelsEventStatusReplied:"Replied",channelsEventStatusFailed:"Failed",channelsEventStatusIgnored:"Ignored",channelsDeliveryStatusSent:"Sent",channelsDeliveryStatusFailed:"Failed",channelsDeliveryStatusSkipped:"Skipped",channelsThreadSummary:"{status} · conversation key: {conversationKey}",channelsEventSummary:"{status} · conversation key: {conversationKey}",channelsDeliverySummary:"{status} · latest outbound text",channelsMetaCreatedAt:"Created",channelsMetaUpdatedAt:"Updated",channelsMetaReceivedAt:"Received",channelsMetaExternalUser:"External user",channelsMetaEventId:"External event",channelsMetaProviderRef:"Platform ref",channelsMetaError:"Error",channelsTextFallback:"Empty text",channelsTimeUnknown:"Not available",channelsWechatBindingTitle:"WeChat binding",channelsWechatBindingDescription:"This account uses the Host-managed helper for QR login, polling, and outbound delivery.",channelsWechatBoundDescription:"The WeChat account is already bound. You can continue with health checks, manual polling, and later session bridging.",channelsWechatCreateDescription:"Name this WeChat account first. After creation, generate the QR code in the detail panel and finish the bind there.",channelsWechatRuntimeRequiredTitle:"Direct WeChat binding is not available yet",channelsWechatRuntimeRequiredDescription:"The current environment has not enabled the WeChat helper, so this page only shows the account basics. After the helper is enabled, the real QR binding flow appears here.",channelsWechatPendingTitle:"This account is still waiting for binding",channelsWechatPendingDescription:"Finish QR binding first. Polling, outbound delivery, and recent records only appear after the bind succeeds.",channelsWechatBeginBindingAction:"Start binding",channelsWechatContinueBindingAction:"Continue binding",channelsWechatStartLoginAction:"Generate QR code",channelsWechatRestartBindingAction:"Generate a new QR code",channelsWechatRefreshLoginAction:"Refresh binding status",channelsWechatLogoutAction:"Clear binding",channelsWechatBindingModalTitle:"Scan the QR code to bind WeChat",channelsWechatBindingModalDescription:"Scan the QR code below with WeChat, then come back here and click “Refresh binding status”.",channelsWechatBindingModeValue:"QR binding",channelsWechatLoginStatus:"Binding status",channelsWechatLoginStatusNotLoggedIn:"Not bound",channelsWechatLoginStatusWaitingScan:"Waiting for scan",channelsWechatLoginStatusScanConfirmed:"Scanned, waiting confirmation",channelsWechatLoginStatusActive:"Bound",channelsWechatLoginStatusExpired:"QR code expired",channelsWechatQrHint:"After scanning successfully, click “Refresh binding status” to sync the result.",channelsWechatQrAlt:"WeChat claw binding QR code",channelsWechatOpenQrLinkAction:"Open binding QR code",channelsWechatQrRawTitle:"View raw QR content",channelsWechatQrRawDescription:"The raw QR payload returned by the upstream service is kept here first so the scan flow can be debugged.",channelsWechatQrEmpty:"No binding QR code yet",channelsWechatQrEmptyDescription:"Click “Generate QR code” above first, then scan it with WeChat to finish binding.",channelsConfigFieldDingtalkAppKey:"DingTalk AppKey",channelsConfigFieldDingtalkAppKeyDescription:"This identifies the DingTalk app when the real polling API is wired in later.",channelsConfigFieldDingtalkAppKeyPlaceholder:"Enter the DingTalk AppKey",channelsConfigFieldDingtalkAppSecret:"DingTalk AppSecret",channelsConfigFieldDingtalkAppSecretDescription:"Use the production credential for the real duty account so test credentials do not leak into the live polling account.",channelsConfigFieldDingtalkAppSecretPlaceholder:"Enter the DingTalk AppSecret",channelsConfigFieldDingtalkRobotCode:"Robot code",channelsConfigFieldDingtalkRobotCodeDescription:"If replies will eventually be sent through a fixed robot, store the robot code here now.",channelsConfigFieldDingtalkRobotCodePlaceholder:"For example: dingxxxxxxxx",channelsConfigFieldFeishuAppId:"Feishu App ID",channelsConfigFieldFeishuAppIdDescription:"If you do not plan to fill a Tenant Access Token directly, enter this together with the App Secret.",channelsConfigFieldFeishuAppIdPlaceholder:"Enter the Feishu App ID",channelsConfigFieldFeishuAppSecret:"Feishu App Secret",channelsConfigFieldFeishuAppSecretDescription:"If you do not plan to fill a Tenant Access Token directly, enter this together with the App ID.",channelsConfigFieldFeishuAppSecretPlaceholder:"Enter the Feishu App Secret",channelsConfigFieldFeishuTenantAccessToken:"Tenant Access Token",channelsConfigFieldFeishuTenantAccessTokenDescription:"If you can reliably obtain a tenant_access_token, enter it here and you do not need to force App ID plus App Secret as well.",channelsConfigFieldFeishuTenantAccessTokenPlaceholder:"Enter the Feishu tenant_access_token",channelsConfigFieldFeishuChatId:"Target chat ID",channelsConfigFieldFeishuChatIdDescription:"Required. Phase one stays on one fixed chat so the Host knows where to pull messages and send replies.",channelsConfigFieldFeishuChatIdPlaceholder:"For example: oc_xxx or chat_xxx",channelsConfigFieldWechatBaseUrl:"claw service URL",channelsConfigFieldWechatBaseUrlDescription:"Host will use this address to pull messages and send replies. It must be reachable from the Host machine.",channelsConfigFieldWechatBaseUrlPlaceholder:"For example: http://127.0.0.1:8787",channelsConfigFieldWechatBridgeToken:"claw access token",channelsConfigFieldWechatBridgeTokenDescription:"If your claw transport requires an access token, place it here for basic protection.",channelsConfigFieldWechatBridgeTokenPlaceholder:"Enter the claw transport token",channelsConfigFieldWechatPollPath:"Polling path",channelsConfigFieldWechatPollPathDescription:"The default is `/poll`. Override it here if your transport uses another route.",channelsConfigFieldWechatPollPathPlaceholder:"Default: /poll",channelsConfigFieldWechatSendPath:"Send path",channelsConfigFieldWechatSendPathDescription:"The default is `/send`. Override it here if your transport uses another route.",channelsConfigFieldWechatSendPathPlaceholder:"Default: /send",channelsConfigFieldTelegramBotToken:"Telegram Bot Token",channelsConfigFieldTelegramBotTokenDescription:"Telegram polling and outbound replies both require this token. Without it the account cannot work.",channelsConfigFieldTelegramBotTokenPlaceholder:"Enter the Telegram Bot Token",channelsConfigFieldSlackBotToken:"Slack Bot Token",channelsConfigFieldSlackBotTokenDescription:"Required. Slack polling and outbound text replies both depend on this token.",channelsConfigFieldSlackBotTokenPlaceholder:"Enter the Slack Bot Token",channelsConfigFieldSlackAppToken:"Slack App Token",channelsConfigFieldSlackAppTokenDescription:"The minimum working config does not require this. Fill it only when your Slack app setup really needs it.",channelsConfigFieldSlackAppTokenPlaceholder:"Enter the Slack App Token",channelsConfigFieldSlackChannelId:"Channel ID",channelsConfigFieldSlackChannelIdDescription:"Required. Phase one binds the account to one fixed channel so polling and text delivery can work first.",channelsConfigFieldSlackChannelIdPlaceholder:"For example: C0123456789",channelsConfigFieldDiscordBotToken:"Discord Bot Token",channelsConfigFieldDiscordBotTokenDescription:"Required. Discord polling and outbound text replies both depend on this bot token.",channelsConfigFieldDiscordBotTokenPlaceholder:"Enter the Discord Bot Token",channelsConfigFieldDiscordApplicationId:"Application ID",channelsConfigFieldDiscordApplicationIdDescription:"The minimum working config does not require this. Fill it only when your app permissions really depend on it.",channelsConfigFieldDiscordApplicationIdPlaceholder:"Enter the Discord Application ID",channelsConfigFieldDiscordGuildId:"Guild ID",channelsConfigFieldDiscordGuildIdDescription:"Required. Lock the account to one server first. Thread branches will run under this guild.",channelsConfigFieldDiscordGuildIdPlaceholder:"Enter the Discord Guild ID",channelsConfigFieldDiscordChannelId:"Channel ID",channelsConfigFieldDiscordChannelIdDescription:"Required. Lock the account to one channel first. Thread branches will hang under this channel.",channelsConfigFieldDiscordChannelIdPlaceholder:"Enter the Discord Channel ID",channelsConfigChecklistTitle:"Minimum you need for this step",channelsConfigChecklistFeishuSummary:"This Feishu setup stays on fixed-chat polling in phase one, so the Host needs one target chat and one working credential path.",channelsConfigChecklistFeishuItemCredential:"Choose one credential path: either a Tenant Access Token, or both App ID and App Secret.",channelsConfigChecklistFeishuItemChat:"You must enter the target chat ID, otherwise the Host does not know which chat to pull from or reply to.",channelsConfigChecklistFeishuItemScope:"Phase one only handles text messages. Images, files, voice, and cards are not covered yet.",channelsConfigChecklistSlackSummary:"This Slack setup stays on one fixed channel for polling first, so inbound reads and outbound text replies can be verified.",channelsConfigChecklistSlackItemToken:"You must enter the Bot Token. Without it the account cannot read messages or send replies.",channelsConfigChecklistSlackItemChannel:"You must enter the channel ID. This account is fixed to one channel in phase one.",channelsConfigChecklistSlackItemScope:"Phase one only handles text messages, and Slack thread branches are not implemented yet.",channelsConfigChecklistDiscordSummary:"This Discord setup needs one fixed guild and channel first. Later thread branches will live inside that scope.",channelsConfigChecklistDiscordItemToken:"You must enter the Bot Token. Polling reads and outbound text replies both depend on it.",channelsConfigChecklistDiscordItemGuild:"You must enter the Guild ID so the account is fixed to one server first.",channelsConfigChecklistDiscordItemChannel:"You must enter the channel ID. Later thread branches will hang under this channel.",modelManagementTitle:"Quick Model Switching",modelManagementDescription:"This page does not add or edit presets. It only exposes the presets already managed by cc-switch so you can switch quickly.",modelManagementRefresh:"Refresh Models",modelManagementRefreshSuccess:"Model presets refreshed.",modelManagementLoadFailed:"Failed to load model presets.",modelManagementScannedAt:"Last Scanned",modelManagementScannedAtUnknown:"Not scanned yet",modelManagementCurrentProfile:"Current Profile",modelManagementCurrentModel:"Current Model",modelManagementCurrentPreset:"Current Preset",modelManagementModelUnknown:"Unknown",modelManagementPresetMissing:"Not set",modelManagementCurrentTag:"Current",modelManagementOpenSwitcher:"Switch Profile",modelManagementModalTitle:"Provider Profile Switching",modelManagementModalDescription:"Review the existing cc-switch profiles by app and switch the active one here.",modelManagementTabsLabel:"Model app tabs",modelManagementSwitchAction:"Switch",modelManagementSwitchSuccess:"{app} switched to {preset}.",modelManagementOptionsEmpty:"No switchable presets were found.",modelManagementStatusReady:"Ready",modelManagementStatusUnconfigured:"Unconfigured",modelManagementStatusUnavailable:"cc-switch-cli missing",modelManagementStatusError:"Read failed",skills:"Skills",skillsSectionSummary:"Read and sync the local skills owned by each CLI. No marketplace and no remote catalog in this phase.",skillsNavValue:"Local sync",skillManagerTitle:"Local Skill Management",skillManagerDescription:"Read the local skill folders used by Codex, Claude Code, Gemini, and OpenCode, then import unmanaged entries or sync them again.",skillSummaryManagedSkills:"My Skills",skillSummaryManagedEntries:"Active",skillSummaryUnmanagedEntries:"Unmanaged folders",skillSummaryConflictedEntries:"Needs Attention",skillSummaryAssistantRuntimeEntries:"Assistant-only",skillSummaryDiagnostics:"Notices",skillManageAction:"Skill Settings",skillConfigModalTitle:"Skill Settings",skillConfigModalDescription:"Review your skills, built-in assistant skills, and anything that needs your attention.",skillCreateAction:"Add Skill",skillCreateModalTitle:"Add Skill",skillCreateModalDescription:"Bring a new SKILL.md under management. File upload and pasted markdown share the same validation and import flow.",skillCreateSourceTabsLabel:"Add Method",skillCreateSourceFile:"Choose File",skillCreateSourcePaste:"Paste Text",skillCreateSubmitAction:"Add",skillRefresh:"Refresh",skillRefreshSuccess:"Skill list refreshed.",skillScannedAt:"Last Scanned",skillUploadSectionTitle:"Upload Skill",skillUploadSectionDescription:"Choose a SKILL.md file, decide whether it belongs to the workspace or the assistant runtime, then let the app validate, fix, and manage it.",skillUploadPickAction:"Choose SKILL.md",skillUploadSubmitAction:"Upload & Manage",skillUploadEmpty:"No SKILL.md file has been selected yet.",skillUploadPickedFile:"Selected File",skillUploadScopeLabel:"Scope",skillUploadScopeWorkspace:"Workspace Skill",skillUploadScopeAssistant:"Assistant Skill",skillUploadDirectoryLabel:"Directory Name",skillUploadDirectoryPlaceholder:"For example: team-helper",skillUploadDirectoryHint:"Used for the managed folder name and sync target folder. It is generated from the file name or heading by default, so you usually do not need to change it.",skillUploadDirectoryInvalid:"The directory name is invalid. Only letters, numbers, dots, underscores, and dashes are allowed.",skillUploadTargetsLabel:"Target CLI",skillPasteLabel:"Paste SKILL Content",skillPastePlaceholder:"Paste the full SKILL.md content here",skillPasteEmpty:"There is no SKILL content ready to manage yet.",skillUploadDirectoryRequiredNote:"The file name does not produce a valid directory name, so you need to fill one in manually.",skillUploadTargetRequired:"Select at least one target CLI.",skillUploadHeadingNote:"The markdown does not contain a level-one heading. One will be added automatically during import.",skillUploadNormalizedNote:"Whitespace and line endings were normalized for upload.",skillUploadReadFailed:"Failed to read the uploaded SKILL.md file.",skillUploadContentEmpty:"The uploaded SKILL.md file cannot be empty.",skillUploadSuccess:"{name} was added.",skillManagedListTitle:"My Skills",skillManagedEmpty:"You have not added any skills yet.",skillManagedItemDescription:"Added to {targets}.",skillManagedItemNoTarget:"This skill has not been applied to any client yet.",skillUnmanagedListTitle:"Skills to Add",skillUnmanagedEmpty:"There are no new skills to add right now.",skillUnmanagedItemDescription:"Found in {target}. You can add it to your list.",skillUnmanagedItemDisabledDescription:"Found in {target}, but that target is disabled right now, so it cannot be added again yet.",skillAssistantRuntimeListTitle:"Built-in Assistant Skills",skillAssistantRuntimeListDescription:"These skills are provided by the system and only used by the assistant.",skillAssistantRuntimeEmpty:"There are no built-in assistant skills right now.",skillAssistantRuntimeItemDescription:"This is a built-in skill. You do not need to manage it yourself.",skillAssistantRuntimeUsedBy:"Available In",skillAssistantRuntimeSourcePath:"Built-in Source Path",skillConflictedListTitle:"Needs Attention",skillConflictedEmpty:"There is nothing to fix right now.",skillConflictedItemDescription:"This item in {target} needs attention.",skillConflictedItemDisabledDescription:"This item still exists in {target}, but that target is disabled right now.",skillDiagnosticsTitle:"Notices",skillDiagnosticsEmpty:"There are no new notices right now.",skillDiagnosticTargetMissingTitle:"{target} Is Not Ready Yet",skillDiagnosticTargetMissingDetail:"The skill folder for {target} was not found yet.",skillDiagnosticReadFailedTitle:"{target} Is Temporarily Unavailable",skillDiagnosticReadFailedDetail:"The skill information for {target} cannot be read right now. Try again later.",skillDiagnosticSyncMissingTitle:"{target} Needs To Be Applied Again",skillDiagnosticSyncMissingDetail:"Some skills have not taken effect in {target} yet.",skillDiagnosticGenericTitle:"{target} Needs Attention",skillDiagnosticGenericDetail:"Something is not ready yet. Refresh and check again later.",skillDirectoryName:"Directory Name",skillSsotPath:"SSOT Path",skillSourceCli:"Source CLI",skillDirectoryPath:"Directory Path",skillImportAction:"Add",skillImportSuccess:"{name} was added and applied to {target}.",skillSyncAction:"Apply Again",skillSyncSuccess:"{name} was applied again.",skillSyncTargetMissing:"This skill has no target yet, so it cannot be applied again.",skillSyncTargetDisabled:"This skill currently only points at disabled targets. Re-enable a provider before applying it again.",skillLoadFailed:"Failed to load the skill overview.",skillOfficeTemplateCreated:"Document template created.",skillOfficeTemplateUpdated:"Document template updated.",skillOpsTargetCreated:"SSH target created.",skillOpsTargetUpdated:"SSH target updated.",skillOpsApprovalApproved:"Ops approval approved.",skillOpsApprovalRejected:"Ops approval rejected.",skillTargetCodex:"Codex",skillTargetClaudeCode:"Claude Code",skillTargetGemini:"Gemini",skillTargetOpenCode:"OpenCode",skillBindingPending:"Preparing",skillBindingSynced:"Available",skillBindingFailed:"Unavailable",skillBindingConflicted:"Needs Attention",skillUploadTargetDisabled:"All available Skill targets are disabled right now. Re-enable a provider in settings first.",skillTargetDisabledTag:"Disabled",skillTagAssistantOnly:"Assistant Only",skillTagWorkspaceSessionOnly:"Workspace Session Only",securityPrivacy:"Security & Privacy",securityPrivacySectionSummary:"Session permissions, risk boundaries, and default approval policy",softwareUpdate:"Software Update",softwareUpdateSectionSummary:"Server and client versions",serverAddress:"Server Address",serverDescription:"Login, API requests, and realtime connections all use this Host entry, while the frontend UI is bundled inside the client itself.",serverRelayTunnelProfileTitle:"CodingNS Connect Entry For This Host",serverRelayTunnelProfileDescription:"Attach a CodingNS Connect entry to the saved Host profile. When enabled, the client connects through the CodingNS Connect domain and control site with end-to-end encryption instead of calling this address directly.",serverRelayTunnelEnabled:"Connect Through CodingNS Connect",serverRelayTunnelUsageHint:"The server address should usually stay as this Host's public entry, for example https://demo.codingns.example .",serverRelayTunnelDomain:"CodingNS Connect Domain",serverRelayTunnelDomainPlaceholder:"For example: demo.codingns.example",serverRelayTunnelControlBaseUrl:"Control Site URL",serverRelayTunnelControlBaseUrlPlaceholder:"For example: https://control.codingns.example",relayTunnelServerAddressDescription:"The official CodingNS Connect address is used by default. If you know the current control site address, you can override it in advanced settings.",relayTunnelServerAddressHint:"This only changes the CodingNS Connect control site used for login, binding, and traffic queries. It does not change the current Host's local API address.",relayTunnelStatus:"CodingNS Connect Status",relayTunnelDescription:"Use CodingNS Connect to let external devices reach this Host securely.",relayTunnelMasterSwitchLabel:"Enable CodingNS Connect",relayTunnelActivationHint:"Turn this on before checking CodingNS Connect status or allowing this Host to accept external access.",relayTunnelPhase:"Current State",relayTunnelDomain:"Access Address",relayTunnelUnbound:"Not bound yet",relayTunnelTrafficRemaining:"Remaining Traffic",relayTunnelHostFingerprint:"Host Fingerprint",relayTunnelTrustBoundaryNotice:"CodingNS Connect only forwards encrypted traffic and cannot read the content between the client and this Host.",relayTunnelRecentError:"Recent error: {message}",relayTunnelAccessTitle:"Connection Settings",relayTunnelAccessDescription:"Sign in with your CodingNS Connect account first, then turn the switch on to bring this device online for external access.",relayTunnelLearnService:"Learn About CodingNS Connect",relayTunnelWizardTitle:"Remote Access Wizard",relayTunnelWizardDescription:"Finish account login, host label confirmation, and CodingNS Connect startup in three steps. After that, the panel stays focused on the actual remote access info.",relayTunnelStatusErrorTitle:"Remote access status is unavailable right now",relayTunnelStatusNetworkError:"The client cannot reach this Host right now ({address}), so the remote access status may be outdated. Check the server address, port, and network connection first.",relayTunnelStepPending:"Pending",relayTunnelStepCurrent:"In Progress",relayTunnelStepDone:"Done",relayTunnelStepLocked:"Finish the previous step first.",relayTunnelStepLoginTitle:"Log In",relayTunnelStepLoginDescription:"Connect your CodingNS Connect account first. Host label checks and traffic queries both depend on it.",relayTunnelStepLoginConnected:"The account is already connected. Continue to the next step.",relayTunnelStepHostLabelTitle:"Set Host Label",relayTunnelStepHostLabelDescription:"Choose the fourth-level domain prefix you will use later and verify that it is available now.",relayTunnelStepStartTitle:"Start CodingNS Connect",relayTunnelStepStartDescription:"After the first two steps are ready, bring the current Host online through CodingNS Connect.",relayTunnelStepStartReady:"The host label is confirmed. You can start CodingNS Connect now.",relayTunnelStartAction:"Start CodingNS Connect",relayTunnelLoginErrorTitle:"Failed to log in to CodingNS Connect",relayTunnelAdvancedSettings:"Advanced Settings",relayTunnelAdvancedSettingsHide:"Hide Advanced Settings",relayTunnelAdvancedSettingsDescription:"The official CodingNS Connect address is used by default. Only override it when you know the exact control site address.",relayTunnelLoginNetworkError:"The login request never reached this Host because it is unavailable right now ({address}). Check the server address and network connection, then try again.",relayTunnelReadyTitle:"Remote Access Is Ready",relayTunnelReadyDescription:"The setup is complete. This view now keeps only the access URL, traffic info, and maintenance actions.",relayTunnelAccessUrlLabel:"Remote Access URL",relayTunnelCopyAccessUrl:"Copy URL",relayTunnelOpenAccessUrl:"Open Page",relayTunnelAccessUrlCopied:"The access URL has been copied.",relayTunnelCopyAccessUrlFailed:"Failed to copy the access URL.",relayTunnelOpenAccessUrlFailed:"Failed to open the access URL.",relayTunnelClientRouteLabel:"Current Client Route",relayTunnelClientRouteAddressLabel:"Current Client Address",relayTunnelClientRouteHintRelay:"The client is still using CodingNS Connect for this Host. If a reachable local address is confirmed, it will switch to a lower-traffic direct route automatically.",relayTunnelClientRouteHintRelayProbing:"The client is checking local direct addresses now. When the check finishes, it will switch to the lower-traffic route automatically.",relayTunnelClientRouteHintLan:"The client has already switched to a LAN direct route, which uses less traffic. The remote access URL can still be used on external devices.",relayTunnelClientRouteHintLoopback:"The client is connecting to this device through its local address, without going through CodingNS Connect.",relayTunnelClientRouteHintTailscale:"The client has already switched to a Tailscale address, without going through CodingNS Connect.",relayTunnelClientRouteHintDirect:"The client is requesting this Host address directly, without going through CodingNS Connect.",relayTunnelReconnectAction:"Reconnect",relayTunnelManageAccountAction:"Manage Account",relayTunnelDisconnectDeviceAction:"Sign Out Device",relayTunnelEnableToggleLabel:"Enable CodingNS Connect",relayTunnelConfigTitle:"CodingNS Connect Site Configuration",relayTunnelConfigDescription:"Configure the CodingNS Connect endpoint and control site here. Login, binding, and traffic operations below all use these addresses.",relayTunnelConfigErrorTitle:"Failed to save the CodingNS Connect site address",relayTunnelConfigNetworkError:"The new tunnel site address has not been saved to this Host because it is unavailable right now ({address}). Check the server address and network connection first.",relayTunnelRelayBaseUrl:"CodingNS Connect Endpoint URL",relayTunnelControlBaseUrl:"Control Site URL",relayTunnelSaveConfig:"Save Configuration",relayTunnelRefresh:"Refresh Status",relayTunnelAccountTitle:"CodingNS Connect Account",relayTunnelAccountDescription:"Sign in with your CodingNS Connect account to bind this Host and review the remaining traffic quota.",relayTunnelAccountEmail:"Email",relayTunnelAccountEmailPlaceholder:"Enter your email",relayTunnelAccountPassword:"Password",relayTunnelAccountPasswordPlaceholder:"Enter your password",relayTunnelLoginAccount:"Log In",relayTunnelLoggedInAs:"Logged in as: {email}",relayTunnelConnectedBannerTitle:"Account Connected",relayTunnelConnectedBannerDescription:"You can now turn on CodingNS Connect so external devices can reach this Host.",relayTunnelConnectedBannerActiveTitle:"CodingNS Connect Is On",relayTunnelConnectedBannerActiveDescription:"This device is now reachable from outside through CodingNS Connect.",relayTunnelConnectedDevice:"Current device: {name}",relayTunnelBoundDomain:"Current access address: {domain}",relayTunnelBindTitle:"Bind Current Host",relayTunnelBindDescription:"Binding first reads the current Host long-term public key, then registers this machine on CodingNS Connect.",relayTunnelHostLabelTitle:"Device Name",relayTunnelHostLabelDescription:"After you sign in, enter the fourth-level domain prefix you plan to use later and check whether that name is currently available.",relayTunnelHostLabel:"Host Label",relayTunnelHostLabelPlaceholder:"Enter the prefix",relayTunnelHostLabelSuffix:".channel.codingns.com",relayTunnelHostLabelCheck:"Check Name",relayTunnelHostLabelChecking:"Checking whether this name is available.",relayTunnelHostLabelAvailable:"This name is available. The public access address will be {domain}",relayTunnelHostLabelReserved:"This name hits a reserved prefix. Choose a different name.",relayTunnelHostLabelOccupied:"This name is already taken. Choose a different name.",relayTunnelHostLabelUnavailable:"The name cannot be verified right now. Try again later.",relayTunnelHostLabelRequired:"Enter a device name first.",relayTunnelBindAction:"Login And Bind Host",relayTunnelActionsTitle:"CodingNS Connect Controls",relayTunnelActionsDescription:"After binding, you can enable, disable, or unbind CodingNS Connect here.",relayTunnelEnable:"Enable CodingNS Connect",relayTunnelDisable:"Disable CodingNS Connect",relayTunnelUnbind:"Disconnect This Device",relayTunnelWalletTitle:"Traffic Wallet",relayTunnelWalletDescription:"This shows the total traffic granted, traffic used, and remaining quota recorded by the control site.",relayTunnelTrafficGranted:"Granted Traffic",relayTunnelTrafficUsed:"Used Traffic",relayTunnelPackagesTitle:"Traffic Packages",relayTunnelPackagesDescription:"Selecting a package opens the official checkout page. After payment succeeds, the quota is granted to the current account automatically.",relayTunnelFeaturedPackage:"Featured",relayTunnelBuyPackage:"Buy Traffic",relayTunnelOrdersTitle:"Recent Orders",relayTunnelOrdersDescription:"Only the most recent orders are shown here so you can confirm payment and quota status quickly.",relayTunnelOrderPending:"Pending",relayTunnelOrderPaid:"Paid",relayTunnelOrderExpired:"Expired",relayTunnelOrderFailed:"Failed",relayTunnelControlBaseUrlRequired:"Fill in the control site URL first.",relayTunnelAccountRequired:"Enter the CodingNS Connect account email and password first.",relayTunnelIdentityUnavailable:"The current Host identity key is not ready yet. Try again later.",relayTunnelLoadFailed:"Failed to load the CodingNS Connect status.",relayTunnelPhaseDisabled:"Disabled",relayTunnelPhaseBlockedUninitialized:"Blocked Until Bootstrap Finishes",relayTunnelPhaseUnbound:"Not Bound",relayTunnelPhaseBinding:"Binding",relayTunnelPhaseConnecting:"Connecting",relayTunnelPhaseRunning:"Running",relayTunnelPhaseQuotaExhausted:"Quota Exhausted",relayTunnelPhaseError:"Error",tailscaleBrand:"Tailscale",tailscaleSectionTitle:"Tailscale Access",tailscaleSectionDescription:"Let this Host stay reachable across your devices with Tailscale.",tailscaleMasterSwitchLabel:"Enable Tailscale",tailscaleActivationHint:"Turn this on before checking Tailscale status or continuing with setup and account binding.",tailscaleCurrentState:"Current State",tailscaleSwitchLabel:"Enabled",tailscaleStatusIndicator:"Status",tailscaleServerAddress:"Server Address",tailscaleAccountName:"Account",tailscaleIpAddress:"IP Address",tailscaleConfigure:"Configure",tailscaleConfigModalTitle:"Configure Tailscale",tailscaleConfigModalDescription:"Edit connectivity settings",tailscaleControlServer:"Control Server",tailscaleControlServerDescription:"Leave empty to use the default control server.",tailscaleControlServerPlaceholder:"Leave empty to use the default control server",tailscaleHostname:"Hostname",tailscaleHostnameDescription:"Optional.",tailscaleHostnamePlaceholder:"For example: codingns-host",tailscaleReachableBaseUrl:"Reachable Base URL",tailscaleTailnetFqdn:"Tailnet FQDN",tailscaleTailnetIpv4:"Tailnet IPv4",tailscaleTailnetIpv6:"Tailnet IPv6",tailscaleDetailAddresses:"Detailed Addresses",tailscaleRefresh:"Refresh",tailscaleInstallAction:"Install Tailscale",tailscaleInstallOpenFailed:"Failed to open the Tailscale install page.",tailscaleEnable:"Enable Tailscale",tailscaleDisable:"Disable Tailscale",tailscaleLogin:"Bind Account",tailscaleLogout:"Unbind Account",tailscaleUnavailable:"Unavailable",tailscaleLoadFailed:"Failed to load Tailscale status.",tailscalePhaseDisabled:"Disabled",tailscalePhaseBlockedUninitialized:"Blocked until bootstrap finishes",tailscalePhaseStarting:"Starting",tailscalePhaseNeedsLogin:"Waiting for login",tailscalePhaseRunning:"Running",tailscalePhaseStopping:"Stopping",tailscalePhaseError:"Error",tailscaleOverviewDisabled:"Remote access is not enabled yet.",tailscaleOverviewBlockedUninitialized:"Finish bootstrap before enabling remote access.",tailscaleOverviewStarting:"Connecting to Tailscale. Please wait.",tailscaleOverviewNeedsLogin:"Tailscale is enabled, but account binding is still required.",tailscaleOverviewRunning:"This instance is reachable through Tailscale now.",tailscaleOverviewStopping:"Remote access is being turned off.",tailscaleOverviewError:"Remote access hit an error. Refresh or reconfigure it first.",releaseChannel:"Release Channel",releaseChannelDescription:"Stable or beta",releaseStable:"Stable",releaseBeta:"Beta",autoReconnect:"Auto Reconnect",autoReconnectDescription:"Retry HTTP and WebSocket links automatically when Host is briefly unavailable.",autoCheckUpdate:"Auto Check Client Updates",autoCheckUpdateDescription:"Clients only",defaultPermissionMode:"Default Session Permissions",defaultPermissionModeDescription:"Controls the default tool permissions for new and resumed sessions. Full access disables approval prompts and should only be used for trusted projects and environments.",authDeviceManagement:"Login Devices",authDeviceManagementDescription:"View the current device, other active devices, and the latest 10 login records, and sign out specific active devices one by one from a primary device.",authDeviceEntryHint:"Open device management to view the current device, other active devices, and recent login records in a dialog.",authDeviceOpenManager:"Manage Devices",authDeviceCurrentTitle:"Current Device",authDeviceOthersTitle:"Other Active Devices",authDeviceRecentTitle:"Recent Login Records",authDeviceCurrentTag:"Current",authDevicePrimaryTag:"Primary",authDeviceLegacyTag:"Legacy",authDeviceLegacyHiddenHint:"Detected {count} compatibility records from legacy sessions. They are hidden by default.",authDeviceLegacyReveal:"Show Compatibility Records",authDeviceLegacyHide:"Hide Compatibility Records",authDeviceLegacyDevicesTitle:"Legacy Active Records",authDeviceLegacyRecentTitle:"Legacy Login Records",authDeviceLegacyLabel:"Unknown Device (Legacy Session)",authDeviceClientDesktop:"Desktop",authDeviceClientWeb:"Web",authDeviceClientIos:"iOS",authDeviceClientAndroid:"Android",authDeviceClientUnknown:"Unknown Device",authDeviceCurrentEmpty:"The current session does not have identifiable device metadata yet. Please sign in again.",authDeviceOthersEmpty:"There are no other active devices.",authDeviceRecentEmpty:"There are no recent login records yet.",authDeviceBrowserValue:"Browser: {value}",authDeviceOsValue:"OS: {value}",authDeviceLastSeen:"Last seen: {value}",authDeviceLoginAt:"Login time: {value}",authDeviceSourceAddressValue:"Source address: {value}",authDeviceSourceAddressUnknown:"Source address: unknown",authDeviceEnablePrimary:"Set as Primary",authDeviceDisablePrimary:"Remove Primary",authDevicePrimaryUnavailable:"The current session does not have a stable device identity yet, so it cannot become a primary device.",authDeviceLogoutOthers:"Sign Out Other Devices",authDeviceLogoutDevice:"Sign Out Device",authDevicePrimaryEnabled:"The current device is now a primary device.",authDevicePrimaryDisabled:"The current device is no longer a primary device.",authDeviceLogoutOthersSuccess:"Signed out other devices. Processed {count}.",authDeviceLogoutDeviceSuccess:'Signed out device "{device}". Processed {count} session(s).',authDeviceLoadFailed:"Failed to load login device information.",authDeviceEnablePrimaryModalTitle:"Set as Primary Device",authDeviceEnablePrimaryModalDescription:"Enter the admin password to confirm that the current device should become a primary device.",authDeviceDisablePrimaryModalTitle:"Remove Primary Device",authDeviceDisablePrimaryModalDescription:"Enter the admin password to confirm that the current device should no longer be a primary device.",authDevicePasswordLabel:"Admin password",permissionModeDefault:"Follow CLI defaults",permissionModeAcceptEdits:"Allow workspace edits without asking",permissionModeBypassPermissions:"Full access without asking",enabled:"Enabled",disabled:"Disabled",serverUpdate:"Server Update",serverUpdateDescription:"",clientUpdate:"Client Update",clientUpdateDescription:"",serverCurrentVersion:"Server Current Version",serverTargetVersion:"Server Target Version",serverPackageName:"npm Package",serverUpdateCommand:"Upgrade Command",serverCheckNow:"Check Server",serverOpenPage:"Open npm",serverLatestUnknown:"Unavailable",serverUpdateReady:"New version found",serverUpToDate:"Up to date",serverCheckFailed:"Check failed",serverInstallWarning:"Installing the update will restart the CodingNS service through PM2 and briefly interrupt the connection.",serverInstallConfirmTitle:"Install Server Update",serverInstallConfirmDescription:"Continuing will install the new version first, then let PM2 restart the current CodingNS service automatically.",serverInstallConfirmAction:"Install And Restart",serverRestarting:"Update installed. Restarting the CodingNS service",serverOpenPageFailed:"Failed to open page",releaseCurrentVersion:"Current Version",releaseTargetVersion:"Target Version",releaseTargetTag:"Target Tag",releasePublishedAt:"Published At",releaseUnknownVersion:"Unknown",releaseNotes:"What's New",releaseNotesEmpty:"No details",releaseCheckNow:"Check Client",releaseInstallNow:"Install",releaseOpenPage:"Open Release",releaseRollback:"Rollback",releaseUpdateBadge:"Update",releaseUpdateReady:"New version found",releaseUpToDate:"Up to date",releaseCheckFailed:"Check failed",releaseInstallerMissing:"A new version is available, but this release does not include a supported installer yet.",releaseSignatureMissing:"A new version is available, but this release does not provide checksum information yet.",releaseInstallStarted:"Install started",releaseInstallFailed:"Install failed",releaseRestartRequired:"Install completed. Please restart the app.",releaseRestartDialogTitle:"Install completed",releaseRestartDialogDescription:"Version {version} has been installed. Restart the app to finish switching to the new build.",releaseRestartLater:"Later",releaseRestartConfirm:"Yes, restart now",releaseRestartFailed:"Failed to restart the app",releasePageOpenFailed:"Failed to open page",androidInstallerStarted:"Handed off to the Android installer. You can still cancel there.",androidInstallPermissionRequired:"Allow installs from this source before retrying.",androidInstallCancelled:"Install was cancelled or not completed. You can try again.",androidInstallSucceeded:"The new version has been detected as installed.",releaseRollbackStarted:"Rollback started",releaseRollbackFailed:"Rollback failed",clientUpdateUnsupported:"Install updates are not supported here",logout:"Log out"},home:{title:"Continue from a session, not from a backend table",subtitle:"Pick a workspace and session here first. The real work starts in the next step.",terminalsEntry:"Open Terminal",workspaceSection:"Workspaces",sessionSection:"Recent Sessions",emptyWorkspaces:"No workspace has been imported yet. Import one on the Host side first, and the entry will appear here.",emptySessions:"There is no session to continue in the current workspace yet.",noActivity:"No activity yet"},terminal:{title:"Terminal",heroTitle:"Keep the real PTY on Host, keep the control surface in the workspace",heroSubtitle:"This page does not fake output and does not mix terminal with process management. It only consumes the real terminal stream managed by Host.",workspaceSection:"Workspace & Terminal",workspaceField:"Current Workspace",shellField:"Shell for New Terminal",runtimeField:"Runtime",runtimeAutoOption:"Auto",runtimeAutoShortLabel:"auto",runtimeAutoDescription:"Use the Host default policy for this terminal runtime.",runtimePersistentLabel:"Persistent Session",runtimePersistentShortLabel:"persist",runtimeTmuxDescription:"Use a persistent external session, ideal for development terminals that should stay alive.",runtimeWindowsPersistentDescription:"Use a Windows persistent session backed by ConPTY so the shell can survive Host restarts.",runtimeEmbeddedDescription:"Managed directly by the current Host and useful as the lightweight fallback.",runtimeConptyPowerShellLabel:"PowerShell Persistent",runtimeConptyCmdLabel:"CMD Persistent",runtimeConptyGitBashLabel:"Git Bash Persistent",runtimeMissingDialogTitle:"tmux is not installed on this system",runtimeMissingDialogDescription:"The tmux runtime cannot create a persistent terminal right now. Install tmux first, or temporarily switch to embedded-pty to continue.",runtimeMissingInstallDescription:"Installing tmux is recommended if you want terminals to survive Host restarts.",runtimeMissingInstallMacArm:"macOS (Apple Silicon / Homebrew): arch -arm64 brew install tmux",runtimeMissingInstallMacIntel:"macOS (Intel Mac / Homebrew): brew install tmux",runtimeMissingInstallDebian:"Ubuntu / Debian: sudo apt install tmux",runtimeMissingInstallFedora:"Fedora: sudo dnf install tmux",runtimeMissingFallbackDescription:"If you switch to embedded-pty now, the terminal can still start, but it will not stay as an external persistent session.",runtimeMissingKeepAction:"Not now",runtimeMissingFallbackAction:"Switch to embedded-pty",runtimeMissingFallbackPending:"Switching...",shellUnavailable:"Unavailable",workspaceLoadFailed:"The workspace or terminal list is not available right now.",terminalSection:"Terminal Instances",templateSection:"Command Templates",stageEmptyTitle:"No terminal selected yet",stageEmptySubtitle:"Create a terminal first, or run a command template.",emptyTerminals:"There is no terminal instance in the current workspace yet.",emptyTemplates:"There is no command template in the current workspace yet.",createButton:"Create Terminal",creating:"Creating terminal...",creationPendingDescription:"Host is starting the real PTY. This pane will take over as soon as the stream is ready.",defaultTerminalName:"Workspace Terminal",created:"The terminal has been created and connected to Host.",createFailed:"Failed to create terminal.",closeButton:"Close Terminal",closing:"Closing terminal...",closed:"The terminal close request has been submitted.",closeCompleted:"Terminal closed.",closePendingDescription:"The close request has been sent to Host. The page stays responsive and keeps syncing the final result in the background.",closeSyncDelayed:"Host is still finishing the close in the background. The list will keep syncing on the next refresh.",closeFailed:"Failed to close terminal.",inputLabel:"Send command to current terminal",inputPlaceholder:"For example: npm test",sendButton:"Send to Terminal",inputFailed:"Failed to send terminal input.",outputEmpty:"The terminal is connected, but there is no output yet.",outputTruncated:"Some output exceeded the cache window while disconnected. Only the retained part has been restored.",connectedHint:"Current output is coming from the real PTY stream on Host.",moreActions:"Terminal Actions",duplicateAction:"Duplicate Tab",duplicateSuccess:"A new terminal tab has been created with the same setup.",duplicateFailed:"Failed to duplicate the terminal tab.",disconnectAction:"Disconnect",disconnected:"Terminal connection has been disconnected.",reconnectAction:"Reconnect",reconnectRequested:"Reconnect request sent.",deleteAction:"Delete",deleting:"Deleting terminal...",deleted:"Terminal record deleted.",deletePendingDescription:"The delete request has been sent to Host. The page stays responsive and keeps syncing the list in the background.",deleteSyncDelayed:"Host is still finishing the delete in the background. The list will keep syncing on the next refresh.",deleteFailed:"Failed to delete the terminal record.",closePendingBadge:"Closing",deletePendingBadge:"Deleting",pinAction:"Pin",unpinAction:"Unpin",zoomLabel:"Terminal Zoom",zoomInAction:"Zoom in terminal display",zoomOutAction:"Zoom out terminal display",zoomResetAction:"Reset terminal zoom",openExternalAction:"Open in Separate Window",openExternalFailed:"Failed to open the detached terminal window.",toolbarToggleAction:"Open terminal tools menu",mobileSwipeHint:"Swipe left or right to switch terminals",mobileSwipePosition:"{current} / {total}",mobileDrawerAction:"Open quick terminal list",mobileDrawerTitle:"Quick Terminals",mobileDrawerDescription:"Swipe right to reveal the list, then tap to jump to another terminal.",mobilePinnedSectionTitle:"Pinned Terminals",mobileDrawerEmptyTitle:"No terminals yet",mobileDrawerEmptyDescription:"Create one first and the quick switcher will appear here.",mobileCreateSheetTitle:"Create Terminal",mobileCreateShellLabel:"Terminal Type",mobileCreateShellDescription:"Pick the shell for this terminal instead of squeezing desktop dropdowns onto mobile.",mobileCreateRuntimeLabel:"Session Type",mobileCreateRuntimeDescription:"Choose whether this terminal should stay persistent or only live in the current runtime.",mobileCreateLoadingShells:"Loading available terminal types for this system...",mobileCreateConfirm:"Create this terminal",createDialogTitle:"Create Terminal",createDialogShellDescription:"Choose the shell for this terminal before creation. On Windows we should not silently fall back to CMD anymore.",createDialogRuntimeDescription:"Choose whether this terminal should stay persistent or only live in the current runtime.",createDialogConfirm:"Create Terminal",mobileRuntimePersistentTitle:"Persistent Session",mobileRuntimePersistentDescription:"Best for development terminals that should stay alive and reconnect as a recoverable session.",mobileRuntimeSessionTitle:"runtime (current session)",mobileRuntimeSessionDescription:"Managed directly by the current Host. Lighter, but not an external persistent session.",mobileWorkspaceSwitcherPlaceholder:"Choose Workspace",mobileEmptyTitle:"No terminal content yet",mobileEmptyDescription:"Create a terminal first, or swipe right to open the quick list and switch to an existing one.",layoutLabel:"Layout",layoutSingleAction:"Single pane",layoutVerticalAction:"Split left and right",layoutHorizontalAction:"Split top and bottom",saveLogAction:"Save Log",saveLogSuccess:"The terminal log has been saved.",saveLogFailed:"Failed to save the terminal log.",logEmpty:"There is no terminal log to save yet.",bindToPaneAction:"Bind to current pane",bindToPrimaryPaneAction:"Bind to main pane",bindToSecondaryPaneAction:"Bind to side pane",panePrimary:"Main Pane",paneSecondary:"Side Pane",splitEmptySubtitle:"Pick a tab or create a terminal first, then bind it to this pane.",statusBadge:{creating:"starting",running:"running",closed:"closed",error:"error"},recoveryComplete:"Recovered to the terminal from before refresh. Key cached output has been restored.",recoveryTruncated:"Recovered to the previous terminal, but some disconnected output exceeded the cache window.",recoveryIdleClosed:"The previous terminal was auto-closed by Host after being idle too long. You are seeing the output kept before close.",reconnect:"Reconnect",liveConnected:"Live stream connected",templateName:"Template Name",templateCommand:"Main Command",templateArgs:"Arguments (space separated)",templateCreateButton:"Save Template",templateCreated:"The command template has been saved.",templateCreateFailed:"Failed to save the command template.",templateRunSent:"The command template has been sent to the current terminal.",templateRunCreatedTerminal:"The command template started in a new terminal.",templateRunFailed:"Failed to run the command template.",connection:{connected:"Connected",reconnecting:"Reconnecting",reconnect_failed:"Reconnect failed",closed:"Closed"}},conversation:{titleFallback:"Continue Conversation",historyLoading:"Loading message history from Host...",historyLoadingOlder:"Loading older messages...",historyLoadFailed:"Message history is not available right now. Try again later.",timelineEmpty:"There are no messages in this session yet. Your first message will go straight into the Host chain.",turnAbortedUser:"The previous turn was stopped by you.",turnAbortedUnexpected:"The previous turn was interrupted unexpectedly and did not finish cleanly.",turnAbortedGeneric:"The previous turn was interrupted before it finished cleanly.",scrollToBottomAction:"Jump to bottom",rawRefLabel:"Source",copyAction:"Copy",copyContentSuccess:"Content copied.",copyContentFailed:"Failed to copy the content.",selectionTodoAction:"Todo",selectionActionButton:"Action",selectionActionSubmit:"Open action child session",selectionActionPromptLabel:"What should it do",selectionActionPromptPlaceholder:"For example: explain this, turn it into notes, or send it to a specific API",selectionActionIncludeContext:"Include current context",selectionActionContextUnavailable:"This selection spans multiple messages, so context inheritance is disabled for safety.",selectionActionDefaultPrompt:"Please process this content.",selectionActionQuotedLabel:"Selected text",selectionActionFailed:"Failed to create the action child session.",actionSessionBadge:"Action",actionInheritedSelectionSummary:'Collapsed the selected text from "{parentTitle}" by default.',forkFromHereAction:"Fork from here",forkingAction:"Forking...",forkMessageSucceeded:"Created a new branch from this message.",forkMessageFailed:"Failed to fork from this message.",forkDraftLabel:"Fork Quote",forkDraftEmpty:"This message does not contain text to quote.",forkDraftClear:"Cancel this fork quote",forkTargetProviderLabel:"Target CLI",forkTargetModelLabel:"Target Model",forkTargetSummary:"Source CLI: {sourceProvider} · Target CLI: {targetProvider}",forkInlineModelLoading:"Loading model options...",forkInlineNativeHint:"Stay on the same CLI and use native fork.",forkInlineCrossHint:"Switched to another CLI. The child session will be reconstructed from text history.",forkSwitchConfirmTitle:"Switch to another CLI?",forkSwitchConfirmDescription:"Using the same CLI keeps the native fork experience. Switching CLI changes this into a cross-provider fork.",forkSwitchConfirmKeepTitle:"Will keep",forkSwitchConfirmKeepBody:"User messages and assistant text before the fork point.",forkSwitchConfirmConvertTitle:"Will convert",forkSwitchConfirmConvertBody:"Reusable text history will be rebuilt into the new CLI session.",forkSwitchConfirmDropTitle:"Will lose",forkSwitchConfirmDropBody:"Tool calls, permission prompts, attachments, and running state.",forkSwitchConfirmAction:"Confirm switch",forkSwitchKeepNative:"Keep native",forkProviderNativeUnsupported:"This provider does not support native fork yet",forkProviderReconstructedUnsupported:"This provider cannot be used as a cross-provider fork target yet",loadMore:"Load More",composerPlaceholder:"State the next step clearly. Let the rest continue inside this session.",sendButton:"Send Message",queueTitle:"Queued Messages",queueDescription:"After the current run finishes, these messages will be processed automatically in order.",queueOrderPrefix:"Queue Position",queueStatusQueued:"Queued",queueStatusFailed:"Dispatch Failed",queueDelete:"Delete",queueDeleting:"Deleting",queueImageOnly:"Image attachments only",sendGuidanceButton:"Add Guidance",queueGuidanceButton:"Queue Guidance",queueSteer:"Steer",queueSteering:"Steering",resendButton:"Resend",quickPhraseTrigger:"Quick Phrases",quickPhraseModalTitle:"Quick Phrases",quickPhraseModalDescription:"Keep the prompts you reuse often in one place and drop them straight into the current composer.",quickPhraseCreateLabel:"New Phrase",quickPhraseOpenCreateAction:"Add Phrase",quickPhraseCreateModalTitle:"Create Quick Phrase",quickPhraseCreateModalDescription:"Save a reusable prompt on its own so it is ready across devices whenever you need it.",quickPhraseCreatePlaceholder:"Write a phrase you want to reuse later.",quickPhraseCreateAction:"Add Phrase",quickPhraseListLabel:"Quick phrase list",quickPhraseEmpty:"There are no quick phrases yet. Add the first one you actually reuse.",quickPhraseOrderLabel:"Item {index}",quickPhraseMoveUp:"Move phrase up",quickPhraseMoveDown:"Move phrase down",quickPhraseDelete:"Delete phrase",quickPhraseSaveFailed:"Failed to save quick phrases. Try again later.",sendingState:"Sending",sentState:"Synced",failedState:"Send failed",contextUsageTitle:"Context Usage",contextUsageUnavailable:"Context usage is not available yet",contextUsageEstimated:"Window is estimated",contextUsageCachedTokens:"{count} cached",contextUsageSourceProviderLog:"window from provider log",contextUsageSourceProviderRuntime:"window from provider runtime",contextUsageSourceProviderConfig:"window from provider config",contextUsageSourceModelMap:"window from model map",headerWorkspace:"Workspace",headerProvider:"Provider",headerCapability:"Capability Summary",connectionConnected:"Connected",connectionReconnecting:"Reconnecting",connectionReconnectFailed:"Reconnect failed",connectionClosed:"Connection closed",runtimeErrorTitle:"Session run failed",runtimeErrorFallbackDetail:"The CLI provider returned an error without additional detail.",runtimeErrorCodeLabel:"Error code",runtimeErrorDetailLabel:"Error detail",permissionRequestSectionTitle:"Pending approvals",permissionRequestSectionDescription:"Provider-side approvals are unified here so you do not need to learn three different dialogs.",permissionRequestToastTitle:"Approval needed",permissionRequestReplyFailed:"Failed to reply to the approval request.",permissionRequestSubmitting:"Submitting...",permissionRequestReasonLabel:"Reason",permissionRequestCommandLabel:"Command",permissionRequestToolLabel:"Tool",permissionRequestCwdLabel:"Working directory",permissionRequestPathsLabel:"Related paths",permissionRequestPermissionsLabel:"Requested permissions",permissionRequestReadLabel:"Read",permissionRequestWriteLabel:"Write",permissionRequestNetworkLabel:"Network",permissionRequestQuestionsLabel:"Questions",permissionRequestDetailLabel:"Details",permissionRequestEmpty:"None",permissionRequestUnknown:"Unknown",permissionRequestKindCommand:"Command",permissionRequestKindFileChange:"File Change",permissionRequestKindPermissions:"Permissions",permissionRequestKindUserInput:"User Input",permissionRequestKindToolCall:"Tool Call",reconnectExplain:"The realtime link is broken. The system is replaying missing messages.",reconnectFailedExplain:"Automatic recovery failed. Retry manually, or reopen the session later.",reconnectExplainWithRoute:"The realtime link is broken. The system is replaying missing messages. Current route: {route}.",reconnectFailedExplainWithRoute:"Automatic recovery failed. Retry manually, or reopen the session later. Current route: {route}.",capabilityDenied:"This action is not supported in the current session.",capabilitySendDisabled:"The current provider does not support sending new messages.",capabilityAttachmentDisabled:"This session does not support attachment input yet.",capabilityInterruptDisabled:"This session does not support interruption.",sidebarTitle:"Current Session Context",sidebarSubtitle:"This sidebar only keeps the minimum capability summary. It does not turn the page into an admin console.",reconnectButton:"Restore Realtime Sync",headerResumedAt:"Last Resumed",headerLastSyncAt:"Last Synced",historyPages:"History Pages",syncStatusIdle:"Sync Idle",syncStatusSyncing:"Syncing",syncStatusError:"Sync Error",capabilityResume:"Resumable",capabilitySend:"Send Enabled",capabilityInterrupt:"Interrupt Enabled",capabilityTools:"Tool Calls",attachmentsLabel:"Attachments",filePanelTitle:"File Manager",filePanelSubtitle:"File capabilities here only serve the current session. This is not a heavy IDE shell.",filePanelNoWorkspace:"There is no selected workspace yet. Browsing or attaching files is unavailable.",filePanelRefresh:"Refresh",filePanelCopyPath:"Copy Path",filePanelCopyAbsolutePath:"Copy Absolute Path",filePanelCopyRelativePath:"Copy Relative Path",filePanelCopyAbsolutePathSuccess:"Absolute path copied.",filePanelCopyRelativePathSuccess:"Relative path copied.",filePanelCopyPathFailed:"Failed to copy the path.",filePanelCopy:"Copy",filePanelCut:"Cut",filePanelPaste:"Paste",filePanelCopySelectionSuccess:"{count} item(s) copied. Paste them into a target folder.",filePanelCutSelectionSuccess:"{count} item(s) cut. Paste them into a target folder.",filePanelPasteSuccess:"{count} item(s) pasted.",filePanelPasteFailed:"Paste failed. Check the target folder and name conflicts.",filePanelSelectionCount:"{count} item(s) selected",filePanelClipboardCopyReady:"{count} item(s) ready to copy",filePanelClipboardCutReady:"{count} item(s) ready to move",filePanelOpenFile:"Open File",filePanelExpandDirectory:"Expand Folder",filePanelCollapseDirectory:"Collapse Folder",filePanelActionsMenu:"File Actions",filePanelSearchPlaceholder:"Enter a file name or path fragment",filePanelSearchButton:"Search",filePanelShowSearch:"Open Search",filePanelHideSearch:"Hide Search",filePanelSearchEmpty:"No matching files found.",filePanelSearchResults:"Search Results",filePanelSearchFailed:"File search failed. Try again later.",filePanelBrowse:"Workspace Files",filePanelCollapseCurrent:"Collapse Current",filePanelCollapseAll:"Collapse All",filePanelBackDirectory:"Go to Parent",filePanelEmptyDirectory:"There are no files to show in this directory.",filePanelRecentTitle:"Recently Opened",filePanelEmptyRecent:"There is no recently opened file yet.",filePanelContextTitle:"Attached Files",filePanelEmptyContexts:"No file is attached to the current session yet.",filePanelEditorTitle:"Preview & Editor",filePanelEditorPlaceholder:"This is a lightweight text editor, not a full IDE.",filePanelSelectHint:"Pick a file first from browse, search, or recent items.",filePanelUnsupported:"This file cannot be edited directly in the sidebar right now.",filePanelAttach:"Attach to Session",filePanelAttached:"Attached",filePanelDetach:"Detach",filePanelSave:"Save",filePanelSaving:"Saving...",filePanelLoadFailed:"Failed to load the file panel.",filePanelOpenFailed:"Failed to open the file.",filePanelSaveSuccess:"File saved.",filePanelSaveFailed:"Failed to save the file.",fileViewerHint:"Opened in {language} mode. Preview and save after editing are supported.",fileViewerModeLabel:"File View Mode",fileViewerPreview:"Preview",fileViewerPresentation:"Presentation",fileViewerCode:"Code",fileViewerEdit:"Edit",fileViewerPlainText:"Plain Text",fileViewerHtml:"HTML",fileViewerImage:"Image",fileViewerPdf:"PDF",fileViewerRefreshPreview:"Refresh",fileViewerRefreshFailed:"Failed to refresh the file preview.",fileViewerExportPdf:"Export PDF",fileViewerExportPdfRunning:"Exporting...",fileViewerExportPdfSuccess:"PDF exported to {path}",fileViewerExportPdfFailed:"Failed to export the PDF.",fileViewerExportPdfTimeout:"PDF export timed out. Try again later.",fileViewerExportPdfMissingHtml:"No HTML content is available for export.",fileViewerExportPptx:"Export PPTX",fileViewerExportPptxRunning:"Exporting...",fileViewerExportPptxSuccess:"PPTX exported to {path}",fileViewerExportPptxFailed:"Failed to export the PPTX.",fileViewerExportPptxMissingHtml:"No HTML content is available for export.",fileViewerExportTaskTimeout:"Export timed out. Try again later.",fileViewerOpenExternal:"Open Externally",fileViewerOpenExternalFailed:"Failed to open the file externally.",fileViewerOpenInWindow:"Separate Window",fileViewerOpenInWindowFailed:"Failed to open the separate window.",fileViewerWindowTitle:"File Preview",fileViewerCollapse:"Collapse Preview",fileViewerExpand:"Expand Preview",fileViewerZoomIn:"Zoom In",fileViewerZoomOut:"Zoom Out",fileViewerFit:"Fit",fileViewerActualSize:"Actual Size",fileViewerFitWidth:"Fit Width",fileViewerPreviousPage:"Previous Page",fileViewerNextPage:"Next Page",fileViewerPageIndicator:"Page {page}",fileViewerSizeLabel:"Viewer Size",fileViewerSizeDefault:"Default",fileViewerSizeWide:"Wide",fileViewerSizeFull:"Full",fileViewerDiffModified:"Modified",fileViewerDiffAdded:"Added Content",fileViewerImageUnavailable:"The image preview is unavailable right now. Try refreshing or opening it externally.",fileViewerPdfUnavailable:"The PDF preview is unavailable right now. Try refreshing or opening it externally.",fileViewerOfficeLoading:"Loading the ONLYOFFICE preview...",fileViewerOfficeUnavailable:"The Office preview is unavailable right now. Check the ONLYOFFICE configuration and service status.",fileViewerOfficeScriptUnavailable:"Failed to load the ONLYOFFICE editor script. Check whether the service URL is reachable.",fileViewerEnterFullscreen:"Full Screen",fileViewerExitFullscreen:"Exit",fileViewerOpenInBrowser:"Open in Browser",fileViewerOpenInBrowserFailed:"Failed to open the browser preview.",fileViewerHtmlPreviewLoading:"Loading the HTML preview...",fileViewerHtmlPreviewUnavailable:"The HTML preview is unavailable right now. Switch to code view instead.",fileViewerHtmlPreviewFailed:"Failed to create the HTML preview link.",fileViewerPresentationBadge:"Static HTML",fileViewerPresentationSummary:"{count} pages detected, canvas {size}",fileViewerPresentationWarningCount:"{count} import warnings detected.",fileViewerPresentationCurrentPage:"Current Page",fileViewerPresentationUntitled:"Untitled Page",fileViewerPresentationReadOnlyHint:"Select a component to view text and layout editing tools.",fileViewerPresentationEditHint:"This pass supports node selection plus basic text and style edits. Complex structures stay read-only.",fileViewerPresentationCanvasSelectHint:"Click a component on the canvas to edit it from the top toolbar, or switch from the component list on the right.",fileViewerPresentationUnsupported:"This HTML file is not ready for presentation view yet.",fileViewerPresentationUnsupportedReason:"Reason: {reason}",fileViewerPresentationSelectNode:"Pick an editable node from the component list on the right first.",fileViewerPresentationAddPage:"Add Page",fileViewerPresentationDuplicatePage:"Duplicate Page",fileViewerPresentationDeletePage:"Delete Page",fileViewerPresentationMovePageUp:"Move Page Up",fileViewerPresentationMovePageDown:"Move Page Down",fileViewerPresentationPageActions:"Page Actions",fileViewerPresentationDragToSort:"Drag to Sort",fileViewerPresentationUndoAction:"Undo Last Action",fileViewerPresentationInspector:"Inspector",fileViewerPresentationComponentList:"Components",fileViewerPresentationEditable:"Editable",fileViewerPresentationReadOnly:"Read Only",fileViewerPresentationTextLabel:"Text Content",fileViewerPresentationTextDescription:"Edit the copy here and the canvas preview updates immediately.",fileViewerPresentationTextToolbar:"Text Toolbar",fileViewerPresentationFontFamilyLabel:"Font Family",fileViewerPresentationFontPresetTitle:"DengXian Light (Headings)",fileViewerPresentationFontPresetSans:"Noto Sans SC",fileViewerPresentationFontPresetSerif:"Serif Body",fileViewerPresentationFontPresetMono:"Monospace",fileViewerPresentationBoldAction:"Bold",fileViewerPresentationItalicAction:"Italic",fileViewerPresentationUnderlineAction:"Underline",fileViewerPresentationFontSizeIncreaseAction:"Increase Font Size",fileViewerPresentationFontSizeDecreaseAction:"Decrease Font Size",fileViewerPresentationLineHeightAuto:"Default Line Spacing",fileViewerPresentationFontSizeLabel:"Font Size",fileViewerPresentationFontWeightLabel:"Font Weight",fileViewerPresentationTextColorLabel:"Text Color",fileViewerPresentationBackgroundColorLabel:"Background Color",fileViewerPresentationTextAlignLabel:"Alignment",fileViewerPresentationLineHeightLabel:"Line Height",fileViewerPresentationPaddingLabel:"Padding",fileViewerPresentationRadiusLabel:"Radius",fileViewerPresentationPositionXLabel:"Position X",fileViewerPresentationPositionYLabel:"Position Y",fileViewerPresentationWidthLabel:"Width",fileViewerPresentationHeightLabel:"Height",fileViewerPresentationDuplicateAction:"Duplicate Selected Node",fileViewerPresentationKeepOriginal:"Keep Original",fileViewerPresentationAlignLeft:"Align Left",fileViewerPresentationAlignCenter:"Align Center",fileViewerPresentationAlignRight:"Align Right",fileViewerPresentationTextMode:"Text",fileViewerPresentationLayoutMode:"Layout",fileViewerPresentationLayoutHint:"This toolbar edits component position and size. Canvas dragging and saving follow the same geometry.",fileViewerPresentationLayoutSelectNode:"Pick a component that supports layout editing first.",fileViewerPresentationLayoutEditable:"Layout Editable",fileViewerPresentationLayoutLocked:"Layout Locked",fileViewerPresentationLayoutUnsupported:"This component is not safe for layout editing yet.",fileViewerPresentationLayoutStrictLocked:"This component is still in flow layout. Convert its container to free layout before dragging it.",fileViewerPresentationLayoutFreezeContainer:"Convert Container to Free Layout",fileViewerPresentationLayoutRootLocked:"Page root containers stay locked in this pass.",fileViewerPresentationLayoutSelectionCount:"{count} components selected",fileViewerPresentationLayoutAlignLeft:"Align Left Edge",fileViewerPresentationLayoutAlignRight:"Align Right Edge",fileViewerPresentationLayoutAlignTop:"Align Top Edge",fileViewerPresentationLayoutAlignBottom:"Align Bottom Edge",fileViewerPresentationResizeHandle:"Resize Component",filePanelAttachSuccess:"The file has been attached to the current session.",filePanelAttachFailed:"Failed to attach the file.",filePanelDetachSuccess:"The file has been detached from the current session.",filePanelDetachFailed:"Failed to detach the file.",filePanelNewFile:"New File",filePanelNewDirectory:"New Directory",filePanelUpload:"Upload File",filePanelDownload:"Download File",filePanelUploadSuccess:"{name} uploaded.",filePanelUploadFailed:"Failed to upload the file.",filePanelDownloadSuccess:"Started downloading {name}.",filePanelDownloadFailed:"Failed to download the file.",filePanelDelete:"Delete",filePanelDeleting:"Deleting...",filePanelDeleteSuccess:"Deleted {name}.",filePanelDeleteConfirmTitle:"Confirm Deletion",filePanelDeleteConfirmDescription:"The selected item will be removed from this workspace immediately and cannot be undone.",filePanelDeleteSelectionConfirm:"Delete the selected {count} items?",filePanelDeleteSelectionSuccess:"Deleted {count} items.",filePanelRenameMove:"Rename / Move",filePanelRenameSuccess:"Renamed to {name}.",filePanelMutateFailed:"File operation failed. Check the path and current state.",filePanelCreateFilePrompt:"Enter the relative path of the file to create",filePanelCreateDirectoryPrompt:"Enter the relative path of the directory to create",filePanelCreateFileDescription:"Enter a relative path inside the workspace. The file will be created immediately.",filePanelCreateDirectoryDescription:"Enter a relative path inside the workspace. The folder will be created immediately.",filePanelPathFieldLabel:"Relative Path",filePanelPathFieldPlaceholder:"For example: src/features/files/index.ts",filePanelCreateFileSubmit:"Create File",filePanelCreateDirectorySubmit:"Create Folder",filePanelCreatingFile:"Creating file...",filePanelCreatingDirectory:"Creating folder...",exportAction:"Export Session",exportDialogTitle:"Export Current Session",exportDialogDescription:"Export the full session as Markdown, or print the current message layout and save it as PDF.",exportMarkdownAction:"Export Markdown",exportMarkdownHint:"Exports the full message content for editing, archiving, or commit history.",exportPdfAction:"Export PDF",exportPdfHint:"Downloads a PDF file directly and keeps the current conversation content layout.",exportHtmlAction:"Export HTML",exportPreparing:"Preparing the export content...",exportMarkdownSuccess:"The Markdown export has started.",exportPdfPreparing:"The PDF download has started.",exportHtmlSuccess:"The HTML export has started.",exportLoadFailed:"Export failed because the full session content could not be loaded.",exportDownloadFailed:"Failed to export the file.",exportPrintFailed:"Failed to open the print dialog.",exportPrintContainerTitle:"Session Export",exportMarkdownSessionIdLabel:"Session ID",exportMarkdownProviderLabel:"Provider",exportMarkdownWorkspaceLabel:"Workspace ID",exportMarkdownCreatedAtLabel:"Created At",exportMarkdownExportedAtLabel:"Exported At",exportMarkdownTimeLabel:"Time",exportMarkdownTypeLabel:"Type",exportMarkdownAttachmentsLabel:"Attachment Count",exportMarkdownAttachmentsSectionTitle:"Attachments",exportMarkdownToolSectionTitle:"Tool Call",exportMarkdownToolNameLabel:"Tool Name",exportMarkdownToolStatusLabel:"Status",exportMarkdownToolInputLabel:"Input",exportMarkdownToolOutputLabel:"Output",exportMarkdownToolErrorLabel:"Error",exportMarkdownToolCallType:"Tool Call",exportMarkdownToolResultType:"Tool Result",exportMarkdownTextType:"Text",exportMarkdownUnknownSize:"Unknown Size",filePanelFilterChanges:"Changes Only",filePanelShowAll:"Show All",filePanelNoChanges:"No changed files.",filePanelBinaryPreview:"Binary files cannot be previewed.",filePanelDeleteFileConfirm:"Delete this file? {path}",filePanelDeleteDirectoryConfirm:"Delete this folder? {path}",filePanelRenameMovePrompt:"Enter the new relative path",filePanelRenameDescription:"Only the path changes. Use a new relative path if you also want to move it.",filePanelRenameSubmit:"Confirm Rename",filePanelRenaming:"Renaming...",unavailableAction:"Unavailable",roleUser:"User",roleAssistant:"Assistant",roleTool:"Tool",toolViewImageActiveLabel:"AI is viewing an image",roleSystem:"System"},git:{title:"Git Context",subtitle:"This is the session-side support area. It only handles Git facts inside the current workspace.",loading:"Loading Git context for the current workspace...",refresh:"Refresh",panelLoadFailed:"Git context is not available right now.",uninitializedTitle:"Git is not enabled in this folder yet",uninitializedDescription:"Initialize a Git workspace here first, then you can review changes, commit, and browse history.",initRepository:"Initialize Git Workspace",initInProgress:"Initializing...",initSuccess:"The Git workspace has been initialized.",initFailed:"Failed to initialize the Git workspace.",ahead:"Ahead",behind:"Behind",dirty:"Dirty",clean:"Clean",changeCount:"{count} changed files in the current workspace",noChanges:"There are no pending changes right now.",changesTitle:"Current Changes",rulesFirstHint:"Rules come first. Drafts must not bypass validation.",stage:"Stage",unstage:"Unstage",preview:"Preview",stageFailed:"Stage operation failed.",diffTitle:"Diff Preview",diffLoadFailed:"Diff content is not available right now.",binaryDiff:"This file is a binary change. The sidebar does not render its content directly.",stagedDiff:"Staged diff",worktreeDiff:"Working tree diff",emptyDiff:"There is no text diff to display right now.",diffTruncated:"The diff is too long and has been truncated for safety.",commitTitle:"Commit Draft",defaultRuleName:"Default Commit Rule",language:"Language",maxLength:"Max Length",bodyRequired:"Body Required",bodyOptional:"Body Optional",issueRequired:"Issue Required",issueOptional:"Issue Optional",commitSubject:"Commit Subject",commitSubjectPlaceholder:"Enter the commit message here",commitBody:"Commit Body",commitBodyPlaceholder:"Explain the change clearly. Do not write empty words.",commitFooter:"Commit Footer",commitFooterPlaceholder:"For example: Refs: #123",generateDraft:"AI Draft",validate:"Validate Draft",commit:"Commit",draftFailed:"Failed to generate the commit draft.",validateFailed:"Commit rule validation failed.",commitFailed:"Commit failed.",commitSuccess:"The commit has been written to the current repository.",validationPassed:"Rule validation passed. You can continue to commit.",validationFailed:"Rule validation failed. Fix the issues below first.",branchTitle:"Branch",branchPlaceholder:"Enter the branch name to switch to or create",switchBranch:"Switch",createBranch:"Create",branchFailed:"Branch operation failed.",historyTitle:"Recent History",historyHint:"Only keep the latest few entries here. This is not a graphical history tree.",noHistory:"There is no commit history to show right now.",viewAllVersions:"View All Versions",viewAllVersionsDescription:"Loaded commit history for the current repository. Total entries: {count}.",viewCommitChanges:"View Changed Files and DIFF",copyCommitMessage:"Copy Commit Message",copyCommitMessageSuccess:"The commit message has been copied.",copyCommitVersion:"Copy Git Version",copyCommitVersionSuccess:"The Git version has been copied.",commitDetailTitle:"Commit Detail",commitDetailDescription:"Showing the full change for commit {hash}.",commitDetailLoading:"Loading commit detail...",commitDetailEmpty:"There is no commit detail to show right now.",commitDetailLoadFailed:"The commit detail is not available right now.",commitVersionLabel:"Git Version",commitHashLabel:"Commit Hash",commitAuthorLabel:"Author",commitTimeLabel:"Commit Time",commitMessageLabel:"Commit Message",changedFilesTitle:"Changed Files",commitDiffLabel:"Commit DIFF",renamedFromLabel:"Renamed from {path}",explainCommitTitle:"Explain Commit Change",explainCommitDescription:"Choose a CLI provider first, then start a new session to analyze this commit.",explainCommitAction:"Explain Change",startExplainCommit:"Start Explaining",explainCommitStarted:"The explanation session has been created.",explainCommitFailed:"Failed to explain the commit change.",remoteTitle:"Remote Sync",remoteReady:"A remote is configured for the current repository.",remoteMissing:"The current repository has no remote configured yet.",fetch:"Fetch",pull:"Pull",push:"Push",pushNow:"Push Now",publish:"Publish",remoteFailed:"Remote sync failed.",remoteAuthAction:"Remote Auth",remoteAuthTitle:"Configure Remote Authentication",remoteAuthDescription:"Enter the username, password, or token to use for authenticated remote operations in this page session.",remoteAuthDescriptionGithub:"The current remote points to GitHub. For GitHub HTTPS Git operations, use a Personal Access Token (PAT) instead of your GitHub login password.",remoteAuthStatusLabel:"Authentication",remoteAuthManageHint:"Review and configure per remote",remoteAuthManageTitle:"Manage Remote Authentication",remoteAuthManageDescription:"Each remote repository shows its own credential status and should be configured separately here.",remoteAuthConfigured:"Configured",remoteAuthConfiguredInSession:"Configured In Session",remoteAuthConfiguredOnHost:"Saved On Host",remoteAuthNotConfigured:"Not Configured",remoteAuthGithubPatLabel:"Personal Access Token (PAT)",remoteAuthGithubPatPlaceholder:"Enter GitHub PAT",remoteAuthGithubUsernamePlaceholder:"Enter GitHub username",remoteAuthGithubPatHint:"GitHub does not support account passwords for Git HTTPS authentication. In basic mode, enter GitHub username + PAT. In token mode, you can paste the PAT directly.",remoteAuthRemember:"Remember On Host",remoteAuthSessionHint:"By default this only applies to the current page session. If you enable “Remember On Host”, the credential will be stored on the Host after a successful remote sync and reused later.",remoteAuthRememberHint:"When remember is enabled, this credential will be written to the Host after the remote sync succeeds.",remoteAuthSave:"Save Auth",remoteAuthSaved:"Remote authentication saved. Retry the remote sync now.",remoteAuthCleared:"Remote authentication for this page session has been cleared.",selectRemoteTitle:"Select Remote to Push",selectRemoteDesc:"Select remote repositories to push to. Multiple selection supported.",noRemotes:"No remote repositories are configured.",pushSelected:"Push ({count})",pushing:"Pushing…",pushAllSuccess:"Successfully pushed to {count} remote(s).",errors:{unauthorized:"The current login is no longer valid. Log in again and retry.",workspaceNotFound:"The workspace bound to the current session does not exist. Check whether it is still available.",invalidWorkspace:"The current workspace config is invalid. The Git sidebar must not operate outside the repo root.",notGitRepository:"The current workspace is not a Git repository. The Git sidebar will not fake a state.",repoNotFound:"No usable Git repository root was found for the current workspace.",pathOutOfWorkspace:"The Git target is outside the current workspace repository boundary. The operation was blocked.",invalidTarget:"The Git target path is invalid. Refresh the sidebar and try again.",notStaged:"The target file is not staged yet. Check the current change state first.",emptyStagedChanges:"The staging area is empty. Stage the changes before committing.",branchConflict:"The current branch has conflicts or is not a fast-forward update. Sync and resolve differences first.",branchNotFound:"The target branch does not exist. Check the branch name first.",remoteNotFound:"The current repository does not have a usable origin remote yet.",remoteAuthFailed:"Remote repository authentication failed. Check the current credentials first.",pushFailed:"Push failed. Check remote state and local commits first.",pullFailed:"Pull failed. Check the remote branch state first.",remoteFailed:"Remote sync failed. Check Git output and network state.",initFailed:"Failed to initialize the Git workspace. Make sure the directory is writable and Git is available.",commitValidationFailed:"The commit draft has not passed validation yet. Fix validation issues first.",commandTimeout:"The Git operation timed out. Check repository state and network conditions."}},theme:{light:"浅色",dark:"深色",skyBlue:"赛博",eyeGreen:"护眼",switchLabel:"Theme"},locale:{zhCN:"Simplified Chinese",enUS:"English"}},ch={common:{appName:"CodingNS",loading:"正在准备会话工作区…",retry:"重新尝试",back:"返回",save:"保存",close:"关闭",cancel:"取消",connectionRouteRelay:"CodingNS Connect",connectionRouteLan:"局域网直连",connectionRouteLoopback:"本机直连",connectionRouteTailscale:"Tailscale 直连",connectionRouteDirect:"直接连接",logout:"退出登录",unknown:"未命名会话"},auth:{loginTitle:"继续你的编码会话",loginSubtitle:"INITIALIZING DEVELOPMENT ENVIRONMENT...",serverPreset:"服务器列表",serverCustomOption:"使用自定义服务器",serverAddress:"服务器地址",serverPlaceholder:"例如:http://127.0.0.1:3002",serverHint:"登录、实时消息和终端都会连接到这里。客户端应填写 Host API 地址,例如 http://127.0.0.1:3002;4174、5173 这类前端开发端口不是给正式客户端直接连接的,只有代理和跨域都配好时才适合临时调试。",serverInvalid:"服务器地址无效,请检查后再试。",serverDiscoveredTag:"自动发现",serverCurrent:"当前服务器",bootstrapTitle:"先完成首次初始化",bootstrapSubtitle:"这个 Host 还没有管理员账号,先创建一个最小登录入口。",username:"用户名",password:"密码",rememberPassword:"保存密码",confirmPassword:"确认密码",submitLogin:"进入工作台",submitBootstrap:"创建管理员账号",bootstrapSuccess:"初始化完成,现在可以登录了。",bootstrapMismatch:"两次输入的密码不一致。",authUnavailable:"暂时连不上 Host,请确认服务可访问。",logoutSuccess:"当前登录态已经清空。",demoBanner:"演示环境 — 所有账号数据公开可见,注销后自动清除",demoSessionExpired:"演示会话已过期,请重新登录",captcha:"图形验证码",captchaPlaceholder:"输入图中的字符",captchaHint:"连续输错三次后,需要先完成图形验证码才能继续登录。",captchaImageAlt:"登录图形验证码",serverSettings:"服务器设置",serverSettingsTitle:"服务器配置",saveServerSettings:"保存设置",relayEntryTitle:"正在连接远程 Host",relayEntryDescription:"正在切换到这台 Host 的可信连接入口,完成后会自动回到登录页。",relayEntryInvalid:"当前远程访问入口参数不完整,请重新打开访问地址。",trustedEntryOnlyTitle:"请通过远程访问地址进入",trustedEntryOnlyDescription:"这个可信前端站点只负责加载连接页面,不直接承载 Host API。请重新打开设备的远程访问地址。",trustedEntryOnlyHintTitle:"如何进入",trustedEntryOnlyHint:"请使用类似 https://xxxx.channel.codingns.com:1443 的远程访问地址进入;四级域名会自动把你带到正确的连接入口。"},plugins:{listTitle:"插件",listDescription:"这里统一查看当前工作区可用的插件,并决定要不要继续打开或停用。",loading:"正在读取插件列表…",listLoadFailed:"插件列表加载失败。",emptyTitle:"当前还没有可用插件",emptyDescription:"等 Host 扫描到合法插件后,这里会自动出现。",enabled:"已启用",disabled:"已停用",frontendTag:"前端",backendTag:"动作",detailLoadFailed:"插件详情加载失败。",detailMissingTitle:"没找到这个插件",detailMissingDescription:"可能是插件目录被移除了,或者当前 Host 还没重新扫描到它。",backToList:"返回插件列表",backToDetail:"返回插件详情",summaryTitle:"基本信息",summaryDescription:"先确认这个插件是谁、装在哪里、现在能不能用。",pluginIdLabel:"插件标识",installRootLabel:"安装目录",runtimeLabel:"运行方式",frontendOnly:"只有前端页面,没有后端动作",permissionTitle:"权限边界",permissionDescription:"这里只显示插件明确声明过的权限。没声明的能力默认不放开。",workspaceReadAllowed:"可读取当前工作区",workspaceReadDenied:"未声明工作区读取权限",networkAllowed:"允许联网",networkDenied:"默认不联网",noDesktopPermission:"没有桌面权限",actionTitle:"可调用动作",actionDescription:"这些动作都走统一插件网关,不会私长命令入口。",runHistoryTitle:"最近运行记录",runHistoryDescription:"这里先看最近 10 条,方便排查动作有没有跑起来。",runHistoryEmptyTitle:"还没有运行记录",runHistoryEmptyDescription:"等你第一次运行插件动作后,这里会出现正式记录。",unknownAction:"未知动作",openPlugin:"打开插件",enableAction:"启用插件",disableAction:"停用插件",permissionNameReadFile:"读取文件",permissionNameListDirectory:"查看目录内容",permissionNameWriteFile:"写入文件",permissionNameOpenFile:"在桌面里打开文件",permissionNameRevealInFileManager:"在文件管理器里显示文件",permissionScopeWorkspace:"整个当前工作区",permissionScopeDirectory:"目录:{scopePath}",permissionScopeFile:"文件:{scopePath}",permissionScopeUnknown:"目标范围未明确",permissionGrantModeOnce:"仅这一次",permissionGrantModeSession:"本次打开期间",permissionGrantModePersistent:"长期保留",permissionPromptTitle:"插件需要你先授权",permissionPromptDescription:"先确认这次要放开什么能力,再决定给多久、放到哪里为止。",permissionPromptSummaryTitle:"这次申请什么权限",permissionPromptSummaryDescription:"{pluginName} 这次请求了受控能力,没点同意前不会继续执行。",permissionPromptPermissionLabel:"申请能力",permissionPromptTargetLabel:"作用范围",permissionPromptPendingTag:"待你确认",permissionPromptOptionsTitle:"你可以怎么放权",permissionPromptOptionsDescription:"先给最小范围,别一上来就放大。",permissionPromptOptionOnce:"只放行这一个目标",permissionPromptOptionOnceDescription:"只允许这次请求继续,后面再用时还会重新问你。",permissionPromptOptionSession:"当前打开期间都允许",permissionPromptOptionSessionDescription:"只在这次插件页面打开期间有效,关掉后自动失效。",permissionPromptOptionDirectory:"长期允许这个目录",permissionPromptOptionDirectoryDescription:"后续访问 {scopePath} 和它下面的内容时,不用每次再确认。",permissionPromptDenyAction:"先不授权",permissionPromptNoOptionTitle:"这次没有可用授权方式",permissionPromptNoOptionDescription:"当前请求缺少可放权范围,先返回插件详情再看。",grantedPermissionTitle:"当前工作区已授权内容",grantedPermissionDescription:"这里只看这个工作区已经放开的能力,方便你随时收回。",grantedPermissionEmptyTitle:"当前还没有授权记录",grantedPermissionEmptyDescription:"等插件第一次申请并被你同意后,这里会出现正式授权记录。",permissionGrantLoading:"正在读取授权记录…",permissionGrantLoadFailed:"插件授权记录加载失败。",revokeGrantAction:"撤销授权",revokeGrantSuccess:"插件授权已撤销。",revokeGrantFailed:"撤销插件授权失败。",permissionAuditTitle:"最近授权相关记录",permissionAuditDescription:"这里会记录授权、拒绝和撤销,方便回头排查是谁放开的。",permissionAuditEmptyTitle:"还没有授权相关记录",permissionAuditEmptyDescription:"等出现授权、拒绝或撤销后,这里会自动显示。",permissionEventGranted:"已授权:{permission}",permissionEventRevoked:"已撤销:{permission}",permissionEventDenied:"已拒绝:{permission}",permissionEventUnknown:"未知权限",permissionEventReasonDeclarationMissing:"插件没声明,直接拒绝",permissionEventReasonGrantRequired:"需要你先授权",enableSuccess:"插件已启用。",disableSuccess:"插件已停用。",saveFailed:"插件状态保存失败。",disabledByUserReason:"由用户在插件详情页停用",containerDescription:"插件前端运行在独立容器里,不会直接拿到宿主桌面桥。",containerLoadFailed:"插件运行页加载失败。",containerMissingTitle:"当前插件没有可运行页面",containerMissingDescription:"这个插件可能只有后端动作,或者已经被停用。"},settings:{title:"设置",appearance:"外观",appearanceSectionSummary:"语言、主题与界面配色",language:"语言",languageDescription:"选择界面显示语言,切换后立即应用到当前页面。",theme:"主题",themeDescription:"选择适合你的界面配色方案",autoTheme:"自动跟随系统主题",autoThemeDescription:"开启后根据系统或浏览器的深浅色偏好自动切换日间和夜间模式。",fileManager:"文件管理",workspaceSessionSortMode:"工作区的会话显示排序方式",teableEntryTitle:"Teable 表单",teableEntryDescription:"统一管理 Teable 连接,以及 CodingNS 数据同步到 Teable 表的方式。",teableOpenSettingsAction:"打开设置",teableModalTitle:"Teable 表单设置",teableModalDescription:"这里统一管理 Teable 连接、需要同步的表,以及 CodingNS 数据和 Teable 字段的对应关系。",teableTabConnection:"连接",teableTabForms:"表单",teableTabMirrors:"镜像",teableTabFieldMappings:"字段映射",teableTabConnectionSettings:"连接设置",teableTabFormSettings:"表单设置",teableTabTableSyncSettings:"表同步设置",teableTabSyncLogs:"同步日志",teableTestConnectionAction:"测试连接",teableConnectionTestSuccess:"连接可用,已读取 {tableCount} 张表。",teableLoadFailed:"Teable 设置加载失败。",teableStatusUnknown:"暂未读取到状态",teableStatusIdleHint:"还没有发起过镜像同步。",teableStatusBindingLabel:"连接状态",teableStatusSourceLabel:"已开启数据源",teableStatusSourceDetail:"当前有 {count} 类数据会推送到 Teable。",teableStatusMirrorLabel:"镜像表",teableStatusMirrorDetail:"当前已经记录 {count} 张镜像表绑定。",teableStatusTaskLabel:"最近同步",teableBindingSectionTitle:"连接设置",teableBindingSectionDescription:"先把 Teable 站点、空间、Base 和访问 Token 填对,再决定是否启用。",teableEnabledLabel:"启用 Teable 同步",teableBaseUrlLabel:"Teable 站点地址",teableBaseUrlDescription:"支持 http:// 和 https://。如果 Teable 跟 Host 在同一局域网,可以直接填 http 地址。",teableBaseUrlPlaceholder:"例如:http://192.168.1.20:3000",teableSpaceIdLabel:"Space ID",teableSpaceIdPlaceholder:"填写要绑定的 Space ID",teableBaseIdLabel:"Base ID",teableBaseIdPlaceholder:"填写目标 Base ID",teableAuthRefLabel:"认证引用",teableAuthRefPlaceholder:"例如:secret://teable/main",teableAuthTokenLabel:"访问 Token",teableAuthTokenDescription:"如果已经在 Host 里保存过 token,这里可以留空不改。",teableAuthTokenPlaceholder:"留空表示继续使用已保存 token",teableMirrorModeLabel:"同步方式",teableBindingSaved:"Teable 连接设置已保存。",teableSyncConfigSectionTitle:"工作台推送范围",teableSyncConfigSectionDescription:"这里决定标签、会话和代办哪些会同步到 Teable,以及各自落到哪张表。",teableSyncEnabledLabel:"允许同步这一类数据",teableTargetTableLabel:"目标表",teableTargetTablePlaceholder:"请选择 Teable 已有表",teableTagRootsLabel:"同步哪些标签树",teableSessionScopeModeLabel:"会话同步范围",teableSessionScopeAll:"同步全部工作区会话",teableSessionScopeSelected:"只同步选中的工作区会话",teableWorkspaceMultiSelectLabel:"选择工作区",teableTodoSourceLabel:"代办来源",teableTodoWorkspaceSource:"同步工作区代办",teableTodoAffairsSource:"同步事务代办",teableTodoWorkspaceHint:"如果这里选了工作区,只同步这些工作区里的代办;留空表示不按工作区额外筛选。",teableTargetTableIdLabel:"目标表 ID",teableTargetTableHint:"不填时,Host 会按默认镜像表名自动创建。",teableTargetTableBoundHint:"当前已经绑定到表“{table}”。",teableTargetTableIdPlaceholder:"可选,填已有表 ID 直接复用",teableScopeJsonLabel:"同步范围(JSON)",teableScopeJsonPlaceholder:"这里填这一类数据的同步范围 JSON。",teableScopeJsonInvalid:"同步范围必须是合法 JSON 对象。",teableSyncConfigSaved:"Teable 推送范围已保存。",teableFormsCatalogTitle:"Teable 已有表单",teableFormsCatalogDescription:"这里列出 Teable 里已经存在的表单视图。",teableFormsCatalogEmptyTitle:"还没有可用表单",teableFormsCatalogEmptyDescription:"先到 Teable 里创建表单视图。",teableFormSettingsLeftTitle:"已废弃的表单设置",teableFormSettingsLeftDescription:"设置页不再按表单配置同步,镜像同步只按 Teable 表配置。",teableFormMappingPanelTitle:"已废弃的同步内容设置",teableFormMappingPanelDescription:"设置页不再按表单配置同步,镜像同步只按 Teable 表配置。",teableAddSyncFormAction:"添加同步表单",teableRemoveSyncFormAction:"移除",teableSyncFormAddedTag:"已添加",teableSyncFormAdded:"同步表单已添加。",teableSyncFormRemoved:"同步表单已移除。",teableFormShareReady:"已开启分享",teableFormShareMissing:"未开启分享",teableSelectSyncFormTitle:"先选择一个表单",teableSelectSyncFormDescription:"左侧选择 Teable 表单后,这里会显示同步内容、工作区范围和字段映射。",teableSelectedFormLabel:"当前表单",teableSyncSourceLabel:"同步的信息",teableSyncSource:{sessions:"会话记录",todos:"代办",tags:"文档库标签"},teableWorkspaceScopeLabel:"工作区范围",teableWorkspaceScopeAll:"全部工作区",teableWorkspaceScopeSelected:"指定工作区",teableWorkspaceScopeEmpty:"还没有可选工作区。",teableDocumentTagRootsLabel:"文档库根标签",teableDocumentTagRootsDescription:"只同步选中根标签及其所有子标签;这不是工作区表单绑定。",teableDocumentTagRootsEmpty:"还没有可选的文档库根标签。",teableFieldMappingTitle:"字段映射",teableFieldMappingInlineDescription:"左边是 CodingNS 字段,右边选择 Teable 表里的目标字段。",teableSourceFieldsEmpty:"当前同步内容没有可映射字段。",teableSaveFormSyncSettingsAction:"保存表同步设置",teableFormSyncSettingsSaved:"表同步设置已保存。",teableTableSyncAvailableTitle:"Teable 表目录",teableTableSyncAvailableDescription:"这里不列出表单,只选择当前 Base 下已有的表。选中一张表后点添加,它会进入左侧同步表列表。",teableTableSyncListTitle:"同步表列表",teableTableSyncListDescription:"这里显示已经添加为镜像同步目标的表。选中一张表后,在右侧配置同步内容、范围和字段映射。",teableTableSyncConfigTitle:"当前表配置",teableTableSyncConfigDescription:"这里只配置左侧选中的同步表,不再堆积同步表记录。",teableTableToAddLabel:"选择要添加的表",teableAllTablesAdded:"所有表都已添加",teableAddSyncTableAction:"添加同步表",teableRemoveSyncTableAction:"移除",teableSyncTableAddedTag:"已添加",teableSelectSyncTableTitle:"先添加一张同步表",teableSelectSyncTableDescription:"从左侧 Teable 表目录里添加表后,这里会显示同步内容、工作区范围和字段映射。",teableSelectedSyncTableLabel:"当前同步表",teableTableAssignedDescription:"已配置为同步 {source}",teableTableUnassignedDescription:"还没有配置同步内容",teableSaveTableSyncSettingsAction:"保存表同步设置",teableTableSyncSettingsSaved:"表同步设置已保存。",teableFieldAutoCreateAction:"添加字段并自动映射",teableFieldAutoCreateModalTitle:"添加 Teable 字段",teableFieldAutoCreateModalDescription:"选择要添加到当前 Teable 表的 CodingNS 字段。",teableFieldAutoCreateModalSectionTitle:"选择字段",teableFieldAutoCreateModalSectionDescription:"这些字段会添加到“{table}”,并自动写入字段映射。已经存在同名字段时会直接复用。",teableFieldAutoCreateConfirmAction:"添加并自动映射",teableFieldAutoCreateSuccess:"已添加并映射 {count} 个字段。",teableFieldAutoCreateEmptyError:"请先选择要添加的字段。",teableFieldAlreadyMappedDescription:"已映射到“{field}”。",teableTablesCatalogTitle:"Teable 已有表",teableTablesCatalogDescription:"这里列出当前 Base 下已有的表,方便你给镜像同步和字段映射选目标表。",teableTablesCatalogEmptyTitle:"当前 Base 里还没有可用表",teableTablesCatalogEmptyDescription:"先到 Teable 里创建表,再回来配置同步。",teableTableInspectAction:"查看表结构",teableTableCollapseAction:"收起详情",teableTableFieldsLabel:"当前表字段",teableTableFieldsEmpty:"这张表暂时还没有字段。",teableTableFormViewsLabel:"这张表下的表单视图",teableTableFormViewsEmpty:"这张表当前还没有表单视图。",teableTableFormReadyTag:"可用于工作台",teableTableFormShareMissingTag:"未开启分享",teableTableFormCountTag:"{count} 个表单",teableTableFieldCountPending:"字段数待读取",teableTableFieldCountValue:"{count} 个字段",teableTableFormCountValue:"{count} 个表单视图",teableTablesUsageTitle:"这里主要做什么",teableTablesUsageDescription:"设置页负责配同步和字段映射;工作台里的 Teable 块才负责显示表单。",teableTablesUsageMirrorTitle:"同步配置看表",teableTablesUsageMirrorDescription:"标签、会话、代办同步到哪张 Teable 表,都是在这里按表来配。",teableTablesUsageFormTitle:"工作台块看表单",teableTablesUsageFormDescription:"真正要显示给用户填写的表单,会在工作台画布里的 Teable 块中选择。",teableSyncActionSectionTitle:"同步状态与操作",teableSyncActionSectionDescription:"这里看最近一次任务结果,也可以手动重新发起镜像同步。",teableLatestTaskTitle:"最近一次镜像同步",teableLatestTaskEmpty:"还没有镜像同步记录。",teableSyncLogsTitle:"同步日志",teableSyncLogsDescription:"这里记录手动同步和本地变化触发的同步任务,方便确认数据是否已经推送到 Teable。",teableSyncLogsRefreshAction:"刷新日志",teableSyncLogsEmptyTitle:"还没有同步日志",teableSyncLogsEmptyDescription:"手动同步或本地数据变化触发同步后,这里会显示记录。",teableSyncLogDescription:"{trigger} · {source} · {time}",teableSyncLogCounts:"新增 {created},更新 {updated},删除 {deleted},跳过 {skipped}",teableSyncLogTrigger:{manual:"手动触发",local_change:"本地变化",retry:"重试"},teableFieldMappingSectionTitle:"字段映射",teableFieldMappingSectionDescription:"把 CodingNS 的源字段手动对应到 Teable 目标表字段。同步时只会按这里的关系写入。",teableFieldMappingTargetMissingTitle:"先给这一类数据选择目标表",teableFieldMappingTargetMissingDescription:"先在“镜像”标签页为这类数据指定目标表,再回来做字段映射。",teableFieldMappingSaveAction:"保存字段映射",teableFieldMappingSaved:"字段映射已保存。",teableFieldTargetPlaceholder:"请选择目标字段",teableFieldRequired:"必填",teableFieldOptional:"可选",teableMirrorBindingReady:"镜像表已绑定到“{table}”。",teableMirrorBindingMissing:"这类数据还没有生成镜像表。",teableMirrorBindingReadyTag:"已绑定",teableMirrorBindingPendingTag:"待创建",teableRefreshAction:"刷新状态",teableSaveBindingAction:"保存连接",teableSaveSyncConfigAction:"保存推送范围",teableSyncNowAction:"立即同步",teableBindingStatus:{unbound:"未绑定",ready:"已就绪",disabled:"已关闭",config_invalid:"配置不完整"},teableTaskState:{idle:"未开始",queued:"排队中",running:"同步中",succeeded:"已完成",partial_failed:"部分失败",failed:"失败"},teableMirrorMode:{manual:"手动触发",scheduled:"定时同步(暂未开放)",event_driven:"本地变化自动同步"},teableSource:{tags:{title:"标签镜像",description:"把事务标签同步成 Teable 镜像表,给业务表单做 Link / Lookup 引用。",scopeHint:"例如 includePaths、手动筛选路径。当前后端先保存配置,不在这一轮强解释。"},sessions:{title:"会话镜像",description:"把事务会话摘要同步到 Teable,方便表单引用最近会话和上下文。",scopeHint:"例如 recent / limit 这类范围控制。当前后端先保存配置,不在这一轮强解释。"},todos:{title:"代办镜像",description:"把工作台代办同步到 Teable,方便表单直接引用当前任务。",scopeHint:"例如 open_only、状态筛选。当前后端先保存配置,不在这一轮强解释。"}},pluginManagement:"插件管理",pluginManagementDescription:"统一查看当前 Host 已扫描到的插件,并决定是否启用、停用或继续打开插件页面。",pluginManagementAction:"管理插件",pluginManagementModalTitle:"插件管理",pluginManagementModalDescription:"这里集中查看插件状态、权限边界和最近运行记录,不需要再手动拼路由。",pluginManagementModalListTitle:"插件列表",pluginManagementModalListDescription:"先选一个插件,再看它现在的状态和最近运行情况。",pluginManagementModalDetailTitle:"插件详情",pluginManagementModalDetailDescription:"这里只展示已经通过 Host 正式注册的插件信息和运行记录。",pluginManagementSelectPluginTitle:"先选一个插件",pluginManagementSelectPluginDescription:"左边选中插件后,这里会显示它的权限、动作和最近运行记录。",pluginManagementWorkspaceRequired:"只有绑定到当前工作区后,才能继续打开插件前端页面。",workspaceSessionSortModeDescription:"控制工作区里各处会话列表的默认排序,只影响当前设备。",sessionSortModeCreatedAt:"按照会话创建时间",sessionSortModeUpdatedAt:"按照会话更新时间",sessionSortModeTitle:"按照会话名称",showSystemFiles:"显示系统文件",showSystemFilesDescription:"在文件管理里显示 macOS 和 Windows 常见的系统文件,例如 .DS_Store、Thumbs.db。这个开关只影响当前设备。",serverConnection:"服务器连接",serverConnectionSectionSummary:"服务器地址与连接恢复策略",remoteAccess:"远程访问",remoteAccessSectionSummary:"通过 CodingNS Connect 或 Tailscale,从外部设备连接这台 Host。",remoteAccessNavValue:"CodingNS Connect / Tailscale",remoteAccessManageTitle:"远程访问方式",remoteAccessManageDescription:"需要从外部访问这台 Host 时,在这里选择并配置连接方式。",remoteAccessManageAction:"管理远程访问",remoteAccessModalTitle:"访问方式管理",remoteAccessModalDescription:"选择并配置你要使用的远程访问方式。",remoteAccessTabsLabel:"远程访问方式标签",remoteAccessTunnelTab:"CodingNS Connect",remoteAccessTailscaleTab:"Tailscale接入",remoteAccessFeatureDisabledValue:"未开启",abilityManagement:"能力管理",abilityManagementSectionSummary:"统一管理 CLI 提供方的启用状态,以及模型配置文件的快速切换入口。",abilityManagementNavValue:"提供方 / 配置文件",modelManagement:"模型管理",modelManagementNavValue:"快速切换",modelManagementSectionTitle:"模型配置文件管理",providerManagement:"CLI 提供方",providerManagementSectionSummary:"控制哪些 CLI 会出现在会话、Fork、助手和 Skill 入口里。",providerManagementNavValue:"启用控制",providerManagementDescription:"统一控制这台 Host 当前允许使用的 CLI。能力矩阵、状态和启用开关都放在弹窗里查看和修改。",providerManagementManageAction:"管理 CLI 提供方",providerManagementModalTitle:"CLI 提供方管理",providerManagementModalDescription:"查看每个 CLI 在项目里的能力、当前状态,以及是否继续对外显示。",providerManagementRefresh:"刷新列表",providerManagementRefreshSuccess:"CLI 提供方列表已刷新。",providerManagementLoading:"正在读取可管理的 CLI 提供方...",providerManagementEmpty:"当前还没有可管理的 CLI 提供方。",providerManagementEmptyDescription:"等 Host 注册出可用的 CLI 提供方后,这里会自动出现。",providerManagementLoginRequired:"登录后才能管理 CLI 提供方。",providerManagementLoadFailed:"CLI 提供方列表加载失败。",providerManagementSaveFailed:"CLI 提供方状态保存失败。",providerManagementSummaryTitle:"提供方概况",providerManagementSummaryDescription:"这里先看总量,再决定要不要禁用某个 CLI。",providerManagementSummaryEnabled:"已启用",providerManagementSummaryDisabled:"已禁用",providerManagementSummaryTotal:"总数",providerManagementMatrixTitle:"能力矩阵",providerManagementMatrixDescription:"纵向是 CLI 提供方,横向是产品能力。关闭某个提供方后,它会从项目里的相关入口整体消失。",providerManagementTableProvider:"CLI 提供方",providerManagementTableStatus:"状态",providerManagementTableEnabled:"启用",providerManagementStatusEnabled:"已启用",providerManagementStatusDisabled:"已禁用",providerManagementInstallReady:"已安装",providerManagementInstallMissing:"未检测到",providerManagementInstallUnknown:"状态未知",providerManagementStateEnabled:"当前会出现在新的会话、Fork、助手和 Skill 相关入口里。",providerManagementStateDisabled:"当前已经从新的会话入口里隐藏,旧会话也会从正常列表里收起。",providerManagementStateMissing:"已经允许显示,但本地 CLI 还没准备好,等安装完成后才会真正可用。",providerManagementToggleLabel:"切换 {provider} 的启用状态",providerManagementEnableSuccess:"{provider} 已重新启用。",providerManagementDisableSuccess:"{provider} 已禁用。",providerManagementCapabilityStreaming:"流式输出",providerManagementCapabilityToolCalls:"工具调用",providerManagementCapabilityAssistant:"助手服务",providerManagementCapabilityFork:"会话 Fork",providerManagementCapabilitySkill:"Skill 使用",providerManagementCapabilityAvailable:"可用",providerManagementCapabilityUnavailable:"不可用",providerManagementImpactSessionStart:"新会话启动",providerManagementImpactFork:"会话 Fork",providerManagementImpactAssistant:"助手跟进",providerManagementImpactSkill:"Skill 新目标",providerManagementImpactEnabled:"如果现在关掉,会隐藏旧会话,并阻止 {actions}。",providerManagementImpactDisabled:"当前已经阻止 {actions};重新打开后,这些入口会重新出现。",providerManagementImpactEnabledFallback:"如果现在关掉,这个 CLI 会从项目里的新入口中一起消失。",providerManagementImpactDisabledFallback:"重新打开后,这个 CLI 会重新回到项目里的正常入口中。",channelsManagement:"通讯平台",channelsManagementSectionSummary:"统一管理外部通讯渠道、轮询账号和最近的收发流水。",channelsManagementNavValue:"账号 / 流水",channelsManagementDescription:"在这里管理通讯账号,并查看最近的消息和发送记录。",channelsManageAction:"管理通讯账号",channelsModalTitle:"通讯平台账号管理",channelsAddAccountAction:"添加通讯账号",channelsModalDescription:"先用统一账号模型接入外部通讯平台。第一阶段先把文本消息、固定 provider、polling 和 Butler control session 的映射链路接好。",channelsActionPending:"处理中...",channelsRefresh:"刷新数据",channelsRefreshSuccess:"通讯平台数据已刷新。",channelsLoading:"正在读取通讯平台配置...",channelsLoadingDetails:"正在读取最近的线程和消息...",channelsLoadFailed:"通讯平台列表加载失败。",channelsLoadDetailsFailed:"最近线程和消息加载失败。",channelsSaveFailed:"通讯账号保存失败。",channelsProbeFailed:"账号探活失败。",channelsPollFailed:"手动轮询失败。",channelsRemoveFailed:"通讯账号移除失败。",channelsCreateSuccess:"{account} 已创建。",channelsUpdateSuccess:"{account} 已保存。",channelsRemoveSuccess:"已移除通讯账号“{account}”。",channelsSelectAccountFirst:"请先选择一个已有账号,或者直接新建账号。",channelsSummaryTitle:"通讯平台概况",channelsSummaryAccounts:"账号数",channelsSummaryActive:"正常账号",channelsSummaryPlatforms:"已用平台",channelsWizardTitle:"配置向导",channelsWizardCreateDescription:"先选通讯渠道,再填这个渠道自己的配置,最后把账号绑定到固定的助手引擎。",channelsWizardEditDescription:"当前正在编辑已有账号。平台不在这里切换,改助手引擎只影响新会话,旧会话继续保留原上下文。",channelsWizardStepsTitle:"通讯账号配置步骤",channelsWizardStepPlatform:"选择渠道",channelsWizardStepConfig:"填写渠道配置",channelsWizardStepBinding:"绑定账号",channelsWizardNextToConfig:"继续填写配置",channelsWizardNextToBinding:"继续绑定账号",channelsWizardBackToPlatform:"返回选渠道",channelsWizardBackToConfig:"返回渠道配置",channelsWizardSelectPlatformHint:"先从上面选一个通讯渠道,下面才会出现对应的专用表单。",channelsWizardBindingSummary:"多会话支持",channelsPlatformsTitle:"平台能力清单",channelsPlatformsDescription:"这里按渠道卡片展示第一阶段的 polling 口径、多会话支持情况和当前限制。",channelsPlatformsEmpty:"当前没有可展示的平台能力。",channelsPlatformsEmptyDescription:"等 Host 注册出平台目录后,这里会自动显示。",channelsPlatformSummary:"接入方式:{modes};多会话:{multiSession}",channelsAccountsTitle:"通讯账号",channelsAccountsDescription:"每个账号固定绑定一个助手引擎,并固定走 polling。新会话按账号配置启动,旧会话继续保留原上下文。",channelsAccountsEmpty:"还没有通讯账号。",channelsAccountsEmptyDescription:"先添加一个通讯账号,后面收到消息后这里会开始积累线程和流水。",channelsAccountRowDescription:"{platform} · {provider} · {mode}",channelsCreateAction:"新建账号",channelsSaveAction:"保存账号",channelsResetToCreate:"切到新建",channelsCreateFormTitle:"新建通讯账号",channelsCreateFormDescription:"先把统一字段建出来。平台差异先放进补充配置 JSON,避免第一阶段表单失控。",channelsEditFormTitle:"编辑通讯账号",channelsEditFormDescription:"改 provider 后只会影响新会话,旧会话仍保留原上下文。",channelsFieldDisplayName:"账号显示名",channelsFieldDisplayNamePlaceholder:"例如:飞书值班号",channelsFieldPlatform:"通讯平台",channelsFieldPlatformDescription:"先选平台,再决定接入方式和补充配置。",channelsFieldProvider:"助手引擎",channelsFieldProviderDescription:"第一阶段只允许固定成 Codex 或 Claude Code,不能在同一外部线程里临时切换。",channelsFieldConnectionMode:"接入方式",channelsFieldConnectionModeDescription:"第一阶段六个平台统一按 polling 接入,不在这里切换别的模式。",channelsFieldStatus:"账号状态",channelsFieldStatusDescription:"先用正常、停用、异常降级这三个状态管理账号可用性。",channelsFieldConfig:"平台补充配置(JSON)",channelsFieldConfigDescription:"这里放当前表单里没覆盖到的补充字段。专用表单优先,补充 JSON 只做兜底。",channelsAdvancedConfigTitle:"补充字段(高级)",channelsAdvancedConfigDescription:"只有当前表单没覆盖的字段才放这里,例如回发地址、临时开关或实验参数。",channelsValidationDisplayName:"请先填写账号显示名。",channelsValidationPlatform:"请先选择通讯平台。",channelsValidationConnectionMode:"请先选择接入方式。",channelsValidationConfigJson:"补充配置不是合法 JSON。",channelsValidationConfigObject:"补充配置必须是 JSON 对象。",channelsValidationRequiredField:"请先填写“{field}”。",channelsValidationFeishuCredential:"飞书最少还要补一组凭证:直接填 Tenant Access Token,或者同时填 App ID 和 App Secret。",channelsConfigWechatUnavailableTitle:"个人微信(claw)不需要手填协议参数",channelsConfigWechatUnavailableDescription:"这个通道的扫码、登录态、轮询和回发都交给 Host helper 处理,这一步不用再手填私有协议参数。",channelsDetailTitle:"当前账号概况",channelsDetailDescription:"这里先看当前账号的接入状态、最近收发时间和是否需要人工补查。",channelsDetailPlatform:"平台",channelsDetailProvider:"助手引擎",channelsDetailConnectionMode:"接入方式",channelsDetailStatus:"账号状态",channelsDetailLastInbound:"最近入站",channelsDetailLastOutbound:"最近回发",channelsDetailLastError:"最近错误",channelsProbeAction:"检查连通性",channelsPollAction:"手动轮询",channelsRemoveAction:"移除账号",channelsRemoveConfirmAction:"确认移除",channelsRemoveConfirmDescription:"移除后会同时清理这个账号下的线程映射、入站消息和回发记录。这个操作不能撤回。",channelsWebhookHint:"这个账号是 webhook 模式,不需要手动轮询。",channelsConnectionModeFixedHint:"当前阶段固定按 polling 建模;如果以后换模式,会单独升级账号配置规则。",channelsThreadsTitle:"线程映射",channelsThreadsDescription:"最近 {count} 条线程映射,按 external conversation key 关联到 Butler control session。",channelsThreadsEmpty:"还没有线程映射。",channelsThreadsEmptyDescription:"收到第一条外部消息后,这里会自动出现。",channelsEventsTitle:"入站消息",channelsEventsDescription:"最近 {count} 条入站消息,方便排查消息是否被 Host 接住并成功分发。",channelsEventsEmpty:"还没有入站消息。",channelsEventsEmptyDescription:"等渠道开始真正拉到文本消息后,这里会出现记录。",channelsDeliveriesTitle:"回发记录",channelsDeliveriesDescription:"最近 {count} 条回发记录,用来确认 Butler 首条文本有没有成功送回外部平台。",channelsDeliveriesEmpty:"还没有回发记录。",channelsDeliveriesEmptyDescription:"当 Butler 产出首条文本并触发回发后,这里才会有记录。",channelsConnectionModeWebhook:"Webhook",channelsConnectionModePolling:"Polling",channelsConnectionModeBridge:"Bridge",channelsMultiSessionSupported:"支持多会话",channelsMultiSessionLimited:"有限支持",channelsStatusActive:"正常",channelsStatusDisabled:"已停用",channelsStatusDegraded:"异常降级",channelsThreadStatusActive:"活跃",channelsThreadStatusClosed:"已关闭",channelsThreadStatusFailed:"失败",channelsEventStatusReceived:"已接收",channelsEventStatusDispatched:"已分发",channelsEventStatusReplied:"已回复",channelsEventStatusFailed:"失败",channelsEventStatusIgnored:"已忽略",channelsDeliveryStatusSent:"已发出",channelsDeliveryStatusFailed:"失败",channelsDeliveryStatusSkipped:"已跳过",channelsThreadSummary:"{status} · 会话键:{conversationKey}",channelsEventSummary:"{status} · 会话键:{conversationKey}",channelsDeliverySummary:"{status} · 最近一条回发文本",channelsMetaCreatedAt:"创建时间",channelsMetaUpdatedAt:"更新时间",channelsMetaReceivedAt:"接收时间",channelsMetaExternalUser:"外部用户",channelsMetaEventId:"外部事件",channelsMetaProviderRef:"平台回执",channelsMetaError:"错误",channelsTextFallback:"空文本",channelsTimeUnknown:"暂无",channelsWechatBindingTitle:"微信绑定",channelsWechatBindingDescription:"这个账号会通过 Host 托管的 helper 完成扫码登录、轮询收信和消息回发。",channelsWechatBoundDescription:"微信账号已经绑定成功。现在可以继续做探活、手动轮询和后续会话桥接。",channelsWechatCreateDescription:"先给这个微信账号起个名字。创建完成后,下一步就在详情区生成二维码并扫码绑定。",channelsWechatRuntimeRequiredTitle:"当前还不能直接绑定个人微信",channelsWechatRuntimeRequiredDescription:"当前环境没有启用微信 helper,所以这里只能看到账号基础信息。启用 helper 后,这里会切回真实扫码绑定。",channelsWechatPendingTitle:"这个账号还没完成绑定",channelsWechatPendingDescription:"先完成扫码绑定,绑定成功后才会出现轮询、回发和最近记录。",channelsWechatBeginBindingAction:"开始绑定",channelsWechatContinueBindingAction:"继续绑定",channelsWechatStartLoginAction:"生成二维码",channelsWechatRestartBindingAction:"重新生成二维码",channelsWechatRefreshLoginAction:"刷新绑定状态",channelsWechatLogoutAction:"清除绑定",channelsWechatBindingModalTitle:"扫描二维码绑定微信",channelsWechatBindingModalDescription:"请用微信扫描下面的二维码。扫码后回到这里,点“刷新绑定状态”。",channelsWechatBindingModeValue:"扫码绑定",channelsWechatLoginStatus:"绑定状态",channelsWechatLoginStatusNotLoggedIn:"未绑定",channelsWechatLoginStatusWaitingScan:"等待扫码",channelsWechatLoginStatusScanConfirmed:"已扫码,待确认",channelsWechatLoginStatusActive:"已绑定",channelsWechatLoginStatusExpired:"二维码已过期",channelsWechatQrHint:"扫码成功后,点“刷新绑定状态”同步结果。",channelsWechatQrAlt:"个人微信绑定二维码",channelsWechatOpenQrLinkAction:"打开绑定二维码",channelsWechatQrRawTitle:"查看二维码原始内容",channelsWechatQrRawDescription:"上游返回的原始二维码内容会先保存在这里,方便排查扫码链路。",channelsWechatQrEmpty:"还没有绑定二维码",channelsWechatQrEmptyDescription:"先点上面的“生成二维码”,再用微信扫码完成绑定。",channelsConfigFieldDingtalkAppKey:"钉钉 AppKey",channelsConfigFieldDingtalkAppKeyDescription:"后续接真实拉取接口时,会用这个字段识别钉钉应用。",channelsConfigFieldDingtalkAppKeyPlaceholder:"填写钉钉应用 AppKey",channelsConfigFieldDingtalkAppSecret:"钉钉 AppSecret",channelsConfigFieldDingtalkAppSecretDescription:"建议只填正式值班账号的密钥,避免把测试凭证混进生产轮询账号。",channelsConfigFieldDingtalkAppSecretPlaceholder:"填写钉钉应用 AppSecret",channelsConfigFieldDingtalkRobotCode:"机器人编码",channelsConfigFieldDingtalkRobotCodeDescription:"如果后续消息要回发到固定机器人,可以先把机器人编码记在这里。",channelsConfigFieldDingtalkRobotCodePlaceholder:"例如:dingxxxxxxxx",channelsConfigFieldFeishuAppId:"飞书 App ID",channelsConfigFieldFeishuAppIdDescription:"如果你不打算直接填 Tenant Access Token,这里要和 App Secret 一起填写。",channelsConfigFieldFeishuAppIdPlaceholder:"填写飞书应用 App ID",channelsConfigFieldFeishuAppSecret:"飞书 App Secret",channelsConfigFieldFeishuAppSecretDescription:"如果你不打算直接填 Tenant Access Token,这里要和 App ID 一起填写。",channelsConfigFieldFeishuAppSecretPlaceholder:"填写飞书应用 App Secret",channelsConfigFieldFeishuTenantAccessToken:"Tenant Access Token",channelsConfigFieldFeishuTenantAccessTokenDescription:"如果你已经能稳定拿到 tenant_access_token,直接填这里就行,不用再强制填 App ID 和 App Secret。",channelsConfigFieldFeishuTenantAccessTokenPlaceholder:"填写飞书 tenant_access_token",channelsConfigFieldFeishuChatId:"目标会话 Chat ID",channelsConfigFieldFeishuChatIdDescription:"必填。第一阶段先固定一个群或会话,Host 才知道去哪里拉消息和回发文本。",channelsConfigFieldFeishuChatIdPlaceholder:"例如:oc_xxx 或 chat_xxx",channelsConfigFieldWechatBaseUrl:"claw 服务地址",channelsConfigFieldWechatBaseUrlDescription:"Host 会通过这个地址去拉取消息和发送回复。这里必须能从 Host 所在机器访问到。",channelsConfigFieldWechatBaseUrlPlaceholder:"例如:http://127.0.0.1:8787",channelsConfigFieldWechatBridgeToken:"claw 访问令牌",channelsConfigFieldWechatBridgeTokenDescription:"如果你的 claw transport 有访问令牌,这里填进去做最基本的校验。",channelsConfigFieldWechatBridgeTokenPlaceholder:"填写 claw transport token",channelsConfigFieldWechatPollPath:"拉取路径",channelsConfigFieldWechatPollPathDescription:"默认会用 `/poll`。如果你的 transport 路径不同,可以在这里改。",channelsConfigFieldWechatPollPathPlaceholder:"默认 /poll",channelsConfigFieldWechatSendPath:"发送路径",channelsConfigFieldWechatSendPathDescription:"默认会用 `/send`。如果你的 transport 路径不同,可以在这里改。",channelsConfigFieldWechatSendPathPlaceholder:"默认 /send",channelsConfigFieldTelegramBotToken:"Telegram Bot Token",channelsConfigFieldTelegramBotTokenDescription:"Telegram 真实轮询和回发都要靠这个 token,没填就不能工作。",channelsConfigFieldTelegramBotTokenPlaceholder:"填写 Telegram Bot Token",channelsConfigFieldSlackBotToken:"Slack Bot Token",channelsConfigFieldSlackBotTokenDescription:"必填。Slack 轮询读消息和回发文本都靠这个 token。",channelsConfigFieldSlackBotTokenPlaceholder:"填写 Slack Bot Token",channelsConfigFieldSlackAppToken:"Slack App Token",channelsConfigFieldSlackAppTokenDescription:"当前最少可用配置不强制要它。只有你的 Slack 应用确实额外要求时再填写。",channelsConfigFieldSlackAppTokenPlaceholder:"填写 Slack App Token",channelsConfigFieldSlackChannelId:"频道 ID",channelsConfigFieldSlackChannelIdDescription:"必填。第一阶段先固定一个频道,先把轮询和文本回发链路打通。",channelsConfigFieldSlackChannelIdPlaceholder:"例如:C0123456789",channelsConfigFieldDiscordBotToken:"Discord Bot Token",channelsConfigFieldDiscordBotTokenDescription:"必填。Discord 轮询读消息和回发文本都要靠这个 bot token。",channelsConfigFieldDiscordBotTokenPlaceholder:"填写 Discord Bot Token",channelsConfigFieldDiscordApplicationId:"Application ID",channelsConfigFieldDiscordApplicationIdDescription:"当前最少可用配置不强制要它。只有你的应用权限配置确实依赖它时再填写。",channelsConfigFieldDiscordApplicationIdPlaceholder:"填写 Discord Application ID",channelsConfigFieldDiscordGuildId:"Guild ID",channelsConfigFieldDiscordGuildIdDescription:"必填。先固定一个服务器,后面的 thread 子分支会在这个服务器下工作。",channelsConfigFieldDiscordGuildIdPlaceholder:"填写 Discord Guild ID",channelsConfigFieldDiscordChannelId:"频道 ID",channelsConfigFieldDiscordChannelIdDescription:"必填。先固定一个频道,后面的 thread 子分支会挂在这个频道下面。",channelsConfigFieldDiscordChannelIdPlaceholder:"填写 Discord Channel ID",channelsConfigChecklistTitle:"这一步最少要准备什么",channelsConfigChecklistFeishuSummary:"飞书这一版先按固定会话做 polling,最少要给 Host 一个目标会话和一套可用凭证。",channelsConfigChecklistFeishuItemCredential:"凭证二选一:直接填 Tenant Access Token,或者同时填 App ID 和 App Secret。",channelsConfigChecklistFeishuItemChat:"必须填目标会话 Chat ID,不然 Host 不知道要跟哪一个群或会话对接。",channelsConfigChecklistFeishuItemScope:"先按文本消息打通,不处理图片、文件、语音和卡片。",channelsConfigChecklistSlackSummary:"Slack 这一版先固定一个频道做 polling,先把读消息和回发文本跑通。",channelsConfigChecklistSlackItemToken:"必须填 Bot Token,缺它就没法拉消息也没法发回复。",channelsConfigChecklistSlackItemChannel:"必须填频道 ID,当前账号先固定绑定到一个频道。",channelsConfigChecklistSlackItemScope:"第一阶段只处理文本消息,thread 子分支暂不在 Slack 里实现。",channelsConfigChecklistDiscordSummary:"Discord 这一版最少要固定服务器和频道,后面的 thread 子分支会落在这个范围里。",channelsConfigChecklistDiscordItemToken:"必须填 Bot Token,轮询读消息和回发文本都要靠它。",channelsConfigChecklistDiscordItemGuild:"必须填 Guild ID,先把账号固定到一个服务器。",channelsConfigChecklistDiscordItemChannel:"必须填频道 ID,后面的 thread 子分支会挂在这个频道下面。",modelManagementTitle:"模型快速切换",modelManagementDescription:"这里不新增也不编辑预设,只把 cc-switch 已有预设图形化展示出来,方便你一键切换。",modelManagementRefresh:"刷新模型",modelManagementRefreshSuccess:"模型预设列表已刷新。",modelManagementLoadFailed:"模型预设加载失败。",modelManagementScannedAt:"最近扫描",modelManagementScannedAtUnknown:"暂未扫描",modelManagementCurrentProfile:"当前配置文件",modelManagementCurrentModel:"当前模型",modelManagementCurrentPreset:"当前预设",modelManagementModelUnknown:"未识别",modelManagementPresetMissing:"未设置",modelManagementCurrentTag:"当前",modelManagementOpenSwitcher:"切换配置",modelManagementModalTitle:"供应商配置切换",modelManagementModalDescription:"这里按应用查看 cc-switch 已有配置文件,并切换当前启用项。",modelManagementTabsLabel:"模型应用标签",modelManagementSwitchAction:"切换",modelManagementSwitchSuccess:"{app} 已切换到 {preset}。",modelManagementOptionsEmpty:"当前没有可切换的预设。",modelManagementStatusReady:"可切换",modelManagementStatusUnconfigured:"未配置",modelManagementStatusUnavailable:"未安装 cc-switch-cli",modelManagementStatusError:"读取失败",skills:"Skills",skillsSectionSummary:"读取并同步各个 CLI 自己的本地 skill,不做市场,不接远端仓库。",skillsNavValue:"本地同步",skillManagerTitle:"本地 Skill 管理",skillManagerDescription:"统一读取 Codex、Claude Code、Gemini、OpenCode 的 skill 目录,支持导入未纳管项并重新同步。",skillSummaryManagedSkills:"我的技能",skillSummaryManagedEntries:"已生效",skillSummaryUnmanagedEntries:"未纳管目录",skillSummaryConflictedEntries:"待处理",skillSummaryAssistantRuntimeEntries:"助手专用目录",skillSummaryDiagnostics:"提醒",skillManageAction:"技能配置",skillConfigModalTitle:"技能配置",skillConfigModalDescription:"在这里查看你的技能、系统自带技能和需要处理的项目。",skillCreateAction:"添加技能",skillCreateModalTitle:"添加技能",skillCreateModalDescription:"把新的 SKILL.md 纳管进来。文件上传和粘贴文本都走同一套校验与纳管流程。",skillCreateSourceTabsLabel:"添加方式",skillCreateSourceFile:"选择文件",skillCreateSourcePaste:"粘贴文本",skillCreateSubmitAction:"添加",skillRefresh:"刷新",skillRefreshSuccess:"技能列表已刷新。",skillScannedAt:"最近扫描",skillUploadSectionTitle:"上传 Skill",skillUploadSectionDescription:"选择一个 SKILL.md 文件,先选它属于工作区还是助手运行时,再做基础校验和轻量纠正并纳管。",skillUploadPickAction:"选择 SKILL.md",skillUploadSubmitAction:"上传并纳管",skillUploadEmpty:"当前还没有选择要上传的 SKILL.md 文件。",skillUploadPickedFile:"已选文件",skillUploadScopeLabel:"作用域",skillUploadScopeWorkspace:"工作区 Skill",skillUploadScopeAssistant:"助手专用 Skill",skillUploadDirectoryLabel:"目录名",skillUploadDirectoryPlaceholder:"例如 team-helper",skillUploadDirectoryHint:"用于生成纳管目录和同步目标目录。默认按文件名或标题自动生成,通常不用手动改。",skillUploadDirectoryInvalid:"目录名不合法,只允许字母、数字、点、下划线和短横线。",skillUploadTargetsLabel:"应用 CLI",skillPasteLabel:"粘贴 SKILL 内容",skillPastePlaceholder:"直接粘贴完整的 SKILL.md 内容",skillPasteEmpty:"当前还没有可纳管的 SKILL 内容。",skillUploadDirectoryRequiredNote:"当前文件名推不出合法目录名,请手动补一个。",skillUploadTargetRequired:"至少选择一个目标 CLI。",skillUploadHeadingNote:"当前 markdown 缺少一级标题,纳管时会自动补一个。",skillUploadNormalizedNote:"已按系统规则预处理空白和换行。",skillUploadReadFailed:"读取上传的 SKILL.md 失败。",skillUploadContentEmpty:"上传的 SKILL.md 不能为空。",skillUploadSuccess:"已添加 {name}。",skillManagedListTitle:"我的技能",skillManagedEmpty:"你还没有添加任何技能。",skillManagedItemDescription:"已添加到 {targets}。",skillManagedItemNoTarget:"这项技能还没有应用到任何客户端。",skillUnmanagedListTitle:"待添加技能",skillUnmanagedEmpty:"目前没有新的技能可添加。",skillUnmanagedItemDescription:"已在 {target} 中发现,你可以把它添加到列表。",skillUnmanagedItemDisabledDescription:"已在 {target} 中发现,但这个目标当前已禁用,暂时不能继续添加。",skillAssistantRuntimeListTitle:"助手内置技能",skillAssistantRuntimeListDescription:"这些技能由系统自动提供,只给助手自己使用。",skillAssistantRuntimeEmpty:"当前没有助手内置技能。",skillAssistantRuntimeItemDescription:"这是系统自带技能,你不需要手动处理。",skillAssistantRuntimeUsedBy:"可用于",skillAssistantRuntimeSourcePath:"内置来源路径",skillConflictedListTitle:"待处理",skillConflictedEmpty:"当前没有需要处理的项目。",skillConflictedItemDescription:"{target} 里的这项内容需要处理。",skillConflictedItemDisabledDescription:"{target} 里的这项内容还保留着,但这个目标当前已禁用。",skillDiagnosticsTitle:"提醒",skillDiagnosticsEmpty:"当前没有新的提醒。",skillDiagnosticTargetMissingTitle:"{target} 还没准备好",skillDiagnosticTargetMissingDetail:"当前还没有找到 {target} 的技能目录。",skillDiagnosticReadFailedTitle:"{target} 暂时不可用",skillDiagnosticReadFailedDetail:"暂时无法读取 {target} 的技能信息,请稍后再试。",skillDiagnosticSyncMissingTitle:"{target} 需要重新应用",skillDiagnosticSyncMissingDetail:"有技能还没有在 {target} 中生效。",skillDiagnosticGenericTitle:"{target} 需要留意",skillDiagnosticGenericDetail:"有一项内容暂时没准备好,可以稍后刷新再看。",skillDirectoryName:"目录名",skillSsotPath:"统一存储目录",skillSourceCli:"来源 CLI",skillDirectoryPath:"目录路径",skillImportAction:"添加",skillImportSuccess:"已添加 {name},并应用到 {target}。",skillSyncAction:"重新应用",skillSyncSuccess:"已重新应用 {name}。",skillSyncTargetMissing:"这项技能还没有应用目标,暂时不能重新应用。",skillSyncTargetDisabled:"这项技能当前只剩已禁用目标,先重新启用对应 provider 再继续。",skillLoadFailed:"Skill 概况加载失败。",skillOfficeTemplateCreated:"文档模板已创建。",skillOfficeTemplateUpdated:"文档模板已更新。",skillOpsTargetCreated:"SSH 主机已创建。",skillOpsTargetUpdated:"SSH 主机已更新。",skillOpsApprovalApproved:"运维审批已批准。",skillOpsApprovalRejected:"运维审批已拒绝。",skillTargetCodex:"Codex",skillTargetClaudeCode:"Claude Code",skillTargetGemini:"Gemini",skillTargetOpenCode:"OpenCode",skillBindingPending:"准备中",skillBindingSynced:"可用",skillBindingFailed:"暂不可用",skillBindingConflicted:"需要处理",skillUploadTargetDisabled:"当前可选的 Skill 目标都已经被禁用,先去 provider 设置里重新启用一个。",skillTargetDisabledTag:"已禁用",skillTagAssistantOnly:"仅助手使用",skillTagWorkspaceSessionOnly:"工作区会话使用",securityPrivacy:"安全与隐私",securityPrivacySectionSummary:"会话权限、风险边界与默认授权策略",softwareUpdate:"软件更新",softwareUpdateSectionSummary:"服务端和客户端版本",serverAddress:"服务器地址",serverDescription:"客户端的登录、接口请求和实时连接都通过这个 Host 入口工作;前端界面资源由应用自身携带。",serverRelayTunnelProfileTitle:"当前 Host 的 CodingNS Connect 入口",serverRelayTunnelProfileDescription:"给当前保存的 Host profile 指定 CodingNS Connect 入口。开启后,客户端会通过 CodingNS Connect 域名和控制站点建立端到端加密连接,而不是直接请求这个地址。",serverRelayTunnelEnabled:"通过 CodingNS Connect 连接",serverRelayTunnelUsageHint:"服务器地址建议填写这台 Host 的公开入口地址,例如 https://demo.codingns.example 。",serverRelayTunnelDomain:"CodingNS Connect 域名",serverRelayTunnelDomainPlaceholder:"例如:demo.codingns.example",serverRelayTunnelControlBaseUrl:"控制站点地址",serverRelayTunnelControlBaseUrlPlaceholder:"例如:https://control.codingns.example",relayTunnelServerAddressDescription:"默认使用官方 CodingNS Connect 地址;如果你明确知道当前控制站地址,也可以在高级设置里手动覆盖。",relayTunnelServerAddressHint:"这里只改 CodingNS Connect 控制站点地址,用来覆盖登录、绑定和流量查询使用的站点,不影响当前 Host 的本地 API 地址。",relayTunnelStatus:"CodingNS Connect 状态",relayTunnelDescription:"通过 CodingNS Connect,让外部设备安全连接到这台 Host。",relayTunnelMasterSwitchLabel:"启用 CodingNS Connect",relayTunnelActivationHint:"开启后才会检查 CodingNS Connect 状态,并允许这台 Host 接入公网访问。",relayTunnelPhase:"当前状态",relayTunnelDomain:"访问地址",relayTunnelUnbound:"还没有绑定",relayTunnelTrafficRemaining:"剩余流量",relayTunnelHostFingerprint:"Host 指纹",relayTunnelTrustBoundaryNotice:"CodingNS Connect 只负责转发加密后的流量,无法看到你和 Host 之间的通信内容。",relayTunnelRecentError:"最近错误:{message}",relayTunnelAccessTitle:"连接设置",relayTunnelAccessDescription:"先登录 CodingNS Connect 账号,再打开开关把这台设备接入公网访问。",relayTunnelLearnService:"了解 CodingNS Connect",relayTunnelWizardTitle:"远程访问向导",relayTunnelWizardDescription:"按下面三步完成账号登录、主机名确认和 CodingNS Connect 启动,收住以后就能稳定从外部访问这台 Host。",relayTunnelStatusErrorTitle:"暂时无法读取远程访问状态",relayTunnelStatusNetworkError:"当前连不上这台 Host({address}),远程访问状态可能不是最新的。请先确认服务器地址、端口和网络连接。",relayTunnelStepPending:"待完成",relayTunnelStepCurrent:"进行中",relayTunnelStepDone:"已完成",relayTunnelStepLocked:"先完成上一步,这一步才会开放。",relayTunnelStepLoginTitle:"登录账号",relayTunnelStepLoginDescription:"先连接你的 CodingNS Connect 账号,后续的主机名检查和流量读取都依赖这个账号。",relayTunnelStepLoginConnected:"账号已经连接,可以继续下一步。",relayTunnelStepHostLabelTitle:"设置主机名",relayTunnelStepHostLabelDescription:"填写你以后要访问的四级域名前缀,并先检查这个名称现在能不能用。",relayTunnelStepStartTitle:"启动 CodingNS Connect",relayTunnelStepStartDescription:"前两步都完成后,再把当前 Host 正式接入 CodingNS Connect。",relayTunnelStepStartReady:"主机名已经确认,可以启动 CodingNS Connect 了。",relayTunnelStartAction:"启动 CodingNS Connect",relayTunnelLoginErrorTitle:"登录 CodingNS Connect 账号失败",relayTunnelAdvancedSettings:"高级设置",relayTunnelAdvancedSettingsHide:"收起高级设置",relayTunnelAdvancedSettingsDescription:"默认使用官方 CodingNS Connect 地址。只有在你明确知道当前控制站地址时,才需要在这里覆盖。",relayTunnelLoginNetworkError:"登录请求没有发出去,因为当前连不上这台 Host({address})。请先确认服务器地址和网络连接,再重新尝试。",relayTunnelReadyTitle:"远程访问已开启",relayTunnelReadyDescription:"当前配置已经收住。这里仅保留访问地址、流量信息和维护动作。",relayTunnelAccessUrlLabel:"远程访问地址",relayTunnelCopyAccessUrl:"复制地址",relayTunnelOpenAccessUrl:"打开页面",relayTunnelAccessUrlCopied:"访问地址已复制。",relayTunnelCopyAccessUrlFailed:"访问地址复制失败。",relayTunnelOpenAccessUrlFailed:"访问地址打开失败。",relayTunnelClientRouteLabel:"当前客户端链路",relayTunnelClientRouteAddressLabel:"当前客户端地址",relayTunnelClientRouteHintRelay:"当前客户端还在通过 CodingNS Connect 连接这台 Host;如果系统确认本地地址可达,会自动切到更省流量的直连链路。",relayTunnelClientRouteHintRelayProbing:"正在检查本地可直连地址。检查完成后,会自动切到更省流量的链路。",relayTunnelClientRouteHintLan:"当前客户端已经切到局域网直连,这条链路更省流量;远程访问地址仍然可以继续给外部设备使用。",relayTunnelClientRouteHintLoopback:"当前客户端直接连到这台设备的本机地址,不经过 CodingNS Connect。",relayTunnelClientRouteHintTailscale:"当前客户端已经切到 Tailscale 地址,不经过 CodingNS Connect。",relayTunnelClientRouteHintDirect:"当前客户端直接请求这个 Host 地址,不经过 CodingNS Connect。",relayTunnelReconnectAction:"重新连接",relayTunnelManageAccountAction:"管理账号",relayTunnelDisconnectDeviceAction:"注销设备",relayTunnelEnableToggleLabel:"启用 CodingNS Connect",relayTunnelConfigTitle:"CodingNS Connect 站点配置",relayTunnelConfigDescription:"这里填写 CodingNS Connect 接入地址和控制面的地址。保存后,下面的登录、绑定和流量操作都会走这里。",relayTunnelConfigErrorTitle:"服务地址保存失败",relayTunnelConfigNetworkError:"新的服务地址还没有保存到这台 Host,因为当前连不上它({address})。请先确认服务器地址和网络连接。",relayTunnelRelayBaseUrl:"CodingNS Connect 接入地址",relayTunnelControlBaseUrl:"控制站点地址",relayTunnelSaveConfig:"保存配置",relayTunnelRefresh:"刷新状态",relayTunnelAccountTitle:"CodingNS Connect 账号登录",relayTunnelAccountDescription:"使用 CodingNS Connect 账号登录后,可以绑定当前 Host 并查看剩余流量。",relayTunnelAccountEmail:"邮箱",relayTunnelAccountEmailPlaceholder:"输入你的邮箱",relayTunnelAccountPassword:"密码",relayTunnelAccountPasswordPlaceholder:"输入你的密码",relayTunnelLoginAccount:"登录",relayTunnelLoggedInAs:"当前已登录:{email}",relayTunnelConnectedBannerTitle:"账号已连接",relayTunnelConnectedBannerDescription:"现在可以打开 CodingNS Connect 开关,让外部设备访问这台 Host。",relayTunnelConnectedBannerActiveTitle:"CodingNS Connect 已开启",relayTunnelConnectedBannerActiveDescription:"这台设备已经可以通过 CodingNS Connect 从外部访问。",relayTunnelConnectedDevice:"当前设备:{name}",relayTunnelBoundDomain:"当前访问地址:{domain}",relayTunnelBindTitle:"绑定当前 Host",relayTunnelBindDescription:"绑定时会先读取当前 Host 的长期公钥,再把这台机器登记到 CodingNS Connect 站点。",relayTunnelHostLabelTitle:"设备名称",relayTunnelHostLabelDescription:"登录成功后,在这里填写你将来要使用的四级域名前缀,并检查这个名称当前能不能使用。",relayTunnelHostLabel:"Host 名称",relayTunnelHostLabelPlaceholder:"填写前缀",relayTunnelHostLabelSuffix:".channel.codingns.com",relayTunnelHostLabelCheck:"检查名称",relayTunnelHostLabelChecking:"正在检查这个名称是否可用。",relayTunnelHostLabelAvailable:"名称可用,公开访问地址将会是 {domain}",relayTunnelHostLabelReserved:"这个名称会命中保留前缀,请换一个名称。",relayTunnelHostLabelOccupied:"这个名称已经被占用,请换一个名称。",relayTunnelHostLabelUnavailable:"暂时无法确认这个名称是否可用,请稍后重试。",relayTunnelHostLabelRequired:"请先填写设备名称。",relayTunnelBindAction:"登录并绑定 Host",relayTunnelActionsTitle:"CodingNS Connect 开关",relayTunnelActionsDescription:"绑定完成后,可以在这里启用、停用或解绑 CodingNS Connect。",relayTunnelEnable:"启用 CodingNS Connect",relayTunnelDisable:"停用 CodingNS Connect",relayTunnelUnbind:"断开此设备",relayTunnelWalletTitle:"流量钱包",relayTunnelWalletDescription:"这里显示控制站点记录的总流量、已用流量和剩余额度。",relayTunnelTrafficGranted:"总流量",relayTunnelTrafficUsed:"已用流量",relayTunnelPackagesTitle:"流量套餐",relayTunnelPackagesDescription:"选择一个套餐后会跳转到官方支付页完成付款,支付成功后自动发放到当前账号钱包。",relayTunnelFeaturedPackage:"推荐",relayTunnelBuyPackage:"购买流量",relayTunnelOrdersTitle:"最近订单",relayTunnelOrdersDescription:"这里只显示最近几笔套餐订单,方便确认支付和到账状态。",relayTunnelOrderPending:"待支付",relayTunnelOrderPaid:"已支付",relayTunnelOrderExpired:"已过期",relayTunnelOrderFailed:"支付失败",relayTunnelControlBaseUrlRequired:"请先填写控制站点地址。",relayTunnelAccountRequired:"请先输入 CodingNS Connect 账号邮箱和密码。",relayTunnelIdentityUnavailable:"当前 Host 身份公钥还没有准备好,请稍后重试。",relayTunnelLoadFailed:"CodingNS Connect 状态读取失败。",relayTunnelPhaseDisabled:"未启用",relayTunnelPhaseBlockedUninitialized:"实例未初始化,已阻断暴露",relayTunnelPhaseUnbound:"还没有绑定",relayTunnelPhaseBinding:"正在绑定",relayTunnelPhaseConnecting:"正在连接",relayTunnelPhaseRunning:"运行中",relayTunnelPhaseQuotaExhausted:"流量耗尽",relayTunnelPhaseError:"状态异常",tailscaleBrand:"Tailscale",tailscaleSectionTitle:"Tailscale 接入",tailscaleSectionDescription:"让这台 Host 通过 Tailscale 在你的设备间可访问。",tailscaleMasterSwitchLabel:"启用 Tailscale",tailscaleActivationHint:"开启后才会检查 Tailscale 状态,并允许继续配置和绑定账号。",tailscaleCurrentState:"当前状态",tailscaleSwitchLabel:"启用开关",tailscaleStatusIndicator:"状态指示器",tailscaleServerAddress:"服务器地址",tailscaleAccountName:"账号名",tailscaleIpAddress:"IP 地址",tailscaleConfigure:"配置",tailscaleConfigModalTitle:"配置 Tailscale",tailscaleConfigModalDescription:"修改接入参数",tailscaleControlServer:"Control Server",tailscaleControlServerDescription:"留空时使用默认 control server。",tailscaleControlServerPlaceholder:"留空表示使用默认 control server",tailscaleHostname:"设备名称",tailscaleHostnameDescription:"可选。",tailscaleHostnamePlaceholder:"例如:codingns-host",tailscaleReachableBaseUrl:"外部访问地址",tailscaleTailnetFqdn:"Tailnet FQDN",tailscaleTailnetIpv4:"Tailnet IPv4",tailscaleTailnetIpv6:"Tailnet IPv6",tailscaleDetailAddresses:"详细地址",tailscaleRefresh:"刷新状态",tailscaleInstallAction:"安装 Tailscale",tailscaleInstallOpenFailed:"打开 Tailscale 安装页面失败。",tailscaleEnable:"启用 Tailscale",tailscaleDisable:"停用 Tailscale",tailscaleLogin:"开始绑定",tailscaleLogout:"解绑账号",tailscaleUnavailable:"暂不可用",tailscaleLoadFailed:"Tailscale 状态读取失败。",tailscalePhaseDisabled:"未启用",tailscalePhaseBlockedUninitialized:"实例未初始化,已阻断暴露",tailscalePhaseStarting:"正在启动",tailscalePhaseNeedsLogin:"等待绑定账号",tailscalePhaseRunning:"运行中",tailscalePhaseStopping:"正在停止",tailscalePhaseError:"状态异常",tailscaleOverviewDisabled:"当前还没有启用远程访问。",tailscaleOverviewBlockedUninitialized:"先完成初始化,再启用远程访问。",tailscaleOverviewStarting:"正在接入 Tailscale,请稍等。",tailscaleOverviewNeedsLogin:"启用完成后,还需要绑定账号。",tailscaleOverviewRunning:"当前实例已经可以通过 Tailscale 访问。",tailscaleOverviewStopping:"正在关闭远程访问。",tailscaleOverviewError:"远程访问状态异常,请先刷新或重新配置。",releaseChannel:"发布通道",releaseChannelDescription:"稳定版或测试版",releaseStable:"稳定版",releaseBeta:"测试版",autoReconnect:"自动重连",autoReconnectDescription:"当 Host 短暂不可达时,自动尝试恢复 HTTP 和 WebSocket 链路。",autoCheckUpdate:"自动检查客户端更新",autoCheckUpdateDescription:"仅客户端",defaultPermissionMode:"默认会话权限",defaultPermissionModeDescription:"控制新建和继续会话时默认使用的工具权限。完整权限会关闭询问,只适合你已经信任当前项目和运行环境时使用。",authDeviceManagement:"登录设备管理",authDeviceManagementDescription:"查看当前设备、其他在线设备和最近 10 条登录记录,并在主设备上按设备逐个退出其他在线设备。",authDeviceEntryHint:"点击“设备管理”后,可在弹窗中查看当前设备、其他在线设备和最近登录记录。",authDeviceOpenManager:"设备管理",authDeviceCurrentTitle:"当前设备",authDeviceOthersTitle:"其他在线设备",authDeviceRecentTitle:"最近登录记录",authDeviceCurrentTag:"当前设备",authDevicePrimaryTag:"主设备",authDeviceLegacyTag:"旧登录态",authDeviceLegacyHiddenHint:"检测到 {count} 条兼容旧登录态记录,默认已隐藏。",authDeviceLegacyReveal:"查看兼容记录",authDeviceLegacyHide:"隐藏兼容记录",authDeviceLegacyDevicesTitle:"兼容旧在线记录",authDeviceLegacyRecentTitle:"兼容旧登录记录",authDeviceLegacyLabel:"未知设备(旧登录态)",authDeviceClientDesktop:"Desktop",authDeviceClientWeb:"Web",authDeviceClientIos:"iOS",authDeviceClientAndroid:"Android",authDeviceClientUnknown:"未知设备",authDeviceCurrentEmpty:"当前登录态还没有可识别的设备信息,请重新登录后重试。",authDeviceOthersEmpty:"当前没有其他在线设备。",authDeviceRecentEmpty:"当前还没有最近登录记录。",authDeviceBrowserValue:"浏览器:{value}",authDeviceOsValue:"系统:{value}",authDeviceLastSeen:"最近在线:{value}",authDeviceLoginAt:"登录时间:{value}",authDeviceSourceAddressValue:"来源地址:{value}",authDeviceSourceAddressUnknown:"来源地址:未知",authDeviceEnablePrimary:"设为主设备",authDeviceDisablePrimary:"取消主设备",authDevicePrimaryUnavailable:"当前登录态缺少稳定设备标识,暂时不能设置主设备。",authDeviceLogoutOthers:"退出其他设备",authDeviceLogoutDevice:"退出设备",authDevicePrimaryEnabled:"当前设备已设为主设备。",authDevicePrimaryDisabled:"当前设备已取消主设备。",authDeviceLogoutOthersSuccess:"已退出其他设备,共处理 {count} 台。",authDeviceLogoutDeviceSuccess:"已退出设备“{device}”,共处理 {count} 个会话。",authDeviceLoadFailed:"登录设备信息加载失败。",authDeviceEnablePrimaryModalTitle:"设为主设备",authDeviceEnablePrimaryModalDescription:"请输入管理员密码,确认把当前设备设为主设备。",authDeviceDisablePrimaryModalTitle:"取消主设备",authDeviceDisablePrimaryModalDescription:"请输入管理员密码,确认取消当前设备的主设备状态。",authDevicePasswordLabel:"管理员密码",permissionModeDefault:"跟随 CLI 默认策略",permissionModeAcceptEdits:"允许编辑工作区,不询问",permissionModeBypassPermissions:"完整权限,不询问",enabled:"已启用",disabled:"已关闭",serverUpdate:"服务端更新",serverUpdateDescription:"",clientUpdate:"客户端更新",clientUpdateDescription:"",serverCurrentVersion:"服务端当前版本",serverTargetVersion:"服务端目标版本",serverPackageName:"npm 包名",serverUpdateCommand:"升级命令",serverCheckNow:"检查服务端",serverOpenPage:"打开 npm",serverLatestUnknown:"暂未获取",serverUpdateReady:"发现新版本",serverUpToDate:"已是最新版本",serverCheckFailed:"检查失败",serverInstallWarning:"安装更新会通过 PM2 自动重启 CodingNS 服务,连接会短暂中断。",serverInstallConfirmTitle:"安装服务端更新",serverInstallConfirmDescription:"继续后会先安装新版本,再由 PM2 自动重启当前 CodingNS 服务。",serverInstallConfirmAction:"继续安装并重启服务",serverRestarting:"更新已安装,正在重启 CodingNS 服务",serverOpenPageFailed:"打开页面失败",releaseCurrentVersion:"当前版本",releaseTargetVersion:"目标版本",releaseTargetTag:"目标 Tag",releasePublishedAt:"发布时间",releaseUnknownVersion:"未知",releaseNotes:"更新内容",releaseNotesEmpty:"暂无更新内容",releaseCheckNow:"检查客户端",releaseInstallNow:"安装更新",releaseOpenPage:"打开发布页",releaseRollback:"回退版本",releaseUpdateBadge:"新版本",releaseUpdateReady:"发现新版本",releaseUpToDate:"已是最新版本",releaseCheckFailed:"检查失败",releaseInstallerMissing:"有新版本,暂无安装包",releaseSignatureMissing:"有新版本,缺少校验信息",releaseInstallStarted:"安装已开始",releaseInstallFailed:"安装失败",releaseRestartRequired:"安装成功,请重启应用程序",releaseRestartDialogTitle:"安装成功",releaseRestartDialogDescription:"新版本 {version} 已安装完成,请重启应用程序后继续使用。",releaseRestartLater:"稍后",releaseRestartConfirm:"是,立即重启",releaseRestartFailed:"重启应用失败",releasePageOpenFailed:"打开页面失败",androidInstallerStarted:"已交给系统安装器,安装完成前你仍可以取消",androidInstallPermissionRequired:"请先允许当前应用安装未知来源应用",androidInstallCancelled:"安装已取消或未完成,可重新触发安装",androidInstallSucceeded:"已检测到新版本完成安装",releaseRollbackStarted:"已开始回退",releaseRollbackFailed:"回退失败",clientUpdateUnsupported:"当前不支持安装更新",logout:"退出登录"},home:{title:"从一条会话继续,而不是从后台表格开始",subtitle:"这里先挑一个工作区和会话,真正的工作区在下一步。",terminalsEntry:"进入终端页",workspaceSection:"工作区",sessionSection:"最近会话",emptyWorkspaces:"还没有导入工作区。先在 Host 侧导入后,这里会出现入口。",emptySessions:"当前工作区还没有可继续的会话。",noActivity:"暂时还没有活动"},terminal:{title:"终端",heroTitle:"把真实 PTY 留在 Host,把操作入口留在工作台",heroSubtitle:"这里不伪造输出,不把终端和进程搅在一起,只消费 Host 统一托管的真实终端流。",workspaceSection:"工作区与终端",workspaceField:"当前工作区",shellField:"新终端使用的 Shell",runtimeField:"Runtime",runtimeAutoOption:"自动选择",runtimeAutoShortLabel:"auto",runtimeAutoDescription:"按 Host 默认策略选择当前终端 runtime。",runtimePersistentLabel:"持久会话",runtimePersistentShortLabel:"持久",runtimeTmuxDescription:"持久化外部会话,适合需要后台常驻的开发终端。",runtimeWindowsPersistentDescription:"使用基于 ConPTY 的 Windows 持久化会话,让终端在 Host 重启后仍可继续保留。",runtimeEmbeddedDescription:"由当前 Host 直接托管,适合作为轻量回退方案。",runtimeConptyPowerShellLabel:"PowerShell 持久会话",runtimeConptyCmdLabel:"CMD 持久会话",runtimeConptyGitBashLabel:"Git Bash 持久会话",runtimeMissingDialogTitle:"当前系统没有安装 tmux",runtimeMissingDialogDescription:"tmux runtime 无法继续创建持久化终端。你可以先安装 tmux,或者临时切换到 embedded-pty 继续。",runtimeMissingInstallDescription:"建议优先安装 tmux,这样终端才能在 Host 重启后继续保留。",runtimeMissingInstallMacArm:"macOS(Apple Silicon / Homebrew):arch -arm64 brew install tmux",runtimeMissingInstallMacIntel:"macOS(Intel Mac / Homebrew):brew install tmux",runtimeMissingInstallDebian:"Ubuntu / Debian:sudo apt install tmux",runtimeMissingInstallFedora:"Fedora:sudo dnf install tmux",runtimeMissingFallbackDescription:"如果现在先切到 embedded-pty,本次终端可以继续创建,但它不会作为外部持久会话保留。",runtimeMissingKeepAction:"先不切换",runtimeMissingFallbackAction:"切换到 embedded-pty 并继续",runtimeMissingFallbackPending:"正在切换…",shellUnavailable:"当前不可用",workspaceLoadFailed:"工作区或终端列表暂时没有拉回来。",terminalSection:"终端实例",templateSection:"命令模板",stageEmptyTitle:"还没有选中终端",stageEmptySubtitle:"先创建一个终端,或者运行一个命令模板。",emptyTerminals:"当前工作区还没有终端实例。",emptyTemplates:"当前工作区还没有命令模板。",createButton:"新建终端",creating:"正在创建终端…",creationPendingDescription:"Host 正在启动真实 PTY,连上以后这个窗口会立刻接管显示。",defaultTerminalName:"工作终端",created:"终端已经创建并接入 Host。",createFailed:"终端创建失败。",closeButton:"关闭终端",closing:"正在关闭终端…",closed:"终端关闭请求已经提交。",closeCompleted:"终端已关闭。",closePendingDescription:"关闭请求已经发给 Host,前台不会阻塞,系统会继续同步最终结果。",closeSyncDelayed:"Host 还在后台处理关闭,列表会在后续刷新时继续同步。",closeFailed:"终端关闭失败。",inputLabel:"向当前终端发送命令",inputPlaceholder:"例如:pnpm test",sendButton:"发送到终端",inputFailed:"终端输入发送失败。",outputEmpty:"终端已经连上,但暂时还没有输出。",outputTruncated:"断线期间有一段输出超出缓存窗口,当前只补回了仍保留的部分。",connectedHint:"当前输出来自 Host 真实 PTY 流。",moreActions:"终端操作",duplicateAction:"复制标签",duplicateSuccess:"已按当前终端配置新建一个标签。",duplicateFailed:"复制终端标签失败。",disconnectAction:"断开",disconnected:"终端连接已断开。",reconnectAction:"重连",reconnectRequested:"终端重连请求已发出。",deleteAction:"删除",deleting:"正在删除终端…",deleted:"终端记录已删除。",deletePendingDescription:"删除请求已经发给 Host,前台不会阻塞,系统会在后台继续同步列表。",deleteSyncDelayed:"Host 还在后台处理删除,列表会在后续刷新时继续同步。",deleteFailed:"终端记录删除失败。",closePendingBadge:"关闭中",deletePendingBadge:"删除中",pinAction:"固定",unpinAction:"取消固定",zoomLabel:"终端缩放",zoomInAction:"放大终端显示",zoomOutAction:"缩小终端显示",zoomResetAction:"恢复默认缩放",openExternalAction:"独立窗口",openExternalFailed:"打开终端独立窗口失败。",toolbarToggleAction:"展开终端工具菜单",mobileSwipeHint:"左右滑动切换终端",mobileSwipePosition:"{current} / {total}",mobileDrawerAction:"打开快捷终端列表",mobileDrawerTitle:"快捷终端",mobileDrawerDescription:"右滑呼出列表,点一下就切到别的终端。",mobilePinnedSectionTitle:"已固定终端",mobileDrawerEmptyTitle:"当前还没有终端",mobileDrawerEmptyDescription:"先新建一个终端,这里才会出现可切换的列表。",mobileCreateSheetTitle:"新建终端",mobileCreateShellLabel:"终端类型",mobileCreateShellDescription:"先选这次要开的 Shell,别把桌面端那套下拉框搬到手机上。",mobileCreateRuntimeLabel:"会话方式",mobileCreateRuntimeDescription:"再决定它是持久保留,还是只作为当前 runtime 会话。",mobileCreateLoadingShells:"正在读取当前系统可用的终端类型…",mobileCreateConfirm:"创建这个终端",createDialogTitle:"新建终端",createDialogShellDescription:"先选这次要开的 Shell,再创建终端。Windows 下不再偷偷按默认值直接起。",createDialogRuntimeDescription:"再决定它是持久保留,还是只作为当前 runtime 会话。",createDialogConfirm:"创建终端",mobileRuntimePersistentTitle:"持久会话",mobileRuntimePersistentDescription:"适合需要一直挂着的开发终端,创建后会作为可恢复会话保留。",mobileRuntimeSessionTitle:"runtime(当前会话)",mobileRuntimeSessionDescription:"直接由当前 Host 托管,创建更轻,但不会保留成外部持久会话。",mobileWorkspaceSwitcherPlaceholder:"选择项目",mobileEmptyTitle:"这里还没有终端内容",mobileEmptyDescription:"先新建一个终端,或者右滑呼出快捷列表,切到当前工作区已有的终端。",layoutLabel:"分栏布局",layoutSingleAction:"单栏显示",layoutVerticalAction:"左右分栏",layoutHorizontalAction:"上下分栏",saveLogAction:"保存日志",saveLogSuccess:"终端日志已保存。",saveLogFailed:"终端日志保存失败。",logEmpty:"当前终端还没有可保存的日志内容。",bindToPaneAction:"绑定到当前分栏",bindToPrimaryPaneAction:"绑定到主分栏",bindToSecondaryPaneAction:"绑定到副分栏",panePrimary:"主分栏",paneSecondary:"副分栏",splitEmptySubtitle:"先点一个标签,或者新建一个终端,把它绑定到当前分栏。",statusBadge:{creating:"启动中",running:"运行中",closed:"已关闭",error:"异常"},recoveryComplete:"已回到刷新前的终端,缓存内的关键输出已经补回。",recoveryTruncated:"已恢复到上一个终端,但断线期间的部分输出已经超出缓存窗口。",recoveryIdleClosed:"上一个终端已因空闲超时被 Host 自动关闭,你现在看到的是关闭前保留的输出。",reconnect:"手动重连",liveConnected:"实时流已接入",templateName:"模板名称",templateCommand:"主命令",templateArgs:"参数(空格分隔)",templateCreateButton:"保存模板",templateCreated:"命令模板已经保存。",templateCreateFailed:"命令模板保存失败。",templateRunSent:"命令模板已经发送到当前终端。",templateRunCreatedTerminal:"命令模板已在新终端中启动。",templateRunFailed:"命令模板执行失败。",connection:{connected:"已连接",reconnecting:"正在重连",reconnect_failed:"重连失败",closed:"已关闭"}},conversation:{titleFallback:"继续对话",historyLoading:"正在从 Host 拉取消息历史…",historyLoadingOlder:"正在加载更早的消息…",historyLoadFailed:"历史消息暂时没有拉回来,可以稍后再试。",timelineEmpty:"这条会话还没有消息。你发出的第一句话会直接进入 Host 链路。",turnAbortedUser:"上一轮已由你手动停止。",turnAbortedUnexpected:"上一轮意外中断,没有正常结束。",turnAbortedGeneric:"上一轮已中断,没有正常结束。",scrollToBottomAction:"回到底部",rawRefLabel:"来源",copyAction:"复制",copyContentSuccess:"内容已复制。",copyContentFailed:"内容复制失败。",selectionTodoAction:"代办",selectionActionButton:"操作",selectionActionSubmit:"新开操作子会话",selectionActionPromptLabel:"你想让它做什么",selectionActionPromptPlaceholder:"比如:解释这段话、整理成笔记,或调用指定接口处理它",selectionActionIncludeContext:"包含当前上下文",selectionActionContextUnavailable:"当前选区跨了多条消息,没法安全继承上下文,只能按无上下文新建子会话。",selectionActionDefaultPrompt:"请处理这段内容。",selectionActionPreviewLabel:"已选内容",selectionActionTargetLabel:"新会话设置",selectionActionQuotedLabel:"选中文本",selectionActionFailed:"创建操作子会话失败。",actionSessionBadge:"操作",actionInheritedSelectionSummary:"已默认折叠来自“{parentTitle}”的一段选中文本。",forkFromHereAction:"从这里分叉",forkingAction:"正在分叉…",forkMessageSucceeded:"已从这条消息创建新分支。",forkMessageFailed:"从这条消息分叉失败。",forkDraftLabel:"分叉引用",forkDraftEmpty:"这条消息没有可引用的文本内容。",forkDraftClear:"取消这次分叉引用",forkTargetProviderLabel:"目标 CLI",forkTargetModelLabel:"目标模型",forkTargetSummary:"源 CLI:{sourceProvider} · 目标 CLI:{targetProvider}",forkInlineModelLoading:"正在读取模型列表…",forkInlineNativeHint:"保持同一 CLI,继续走原生分叉。",forkInlineCrossHint:"已切到不同 CLI,将按文本历史重建新会话。",forkSwitchConfirmTitle:"切换到其他 CLI?",forkSwitchConfirmDescription:"同一 CLI 会尽量保留原生分叉体验;切到其他 CLI 会改成跨供应商分叉。",forkSwitchConfirmKeepTitle:"会保留",forkSwitchConfirmKeepBody:"分叉点之前的用户消息和助手文本。",forkSwitchConfirmConvertTitle:"会转换",forkSwitchConfirmConvertBody:"可继承文本会重建到新的 CLI 会话里。",forkSwitchConfirmDropTitle:"会丢失",forkSwitchConfirmDropBody:"工具调用、权限交互、附件和运行中状态。",forkSwitchConfirmAction:"确认切换",forkSwitchKeepNative:"保持原生",forkProviderNativeUnsupported:"当前 provider 还不支持原生 fork",forkProviderReconstructedUnsupported:"当前 provider 还不能作为跨 provider 分叉目标",loadMore:"加载更多消息",composerPlaceholder:"把下一步交代清楚,剩下的交给这条会话继续跑。",sendButton:"发送消息",queueTitle:"待发队列",queueDescription:"当前这轮结束后,队列里的消息会按顺序自动继续处理。",queueOrderPrefix:"队列序号",queueStatusQueued:"等待中",queueStatusFailed:"发送失败",queueDelete:"删除",queueDeleting:"删除中",queueImageOnly:"仅图片附件",sendGuidanceButton:"追加引导",queueGuidanceButton:"加入队列",queueSteer:"引导",queueSteering:"引导中",resendButton:"重试发送",quickPhraseTrigger:"快捷短语",quickPhraseModalTitle:"快捷短语",quickPhraseModalDescription:"这里集中管理你常用的会话指令,点一下就能直接填回当前输入框。",quickPhraseCreateLabel:"新增短语",quickPhraseOpenCreateAction:"新增短语",quickPhraseCreateModalTitle:"新增快捷短语",quickPhraseCreateModalDescription:"把常用指令单独存起来,后面在任何设备上都能直接复用。",quickPhraseCreatePlaceholder:"输入一条常用短语,保存后下次可以直接复用。",quickPhraseCreateAction:"添加短语",quickPhraseListLabel:"快捷短语列表",quickPhraseEmpty:"还没有可用的快捷短语,先加一条最常用的。",quickPhraseOrderLabel:"第 {index} 条",quickPhraseMoveUp:"上移短语",quickPhraseMoveDown:"下移短语",quickPhraseDelete:"删除短语",quickPhraseSaveFailed:"快捷短语保存失败,请稍后再试。",sendingState:"发送中",sentState:"已同步",failedState:"发送失败",contextUsageTitle:"当前上下文占用",contextUsageUnavailable:"当前上下文占用暂时不可用",contextUsageEstimated:"上限为估算值",contextUsageCachedTokens:"缓存命中 {count}",contextUsageSourceProviderLog:"上限来自 provider 运行日志",contextUsageSourceProviderRuntime:"上限来自 provider runtime",contextUsageSourceProviderConfig:"上限来自 provider 配置",contextUsageSourceModelMap:"上限来自模型映射",headerWorkspace:"工作区",headerProvider:"Provider",headerCapability:"能力摘要",connectionConnected:"已连接",connectionReconnecting:"正在重连",connectionReconnectFailed:"重连失败",connectionClosed:"连接已关闭",runtimeErrorTitle:"会话运行失败",runtimeErrorFallbackDetail:"CLI 提供商返回了错误,但没有提供更多细节。",runtimeErrorCodeLabel:"错误码",runtimeErrorDetailLabel:"错误详情",reconnectExplain:"实时链路断开了,系统正在补回缺失消息。",reconnectFailedExplain:"自动恢复没有成功。你可以手动重试,或者稍后重新进入会话。",reconnectExplainWithRoute:"实时链路断开了,系统正在补回缺失消息。当前连接方式:{route}。",reconnectFailedExplainWithRoute:"自动恢复没有成功。你可以手动重试,或者稍后重新进入会话。当前连接方式:{route}。",capabilityDenied:"当前会话不支持这个动作",capabilitySendDisabled:"当前 provider 不支持发送新消息",capabilityAttachmentDisabled:"当前会话还不支持附件输入",capabilityInterruptDisabled:"当前会话不支持中断运行",sidebarTitle:"当前会话上下文",sidebarSubtitle:"这里只保留最小能力摘要,不把页面做成后台控制台。",reconnectButton:"手动恢复实时同步",headerResumedAt:"最近续接",headerLastSyncAt:"最近同步",historyPages:"历史分页",syncStatusIdle:"同步空闲",syncStatusSyncing:"同步中",syncStatusError:"同步异常",capabilityResume:"可续接",capabilitySend:"可发送",capabilityInterrupt:"可中断",capabilityTools:"工具调用",attachmentsLabel:"附件",filePanelTitle:"文件管理",filePanelSubtitle:"这里的文件能力只服务当前会话,不把页面拉成重型 IDE。",filePanelNoWorkspace:"当前还没有选中项目,暂时不能浏览或挂载文件。",filePanelRefresh:"刷新",filePanelCopyPath:"复制路径",filePanelCopyAbsolutePath:"复制绝对路径",filePanelCopyRelativePath:"复制相对路径",filePanelCopyAbsolutePathSuccess:"绝对路径已复制。",filePanelCopyRelativePathSuccess:"相对路径已复制。",filePanelCopyPathFailed:"路径复制失败。",filePanelCopy:"复制",filePanelCut:"剪切",filePanelPaste:"粘贴",filePanelCopySelectionSuccess:"已复制 {count} 项,可到目标目录粘贴。",filePanelCutSelectionSuccess:"已剪切 {count} 项,可到目标目录粘贴。",filePanelPasteSuccess:"已粘贴 {count} 项。",filePanelPasteFailed:"粘贴失败,请检查目标目录和重名冲突。",filePanelSelectionCount:"已选 {count} 项",filePanelClipboardCopyReady:"剪贴板中有 {count} 个待复制项目",filePanelClipboardCutReady:"剪贴板中有 {count} 个待移动项目",filePanelOpenFile:"打开文件",filePanelExpandDirectory:"展开文件夹",filePanelCollapseDirectory:"折叠文件夹",filePanelActionsMenu:"文件操作",filePanelSearchPlaceholder:"输入文件名或路径片段",filePanelSearchButton:"搜索",filePanelShowSearch:"打开搜索",filePanelHideSearch:"收起搜索",filePanelSearchEmpty:"没有找到匹配的文件。",filePanelSearchResults:"搜索结果",filePanelSearchFailed:"文件搜索失败,请稍后再试。",filePanelBrowse:"工作区文件",filePanelCollapseCurrent:"折叠当前选中",filePanelCollapseAll:"全部折叠",filePanelBackDirectory:"返回上级",filePanelEmptyDirectory:"这个目录里暂时没有可显示的文件。",filePanelRecentTitle:"最近打开",filePanelEmptyRecent:"最近还没有打开记录。",filePanelContextTitle:"已挂载文件",filePanelEmptyContexts:"当前会话还没有挂载文件管理。",filePanelEditorTitle:"预览与编辑",filePanelEditorPlaceholder:"这里只做轻量文本编辑,不在这里做完整 IDE。",filePanelSelectHint:"先从目录、搜索或最近打开里选一个文件。",filePanelUnsupported:"这个文件当前不能在侧栏里直接编辑。",filePanelAttach:"挂到会话",filePanelAttached:"已挂载",filePanelDetach:"解绑",filePanelSave:"保存",filePanelSaving:"保存中",filePanelLoadFailed:"文件管理面板加载失败。",filePanelOpenFailed:"文件打开失败。",filePanelSaveSuccess:"文件已经保存。",filePanelSaveFailed:"文件保存失败。",fileViewerHint:"当前以 {language} 模式打开,支持预览与编辑保存。",fileViewerModeLabel:"文件查看模式",fileViewerPreview:"预览",fileViewerPresentation:"演示文档",fileViewerCode:"代码",fileViewerEdit:"编辑",fileViewerPlainText:"纯文本",fileViewerHtml:"HTML",fileViewerImage:"图片",fileViewerPdf:"PDF",fileViewerRefreshPreview:"刷新",fileViewerRefreshFailed:"文件预览刷新失败。",fileViewerExportPdf:"导出 PDF",fileViewerExportPdfRunning:"导出中",fileViewerExportPdfSuccess:"PDF 已导出到 {path}",fileViewerExportPdfFailed:"PDF 导出失败。",fileViewerExportPdfTimeout:"PDF 导出超时,请稍后重试。",fileViewerExportPdfMissingHtml:"当前没有可导出的 HTML 内容。",fileViewerExportPptx:"导出 PPTX",fileViewerExportPptxRunning:"导出中",fileViewerExportPptxSuccess:"PPTX 已导出到 {path}",fileViewerExportPptxFailed:"PPTX 导出失败。",fileViewerExportPptxMissingHtml:"当前没有可导出的 HTML 内容。",fileViewerExportTaskTimeout:"导出超时,请稍后重试。",fileViewerOpenExternal:"外部打开",fileViewerOpenExternalFailed:"外部打开失败。",fileViewerOpenInWindow:"独立窗口",fileViewerOpenInWindowFailed:"独立窗口打开失败。",fileViewerWindowTitle:"文件预览",fileViewerCollapse:"收起预览",fileViewerExpand:"展开预览",fileViewerZoomIn:"放大",fileViewerZoomOut:"缩小",fileViewerFit:"适配",fileViewerActualSize:"原始大小",fileViewerFitWidth:"适宽",fileViewerPreviousPage:"上一页",fileViewerNextPage:"下一页",fileViewerPageIndicator:"第 {page} 页",fileViewerSizeLabel:"查看器尺寸",fileViewerSizeDefault:"默认",fileViewerSizeWide:"加宽",fileViewerSizeFull:"铺满",fileViewerDiffModified:"已修改",fileViewerDiffAdded:"新增内容",fileViewerImageUnavailable:"当前无法显示图片预览,请尝试刷新或外部打开。",fileViewerPdfUnavailable:"当前无法显示 PDF 预览,请尝试刷新或外部打开。",fileViewerOfficeLoading:"正在加载 ONLYOFFICE 预览…",fileViewerOfficeUnavailable:"当前无法显示 Office 预览,请先检查 ONLYOFFICE 配置和服务状态。",fileViewerOfficeScriptUnavailable:"ONLYOFFICE 编辑器脚本加载失败,请检查服务地址是否可访问。",fileViewerEnterFullscreen:"全屏",fileViewerExitFullscreen:"退出",fileViewerOpenInBrowser:"在浏览器中打开",fileViewerOpenInBrowserFailed:"打开浏览器预览失败。",fileViewerHtmlPreviewLoading:"正在加载 HTML 预览...",fileViewerHtmlPreviewUnavailable:"当前无法显示 HTML 预览,请先切到代码模式查看。",fileViewerHtmlPreviewFailed:"HTML 预览链接生成失败。",fileViewerPresentationBadge:"静态 HTML",fileViewerPresentationSummary:"已识别 {count} 页,画布基准 {size}",fileViewerPresentationWarningCount:"当前有 {count} 条导入提醒。",fileViewerPresentationCurrentPage:"当前页面",fileViewerPresentationUntitled:"未命名页面",fileViewerPresentationReadOnlyHint:"请选择要编辑的组件以查看文本和布局编辑工具",fileViewerPresentationEditHint:"这一版已经支持选中组件、修改文字和基础样式,复杂结构继续保持只读。",fileViewerPresentationCanvasSelectHint:"可以直接点击画布里的组件进入顶部编辑栏,也可以在右侧组件列表里切换。",fileViewerPresentationUnsupported:"这份 HTML 还不适合进入演示文档视图。",fileViewerPresentationUnsupportedReason:"原因:{reason}",fileViewerPresentationSelectNode:"先在右侧组件列表里选一个可编辑节点。",fileViewerPresentationAddPage:"新增页面",fileViewerPresentationDuplicatePage:"复制页面",fileViewerPresentationDeletePage:"删除页面",fileViewerPresentationMovePageUp:"上移页面",fileViewerPresentationMovePageDown:"下移页面",fileViewerPresentationPageActions:"页面操作",fileViewerPresentationDragToSort:"拖拽排序",fileViewerPresentationUndoAction:"撤销上一步",fileViewerPresentationInspector:"组件属性",fileViewerPresentationComponentList:"组件列表",fileViewerPresentationEditable:"可编辑",fileViewerPresentationReadOnly:"只读",fileViewerPresentationTextLabel:"文字内容",fileViewerPresentationTextDescription:"这里直接改组件文案,中间画布会实时刷新。",fileViewerPresentationTextToolbar:"文字工具栏",fileViewerPresentationFontFamilyLabel:"字体",fileViewerPresentationFontPresetTitle:"等线 Light(标题)",fileViewerPresentationFontPresetSans:"思源黑体",fileViewerPresentationFontPresetSerif:"衬线正文",fileViewerPresentationFontPresetMono:"等宽字体",fileViewerPresentationBoldAction:"加粗",fileViewerPresentationItalicAction:"倾斜",fileViewerPresentationUnderlineAction:"下划线",fileViewerPresentationFontSizeIncreaseAction:"字体放大",fileViewerPresentationFontSizeDecreaseAction:"字体缩小",fileViewerPresentationLineHeightAuto:"默认行距",fileViewerPresentationFontSizeLabel:"字号",fileViewerPresentationFontWeightLabel:"字重",fileViewerPresentationTextColorLabel:"文字颜色",fileViewerPresentationBackgroundColorLabel:"背景颜色",fileViewerPresentationTextAlignLabel:"对齐",fileViewerPresentationLineHeightLabel:"行高",fileViewerPresentationPaddingLabel:"内边距",fileViewerPresentationRadiusLabel:"圆角",fileViewerPresentationPositionXLabel:"水平位置",fileViewerPresentationPositionYLabel:"垂直位置",fileViewerPresentationWidthLabel:"组件宽度",fileViewerPresentationHeightLabel:"组件高度",fileViewerPresentationDuplicateAction:"复制当前组件",fileViewerPresentationKeepOriginal:"保持原样",fileViewerPresentationAlignLeft:"左对齐",fileViewerPresentationAlignCenter:"居中",fileViewerPresentationAlignRight:"右对齐",fileViewerPresentationTextMode:"文本",fileViewerPresentationLayoutMode:"布局",fileViewerPresentationLayoutHint:"这里改的是组件位置和尺寸,画布拖拽与保存会一起生效。",fileViewerPresentationLayoutSelectNode:"先选一个支持布局编辑的组件。",fileViewerPresentationLayoutEditable:"可做布局编辑",fileViewerPresentationLayoutLocked:"当前不能做布局编辑",fileViewerPresentationLayoutUnsupported:"这个组件当前还不能安全做布局编辑。",fileViewerPresentationLayoutStrictLocked:"该组件处在流式布局里,不能直接自由拖动。先把它所在容器转换成自由布局。",fileViewerPresentationLayoutFreezeContainer:"转换当前容器为自由布局",fileViewerPresentationLayoutRootLocked:"页面根容器这轮不允许直接改布局。",fileViewerPresentationLayoutSelectionCount:"已选中 {count} 个组件",fileViewerPresentationLayoutAlignLeft:"左边对齐",fileViewerPresentationLayoutAlignRight:"右边对齐",fileViewerPresentationLayoutAlignTop:"顶部对齐",fileViewerPresentationLayoutAlignBottom:"底部对齐",fileViewerPresentationResizeHandle:"调整组件大小",filePanelAttachSuccess:"文件已经挂到当前会话。",filePanelAttachFailed:"文件挂载失败。",filePanelDetachSuccess:"文件已经从当前会话解绑。",filePanelDetachFailed:"文件解绑失败。",filePanelNewFile:"新建文件",filePanelNewDirectory:"新建目录",filePanelUpload:"上传文件",filePanelDownload:"下载文件",filePanelUploadSuccess:"已上传 {name}。",filePanelUploadFailed:"文件上传失败。",filePanelDownloadSuccess:"已开始下载 {name}。",filePanelDownloadFailed:"文件下载失败。",filePanelDelete:"删除",filePanelDeleting:"删除中...",filePanelDeleteSuccess:"已删除 {name}。",filePanelDeleteConfirmTitle:"确认删除",filePanelDeleteConfirmDescription:"删除后会立即从当前项目移除,这一步不能撤销。",filePanelDeleteSelectionConfirm:"确认删除选中的 {count} 项吗?",filePanelDeleteSelectionSuccess:"已删除 {count} 项。",filePanelRenameMove:"重命名/移动",filePanelRenameSuccess:"已重命名为 {name}。",filePanelMutateFailed:"文件操作失败,请检查路径和当前状态。",filePanelCreateFilePrompt:"输入要创建的相对文件路径",filePanelCreateDirectoryPrompt:"输入要创建的相对目录路径",filePanelCreateFileDescription:"输入工作区内的相对路径,文件会立刻创建出来。",filePanelCreateDirectoryDescription:"输入工作区内的相对路径,文件夹会立刻创建出来。",filePanelPathFieldLabel:"相对路径",filePanelPathFieldPlaceholder:"例如 src/features/files/index.ts",filePanelCreateFileSubmit:"创建文件",filePanelCreateDirectorySubmit:"创建文件夹",filePanelCreatingFile:"创建文件中...",filePanelCreatingDirectory:"创建文件夹中...",exportAction:"导出会话",exportDialogTitle:"导出当前会话",exportDialogDescription:"可以导出成 Markdown 文件,或者按当前消息样式打印并保存为 PDF。",exportMarkdownAction:"导出 Markdown",exportMarkdownHint:"导出完整消息内容,适合继续编辑、归档和提交。",exportPdfAction:"导出 PDF",exportPdfHint:"会直接下载 PDF 文件,保留当前会话内容排版。",exportHtmlAction:"导出 HTML",exportPreparing:"正在准备导出内容...",exportMarkdownSuccess:"Markdown 已开始导出。",exportPdfPreparing:"PDF 已开始下载。",exportHtmlSuccess:"HTML 已开始导出。",exportLoadFailed:"导出失败,当前会话内容没有完整拉取下来。",exportDownloadFailed:"导出文件失败。",exportPrintFailed:"打开打印窗口失败。",exportPrintContainerTitle:"会话导出",exportMarkdownSessionIdLabel:"会话 ID",exportMarkdownProviderLabel:"Provider",exportMarkdownWorkspaceLabel:"工作区 ID",exportMarkdownCreatedAtLabel:"创建时间",exportMarkdownExportedAtLabel:"导出时间",exportMarkdownTimeLabel:"时间",exportMarkdownTypeLabel:"类型",exportMarkdownAttachmentsLabel:"附件数量",exportMarkdownAttachmentsSectionTitle:"附件",exportMarkdownToolSectionTitle:"工具调用",exportMarkdownToolNameLabel:"工具名",exportMarkdownToolStatusLabel:"状态",exportMarkdownToolInputLabel:"输入",exportMarkdownToolOutputLabel:"输出",exportMarkdownToolErrorLabel:"错误",exportMarkdownToolCallType:"工具调用",exportMarkdownToolResultType:"工具结果",exportMarkdownTextType:"正文",exportMarkdownUnknownSize:"大小未知",filePanelFilterChanges:"仅显示变更",filePanelShowAll:"显示全部",filePanelNoChanges:"当前没有变更文件。",filePanelBinaryPreview:"二进制文件不支持预览。",filePanelDeleteFileConfirm:"确认删除这个文件吗?{path}",filePanelDeleteDirectoryConfirm:"确认删除这个文件夹吗?{path}",filePanelRenameMovePrompt:"输入新的相对路径",filePanelRenameDescription:"只改路径,不改文件内容。填新路径就会同时支持移动目录层级。",filePanelRenameSubmit:"确认重命名",filePanelRenaming:"重命名中...",unavailableAction:"当前不可用",roleUser:"你",roleAssistant:"助手",roleTool:"工具",toolViewImageActiveLabel:"AI正在查看图片",roleSystem:"系统"},git:{title:"Git 上下文",subtitle:"这里是会话侧边的辅助区,只处理当前工作区里的 Git 事实。",loading:"正在读取当前工作区的 Git 上下文。",refresh:"刷新",panelLoadFailed:"Git 上下文暂时没有加载出来。",uninitializedTitle:"当前目录还没有启用 Git",uninitializedDescription:"先初始化这个目录的 Git 工作区,后面才能查看改动、写提交和追踪历史。",initRepository:"初始化 Git 工作区",initInProgress:"正在初始化…",initSuccess:"Git 工作区已初始化。",initFailed:"初始化 Git 工作区失败。",ahead:"领先",behind:"落后",dirty:"有改动",clean:"已干净",changeCount:"当前有 {count} 个变更文件",noChanges:"当前没有待处理改动。",changesTitle:"当前变更",rulesFirstHint:"规则先于生成,草稿不能绕过校验。",stage:"暂存",unstage:"取消暂存",preview:"预览",stageFailed:"暂存操作失败。",diffTitle:"差异预览",diffLoadFailed:"差异内容暂时没有拉回来。",binaryDiff:"这个文件是二进制改动,侧栏不直接展示内容。",stagedDiff:"暂存区 diff",worktreeDiff:"工作区 diff",emptyDiff:"当前没有可展示的文本差异。",diffTruncated:"差异内容过长,已经做了截断保护。",commitTitle:"提交草稿",defaultRuleName:"默认提交规则",language:"语言",maxLength:"长度",bodyRequired:"正文必填",bodyOptional:"正文可选",issueRequired:"Issue 必填",issueOptional:"Issue 可选",commitSubject:"提交标题",commitSubjectPlaceholder:"在这里输入提交信息",commitBody:"提交正文",commitBodyPlaceholder:"把这次改动说清楚,别写空话。",commitFooter:"提交脚注",commitFooterPlaceholder:"例如:Refs: #123",generateDraft:"AI 起草",validate:"校验草稿",commit:"执行提交",draftFailed:"提交草稿生成失败。",validateFailed:"提交规则校验失败。",commitFailed:"提交失败。",commitSuccess:"提交已经写入当前仓库。",validationPassed:"规则校验通过,可以继续提交。",validationFailed:"规则校验没有通过,先把下面的问题修掉。",branchTitle:"分支",branchPlaceholder:"输入要切换或创建的分支名",switchBranch:"切换",createBranch:"新建",branchFailed:"分支操作失败。",historyTitle:"最近历史",historyHint:"只放最近几条,不做图形历史树。",noHistory:"当前没有可展示的提交历史。",viewAllVersions:"查看所有版本",viewAllVersionsDescription:"这里展示当前仓库已加载的版本历史,共 {count} 条。",viewCommitChanges:"查看更改文件与 DIFF",copyCommitMessage:"复制提交信息",copyCommitMessageSuccess:"提交信息已复制。",copyCommitVersion:"复制 Git 版本号",copyCommitVersionSuccess:"Git 版本号已复制。",commitDetailTitle:"版本详情",commitDetailDescription:"当前查看提交 {hash} 的完整改动。",commitDetailLoading:"正在读取提交详情…",commitDetailEmpty:"当前没有可展示的提交详情。",commitDetailLoadFailed:"提交详情暂时没有拉回来。",commitVersionLabel:"Git 版本号",commitHashLabel:"提交 Hash",commitAuthorLabel:"作者",commitTimeLabel:"提交时间",commitMessageLabel:"提交信息",changedFilesTitle:"变更文件",commitDiffLabel:"提交 DIFF",renamedFromLabel:"从 {path} 重命名",explainCommitTitle:"解释版本更改",explainCommitDescription:"先选择一个 CLI 供应商,再新建会话分析这个提交。",explainCommitAction:"解释更改",startExplainCommit:"开始解释",explainCommitStarted:"解释会话已经创建。",explainCommitFailed:"解释更改失败。",remoteTitle:"远程同步",remoteReady:"当前仓库已配置远程。",remoteMissing:"当前仓库还没有远程。",fetch:"Fetch",pull:"Pull",push:"Push",pushNow:"立即推送",publish:"Publish",remoteFailed:"远程同步失败。",remoteAuthAction:"远程认证",remoteAuthTitle:"设置远程仓库认证",remoteAuthDescription:"需要认证的远程仓库,在这里填写本次页面会话使用的用户名、密码或 token。",remoteAuthDescriptionGithub:"检测到当前远程仓库来自 GitHub。GitHub 的 HTTPS Git 操作请使用 Personal Access Token (PAT),不要填写 GitHub 登录密码。",remoteAuthStatusLabel:"认证状态",remoteAuthManageHint:"按仓库分别查看和配置",remoteAuthManageTitle:"管理远程仓库认证",remoteAuthManageDescription:"每个远程仓库单独显示自己的凭据状态,也在这里分别配置。",remoteAuthConfigured:"已配置",remoteAuthConfiguredInSession:"当前页面已配置",remoteAuthConfiguredOnHost:"Host 已配置",remoteAuthNotConfigured:"未配置",remoteAuthGithubPatLabel:"Personal Access Token (PAT)",remoteAuthGithubPatPlaceholder:"输入 GitHub PAT",remoteAuthGithubUsernamePlaceholder:"输入 GitHub 用户名",remoteAuthGithubPatHint:"GitHub 不支持用账号密码做 Git HTTPS 认证。basic 模式请填写 GitHub 用户名 + PAT;token 模式可以直接填写 PAT。",remoteAuthRemember:"记住账号密码到 Host",remoteAuthSessionHint:"默认只在当前页面会话里生效;勾选“记住账号密码到 Host”后,远程同步成功时会写到 Host,后续自动复用。",remoteAuthRememberHint:"勾选记住后,本次远程同步成功时会把认证写到 Host。",remoteAuthSave:"保存认证",remoteAuthSaved:"远程仓库认证已保存,请重新执行同步。",remoteAuthCleared:"已清除当前页面会话里的远程认证设置。",selectRemoteTitle:"选择推送仓库",selectRemoteDesc:"勾选要推送到的远程仓库,支持多选。",noRemotes:"当前仓库没有配置任何远程仓库。",pushSelected:"推送 ({count})",pushing:"推送中…",pushAllSuccess:"已成功推送到 {count} 个远程仓库。",errors:{unauthorized:"当前登录态已经失效,请重新登录后再试。",workspaceNotFound:"当前会话绑定的工作区不存在,先确认工作区是否还可用。",invalidWorkspace:"当前工作区配置无效,Git 侧栏不能脱离仓库根目录执行。",notGitRepository:"当前工作区不是 Git 仓库,Git 侧栏不会伪造状态。",repoNotFound:"当前工作区找不到可用的 Git 仓库根目录。",pathOutOfWorkspace:"Git 目标超出了当前工作区仓库边界,操作已被拦截。",invalidTarget:"Git 目标路径无效,请先刷新侧栏后重试。",notStaged:"目标文件还不在暂存区里,先确认当前变更状态。",emptyStagedChanges:"暂存区为空,先把要提交的改动放进暂存区。",branchConflict:"当前分支存在冲突或不是快进更新,先同步并处理差异。",branchNotFound:"目标分支不存在,先确认分支名是否正确。",remoteNotFound:"当前仓库还没有可用的 origin 远程,先配置远程再同步。",remoteAuthFailed:"远程仓库认证失败,请先确认当前仓库凭据可用。",pushFailed:"推送失败,请先检查远程状态和本地提交。",pullFailed:"拉取失败,请先确认远程分支状态。",remoteFailed:"远程同步失败,请检查 Git 输出和网络状态。",initFailed:"Git 工作区初始化失败,请确认当前目录可写且 Git 可用。",commitValidationFailed:"提交草稿还没通过规则校验,先把校验问题修掉。",commandTimeout:"Git 操作超时了,先确认仓库状态和网络环境。"}}},Gl="default-host";function Wd(i){return!!(i&&"discoveryKey"in i&&typeof i.discoveryKey=="string")}function uh(i,r){var o;return r?i.hosts.find(c=>c.id===r)??((o=i.discoveredHosts)==null?void 0:o.find(c=>c.id===r))??null:null}function dh(i,r){var o;return r?i.hosts.find(c=>c.baseUrl===r)??((o=i.discoveredHosts)==null?void 0:o.find(c=>c.baseUrl===r))??null:null}function kn(i){var r,o,c,u;return i.activeDiscoveredHostId&&((r=i.discoveredHosts)!=null&&r.some(p=>p.id===i.activeDiscoveredHostId))?i.activeDiscoveredHostId:i.activeHostId&&i.hosts.some(p=>p.id===i.activeHostId)?i.activeHostId:((o=i.hosts[0])==null?void 0:o.id)??((u=(c=i.discoveredHosts)==null?void 0:c[0])==null?void 0:u.id)??null}function Da(i){return uh(i,kn(i))}function ph(i){var r;return((r=Da(i))==null?void 0:r.baseUrl)??null}function fh(i){return i==="http:"||i==="https:"}function We(i){const r=i.trim();if(!r)throw new Error("EMPTY_SERVER_URL");const o=/^[a-zA-Z][a-zA-Z\d+.-]*:\/\//.test(r)?r:`http://${r}`,c=new URL(o);if(!fh(c.protocol))throw new Error("INVALID_SERVER_PROTOCOL");c.hash="",c.search="";const u=c.pathname.replace(/\/+$/,"");return`${c.origin}${u==="/"?"":u}`}const kt="codingns.auth.remembered-login";function Ji(){return typeof window<"u"&&typeof window.localStorage<"u"}function Ky(i){return i.isNativeMobile?!0:i.isDesktop?i.ui.osFamily==="windows"||i.ui.osFamily==="macos":!1}function mh(i){const r={credentials:null,legacyServerBaseUrl:null};if(!Ji())return r;const o=window.localStorage.getItem(kt);if(!o)return r;try{const c=JSON.parse(o);if(Kl(c))return{credentials:i?c[i]??null:null,legacyServerBaseUrl:null};const u=_d(c);if(!u||!i)return{credentials:null,legacyServerBaseUrl:(u==null?void 0:u.serverBaseUrl)??null};const p={hostId:i,username:u.username,password:u.password,savedAt:Date.now()},y={[i]:p};return window.localStorage.setItem(kt,JSON.stringify(y)),{credentials:p,legacyServerBaseUrl:u.serverBaseUrl}}catch{return window.localStorage.removeItem(kt),r}}function Qy(i){return mh(i).credentials}function Yy(i){if(!Ji())return;const r=Ud(),o={hostId:i.hostId,username:i.username.trim(),password:i.password,savedAt:Date.now()};!o.hostId||!o.username||!o.password||window.localStorage.setItem(kt,JSON.stringify({...r,[o.hostId]:o}))}function hh(i){if(!Ji())return;const r=window.localStorage.getItem(kt);if(r)try{const o=JSON.parse(r);if(Kl(o))return;const c=_d(o);if(!c){window.localStorage.removeItem(kt);return}window.localStorage.setItem(kt,JSON.stringify({...c,serverBaseUrl:We(i)}))}catch{window.localStorage.removeItem(kt)}}function $y(i){if(!Ji()||!i)return;const r=Ud();if(!r[i])return;const o={...r};if(delete o[i],Object.keys(o).length===0){window.localStorage.removeItem(kt);return}window.localStorage.setItem(kt,JSON.stringify(o))}function Ud(){if(!Ji())return{};const i=window.localStorage.getItem(kt);if(!i)return{};try{const r=JSON.parse(i);return Kl(r)?r:{}}catch{return{}}}function Kl(i){return typeof i!="object"||i===null||Array.isArray(i)?!1:Object.values(i).every(r=>gh(r))}function gh(i){if(typeof i!="object"||i===null)return!1;const r=i;return typeof r.hostId=="string"&&typeof r.username=="string"&&typeof r.password=="string"&&typeof r.savedAt=="number"&&r.username.trim().length>0&&r.password.length>0}function _d(i){if(typeof i!="object"||i===null)return null;const r=i;if(typeof r.username!="string"||typeof r.password!="string"||typeof r.serverBaseUrl!="string")return null;const o=r.username.trim(),c=r.password,u=We(r.serverBaseUrl);return!o||!c?null:{username:o,password:c,serverBaseUrl:u}}function bh(i){return{filePath:(i==null?void 0:i.filePath)??null,routePath:(i==null?void 0:i.routePath)??null}}function Vd(i={}){return{x:i.x??null,y:i.y??null,width:i.width??1200,height:i.height??780,minWidth:i.minWidth??720,minHeight:i.minHeight??480}}function Jy(i){return{windowId:i.windowId,kind:i.kind,workspaceId:i.workspaceId??null,workspaceName:i.workspaceName??null,sessionId:i.sessionId??null,mode:i.mode??"docked",bounds:Vd(i.bounds),focusOwner:i.focusOwner??null,payload:bh(i.payload)}}function ti(i){return{...i,bounds:{...i.bounds},payload:{...i.payload}}}function yh(i){return{descriptors:Object.fromEntries(Object.entries(i.descriptors).map(([o,c])=>[o,ti(c)])),openWindowIds:[...i.openWindowIds],lastActiveWindowId:i.lastActiveWindowId}}function sd(){return{descriptors:{},openWindowIds:[],lastActiveWindowId:null}}function Sh(i,r){return{...i,...r,windowId:i.windowId,bounds:Vd({...i.bounds,...r.bounds}),payload:{...i.payload,...r.payload}}}class kh{constructor(){A(this,"state",sd());A(this,"listeners",new Set);A(this,"subscribe",r=>(this.listeners.add(r),()=>{this.listeners.delete(r)}));A(this,"getState",()=>yh(this.state))}registerDescriptor(r){const o=ti(r),c=this.state.openWindowIds.includes(o.windowId);return this.state={...this.state,descriptors:{...this.state.descriptors,[o.windowId]:o},lastActiveWindowId:c?o.windowId:this.state.lastActiveWindowId},this.emit(),ti(o)}updateDescriptor(r,o){const c=this.state.descriptors[r];if(!c)return null;const u=Sh(c,o);return this.state={...this.state,descriptors:{...this.state.descriptors,[r]:u}},this.emit(),ti(u)}getDescriptor(r){const o=this.state.descriptors[r];return o?ti(o):null}getWindows(){return Object.values(this.state.descriptors).map(r=>({descriptor:ti(r),isOpen:this.state.openWindowIds.includes(r.windowId)}))}markWindowOpen(r){if(!this.state.descriptors[r])return!1;const o=this.state.openWindowIds.filter(c=>c!==r);return this.state={...this.state,openWindowIds:[...o,r],lastActiveWindowId:r},this.emit(),!0}markWindowClosed(r){if(!this.state.openWindowIds.includes(r))return!1;const o=this.state.openWindowIds.filter(c=>c!==r);return this.state={...this.state,openWindowIds:o,lastActiveWindowId:this.state.lastActiveWindowId===r?o.at(-1)??null:this.state.lastActiveWindowId},this.emit(),!0}isWindowOpen(r){return this.state.openWindowIds.includes(r)}removeWindow(r){if(!this.state.descriptors[r])return!1;const o={...this.state.descriptors};delete o[r];const c=this.state.openWindowIds.filter(u=>u!==r);return this.state={descriptors:o,openWindowIds:c,lastActiveWindowId:this.state.lastActiveWindowId===r?c.at(-1)??null:this.state.lastActiveWindowId},this.emit(),!0}clear(){const r=this.state.openWindowIds.length>0||this.state.lastActiveWindowId!==null||Object.keys(this.state.descriptors).length>0;this.state=sd(),r&&this.emit()}emit(){for(const r of this.listeners)r()}}function Th(){return new kh}const Hl=Th();function wh(){return Hl}function Xy(i){return He.useSyncExternalStore(Hl.subscribe,()=>i(Hl.getState()))}const vh=wh();function zd(){return typeof window<"u"&&typeof window.__TAURI_INTERNALS__<"u"}function jd(){var p,y;if(typeof navigator>"u")return"unknown";const i=navigator.userAgent.toLowerCase(),r=navigator.userAgentData,o=((p=r==null?void 0:r.platform)==null?void 0:p.toLowerCase())??((y=navigator.platform)==null?void 0:y.toLowerCase())??"",c=`${o} ${i}`,u=o.includes("mac")&&navigator.maxTouchPoints>1;return c.includes("android")?"android":c.includes("iphone")||c.includes("ipad")||c.includes("ipod")||u?"ios":c.includes("mac")?"macos":c.includes("win")?"windows":c.includes("linux")?"linux":"unknown"}function Ch(i){var r;return typeof i=="number"&&Number.isFinite(i)&&i>0?i:typeof window<"u"&&Number.isFinite(window.innerWidth)&&window.innerWidth>0?window.innerWidth:typeof document<"u"&&Number.isFinite((r=document.documentElement)==null?void 0:r.clientWidth)&&document.documentElement.clientWidth>0?document.documentElement.clientWidth:1280}function Dh(i){const r=Ch(i);return r<768?"compact":r<1024?"medium":"expanded"}function Ph(i){const r=jd();return i==="desktop"?{osFamily:r,windowControlsStyle:r==="macos"?"traffic-lights":r==="windows"?"windows":"none",prefersDesktopChrome:!0,prefersOverlayTitlebar:r==="macos",prefersSystemFontStack:!0}:{osFamily:r,windowControlsStyle:"none",prefersDesktopChrome:!1,prefersOverlayTitlebar:!1,prefersSystemFontStack:!0}}function _(i){return{ok:!1,errorCode:"PLATFORM_NOT_SUPPORTED",detail:i}}function Lh(i){const r=i instanceof Error?i.message:"桌面壳调用失败。",o=r.match(/^([A-Z0-9_]+):\s*(.+)$/);return o?{errorCode:o[1],detail:o[2]}:{errorCode:"SHELL_BRIDGE_ERROR",detail:r}}async function se(i,r){return Qi(i,r)}async function Qi(i,r){if(!zd())return _("当前运行环境不支持桌面壳能力。");try{return{ok:!0,value:await window.__TAURI_INTERNALS__.invoke(i,r)}}catch(o){return{ok:!1,...Lh(o)}}}function Ah(i){switch(i){case"selection":return 10;case"action":return[12];case"gesture":return[10,18,10];case"success":return[16,30,20];case"warning":return[20,36,18];case"error":return[24,40,24,40,20];default:return 10}}function qd(){return typeof navigator<"u"&&typeof navigator.vibrate=="function"}async function Gd(i){if(qd())try{navigator.vibrate(Ah(i))}catch{return}}async function Ql(i,r){if(typeof window>"u"||typeof Notification>"u")return _("当前环境不支持系统通知。");try{if(Notification.permission==="default"&&await Notification.requestPermission()!=="granted"||Notification.permission!=="granted")return _("系统通知权限未授予。");const o=new Notification(i,{body:r});return o.onerror=()=>{},{ok:!0}}catch(o){return{ok:!1,errorCode:"NOTIFICATION_FAILED",detail:o instanceof Error?o.message:"系统通知发送失败。"}}}class Rh{constructor(){A(this,"supported",!1)}openExternal(r){return typeof window>"u"?Promise.resolve(_("当前环境无法打开外部链接。")):(window.open(r,"_blank","noopener,noreferrer"),Promise.resolve({ok:!0}))}openLocalFile(){return Promise.resolve(_("当前不是桌面端运行环境。"))}revealInFileManager(){return Promise.resolve(_("当前不是桌面端运行环境。"))}getPlatformInfo(){return Promise.resolve(_("当前不是桌面端运行环境。"))}showNotification(r,o){return Ql(r,o)}writeClipboardText(){return Promise.resolve(_("当前不是桌面端运行环境。"))}setWindowState(){return Promise.resolve(_("当前不是桌面端运行环境。"))}readDesktopConfig(){return Promise.resolve(_("当前不是桌面端运行环境。"))}writeDesktopConfig(){return Promise.resolve(_("当前不是桌面端运行环境。"))}scanLocalHosts(){return Promise.resolve(_("当前不是桌面端运行环境。"))}getRuntimeInfo(){return Promise.resolve(_("当前不是桌面端运行环境。"))}checkForUpdate(){return Promise.resolve(_("当前不是桌面端运行环境。"))}installUpdate(){return Promise.resolve({ok:!1,errorCode:"PLATFORM_NOT_SUPPORTED",detail:"当前不是桌面端运行环境。"})}getAndroidRuntimeInfo(){return Promise.resolve(_("当前不是 Android 原生运行环境。"))}installAndroidUpdate(){return Promise.resolve({ok:!1,status:"failed",detail:"当前不是 Android 原生运行环境。"})}rollbackToPreviousVersion(){return Promise.resolve(_("当前不是桌面端运行环境。"))}pickDirectory(){return Promise.resolve(_("当前不是桌面端运行环境。"))}createWindow(){return Promise.resolve(_("当前不是桌面端运行环境。"))}closeWindow(){return Promise.resolve(_("当前不是桌面端运行环境。"))}focusWindow(){return Promise.resolve(_("当前不是桌面端运行环境。"))}listWindows(){return Promise.resolve(_("当前不是桌面端运行环境。"))}isWindowOpen(){return Promise.resolve(_("当前不是桌面端运行环境。"))}getWindowDescriptor(){return Promise.resolve(_("当前不是桌面端运行环境。"))}syncWindowDescriptor(){return Promise.resolve(_("当前不是桌面端运行环境。"))}updateWindowBounds(){return Promise.resolve(_("当前不是桌面端运行环境。"))}syncNativeSidebarLayout(){return Promise.resolve(_("当前不是桌面端运行环境。"))}}class Fh{constructor(){A(this,"supported",qd())}trigger(r){return Gd(r)}}class Eh{constructor(){A(this,"supported",!0)}openExternal(r){return se("open_external",{url:r})}openLocalFile(r){return se("open_local_file",{path:r})}revealInFileManager(r){return se("reveal_in_file_manager",{path:r})}getPlatformInfo(){return se("get_platform_info")}async showNotification(r,o){const c=await Ql(r,o);return c.ok?c:se("show_notification",{title:r,body:o})}writeClipboardText(r){return se("copy_text",{text:r})}setWindowState(r){return se("set_window_state",{state:r})}readDesktopConfig(){return se("read_desktop_config")}writeDesktopConfig(r){return se("write_desktop_config",{patch:r})}scanLocalHosts(){return se("scan_local_hosts")}getRuntimeInfo(){return se("get_runtime_info")}checkForUpdate(r){return se("check_for_update",{channel:r})}async installUpdate(r){const o=await se("install_update",{channel:r});return o.ok?o.value??{ok:!0}:{ok:!1,errorCode:o.errorCode,detail:o.detail}}getAndroidRuntimeInfo(){return Promise.resolve(_("当前不是 Android 原生运行环境。"))}installAndroidUpdate(){return Promise.resolve({ok:!1,status:"failed",detail:"当前不是 Android 原生运行环境。"})}rollbackToPreviousVersion(){return se("rollback_to_previous_version")}pickDirectory(){return se("pick_directory")}createWindow(r){return se("create_window",{descriptor:r})}closeWindow(r){return se("close_window",{windowId:r})}focusWindow(r){return se("focus_window",{windowId:r})}listWindows(){return se("list_windows")}isWindowOpen(r){return se("is_window_open",{windowId:r})}getWindowDescriptor(r){return typeof r=="string"?se("get_window_descriptor",{windowId:r}):se("get_window_descriptor")}syncWindowDescriptor(r){return se("sync_window_descriptor",{descriptor:r})}updateWindowBounds(r,o){return se("update_window_bounds",{windowId:r,bounds:o})}syncNativeSidebarLayout(r){return se("sync_native_sidebar_layout",{layout:r})}}class Mh{constructor(){A(this,"supported",!0)}async trigger(r){(await Qi("perform_haptic_feedback",{kind:r})).ok||await Gd(r)}}class Ih{constructor(r){A(this,"supported",!0);this.platform=r}openExternal(r){return typeof window>"u"?Promise.resolve(_("当前环境无法打开外部链接。")):(window.open(r,"_blank","noopener,noreferrer"),Promise.resolve({ok:!0}))}openLocalFile(){return Promise.resolve(_("当前不是桌面端运行环境。"))}revealInFileManager(){return Promise.resolve(_("当前不是桌面端运行环境。"))}getPlatformInfo(){return Promise.resolve(_("当前不是桌面端运行环境。"))}showNotification(r,o){return Ql(r,o)}writeClipboardText(r){return Qi("copy_text",{text:r})}setWindowState(){return Promise.resolve(_("当前平台不支持窗口控制。"))}readDesktopConfig(){return Promise.resolve(_("当前不是桌面端运行环境。"))}writeDesktopConfig(){return Promise.resolve(_("当前不是桌面端运行环境。"))}scanLocalHosts(){return Promise.resolve(_("当前不是桌面端运行环境。"))}getRuntimeInfo(){return Promise.resolve(_("当前不是桌面端运行环境。"))}checkForUpdate(){return Promise.resolve(_("当前不是桌面端运行环境。"))}installUpdate(){return Promise.resolve({ok:!1,errorCode:"PLATFORM_NOT_SUPPORTED",detail:"当前不是桌面端运行环境。"})}getAndroidRuntimeInfo(){return this.platform!=="android"?Promise.resolve(_("当前不是 Android 原生运行环境。")):Qi("get_android_runtime_info")}async installAndroidUpdate(r){if(this.platform!=="android")return{ok:!1,status:"failed",detail:"当前不是 Android 原生运行环境。"};const o=await Qi("install_android_update",{manifest:r});return o.ok?o.value??{ok:!1,status:"failed",detail:"Android 更新结果为空。"}:{ok:!1,status:"failed",detail:o.detail}}rollbackToPreviousVersion(){return Promise.resolve(_("当前不是桌面端运行环境。"))}pickDirectory(){return Promise.resolve(_("当前不是桌面端运行环境。"))}createWindow(){return Promise.resolve(_("当前不是桌面端运行环境。"))}closeWindow(){return Promise.resolve(_("当前不是桌面端运行环境。"))}focusWindow(){return Promise.resolve(_("当前不是桌面端运行环境。"))}listWindows(){return Promise.resolve(_("当前不是桌面端运行环境。"))}isWindowOpen(){return Promise.resolve(_("当前不是桌面端运行环境。"))}getWindowDescriptor(){return Promise.resolve(_("当前不是桌面端运行环境。"))}syncWindowDescriptor(){return Promise.resolve(_("当前不是桌面端运行环境。"))}updateWindowBounds(){return Promise.resolve(_("当前不是桌面端运行环境。"))}syncNativeSidebarLayout(){return Promise.resolve(_("当前不是桌面端运行环境。"))}}function Yl(){if(!zd())return"web";const i=jd();return i==="ios"?"ios":i==="android"?"android":"desktop"}function An(i={}){const r=Yl(),o=Dh(i.viewportWidth),c=r==="ios"||r==="android";return{platform:r,isDesktop:r==="desktop",isWeb:r==="web",isMobile:o!=="expanded",isNativeMobile:c,viewportClass:o,ui:Ph(r),bridge:r==="desktop"?new Eh:c?new Ih(r):new Rh,windows:vh,haptics:c?new Mh:new Fh}}const Nl="codingns.client.runtime-config";function xh(i){return i==="desktop"||i==="ios"||i==="android"}function Bl(i){return i==="en"||i==="en-US"?"en-US":"zh-CN"}function Oh(){return typeof navigator>"u"?"zh-CN":Bl(navigator.language)}function cd(i){return i==="acceptEdits"||i==="bypassPermissions"?i:"default"}function Kd(){return typeof window<"u"&&typeof window.localStorage<"u"}function Hh(){if(!Kd())return null;const i=window.localStorage.getItem(Nl);if(!i)return null;try{return JSON.parse(i)}catch{return window.localStorage.removeItem(Nl),null}}function Qd(i){Kd()&&window.localStorage.setItem(Nl,JSON.stringify(Zd(i)))}function Nh(){var i;return typeof window>"u"||!((i=window.location)!=null&&i.origin)?null:window.location.origin}function Bh(i){if(!i)return null;try{return We(i)}catch{return null}}function Yd(i){if(i==="web"){const r=Bh(Nh());if(r)return r}return We("http://127.0.0.1:3002")}function $d(){return new Date().toISOString()}function Wh(){return{status:"idle",lastScannedAt:null,cooldownUntil:null,errorCode:null,errorDetail:null}}function Ce(i){return typeof i=="string"&&i.trim()?i.trim():null}function ud(i,r){return Ce(i)??r}function Jd(i){try{const r=new URL(i).hostname.toLowerCase();return r==="localhost"||r==="127.0.0.1"||r==="::1"||r==="[::1]"?"local":/^10\./.test(r)||/^192\.168\./.test(r)||/^172\.(1[6-9]|2\d|3[0-1])\./.test(r)?"lan":"remote"}catch{return"custom"}}function Xd(i){try{const r=new URL(i),o=r.pathname==="/"?"":r.pathname.replace(/\/+$/,"");return`${r.host}${o}`}catch{return i}}function Tn(i,r,o={}){const c=We(i);return{id:Ce(o.id)??Gl,name:Ce(o.name)??Xd(c),baseUrl:c,kind:o.kind??Jd(c),createdAt:ud(o.createdAt,r),updatedAt:ud(o.updatedAt,r),lastConnectedAt:Ce(o.lastConnectedAt)??null,lastUserId:Ce(o.lastUserId)??null,lastUsername:Ce(o.lastUsername)??null,relayTunnel:Vh(o.relayTunnel)}}function Uh(i){return typeof i=="object"&&i!==null}function dd(i,r){if(!Array.isArray(i))return[];const o=new Set,c=[];for(let u=0;u<i.length;u+=1){const p=i[u];if(!Uh(p))continue;const y=Ce(p.baseUrl);if(y)try{const k=u===0?Gl:`host-${u+1}`,L=Tn(y,r,{...p,id:Ce(p.id)??k});if(o.has(L.id))continue;o.add(L.id),c.push(L)}catch{continue}}return c}function _h(i){return typeof i=="object"&&i!==null}function Vh(i){if(typeof i!="object"||i===null||Array.isArray(i))return null;const r=Ce(i.provider),o=i.enabled,c=Ce(i.tunnelDomain),u=Ce(i.controlBaseUrl),p=Ce(i.bindingId),y=Ce(i.hostFingerprint),k=zh(i.candidateEndpoints);if(r!=="codingns_relay"||typeof o!="boolean"||!c||!u)return null;try{const L=We(u);return/^[a-z0-9-]+(\.[a-z0-9-]+)+$/i.test(c)?{provider:r,enabled:o,tunnelDomain:c.trim().toLowerCase(),controlBaseUrl:L,bindingId:p,hostFingerprint:y,candidateEndpoints:k}:null}catch{return null}}function zh(i){if(!Array.isArray(i))return[];const r=[],o=new Set;for(const c of i){if(typeof c!="object"||c===null||Array.isArray(c))continue;const u=Ce(c.endpointId),p=Ce(c.kind),y=Ce(c.url),k=c.priority,L=Ce(c.expiresAt),O=Ce(c.source);if(!(!u||!y||typeof k!="number"||!Number.isFinite(k)||p!=="relay"&&p!=="lan"&&p!=="loopback"&&p!=="tailscale"&&p!=="custom"||O!=="host_reported"&&O!=="desktop_scan"&&O!=="user_saved"))try{const E=We(y);if(o.has(E))continue;r.push({endpointId:u,kind:p,url:E,priority:k,expiresAt:L,source:O}),o.add(E)}catch{continue}}return r.sort((c,u)=>c.priority!==u.priority?c.priority-u.priority:c.url.localeCompare(u.url))}function pd(i,r,o){const c=We(r),u=Da(i);return u?i.hosts.map(p=>p.id===u.id?Tn(c,o,{...p,name:Xd(c),kind:Jd(c),createdAt:p.createdAt,updatedAt:o}):p):[Tn(c,o)]}function $l(i){const r=$d();return{platform:i,activeHostId:Gl,hosts:[Tn(Yd(i),r)],discoveredHosts:[],activeDiscoveredHostId:null,localHostDiscovery:Wh(),releaseChannel:"stable",autoReconnect:!0,autoCheckUpdate:i==="desktop",language:Oh(),defaultPermissionMode:"default"}}function wn(i,r){var L,O;if(!r||!_h(r))return i;const o=r.platform??i.platform,c=$l(o),u=$d();if(!xh(o)){let E=r.hosts!==void 0?dd(r.hosts,u):c.hosts;r.hostBaseUrl&&(E=pd(i,r.hostBaseUrl,u)),E.length===0&&(E=c.hosts);const B=r.activeHostId??i.activeHostId??c.activeHostId,j=E.some(Z=>Z.id===B)?B:((L=E[0])==null?void 0:L.id)??null;return{platform:o,activeHostId:j,hosts:E,discoveredHosts:i.discoveredHosts,activeDiscoveredHostId:null,localHostDiscovery:i.localHostDiscovery,releaseChannel:r.releaseChannel??i.releaseChannel,autoReconnect:r.autoReconnect??i.autoReconnect,autoCheckUpdate:r.autoCheckUpdate??i.autoCheckUpdate,language:Bl(r.language??i.language),defaultPermissionMode:cd(r.defaultPermissionMode??i.defaultPermissionMode)}}let p=r.hosts!==void 0?dd(r.hosts,u):i.hosts;r.hostBaseUrl&&(p=pd(i,r.hostBaseUrl,u)),p.length===0&&(p=c.hosts);const y=r.activeHostId??i.activeHostId,k=p.some(E=>E.id===y)?y:((O=p[0])==null?void 0:O.id)??null;return{platform:o,activeHostId:k,hosts:p,discoveredHosts:i.discoveredHosts,activeDiscoveredHostId:i.activeDiscoveredHostId&&i.discoveredHosts.some(E=>E.id===i.activeDiscoveredHostId)?i.activeDiscoveredHostId:null,localHostDiscovery:i.localHostDiscovery,releaseChannel:r.releaseChannel??i.releaseChannel,autoReconnect:r.autoReconnect??i.autoReconnect,autoCheckUpdate:r.autoCheckUpdate??i.autoCheckUpdate,language:Bl(r.language??i.language),defaultPermissionMode:cd(r.defaultPermissionMode??i.defaultPermissionMode)}}function Zd(i){return{platform:i.platform,activeHostId:i.activeHostId,hosts:i.hosts,releaseChannel:i.releaseChannel,autoReconnect:i.autoReconnect,autoCheckUpdate:i.autoCheckUpdate,language:i.language,defaultPermissionMode:i.defaultPermissionMode}}function ep(i,r){return wn($l(r),i)}async function jh(){const i=An(),r=$l(i.platform),o=Hh();let c=null;if(i.isDesktop){const p=await i.bridge.readDesktopConfig();p.ok&&p.value&&(c=p.value)}const u=wn(wn(r,o),c);return Qd(u),u}async function qh(i,r){var p;const o=wn(i,r);Qd(o);const c=(p=Da(o))==null?void 0:p.baseUrl;c&&hh(c);const u=An();return u.isDesktop&&await u.bridge.writeDesktopConfig(Zd(o)),o}function Gh(){return ep(null,Yl())}class Kh{constructor(){A(this,"state",Gh());A(this,"initialized",!1);A(this,"listeners",new Set);A(this,"subscribe",r=>(this.listeners.add(r),()=>{this.listeners.delete(r)}));A(this,"getState",()=>this.state);A(this,"isInitialized",()=>this.initialized)}hydrate(r){this.state=ep(r,this.state.platform),this.initialized=!0,this.emit()}updateRuntime(r){const o=r.discoveredHosts??this.state.discoveredHosts,c=r.activeDiscoveredHostId!==void 0?r.activeDiscoveredHostId:this.state.activeDiscoveredHostId,u=c&&o.some(y=>y.id===c)?c:null,p=r.localHostDiscovery??this.state.localHostDiscovery;o===this.state.discoveredHosts&&u===this.state.activeDiscoveredHostId&&p===this.state.localHostDiscovery||(this.state={...this.state,discoveredHosts:o,activeDiscoveredHostId:u,localHostDiscovery:p},this.emit())}async initialize(){const r=await jh();return this.hydrate(r),r}async update(r){const o=await qh(this.state,r);return this.hydrate(o),o}emit(){for(const r of this.listeners)r()}}const X=new Kh;function Zy(i){return He.useSyncExternalStore(X.subscribe,()=>i(X.getState()))}function Qh(i){return i.endsWith("/")?i:`${i}/`}function Yh(i){return i.replace(/^\/+/,"")}function Jl(){const i=X.getState();return ph(i)??Yd(i.platform)}function Rn(i,r=Jl()){return new URL(Yh(i),Qh(r)).toString()}function eS(i,r=Jl()){const o=new URL(Rn(i,r));return o.protocol=o.protocol==="https:"?"wss:":"ws:",o.toString()}const $h=3e4;class Jh{constructor(){A(this,"hints",new Map);A(this,"listeners",new Set);A(this,"subscribe",r=>(this.listeners.add(r),()=>{this.listeners.delete(r)}))}remember(r,o){const c=r.trim(),u=o.trim();!c||!u||(this.hints.set(c,{hostId:c,baseUrl:u,savedAt:Date.now()}),this.emit())}forget(r){const o=r==null?void 0:r.trim();!o||!this.hints.delete(o)||this.emit()}clear(){this.hints.size!==0&&(this.hints.clear(),this.emit())}get(r){const o=r==null?void 0:r.trim();if(!o)return null;const c=this.hints.get(o);return c?Date.now()-c.savedAt>$h?(this.hints.delete(o),this.emit(),null):c:null}emit(){for(const r of this.listeners)r()}}const Ca=new Jh;let Xl=!1,fd=!1;function md(){return Xh(),Xl}function Xh(){fd||typeof window>"u"||(fd=!0,window.addEventListener("beforeunload",hd,{capture:!0}),window.addEventListener("pagehide",hd,{capture:!0}),window.addEventListener("pageshow",Zh,{capture:!0}))}function hd(){Xl=!0}function Zh(){Xl=!1}class et extends Error{constructor(o,c){super(c.detail);A(this,"status");A(this,"errorCode");A(this,"field");A(this,"data");this.name="ApiError",this.status=o,this.errorCode=c.error_code,this.field=c.field,this.data=c.data}}function tS(i){return i instanceof et&&i.errorCode==="NETWORK_ERROR"}function aS(i){return i instanceof et&&i.errorCode==="INVALID_RESPONSE"}const gd="codingns.auth.client-instance-id",eg="x-codingns-client-type",tg="x-codingns-client-instance-id";let oa=null;function tp(){return{[eg]:ag(),[tg]:ig()}}function ag(){const i=Yl();switch(i){case"desktop":case"ios":case"android":return i;default:return"web"}}function ig(){var o;if(oa)return oa;if(!rg())return oa=bd(),oa;const i=(o=window.localStorage.getItem(gd))==null?void 0:o.trim();if(i)return oa=i,oa;const r=bd();return window.localStorage.setItem(gd,r),oa=r,oa}function bd(){var i;return typeof((i=globalThis.crypto)==null?void 0:i.randomUUID)=="function"?globalThis.crypto.randomUUID():`client-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`}function rg(){return typeof window<"u"&&typeof window.localStorage<"u"}const dn="codingns.auth.session",ng=3e3,og=15e3;class lg{constructor(){A(this,"state",{status:"anonymous",session:null,sessionReady:!0});A(this,"listeners",new Set);A(this,"sessionMap",{});A(this,"lastRuntimeConfigSyncKey",null);A(this,"lastStoredSessionValidationKey",null);A(this,"refreshInFlight",null);A(this,"subscribe",r=>(this.listeners.add(r),()=>{this.listeners.delete(r)}));A(this,"getState",()=>this.state);this.syncCurrentHostSession(),X.subscribe(()=>{this.syncCurrentHostSession()})}async login(r,o){const c=this.getCurrentHost();if(!c){const{loginRequest:p}=await sa(async()=>{const{loginRequest:k}=await Promise.resolve().then(()=>Ol);return{loginRequest:k}},void 0),y=await p(r,o);return this.updateState({status:"authenticated",session:y,sessionReady:!0}),y}const u=await this.loginForHost(c,r,o);return this.updateState({status:"authenticated",session:u,sessionReady:!0}),u}async loginForHost(r,o,c){var O;const{loginRequest:u}=await sa(async()=>{const{loginRequest:E}=await Promise.resolve().then(()=>Ol);return{loginRequest:E}},void 0),{resolveLoginBaseUrlWithDirectCandidates:p}=await sa(async()=>{const{resolveLoginBaseUrlWithDirectCandidates:E}=await import("./login-direct-candidate-resolver-CGaxAXV8.js");return{resolveLoginBaseUrlWithDirectCandidates:E}},[]),y=c??r.baseUrl,k=await p({host:r,requestedBaseUrl:y,platform:X.getState().platform}),L=await u(o,k);return k!==r.baseUrl?Ca.remember(r.id,k):Ca.forget(r.id),this.persistSession(r,L),((O=this.getCurrentHost())==null?void 0:O.id)===r.id&&(this.updateState({status:"authenticated",session:L,sessionReady:!0}),this.scheduleRuntimeConfigSync(r,L)),L}async bootstrap(r,o,c){const{setupRequest:u}=await sa(async()=>{const{setupRequest:p}=await Promise.resolve().then(()=>Ol);return{setupRequest:p}},void 0);await u({username:r,password:o},c)}hydrate(r){if(!r){this.clear();return}this.setSession(r)}async refresh(){if(this.refreshInFlight)return await this.refreshInFlight;const r=this.runRefresh();this.refreshInFlight=r;try{return await r}finally{this.refreshInFlight===r&&(this.refreshInFlight=null)}}shouldRefreshCurrentSession(r=Date.now()){return gg(this.getCurrentSessionEnvelope(),r)}async runRefresh(){const r=this.state.session,o=r==null?void 0:r.refreshToken,c=this.getCurrentHost();if(!o)return this.clear(),{status:"invalid",session:null};this.state={...this.state,status:"refreshing"},this.emit();try{const u=await Sd(o,c==null?void 0:c.baseUrl);return this.setSession(u,c),this.scheduleRuntimeConfigSync(c,u),{status:"refreshed",session:u}}catch(u){return yd(u)?(this.clear(),{status:"invalid",session:null}):(this.state={status:r?"authenticated":"anonymous",session:r,sessionReady:this.state.sessionReady},this.emit(),{status:"deferred",session:r,error:u})}}clear(){const r=this.getCurrentHost();if(this.lastRuntimeConfigSyncKey=null,this.lastStoredSessionValidationKey=null,!r){Ca.clear(),this.sessionMap={},this.persistSessionMap(),this.updateState({status:"anonymous",session:null,sessionReady:!0});return}if(Ca.forget(r.id),this.sessionMap[r.id]){const o={...this.sessionMap};delete o[r.id],this.sessionMap=o,this.persistSessionMap()}this.updateState({status:"anonymous",session:null,sessionReady:!0})}clearHostSession(r){var c;if(!r||(Ca.forget(r),!this.sessionMap[r]))return;const o={...this.sessionMap};delete o[r],this.sessionMap=o,this.persistSessionMap(),((c=this.getCurrentHost())==null?void 0:c.id)===r&&(this.lastRuntimeConfigSyncKey=null,this.lastStoredSessionValidationKey=null,this.updateState({status:"anonymous",session:null,sessionReady:!0}))}setSession(r,o=this.getCurrentHost(),c={}){o&&(this.persistSession(o,r),this.lastStoredSessionValidationKey=pn(o,r),this.updateState({status:"authenticated",session:r,sessionReady:c.sessionReady??!0}))}persistSession(r,o){this.lastStoredSessionValidationKey=pn(r,o),this.sessionMap={...this.sessionMap,[r.id]:{hostId:r.id,session:o,savedAt:Date.now()}},this.persistSessionMap();const c=new Date().toISOString();if(Wd(r)){X.updateRuntime({discoveredHosts:X.getState().discoveredHosts.map(u=>u.id===r.id?{...u,lastConnectedAt:c,lastUserId:o.user.userId,lastUsername:o.user.username,updatedAt:c}:u)});return}X.update({hosts:X.getState().hosts.map(u=>u.id===r.id?{...u,lastConnectedAt:c,lastUserId:o.user.userId,lastUsername:o.user.username,updatedAt:c}:u)}).catch(()=>{})}syncCurrentHostSession(){var k;if(!X.isInitialized())return;const r=this.getCurrentHost(),{sessionMap:o,migrated:c}=this.readSessionMapFromStorage(r),u=mg(o);this.sessionMap=u,(c||Object.keys(u).length!==Object.keys(o).length)&&this.persistSessionMap();const p=r?((k=u[r.id])==null?void 0:k.session)??null:null;if(!r||!p){this.lastStoredSessionValidationKey=null,this.updateState({status:"anonymous",session:null,sessionReady:!0}),this.lastRuntimeConfigSyncKey=null;return}const y=pn(r,p);if(this.lastStoredSessionValidationKey===y){this.updateState({status:"authenticated",session:p,sessionReady:!0});return}this.updateState({status:"authenticated",session:p,sessionReady:!1}),this.scheduleStoredSessionValidation(r,p)}getCurrentHost(){return Da(X.getState())}getCurrentSessionEnvelope(){const r=this.getCurrentHost();return r?this.sessionMap[r.id]??null:null}readSessionMapFromStorage(r){if(typeof window>"u"||typeof window.localStorage>"u")return{sessionMap:{},migrated:!1};const o=window.localStorage.getItem(dn);if(!o)return{sessionMap:{},migrated:!1};try{const c=JSON.parse(o);if(ug(c))return{sessionMap:c,migrated:!1};const u=pg(c,r);if(u)return{sessionMap:u,migrated:!0}}catch{}return window.localStorage.removeItem(dn),{sessionMap:{},migrated:!1}}persistSessionMap(){if(!(typeof window>"u"||typeof window.localStorage>"u")){if(Object.keys(this.sessionMap).length===0){window.localStorage.removeItem(dn);return}window.localStorage.setItem(dn,JSON.stringify(this.sessionMap))}}updateState(r){this.state.status===r.status&&this.state.session===r.session&&this.state.sessionReady===r.sessionReady||(this.state=r,this.emit())}async ensureRuntimeConfigSynced(r,o){var u;if(!r||!o||md()){this.lastRuntimeConfigSyncKey=null;return}if(((u=this.getCurrentHost())==null?void 0:u.id)!==r.id)return;const c=`${r.id}:${o.accessToken}`;if(this.lastRuntimeConfigSyncKey!==c){this.lastRuntimeConfigSyncKey=c;try{const{syncActiveHostAuthenticatedRuntimeConfig:p}=await sa(async()=>{const{syncActiveHostAuthenticatedRuntimeConfig:y}=await import("./client-runtime-manager-CgPJq21V.js");return{syncActiveHostAuthenticatedRuntimeConfig:y}},[]);await cg(p(),ng,"runtime_config_sync_timeout")}catch{this.lastRuntimeConfigSyncKey===c&&(this.lastRuntimeConfigSyncKey=null)}}}scheduleRuntimeConfigSync(r,o){this.ensureRuntimeConfigSynced(r,o)}scheduleStoredSessionValidation(r,o){this.ensureStoredSessionValidated(r,o)}async ensureStoredSessionValidated(r,o){var u,p,y,k,L,O;if(md()||((u=this.getCurrentHost())==null?void 0:u.id)!==r.id||((p=this.state.session)==null?void 0:p.refreshToken)!==o.refreshToken)return;const c=pn(r,o);try{const E=await Sd(o.refreshToken,r.baseUrl);if(((y=this.getCurrentHost())==null?void 0:y.id)!==r.id||((k=this.state.session)==null?void 0:k.refreshToken)!==o.refreshToken)return;this.lastStoredSessionValidationKey=c,this.setSession(E,r,{sessionReady:!0}),this.scheduleRuntimeConfigSync(r,E)}catch(E){if(((L=this.getCurrentHost())==null?void 0:L.id)!==r.id||((O=this.state.session)==null?void 0:O.refreshToken)!==o.refreshToken)return;if(yd(E)){this.clear();return}this.lastStoredSessionValidationKey=c,this.updateState({status:"authenticated",session:o,sessionReady:!0})}}emit(){for(const r of this.listeners)r()}}const Me=new lg;function iS(i){return He.useSyncExternalStore(Me.subscribe,()=>i(Me.getState()))}function sg(i){if(typeof i!="object"||i===null)return!1;const r=i;return typeof r.hostId=="string"&&typeof r.savedAt=="number"&&Fn(r.session)}function cg(i,r,o){return new Promise((c,u)=>{const p=globalThis.setTimeout(()=>{u(new Error(o))},r);i.then(y=>{globalThis.clearTimeout(p),c(y)},y=>{globalThis.clearTimeout(p),u(y)})})}function ug(i){return typeof i!="object"||i===null||Array.isArray(i)?!1:Object.values(i).every(r=>sg(r))}function dg(i){return typeof i!="object"||i===null?!1:"session"in i&&Fn(i.session)}function Fn(i){if(typeof i!="object"||i===null)return!1;const r=i;return typeof r.accessToken=="string"&&typeof r.refreshToken=="string"&&typeof r.expiresIn=="number"&&typeof r.user=="object"&&r.user!==null}function pg(i,r){const o=(r==null?void 0:r.id)??null;if(!o)return null;if(dg(i)){const c=fg(i.serverBaseUrl,r)??o;return{[c]:{hostId:c,session:i.session,savedAt:Date.now()}}}return Fn(i)?{[o]:{hostId:o,session:i,savedAt:Date.now()}}:null}function fg(i,r){if(!i)return(r==null?void 0:r.id)??null;const c=X.getState().hosts.find(u=>u.baseUrl===i);return(c==null?void 0:c.id)??(r==null?void 0:r.id)??null}function yd(i){return i instanceof et?i.status===401?!0:i.status===403&&i.errorCode==="BOOTSTRAP_REQUIRED":!1}function mg(i){const r=Object.entries(i).filter(([,o])=>!hg(o));return Object.fromEntries(r)}function hg(i){var o;const r=(o=i.session)==null?void 0:o.expiresIn;return typeof r!="number"||!Number.isFinite(r)||r<=0?!0:i.savedAt+r*1e3<=Date.now()}function gg(i,r){var c;const o=(c=i==null?void 0:i.session)==null?void 0:c.expiresIn;return!(i!=null&&i.session)||typeof o!="number"||!Number.isFinite(o)||o<=0?!1:i.savedAt+o*1e3<=r+og}function pn(i,r){return`${i.id}:${r.refreshToken}`}async function Sd(i,r){const o=await fetch(Rn("/api/auth/refresh",r),{method:"POST",headers:{...tp(),"Content-Type":"application/json"},body:JSON.stringify({refreshToken:i})}),c=await o.text(),u=c?bg(c):null;if(!o.ok)throw new et(o.status,{detail:(u==null?void 0:u.detail)??`请求失败(HTTP ${o.status})`,error_code:(u==null?void 0:u.error_code)??(o.status===401?"UNAUTHORIZED":"HTTP_ERROR"),field:u==null?void 0:u.field,data:u==null?void 0:u.data,timestamp:u==null?void 0:u.timestamp});if(!u||!Fn(u))throw new et(o.status,{detail:"刷新登录态返回了无效响应",error_code:"HTTP_ERROR"});return u}function bg(i){try{return JSON.parse(i)}catch{return null}}const ai=new Map,ap=48;function Pa(){return typeof window<"u"&&typeof window.sessionStorage<"u"}function kd(i,r){return!Number.isFinite(i)||Date.now()-i>r}function yg(i){return!i||typeof i!="object"||!("savedAt"in i)||!("value"in i)?!1:Number.isFinite(i.savedAt)}function ip(i){try{const r=JSON.parse(i);return yg(r)?r:null}catch{return null}}function Sg(){if(!Pa())return[];try{return Array.from({length:window.sessionStorage.length},(i,r)=>window.sessionStorage.key(r)).filter(i=>typeof i=="string"&&i.length>0)}catch{return[]}}function rp(){if(!Pa())return[];const i=[];for(const r of Sg()){let o=null;try{o=window.sessionStorage.getItem(r)}catch{continue}if(!o)continue;const c=ip(o);c&&i.push({key:r,savedAt:c.savedAt})}return i.sort((r,o)=>r.savedAt-o.savedAt)}function Yi(i){if(Pa())try{window.sessionStorage.removeItem(i)}catch{}}function fn(i){const r=new Set((i==null?void 0:i.preserveKeys)??[]),o=(i==null?void 0:i.maxCount)??ap,c=rp().filter(p=>!r.has(p.key)),u=Math.max(0,r.size+c.length-o);for(let p=0;p<u;p+=1){const y=c[p];if(!y)break;Yi(y.key)}}function kg(i){return i instanceof DOMException&&(i.name==="QuotaExceededError"||i.name==="NS_ERROR_DOM_QUOTA_REACHED"||i.code===22||i.code===1014)}function Ml(i,r){if(!Pa())return"failed";try{return window.sessionStorage.setItem(i,r),"success"}catch(o){return kg(o)?"quota_exceeded":"failed"}}function Tg(i,r){const o=Ml(i,r);if(o==="success"){fn({preserveKeys:[i]});return}if(o==="quota_exceeded"){if(Yi(i),fn({maxCount:Math.max(0,ap-1)}),Ml(i,r)==="success"){fn({preserveKeys:[i]});return}for(const c of rp())if(c.key!==i&&(Yi(c.key),Ml(i,r)==="success")){fn({preserveKeys:[i]});return}}}function wg(i,r){const o=ai.get(i);if(o){if(!kd(o.savedAt,r))return o.value;ai.delete(i)}if(!Pa())return null;let c=null;try{c=window.sessionStorage.getItem(i)}catch{return null}if(!c)return null;const u=ip(c);return!u||kd(u.savedAt,r)?(Yi(i),ai.delete(i),null):(ai.set(i,u),u.value)}function vg(i,r){const o={savedAt:Date.now(),value:r};if(ai.set(i,o),!!Pa())try{Tg(i,JSON.stringify(o))}catch{}}function rS(i){ai.delete(i),Pa()&&Yi(i)}const Cg="workbench.affairs.dashboard.",np=7,Dg=365*24*60*60*1e3,Pg=/\.(html?|HTML?)$/;function op(i){return`${Cg}${i}`}function La(i){var r;return typeof((r=globalThis.crypto)==null?void 0:r.randomUUID)=="function"?`${i}-${globalThis.crypto.randomUUID()}`:`${i}-${Date.now()}-${Math.random().toString(16).slice(2)}`}function Rt(i){return!!i&&typeof i=="object"&&!Array.isArray(i)}function mn(i){return Number.isInteger(i)&&Number(i)>0}function Td(i){return Number.isInteger(i)&&Number(i)>=0}function Zl(i){const r=i.trim().replace(/\\/g,"/"),o=r.split("/").filter(Boolean);return o[o.length-1]??r}function nS(i){const r=(i==null?void 0:i.trim())??"";return r.length>0&&Pg.test(r)}function lp(i,r,o="embed"){return i==="todo"?tt("shell.affairsTodoAllFilter"):i==="automation"?tt("shell.affairsAutomationStageTitle"):i==="teable"?tt("shell.teableRuntimeDefaultBlockTitle"):r!=null&&r.trim()?Zl(r):Lg(o)}function Lg(i){return tt(i==="app"?"shell.affairsWorkbenchHtmlAppDefaultTitle":i==="stat"?"shell.affairsWorkbenchHtmlStatDefaultTitle":"shell.affairsWorkbenchHtmlEmbedDefaultTitle")}function sp(i,r=new Date().toISOString()){var c,u,p;const o=i.type==="html"?Wl(i.variant)??"embed":void 0;return{id:La("dashboard-widget"),type:i.type,variant:o,title:((c=i.title)==null?void 0:c.trim())||lp(i.type,(u=i.sourceRef)==null?void 0:u.sourceId,o),sourceRef:i.sourceRef?{...i.sourceRef,workspaceId:((p=i.sourceRef.workspaceId)==null?void 0:p.trim())||void 0}:void 0,config:Rt(i.config)?i.config:{},createdAt:r,updatedAt:r}}function Ag(i){return sp({type:"todo",title:tt("shell.affairsTodoAllFilter"),config:{filter:"all",view:"compact"}},i)}function Rg(i){return sp({type:"automation",title:tt("shell.affairsAutomationStageTitle"),config:{scope:"all",view:"list"}},i)}function cp(i){return i.map((r,o)=>({widgetId:r.id,x:o===0?0:6,y:0,w:6,h:5,minW:4,minH:3}))}function oS(i,r=new Date().toISOString()){return{id:La("dashboard-tab"),title:i.trim()||tt("shell.affairsWorkbenchDefaultTabTitle"),widgets:[],layout:[],createdAt:r,updatedAt:r}}function Fg(i=new Date().toISOString()){const r=[Ag(i),Rg(i)];return{id:La("dashboard-tab"),title:tt("shell.affairsWorkbenchDefaultTabTitle"),widgets:r,layout:cp(r),createdAt:i,updatedAt:i}}function lS(i,r=new Date().toISOString()){var y,k;const o=i.entryPath.trim(),c=i.workspaceId.trim(),u=((y=i.sourceId)==null?void 0:y.trim())||o,p=i.sourceKind==="affairs_library"?"affairs_library":"workspace";return{id:La("shortcut-app"),title:((k=i.title)==null?void 0:k.trim())||Zl(o),sourceKind:p,workspaceId:c,sourceId:u,entryPath:o,createdAt:r,updatedAt:r}}function Eg(i,r=new Date().toISOString()){const o=Fg(r);return{workspaceId:i,version:np,layoutLocked:!0,activeTabId:o.id,tabs:[o],shortcutApps:[],updatedAt:r}}function Mg(i,r){if(!Rt(i))return null;const o=Ng(i.type,Rt(i.config)?i.config.variant:void 0,i.variant);if(!o)return null;const c=Rt(i.sourceRef)?{kind:i.sourceRef.kind==="html_shortcut"?"html_shortcut":i.sourceRef.kind==="affairs_library_html"?"affairs_library_html":"plugin_runtime",workspaceId:typeof i.sourceRef.workspaceId=="string"&&i.sourceRef.workspaceId.trim()?i.sourceRef.workspaceId.trim():void 0,sourceId:typeof i.sourceRef.sourceId=="string"?i.sourceRef.sourceId.trim():"",entryId:typeof i.sourceRef.entryId=="string"&&i.sourceRef.entryId.trim()?i.sourceRef.entryId.trim():void 0}:void 0;return o.type==="html"&&!(c!=null&&c.sourceId)||o.type==="teable"&&!Rt(i.config)?null:{id:typeof i.id=="string"&&i.id.trim()?i.id.trim():La("dashboard-widget"),type:o.type,variant:o.variant,title:typeof i.title=="string"&&i.title.trim()?i.title.trim():lp(o.type,c==null?void 0:c.sourceId,o.variant??"embed"),sourceRef:c,config:Bg(Rt(i.config)?i.config:{}),createdAt:typeof i.createdAt=="string"&&i.createdAt.trim()?i.createdAt:r,updatedAt:typeof i.updatedAt=="string"&&i.updatedAt.trim()?i.updatedAt:r}}function Ig(i){return!Rt(i)||typeof i.widgetId!="string"||!i.widgetId.trim()||!Td(i.x)||!Td(i.y)||!mn(i.w)||!mn(i.h)?null:{widgetId:i.widgetId.trim(),x:i.x,y:i.y,w:i.w,h:i.h,minW:mn(i.minW)?i.minW:void 0,minH:mn(i.minH)?i.minH:void 0}}function xg(i,r){if(!Rt(i))return null;const o=i.sourceKind==="affairs_library"?"affairs_library":"workspace",c=typeof i.workspaceId=="string"?i.workspaceId.trim():"",u=typeof i.entryPath=="string"?i.entryPath.trim():"";if(!c||!u)return null;const p=typeof i.sourceId=="string"&&i.sourceId.trim()?i.sourceId.trim():u;return{id:typeof i.id=="string"&&i.id.trim()?i.id.trim():La("shortcut-app"),title:typeof i.title=="string"&&i.title.trim()?i.title.trim():Zl(u),sourceKind:o,workspaceId:c,sourceId:p,entryPath:u,createdAt:typeof i.createdAt=="string"&&i.createdAt.trim()?i.createdAt:r,updatedAt:typeof i.updatedAt=="string"&&i.updatedAt.trim()?i.updatedAt:r}}function Og(i,r){if(!Rt(i))return null;const o=(Array.isArray(i.widgets)?i.widgets:[]).map(p=>Mg(p,r)).filter(p=>p!==null),c=new Map((Array.isArray(i.layout)?i.layout:[]).map(p=>Ig(p)).filter(p=>p!==null).map(p=>[p.widgetId,p])),u=cp(o);return{id:typeof i.id=="string"&&i.id.trim()?i.id.trim():La("dashboard-tab"),title:typeof i.title=="string"&&i.title.trim()?i.title.trim():tt("shell.affairsWorkbenchDefaultTabTitle"),widgets:o,layout:o.map((p,y)=>c.get(p.id)??u[y]),createdAt:typeof i.createdAt=="string"&&i.createdAt.trim()?i.createdAt:r,updatedAt:typeof i.updatedAt=="string"&&i.updatedAt.trim()?i.updatedAt:r}}function up(i,r){if(!Rt(r))return null;const o=new Date().toISOString(),c=(Array.isArray(r.tabs)?r.tabs:[]).map(k=>Og(k,o)).filter(k=>k!==null),u=(Array.isArray(r.shortcutApps)?r.shortcutApps:[]).map(k=>xg(k,o)).filter(k=>k!==null);if(c.length===0)return{...Eg(i,o),shortcutApps:u};const p=typeof r.activeTabId=="string"?r.activeTabId.trim():"",y=c.some(k=>k.id===p)?p:c[0].id;return{workspaceId:i,version:np,layoutLocked:typeof r.layoutLocked=="boolean"?r.layoutLocked:!0,activeTabId:y,tabs:c,shortcutApps:u,updatedAt:typeof r.updatedAt=="string"&&r.updatedAt.trim()?r.updatedAt:o}}function Wl(i){return i==="app"||i==="stat"||i==="embed"?i:null}function Hg(i){return i==="html_app"?"app":i==="html_stat"?"stat":i==="html_embed"?"embed":null}function Ng(i,r,o){if(i==="todo"||i==="automation"||i==="teable")return{type:i};if(i==="html")return{type:"html",variant:Wl(o)??Wl(r)??"embed"};const c=Hg(i);return c?{type:"html",variant:c}:null}function Bg(i){if(!("variant"in i))return i;const{variant:r,...o}=i;return o}function sS(i){const r=i==null?void 0:i.trim();if(!r)return null;const o=wg(op(r),Dg);return o?up(r,o):null}function cS(i){vg(op(i.workspaceId),i)}const En=["claude-code","codex","opencode","gemini","kimi"],dp="codingns.account.preferences.shadow",Wg="codingns.client.runtime-config",Ug="codingns-theme",_g="composer-selected-model:",Vg="composer-reasoning-level:",es={start:43e3,end:47999};function Xi(){return typeof window<"u"&&typeof window.localStorage<"u"}function ts(i){return i==="en-US"||i==="en"?"en-US":i==="zh-CN"?"zh-CN":null}function zg(){return typeof navigator>"u"?"zh-CN":ts(navigator.language)??"zh-CN"}function pp(i){return i==="light"||i==="dark"||i==="sky-blue"||i==="eye-green"?i:null}function jg(){return typeof window>"u"||typeof window.matchMedia!="function"?"light":window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function qg(i){return typeof i=="boolean"?i:null}function fp(i){return i==="acceptEdits"||i==="bypassPermissions"||i==="default"?i:null}function mp(i){return i==="low"||i==="medium"||i==="high"||i==="xhigh"?i:null}function hp(){return{"claude-code":{defaultModel:null,defaultReasoningLevel:null},codex:{defaultModel:null,defaultReasoningLevel:null},opencode:{defaultModel:null,defaultReasoningLevel:null},gemini:{defaultModel:null,defaultReasoningLevel:null},kimi:{defaultModel:null,defaultReasoningLevel:null}}}function gp(){return{initialized:!0,profile:{language:zg(),theme:jg(),autoTheme:!1,defaultPermissionMode:"default",debugPortPools:Dn(es)},providers:hp(),affairsDashboardStatesByWorkspace:{},updatedAt:null,source:"default"}}function Gg(){const i=X.getState(),r={language:i.language,defaultPermissionMode:i.defaultPermissionMode};if(!Xi())return r;const o=window.localStorage.getItem(Wg);if(!o)return r;try{const c=JSON.parse(o);return{language:ts(c.language)??r.language,defaultPermissionMode:fp(c.defaultPermissionMode)??r.defaultPermissionMode}}catch{return r}}function Kg(){return Xi()?pp(window.localStorage.getItem(Ug)):null}function Qg(){var r;if(!Xi())return;const i={};for(const o of En){const c=((r=window.localStorage.getItem(`${_g}${o}`))==null?void 0:r.trim())||null,u=mp(window.localStorage.getItem(`${Vg}${o}`));c===null&&u===null||(i[o]={defaultModel:c,defaultReasoningLevel:u})}return Object.keys(i).length>0?i:void 0}function bp(){const i=Gg(),r=Kg(),o=Qg(),c={};return i.language&&(c.language=i.language),r&&(c.theme=r),i.defaultPermissionMode&&(c.defaultPermissionMode=i.defaultPermissionMode),o&&(c.providers=o),yp(c)?c:null}function yp(i){return i?i.language!==void 0||i.theme!==void 0||i.autoTheme!==void 0||i.defaultPermissionMode!==void 0||i.debugPortPools!==void 0||i.affairsDashboardStatesByWorkspace!==void 0||i.providers!==void 0&&Object.keys(i.providers).length>0:!1}function vn(i){var c;const r=gp(),o=hp();for(const u of En){const p=(c=i==null?void 0:i.providers)==null?void 0:c[u];o[u]={defaultModel:typeof(p==null?void 0:p.defaultModel)=="string"&&p.defaultModel.trim()||null,defaultReasoningLevel:mp(p==null?void 0:p.defaultReasoningLevel)??null}}return{language:ts(i==null?void 0:i.language)??r.profile.language,theme:pp(i==null?void 0:i.theme)??r.profile.theme,autoTheme:qg(i==null?void 0:i.autoTheme)??r.profile.autoTheme,defaultPermissionMode:fp(i==null?void 0:i.defaultPermissionMode)??r.profile.defaultPermissionMode,debugPortPools:$g(i==null?void 0:i.debugPortPools)??r.profile.debugPortPools,providers:o,affairsDashboardStatesByWorkspace:kp(i==null?void 0:i.affairsDashboardStatesByWorkspace),updatedAt:typeof(i==null?void 0:i.updatedAt)=="string"?i.updatedAt:null}}function Yg(){var r,o,c,u,p;if(!Xi())return null;const i=window.localStorage.getItem(dp);if(!i)return null;try{const y=JSON.parse(i),k=vn({language:(r=y.profile)==null?void 0:r.language,theme:(o=y.profile)==null?void 0:o.theme,autoTheme:(c=y.profile)==null?void 0:c.autoTheme,defaultPermissionMode:(u=y.profile)==null?void 0:u.defaultPermissionMode,debugPortPools:(p=y.profile)==null?void 0:p.debugPortPools,providers:y.providers,affairsDashboardStatesByWorkspace:y.affairsDashboardStatesByWorkspace,updatedAt:y.updatedAt});return{profile:{language:k.language,theme:k.theme,autoTheme:k.autoTheme,defaultPermissionMode:k.defaultPermissionMode,debugPortPools:k.debugPortPools},providers:k.providers,affairsDashboardStatesByWorkspace:k.affairsDashboardStatesByWorkspace,updatedAt:k.updatedAt}}catch{return null}}function Cn(i){if(!Xi())return;const r={profile:i.profile,providers:i.providers,affairsDashboardStatesByWorkspace:i.affairsDashboardStatesByWorkspace,updatedAt:i.updatedAt};window.localStorage.setItem(dp,JSON.stringify(r))}function ei(){const i=gp(),r=bp(),o=r?Sp(i,r,"default"):i,c=Yg();return c?{initialized:!0,profile:c.profile,providers:c.providers,affairsDashboardStatesByWorkspace:c.affairsDashboardStatesByWorkspace,updatedAt:c.updatedAt,source:"shadow"}:o}function Ul(i,r){return{initialized:!0,profile:{language:i.language,theme:i.theme,autoTheme:i.autoTheme,defaultPermissionMode:i.defaultPermissionMode,debugPortPools:Dn(i.debugPortPools??es)},providers:i.providers,affairsDashboardStatesByWorkspace:i.affairsDashboardStatesByWorkspace??{},updatedAt:i.updatedAt,source:r}}function Sp(i,r,o){const c={...i.providers};if(r.providers)for(const u of En){const p=r.providers[u];p&&(c[u]={defaultModel:p.defaultModel!==void 0?p.defaultModel??null:i.providers[u].defaultModel,defaultReasoningLevel:p.defaultReasoningLevel!==void 0?p.defaultReasoningLevel??null:i.providers[u].defaultReasoningLevel})}return{initialized:!0,profile:{language:r.language??i.profile.language,theme:r.theme??i.profile.theme,autoTheme:r.autoTheme??i.profile.autoTheme,defaultPermissionMode:r.defaultPermissionMode??i.profile.defaultPermissionMode,debugPortPools:r.debugPortPools?Dn(r.debugPortPools):i.profile.debugPortPools??Dn(es)},providers:c,affairsDashboardStatesByWorkspace:r.affairsDashboardStatesByWorkspace!==void 0?kp(r.affairsDashboardStatesByWorkspace):i.affairsDashboardStatesByWorkspace??{},updatedAt:i.updatedAt,source:o}}function kp(i){if(!i||typeof i!="object"||Array.isArray(i))return{};const r={};for(const[o,c]of Object.entries(i)){const u=o.trim();if(!u)continue;const p=up(u,c);p&&(r[u]=p)}return r}function $g(i){if(!i||typeof i!="object"||Array.isArray(i))return null;const r=Tp(i);return r||Jg(i)}function wd(i){if(!Number.isInteger(i))return null;const r=Number(i);return r>=1024&&r<=65535?r:null}function Tp(i){if(!i||typeof i!="object"||Array.isArray(i))return null;const r=i;if(!Object.prototype.hasOwnProperty.call(r,"start")||!Object.prototype.hasOwnProperty.call(r,"end"))return null;const o=wd(r.start),c=wd(r.end);return o===null||c===null||o>=c?null:{start:o,end:c}}function Jg(i){if(!i||typeof i!="object"||Array.isArray(i))return null;const r=["frontend","backend","worker","mock","custom"];let o=Number.POSITIVE_INFINITY,c=Number.NEGATIVE_INFINITY;for(const u of r){const p=Tp(i[u]);if(!p)return null;o=Math.min(o,p.start),c=Math.max(c,p.end)}return Number.isFinite(o)&&Number.isFinite(c)&&o<c?{start:o,end:c}:null}function Dn(i){return{...i}}async function Xg(){const{fetchPreferencesProfile:i,updatePreferencesProfile:r}=await sa(async()=>{const{fetchPreferencesProfile:u,updatePreferencesProfile:p}=await import("./preferences-service-lOhnlxzP.js");return{fetchPreferencesProfile:u,updatePreferencesProfile:p}},[]),o=vn(await i());if(o.updatedAt===null){const u=bp();if(yp(u)){const p=vn(await r(u)),y=Ul(p,"remote");return Cn(y),y}}const c=Ul(o,"remote");return Cn(c),c}class Zg{constructor(){A(this,"state",ei());A(this,"listeners",new Set);A(this,"subscribe",r=>(this.listeners.add(r),()=>{this.listeners.delete(r)}));A(this,"getState",()=>this.state);X.subscribe(()=>{Me.getState().session||this.state.source==="remote"||this.hydrate(ei())})}hydrate(r){this.state=r,this.emit()}resetToLocalFallback(){this.hydrate(ei())}async initialize(){if(!Me.getState().session){const r=ei();return this.hydrate(r),r}return this.refreshForAuthenticatedUser()}async refreshForAuthenticatedUser(){if(!Me.getState().session){const r=ei();return this.hydrate(r),r}try{const r=await Xg();return this.hydrate(r),r}catch{const r=ei();return this.hydrate(r),r}}async updateProfile(r){const o=this.state,c=Sp(o,r,o.source);if(this.hydrate(c),!Me.getState().session)return Cn(c),c;try{const{updatePreferencesProfile:u}=await sa(async()=>{const{updatePreferencesProfile:k}=await import("./preferences-service-lOhnlxzP.js");return{updatePreferencesProfile:k}},[]),p=vn(await u(r)),y=Ul(p,"remote");return Cn(y),this.hydrate(y),y}catch(u){throw this.hydrate(o),u}}async updateProviderPreference(r,o){return this.updateProfile({providers:{[r]:o}})}emit(){for(const r of this.listeners)r()}}const ri=new Zg;function wp(i){return He.useSyncExternalStore(ri.subscribe,()=>i(ri.getState()))}function eb(i){return En.includes(i)}const uS=Object.freeze(Object.defineProperty({__proto__:null,isPreferenceProviderId:eb,useUserPreferenceSelector:wp,userPreferenceStore:ri},Symbol.toStringTag,{value:"Module"}));function tb(){return ri.initialize()}function dS(i){return ri.updateProfile(i)}function ab(i){return wp(r=>i({profile:{...r.profile,providers:r.providers,affairsDashboardStatesByWorkspace:r.affairsDashboardStatesByWorkspace??{},updatedAt:r.updatedAt},isFetching:!1,error:null}))}const ib={common:{close:"关闭",cancel:"取消",copy:"复制",copyFailed:"复制失败",enabled:"已启用",disabled:"已关闭",logout:"退出登录",language:"语言",none:"无"},locale:{zhCN:"简体中文",enUS:"English"},settings:{title:"设置",appearance:"外观",language:"语言",languageDescription:"选择界面显示语言,切换后立即应用到当前页面。",theme:"主题",themeDescription:"选择适合你的界面配色方案",connection:"连接与更新",serverAddress:"服务地址",serverDescription:"桌面端和 H5 都通过这个 Host 入口工作。",releaseChannel:"发布通道",releaseChannelDescription:"稳定版或测试版",releaseStable:"Stable",releaseBeta:"Beta",autoReconnect:"自动重连",autoReconnectDescription:"当 Host 短暂不可达时,自动尝试恢复 HTTP 和 WebSocket 链路。",autoCheckUpdate:"自动检查客户端更新",autoCheckUpdateDescription:"仅客户端",notificationSettings:"通知",notificationSettingsDescription:"单独控制会话相关的系统通知提醒。",notifyOnPermissionRequest:"会话等待审批时通知",notifyOnPermissionRequestDescription:"后台会话出现新的权限申请时推送通知。",notifyOnSessionCompleted:"会话完成时通知",notifyOnSessionCompletedDescription:"后台会话变为已完成时推送通知。",notifyOnSessionFailed:"会话异常时通知",notifyOnSessionFailedDescription:"后台会话运行失败时推送通知。",enabled:"已启用",disabled:"已关闭",serverUpdate:"服务端更新",serverUpdateDescription:"",clientUpdate:"客户端更新",clientUpdateDescription:"",serverCurrentVersion:"服务端当前版本",serverTargetVersion:"服务端目标版本",serverPackageName:"npm 包名",serverUpdateCommand:"升级命令",serverCheckNow:"检查服务端",serverInstallNow:"安装更新",serverOpenPage:"打开 npm",serverLatestUnknown:"暂未获取",serverUpdateReady:"发现新版本",serverUpToDate:"已是最新版本",serverCheckFailed:"检查失败",serverInstallWarning:"安装更新会通过 PM2 自动重启 CodingNS 服务,连接会短暂中断。",serverInstallConfirmTitle:"安装服务端更新",serverInstallConfirmDescription:"继续后会先安装新版本,再由 PM2 自动重启当前 CodingNS 服务。",serverInstallConfirmAction:"继续安装并重启服务",serverRestarting:"更新已安装,正在重启 CodingNS 服务",serverInstallQueued:"已加入更新队列",serverInstalling:"正在安装更新",serverInstallSucceeded:"更新已完成",serverInstallFailed:"安装失败",serverInstallCancelled:"安装已取消",serverInstallTimeout:"安装超时",serverRestartRequired:"新版本已安装,重启 Host 后生效",serverOpenPageFailed:"打开页面失败",runtimePlatform:"当前运行平台",runtimePlatformDescription:"用来确认现在是 Web/H5、Desktop、iOS 还是 Android 运行环境。",platformDesktop:"Desktop",platformWeb:"Web",platformIos:"iOS",platformAndroid:"Android",releaseDesktopOnly:"当前是 Web/H5 运行环境,不支持桌面更新。",releaseCurrentVersion:"当前版本",releaseTargetVersion:"目标版本",releaseUnknownVersion:"未知",releaseNotes:"更新内容",releaseNotesEmpty:"暂无更新内容",releaseCheckNow:"检查客户端",releaseInstallNow:"安装更新",releaseOpenPage:"打开发布页",releaseManualOnly:"当前版本只能手动安装",releaseUpdateBadge:"新版本",releaseUpdateReady:"发现新版本",releaseUpToDate:"已是最新版本",releaseCheckFailed:"检查失败",releaseInstallStarted:"安装已开始",releaseInstallFailed:"安装失败",releasePageOpenFailed:"打开发布页失败",androidInstallerStarted:"已交给系统安装器,安装完成前你仍可以取消",androidInstallPermissionRequired:"请先允许当前应用安装未知来源应用",androidInstallCancelled:"安装已取消或未完成,可重新触发安装",androidInstallSucceeded:"已检测到新版本完成安装",clientUpdateUnsupported:"当前不支持安装更新",account:"账号",logout:"退出登录",logoutDescription:"退出当前账号并返回登录页面",advancedSettings:"高级设置",parallelTaskDebug:"并行任务调试",parallelTaskDebugDescription:"打开后才会启用运行时采样,用来实时看后台任务、调度器和主线程压力指标。",debugPortPool:"调试端口池",debugPortPoolDescription:"给子工作区的已登记启动项分配可用端口。所有调试服务统一从这个范围里拿空闲端口,不再分前后端和 Worker。",debugPortPoolRangeLabel:"端口范围",debugPortPoolRangeHint:"子工作区里的前端、后端、Worker、Mock 和自定义服务统一从这里取可用端口",debugPortPoolStart:"起始",debugPortPoolEnd:"结束",debugPortPoolRangeSeparator:"到",debugPortPoolSaveAction:"保存端口池",debugPortPoolSaved:"端口池已保存",debugPortPoolSaveFailed:"端口池保存失败",debugPortPoolValidationInteger:"端口池的起止值必须是整数",debugPortPoolValidationRange:"端口池必须在 1024 到 65535 之间,且起始值必须小于结束值",debugPortPoolValidationOverlap:"各角色的端口池不能重叠",debugPortPoolRoleFrontend:"前端",debugPortPoolRoleBackend:"后端",debugPortPoolRoleWorker:"Worker",debugPortPoolRoleMock:"Mock",debugPortPoolRoleCustom:"自定义",debugPortPoolRoleHint:"{role} 统一从这个范围里拿可用端口",parallelTaskDebugAction:"打开调试面板",parallelTaskDebugModalTitle:"并行任务调试",parallelTaskDebugModalDescription:"这个窗口打开时才会继续采集任务活动和 event loop 指标,关掉后立即停止。",parallelTaskDebugClose:"关闭并行任务调试",parallelTaskDebugLoading:"正在建立观测会话并拉取快照…",parallelTaskDebugLoadFailed:"加载并行任务调试信息失败",parallelTaskDebugEmpty:"当前没有可展示的执行记录。",parallelTaskDebugStatusActive:"采集中",parallelTaskDebugStatusError:"采集异常",parallelTaskDebugObservedAt:"最后更新",parallelTaskDebugSessionExpireAt:"会话到期时间",parallelTaskDebugSessionTtl:"会话 TTL",parallelTaskDebugCollectorState:"采集器状态",parallelTaskDebugCollectorEnabled:"已启用",parallelTaskDebugCollectorDisabled:"未启用",parallelTaskDebugAutoRefresh:"每秒自动刷新",parallelTaskDebugCountersTitle:"总指标",parallelTaskDebugRegisteredTasksTitle:"已注册任务列表",parallelTaskDebugRegisteredTasksEmpty:"当前没有可展示的已注册任务。",parallelTaskDebugTaskMetricsTitle:"最近活跃任务指标",parallelTaskDebugActiveTaskMetricsEmpty:"当前观测窗口内还没有活跃任务指标。",parallelTaskDebugSchedulerTitle:"调度器指标",parallelTaskDebugEventLoopTitle:"Event Loop",parallelTaskDebugRecentActivitiesTitle:"最近执行记录",parallelTaskDebugWaitAvg:"平均等待",parallelTaskDebugRunAvg:"平均执行",parallelTaskDebugRunMax:"最长执行",parallelTaskDebugStartedCount:"启动次数",parallelTaskDebugFinishedCount:"完成次数",parallelTaskDebugFailedCount:"失败次数",parallelTaskDebugCacheHitCount:"缓存命中",parallelTaskDebugIdle:"空转",parallelTaskDebugBusy:"已命中任务",parallelTaskDebugTickTotal:"tick 总数",parallelTaskDebugIdleTickTotal:"空转 tick",parallelTaskDebugTaskCountTotal:"命中任务",parallelTaskDebugSchedulerErrorTotal:"异常次数",parallelTaskDebugLastDuration:"上次耗时",parallelTaskDebugNextDelay:"下次延迟",parallelTaskDebugEventLoopResolution:"采样粒度",parallelTaskDebugEventLoopMean:"平均延迟",parallelTaskDebugEventLoopP95:"P95 延迟",parallelTaskDebugEventLoopP99:"P99 延迟",parallelTaskDebugEventLoopMax:"最大延迟",parallelTaskDebugTaskTimeout:"超时设置",parallelTaskDebugTaskConcurrency:"并发限制",parallelTaskDebugTaskRetry:"重试次数",parallelTaskDebugTaskCategory:"任务类型",parallelTaskDebugTaskCategoryBuiltinIndexer:"内置索引器",parallelTaskDebugTaskCategoryGeneric:"常规后台任务",parallelTaskDebugTaskRuntime:"运行方式",parallelTaskDebugTaskRuntimeBuiltinHelper:"Host 内置 Helper",parallelTaskDebugTaskRuntimeHelperProcess:"通用 Helper 进程",parallelTaskDebugTaskRuntimeHostBackground:"Host 后台内执行",parallelTaskDebugTaskRuntimeExternalProcess:"外部进程",parallelTaskDebugTaskRuntimeMainThread:"请求主线程",parallelTaskDebugTaskHelper:"Helper 处理器",parallelTaskDebugTaskKey:"任务 Key",parallelTaskDebugStatus:"状态",parallelTaskDebugAttempt:"尝试",parallelTaskDebugWaitMs:"等待",parallelTaskDebugRunMs:"执行",parallelTaskDebugSource:"来源",parallelTaskDebugError:"错误",parallelTaskDebugMetricEnqueue:"入队",parallelTaskDebugMetricDedupe:"去重",parallelTaskDebugMetricStarted:"已启动",parallelTaskDebugMetricFinished:"已完成",parallelTaskDebugMetricFailed:"失败",parallelTaskDebugMetricCancelled:"已取消",parallelTaskDebugMetricTimeout:"超时",parallelTaskDebugMetricCacheHit:"缓存命中",parallelTaskDebugLaneRequestMainThread:"请求主线程",parallelTaskDebugLaneHostBackground:"Host 后台",parallelTaskDebugLaneHelperProcess:"Helper 进程",parallelTaskDebugLaneExternalProcess:"外部进程",parallelTaskDebugEventEnqueued:"入队",parallelTaskDebugEventDeduped:"去重复用",parallelTaskDebugEventStarted:"开始",parallelTaskDebugEventFinished:"完成",parallelTaskDebugEventFailed:"失败",parallelTaskDebugEventCancelled:"取消",parallelTaskDebugEventTimeout:"超时",parallelTaskDebugEventCacheHit:"命中缓存",parallelTaskDebugTaskStatusQueued:"排队中",parallelTaskDebugTaskStatusRunning:"运行中",parallelTaskDebugTaskStatusSucceeded:"已成功",parallelTaskDebugTaskStatusFailed:"已失败",parallelTaskDebugTaskStatusCancelled:"已取消",parallelTaskDebugTaskStatusTimeout:"已超时",opencliSectionTitle:"OpenCLI 接入",opencliSectionDescription:"这里管理 CodingNS 会话里可见的 OpenCLI CLI技能,不改你机器上的全局安装。",opencliEnableAction:"启用",opencliRefreshAction:"刷新",opencliSaveAction:"保存",opencliLoading:"正在读取 OpenCLI 状态…",opencliLoadFailed:"读取 OpenCLI 状态失败",opencliSummaryInstallState:"安装状态",opencliSummaryCatalogCount:"目录总数",opencliSummaryEnabledCount:"当前启用",opencliSummaryBrowserCount:"依赖浏览器",opencliProviderToggleLabel:"在新会话里启用 OpenCLI",opencliProviderHint:"这里控制的是 CodingNS 托管会话里能不能用,不会改你自己终端里的全局 opencli。",opencliVersionLabel:"版本",opencliCatalogSourceLabel:"目录来源",opencliLastCheckedLabel:"最近检查",opencliCatalogRefreshedLabel:"最近刷新",opencliInstallPathLabel:"安装目录",opencliInstallInstalled:"已安装",opencliInstallBroken:"安装损坏",opencliInstallMissing:"未安装",opencliHealthReady:"可运行",opencliHealthBridgeMissing:"浏览器桥缺失",opencliHealthBinaryReady:"命令可用",opencliHealthRuntimeBuildFailed:"运行时构建失败",opencliHealthUnknown:"未检查",opencliCatalogSourceManifest:"安装目录 manifest",opencliCatalogSourceCliList:"opencli list",opencliCatalogSourceLocalManifest:"本地 manifest",opencliCatalogSourceCache:"最近一次缓存",opencliRuntimeReady:"裁剪运行时已就绪",opencliRuntimeFailed:"裁剪运行时失败",opencliRuntimePending:"裁剪运行时构建中",opencliRuntimeStale:"裁剪运行时已过期",opencliRuntimeIdle:"还没生成运行时",opencliRefreshDone:"OpenCLI 状态已刷新",opencliRefreshReady:"OpenCLI 状态已刷新,新会话可使用当前运行时",opencliRefreshCacheRetained:"刷新失败,已保留最近一次成功目录缓存",opencliRefreshUnavailable:"当前无法读取 OpenCLI 目录",opencliSaveReady:"OpenCLI 设置已保存,新会话会使用新的裁剪运行时",opencliSaveEnabled:"OpenCLI 设置已保存,但当前运行时还不可用",opencliSaveDisabled:"OpenCLI 已从新会话里关闭",opencliEmpty:"当前没有可展示的 OpenCLI 命令目录。",opencliEmptyNotInstalled:"当前机器还没发现 OpenCLI 安装,先装好后再回来刷新。",opencliCatalogGridTitle:"CLI技能目录",opencliCatalogGridDescription:"先用标签缩小范围,再按站点卡片查看和切换具体命令。",opencliDetailAction:"详情",opencliDetailTitle:"OpenCLI 详情",opencliDetailStatusHeading:"当前状态",opencliDetailRuntimeIdLabel:"运行时 ID",opencliDetailRuntimeRootLabel:"运行时目录",opencliDetailErrorHeading:"最近错误",opencliEnabledStateLabel:"新会话启用",opencliEnabledStateOn:"已启用",opencliEnabledStateOff:"已关闭",opencliFilterTabsLabel:"OpenCLI CLI技能筛选",opencliFilterAll:"全部",opencliFilterEnabled:"已启用",opencliFilterBrowser:"依赖浏览器",opencliFilterDirect:"可直接运行",opencliFilterStrategy:"策略 {strategy}",opencliFilteredEmpty:"当前筛选条件下没有可展示的 CLI技能。",opencliSiteToggleLabel:"切换站点 {site}",opencliSiteSummary:"已启用 {enabled}/{total},其中 {browser} 条依赖浏览器桥。",opencliSiteSummaryCompact:"{enabled}/{total} 已启用",opencliSiteBrowserCompact:"{count} 条依赖浏览器",opencliSiteDirectCompact:"无需浏览器桥",opencliSiteCommandCount:"{count} 条命令",opencliSiteDescriptionEmpty:"这个站点暂时没有补充说明,你可以展开下面的命令明细继续筛选。",opencliSiteViewAction:"查看",opencliSiteSelectedAction:"正在查看",opencliSiteEnableAction:"启用",opencliSiteDetailTitle:"{site} 命令",opencliSiteDetailDescription:"当前筛选命中 {count} 条,可在这里逐条控制;这个站点总共 {total} 条。",opencliSiteDescriptionHeading:"站点说明",opencliCommandModalFallbackTitle:"命令列表",opencliCommandModalEmpty:"当前筛选条件下,这个 CLI技能站点没有可展示的命令。",opencliCommandSearchLabel:"搜索命令",opencliCommandSearchPlaceholder:"按命令名、说明或策略筛选",opencliCommandSortLabel:"排序方式",opencliCommandSortStatus:"按状态",opencliCommandSortBrowser:"浏览器优先",opencliCommandSortName:"按名称",opencliCommandResultCount:"当前显示 {count} 条",opencliCommandToggleLabel:"切换命令 {commandId}",opencliBrowserTag:"浏览器桥",opencliHttpTag:"HTTP",opencliCommandDescriptionEmpty:"这条目录项没有提供额外说明。",opencliStrategyUnknown:"策略未知",opencliStrategyLabel:"类型:{strategy}",opencliStrategyShortLabel:"{strategy}",opencliStrategyCookie:"Cookie",opencliStrategyHeader:"请求头",opencliStrategyIntercept:"拦截",opencliStrategyLocal:"本地",opencliStrategyPublic:"公开",opencliStrategyUi:"界面",skillConfigTabsLabel:"技能管理标签页",skillConfigTabSkills:"SKILL",skillConfigTabOffice:"办公",skillConfigTabOps:"运维",skillConfigTabOpenCli:"OpenCLI",skillOfficeTemplateCount:"模板数量",skillOfficeBrowserProfileCount:"浏览器配置",skillOfficeBrowserTaskCount:"浏览器任务",skillOnlyOfficeStatusLabel:"Office 集成",skillOnlyOfficeSectionTitle:"ONLYOFFICE 集成",skillOnlyOfficeSectionDescription:"这里配置外部 ONLYOFFICE 服务地址,不开启不影响正常使用。",skillOnlyOfficeSectionEmpty:"当前还没有 ONLYOFFICE 配置。",skillOnlyOfficeEnabledLabel:"启用 ONLYOFFICE 文档预览与编辑",skillOnlyOfficeServerUrlLabel:"ONLYOFFICE 服务地址",skillOnlyOfficeServerUrlPlaceholder:"例如:http://127.0.0.1:8088",skillOnlyOfficePublicBaseUrlLabel:"CodingNS 对外地址",skillOnlyOfficePublicBaseUrlPlaceholder:"例如:http://host.docker.internal:3002",skillOnlyOfficeCallbackBaseUrlLabel:"回调地址(可选)",skillOnlyOfficeCallbackBaseUrlPlaceholder:"留空时默认复用 CodingNS 对外地址",skillOnlyOfficeUserDisplayNameLabel:"ONLYOFFICE 显示名称(可选)",skillOnlyOfficeUserDisplayNameDescription:"留空时默认使用当前登录用户名:{username}",skillOnlyOfficeUserDisplayNamePlaceholder:"留空时自动带入当前登录用户名",skillOnlyOfficeUserAvatarUrlLabel:"ONLYOFFICE 头像地址(可选)",skillOnlyOfficeUserAvatarUrlDescription:"留空时不传头像,填写后会显示在协作用户信息里。",skillOnlyOfficeUserAvatarUrlPlaceholder:"例如:https://example.com/avatar.png",skillOnlyOfficeJwtSecretLabel:"JWT 密钥(可选)",skillOnlyOfficeJwtSecretPlaceholder:"如果 ONLYOFFICE 开了 JWT,这里填同一份密钥",skillOnlyOfficeJwtSecretKeepPlaceholder:"当前已保存 JWT 密钥;留空表示保持不变",skillOnlyOfficeClearJwtSecretLabel:"清空当前 JWT 密钥",skillOnlyOfficeOpenSettingsAction:"设置",skillOnlyOfficeModalTitle:"配置 ONLYOFFICE",skillOnlyOfficeModalDescription:"在这里填写 ONLYOFFICE 服务地址、CodingNS 对外地址和回调地址。保存后会影响 docx、xlsx、pptx 的预览和回写。",skillOnlyOfficeSaveAction:"保存配置",skillOnlyOfficeCheckAction:"重新检测",skillOnlyOfficeSaveSuccess:"ONLYOFFICE 配置已保存。",skillOnlyOfficeCheckSuccess:"ONLYOFFICE 状态已刷新。",skillOnlyOfficeStatusReady:"可用",skillOnlyOfficeStatusWarning:"有风险",skillOnlyOfficeStatusError:"不可用",skillOnlyOfficeStatusMisconfigured:"未配好",skillOnlyOfficeStatusDisabled:"未启用",skillOnlyOfficeStatusUnknown:"状态未知",skillOnlyOfficeCheckPass:"通过",skillOnlyOfficeCheckWarn:"警告",skillOnlyOfficeCheckFail:"失败",skillOnlyOfficeCheckSkip:"跳过",skillOfficeBrowserBridgeSummaryLabel:"真实浏览器调试",skillOfficeWorkspaceScope:"当前范围",skillOfficeScoped:"当前工作区",skillOfficeGlobal:"全局",skillOfficeTemplateFormTitle:"文档模板配置",skillOfficeTemplateFormDescription:"在这里登记或更新当前可用的文档模板。模板 key 已存在时会按同 key 更新当前模板配置。",skillOfficeTemplateKeyLabel:"模板 Key",skillOfficeTemplateNameLabel:"模板名称",skillOfficeTemplateVersionLabel:"模板版本",skillOfficeTemplateFormatsLabel:"输出格式",skillOfficeTemplatePathLabel:"模板来源路径",skillOfficeTemplateSchemaLabel:"模板 Schema JSON",skillOfficeTemplateMappingLabel:"模板 Mapping JSON",skillOfficeTemplateSaveAction:"保存模板",skillOfficeTemplateCreated:"文档模板已创建。",skillOfficeTemplateUpdated:"文档模板已更新。",skillOfficeTemplateImported:"文档模板已导入。",skillOfficeTemplateListTitle:"可用模板",skillOfficeTemplateListDescription:"这里展示当前 Host 已登记的文档模板。",skillOfficeTemplateEmpty:"当前还没有可用的文档模板。",skillOfficeTemplateListMeta:"Key:{key} · 版本:{version}",skillOfficeTemplateEditAction:"模板文件",skillOfficeTemplateOpenCreateAction:"添加模板",skillOfficeTemplateModalTitle:"添加文档模板",skillOfficeTemplateModalDescription:"直接上传 .domt 或 .doct 模板文件,Host 会自动保存并识别模板信息。",skillOfficeTemplateUploadLabel:"模板文件",skillOfficeTemplateUploadDescription:"当前先支持 doct 模板文件导入,会自动生成模板 key、版本和默认映射。",skillOfficeTemplatePickAction:"选择模板文件",skillOfficeTemplateAutoDetectHint:"导入后会按文件名自动生成模板 key,并写入 Host 的模板目录。",skillOfficeBrowserProfileListTitle:"浏览器配置文件",skillOfficeBrowserProfileListDescription:"这里管理办公能力复用的真实浏览器配置,登录态、用户目录和接管方式都在这里看。",skillOfficeBrowserBridgeSummaryDetail:"{provider} 桥接状态:{status}。{detail}",skillOfficeBrowserBridgeDetailReady:"当前可以直接走真实浏览器调试。",skillOfficeBrowserBridgeAvailabilityUnknown:"状态未知",skillOfficeBrowserBridgeAvailabilityReady:"可用",skillOfficeBrowserBridgeAvailabilityDaemonMissing:"Daemon 未就绪",skillOfficeBrowserBridgeAvailabilityExtensionMissing:"扩展未连接",skillOfficeBrowserBridgeAvailabilityUnavailable:"不可用",skillOfficeBrowserProfileEmpty:"当前还没有可用的浏览器配置文件。",skillOfficeBrowserProfileOnlyCurrentWorkspace:"仅显示当前工作区记录",skillOfficeBrowserProfileListMeta:"{engine} · {mode} · {scope}",skillOfficeBrowserProfileOpenCreateAction:"添加浏览器配置",skillOfficeBrowserProfileModalTitle:"添加浏览器配置",skillOfficeBrowserProfileModalDescription:"创建独立浏览器配置,或接管已经开启远程调试端口的浏览器实例。",skillOfficeBrowserProfileFormTitle:"浏览器配置",skillOfficeBrowserProfileNameLabel:"配置名称",skillOfficeBrowserProfileEngineLabel:"浏览器",skillOfficeBrowserProfileModeLabel:"接入方式",skillOfficeBrowserProfileScopeLabel:"归属范围",skillOfficeBrowserProfileCdpEndpointLabel:"CDP 地址",skillOfficeBrowserProfileCdpEndpointDescription:"只有接管现有浏览器时才需要填写,例如 http://127.0.0.1:9222。",skillOfficeBrowserProfileSaveAction:"保存配置",skillOfficeBrowserProfileCreated:"浏览器配置已创建。",skillOfficeBrowserProfileEngineChrome:"Chrome",skillOfficeBrowserProfileEngineEdge:"Edge",skillOfficeBrowserProfileModePersistent:"独立配置",skillOfficeBrowserProfileModeCdpAttached:"接管现有浏览器",skillOfficeBrowserProfileScopeUser:"仅自己可用",skillOfficeBrowserProfileScopeWorkspace:"当前工作区可复用",skillOfficeBrowserProfileScopeTarget:"绑定到目标",skillOfficeBrowserProfileStatusActive:"可用",skillOfficeBrowserProfileStatusLocked:"占用中",skillOfficeBrowserProfileStatusArchived:"已归档",skillOfficeBrowserProfileStatusError:"异常",skillOfficeBrowserProfileUserDataDirLabel:"用户目录",skillOfficeBrowserProfileWorkspaceTag:"工作区:{workspaceName}",skillOfficeBrowserProfileWorkspaceUnbound:"未绑定工作区",skillOfficeBrowserProfileWorkspaceUnknown:"未知工作区",skillOfficeBrowserProfileCrossWorkspaceTag:"跨工作区可用",skillOfficeBrowserProfileOptionAction:"选项",skillOfficeBrowserProfileAllowCrossWorkspaceAction:"允许跨工作区使用",skillOfficeBrowserProfileSetWorkspaceOnlyAction:"设为仅当前工作区可用",skillOfficeBrowserProfileCrossWorkspaceEnabled:"浏览器配置已允许跨工作区使用。",skillOfficeBrowserProfileWorkspaceOnlyEnabled:"浏览器配置已改为仅当前工作区可用。",skillOfficeBrowserProfileWorkspaceRequired:"这个浏览器配置没有绑定工作区,不能切回仅当前工作区可用。",skillOfficeBrowserProfileOptionsModalTitle:"{profileName} 的选项",skillOfficeBrowserProfileOptionsModalDescription:"在这里调整这个浏览器配置的使用范围。",skillOfficeBrowserProfileOptionsSectionTitle:"使用范围",skillOfficeBrowserProfileCrossWorkspaceFieldLabel:"跨工作区使用",skillOfficeBrowserProfileCrossWorkspaceFieldDescription:"开启后,这个浏览器配置可以在其他工作区复用;关闭后,只允许当前工作区使用。",skillOfficeBrowserProfileTaskAction:"查看任务",skillOfficeBrowserProfileDeleteAction:"删除配置",skillOfficeBrowserProfileDeleted:"浏览器配置已删除。",skillOfficeBrowserProfileDeleteModalTitle:"确认删除浏览器配置",skillOfficeBrowserProfileDeleteModalDescription:"删除前会再确认一次,避免误删当前正在使用的配置。",skillOfficeBrowserProfileDeleteModalWarning:"删除后,这个浏览器配置会从办公能力里移除;未开始的关联任务会自动取消。",skillOfficeBrowserProfileDeleteConfirmAction:"确认删除",skillOfficeBrowserProfileCdpEndpointTag:"已接管",skillOfficeBrowserProfileTaskModalTitle:"{profileName} 的任务记录",skillOfficeBrowserProfileTaskModalDescription:"这里集中查看这个浏览器配置对应的任务记录和执行状态。",skillOfficeBrowserProfileTaskListTitle:"任务记录",skillOfficeBrowserProfileTaskListDescription:"所属工作区:{workspaceName}",skillOfficeBrowserProfileTaskEmpty:"这个浏览器配置还没有任务记录。",skillOfficeBrowserInstanceListTitle:"浏览器实例",skillOfficeBrowserInstanceListDescription:"实例本质上就是浏览器任务。这里可以新建、执行、查看当前运行状态,也能直接取消运行中的实例。",skillOfficeBrowserInstanceEmpty:"当前还没有浏览器实例。",skillOfficeBrowserInstanceListMeta:"{profileName} · {status} · 风险 {risk}",skillOfficeBrowserInstanceExecutionIdle:"未启动",skillOfficeBrowserInstanceExecutionQueued:"排队中",skillOfficeBrowserInstanceExecutionRunning:"运行中",skillOfficeBrowserInstanceExecutionSucceeded:"已完成",skillOfficeBrowserInstanceExecutionFailed:"执行失败",skillOfficeBrowserInstanceExecutionCancelled:"已取消",skillOfficeBrowserInstanceExecutionTimeout:"已超时",skillOfficeBrowserExecutionBackendPlaywright:"无头浏览器",skillOfficeBrowserExecutionBackendOpenCliBridge:"真实浏览器调试",skillOfficeBrowserInstanceDetailAction:"查看详情",skillOfficeBrowserInstanceExecuteAction:"启动实例",skillOfficeBrowserInstanceCancelAction:"取消实例",skillOfficeBrowserInstanceStarted:"浏览器实例已开始执行。",skillOfficeBrowserInstanceCancelled:"浏览器实例已取消。",skillOfficeBrowserInstanceSnapshotPending:"还没有执行快照",skillOfficeBrowserInstanceSnapshotMeta:"状态:{status} · 尝试次数:{attempt} · 开始:{startedAt} · 结束:{finishedAt}",skillOpsTaskCount:"当前任务",skillOpsTargetCount:"SSH 主机",skillOpsWorkspaceScope:"当前范围",skillOpsTaskListTitle:"运维任务",skillOpsTaskListDescription:"这里只看运维类型任务,方便快速检查当前工作区的执行状态和审批状态。",skillOpsTaskEmpty:"当前还没有运维任务。",skillOpsTaskListMeta:"状态:{status} · 风险:{risk}",skillOpsTaskDetailAction:"查看详情",skillOpsApprovalApproveAction:"批准",skillOpsApprovalApproveNote:"已在技能面板中批准执行。",skillOpsApprovalRejectNote:"已在技能面板中拒绝执行。",skillOpsApprovalApproved:"运维审批已批准。",skillOpsApprovalRejected:"运维审批已拒绝。",skillOpsTargetFormTitle:"SSH 主机配置",skillOpsTargetFormDescription:"这里先接当前已经真正支持的 SSH 主机字段:主机、用户名、端口、密钥路径和凭据引用。",skillOpsPasswordNotice:"当前正式能力只保证密钥路径和凭据引用链路可用,密码认证链路还没有完整接通。",skillOpsTargetNameLabel:"主机名称",skillOpsTargetEnvironmentLabel:"环境",skillOpsTargetHostLabel:"主机地址",skillOpsTargetPortLabel:"端口",skillOpsTargetUsernameLabel:"登录用户",skillOpsTargetPrivateKeyPathLabel:"私钥路径",skillOpsTargetKnownHostsPathLabel:"known_hosts 路径",skillOpsTargetJumpHostLabel:"跳板机",skillOpsTargetWorkspacePathLabel:"默认工作目录",skillOpsTargetCredentialRefLabel:"凭据引用",skillOpsTargetHostKeyPolicyLabel:"主机校验策略",skillOpsTargetSaveAction:"保存主机",skillOpsTargetResetAction:"清空表单",skillOpsTargetCreated:"SSH 主机已创建。",skillOpsTargetUpdated:"SSH 主机已更新。",skillOpsTargetListTitle:"已保存主机",skillOpsTargetListDescription:"这里展示当前范围内已保存的 SSH 主机配置。",skillOpsTargetEmpty:"当前还没有已保存的 SSH 主机。",skillOpsTargetEditAction:"载入编辑",skillOpsTargetOpenCreateAction:"添加主机",skillOpsTargetModalTitle:"添加 SSH 主机",skillOpsTargetModalDescription:"在这个窗口里登记当前工作区可用的 SSH 主机配置。",skillWorkspaceSessionMcpStatusAction:"查看 MCP 状态",skillWorkspaceSessionMcpModalTitle:"工作区会话 MCP 状态",skillWorkspaceSessionMcpModalDescription:"这里同时检查当前工作区会话 runtime、全局 CLI 安装状态,以及各个 CLI 是否已经具备调用 office MCP 的条件。",skillWorkspaceSessionMcpLoading:"正在读取 MCP 状态…",skillWorkspaceSessionMcpRuntimeTitle:"当前会话 runtime",skillWorkspaceSessionMcpRuntimeDescription:"先看当前工作区会话在全局 CodingNS 目录下的专用 runtime 是否真的落出了 scoped 认证、说明文件和专用 skill;Codex 的 office MCP 依赖这些运行时资产做启动时注入,不再要求写入全局 home。",skillWorkspaceSessionMcpReadyCliCount:"可直接调用",skillWorkspaceSessionMcpConfiguredCliCount:"已写配置/已注入",skillWorkspaceSessionMcpTotalCliCount:"CLI 数量",skillWorkspaceSessionMcpOverallLabel:"总体状态",skillWorkspaceSessionMcpCurrentSessionLabel:"当前会话",skillWorkspaceSessionMcpCodexLabel:"Codex",skillWorkspaceSessionMcpRuntimeHomeLabel:"runtime 目录",skillWorkspaceSessionMcpAuthFileLabel:"scoped 认证文件",skillWorkspaceSessionMcpInstructionFileLabel:"组合说明文件",skillWorkspaceSessionMcpSkillDirLabel:"工作区会话 skill 目录",skillWorkspaceSessionMcpCommandTitle:"CLI 命令状态",skillWorkspaceSessionMcpCommandDescription:"这里区分仓库里的实现是否已具备,和你机器当前全局安装的 CLI 是否已经升级到可用版本。",skillWorkspaceSessionMcpGlobalCodingnsLabel:"全局 codingns",skillWorkspaceSessionMcpGlobalStandaloneLabel:"全局 codingns-workspace-office-mcp",skillWorkspaceSessionMcpGlobalStandaloneMissing:"当前机器还没有这个独立命令入口。",skillWorkspaceSessionMcpRepoCodingnsLabel:"仓库内 codingns.mjs",skillWorkspaceSessionMcpCliTitle:"各 CLI 调用状态",skillWorkspaceSessionMcpCliDescription:"这里按各 CLI 的真实接入方式判断是否可用:Codex 看运行时注入链路,Claude Code / OpenCode 继续看 runtime 配置是否落地。",skillWorkspaceSessionMcpRefreshAction:"刷新 MCP 状态",skillWorkspaceSessionMcpStateReady:"已就绪",skillWorkspaceSessionMcpStatePartial:"部分就绪",skillWorkspaceSessionMcpStateMissing:"未就绪",skillWorkspaceSessionMcpBrowserBridgeLabel:"真实浏览器调试",skillWorkspaceSessionMcpBrowserBridgeDetail:"这里指的是 browser.opencli_bridge。它不是 profile 型任务,不需要先查或先建浏览器 Profile。",skillWorkspaceSessionMcpRecommendedPathLabel:"推荐调用链路",skillWorkspaceSessionMcpValueMissing:"当前没有可用路径",skillWorkspaceSessionMcpEmptyTitle:"还没有拿到 MCP 状态",skillWorkspaceSessionMcpEmptyDescription:"请先确认当前已经进入工作区普通会话,并且这个会话已经在全局 CodingNS 目录下生成专用 runtime。"},shell:{title:"工作台",subtitle:"管理代码项目里的 AI 会话",mobileWorkspacesEntry:"工作区",mobileTerminalsEntry:"终端",mobileSessionsEntry:"对话",mobileToolsEntry:"工具",mobileSettingsEntry:"设置",mobileNavigationAction:"打开工作台菜单",mobileSearchAction:"打开搜索",mobileAuxiliaryAction:"打开工具面板",mobileRevealNavigationAction:"显示主导航",mobileHideNavigationAction:"收起主导航",mobileConversationPreviewTitle:"快速预览",mobileConversationCurrentWorkspaceSection:"当前工作区",mobileConversationCollapsePreviewAction:"收起预览",mobileConversationRestorePreviewAction:"恢复会话预览",iosMoreAction:"更多操作",androidMoreAction:"更多操作",conversationEntry:"对话",terminalsEntry:"终端",butlerEntry:"助手",skillsEntry:"技能",globalNotificationsAction:"通知",globalNotificationsUnreadAria:"未读通知 {count}",globalNotificationsPanelTitle:"通知中心",globalNotificationsPanelDescription:"这里集中看需要你拍板、代办分析结果、跟进状态和验证失败的提醒。",globalNotificationsEmpty:"当前没有新的全局通知。",globalNotificationsShowArchived:"显示已归档通知",globalNotificationsArchiveAction:"归档",globalNotificationsRemoveArchiveAction:"移除归档",globalNotificationsArchiveFailed:"通知归档更新失败",globalNotificationKindWaitingUser:"等待你决定",globalNotificationKindTodoAnalyzed:"代办分析完成",globalNotificationKindTodoAnalyzeFailed:"代办分析失败",globalNotificationKindFollowUpFailed:"跟进失败",globalNotificationKindFollowUpCompleted:"跟进完成",globalNotificationKindVerificationFailed:"验证失败",globalNotificationTodoAnalyzedTitle:"代办分析完成:{title}",globalNotificationTodoAnalyzeFailedTitle:"代办分析失败:{title}",globalNotificationFollowUpWaitingTitle:"需要你决定:{title}",globalNotificationFollowUpFailedTitle:"跟进失败:{title}",globalNotificationFollowUpCompletedTitle:"跟进完成:{title}",globalNotificationVerificationFailedTitle:"验证失败:{title}",globalNotificationVerificationFailedFallback:"最近一次验证没有通过,请尽快查看。",searchEntry:"搜索",workbenchModeTabsLabel:"工作台模式",workbenchModeCode:"代码",workbenchModeAffairs:"事务",workbenchModeCodeOpenInNewWindow:"在新窗口打开代码",workbenchModeAffairsOpenInNewWindow:"在新窗口打开事务",affairsSectionGroupPrimary:"分区入口",affairsSectionGroupFavorites:"收藏",affairsSectionGroupRecent:"最近打开",affairsNavigationDescription:"这里先收口事务分区、收藏和最近对象,别再把对象入口散在各个角落。",affairsLibraryNav:"文档",affairsLibraryNavSummary:"当前先把文档对象和相关操作接进来。",affairsLibrarySummary:"文档对象先落在中间主舞台,右侧再给详情和事务助手。",affairsWorkbenchNav:"工作台",affairsWorkbenchSummary:"把代办、自动化和 HTML 工具都收进统一工作台。",affairsWorkbenchSidebarTitle:"工作台",affairsWorkbenchSidebarDescription:"先把代办和自动化收在一起,再把右侧整块区域交给画布。当前共 {todoCount} 条代办、{automationCount} 个自动化。",affairsWorkbenchSidebarGroupOverview:"总览",affairsWorkbenchStageTitle:"工作台",affairsWorkbenchStageDescription:"这里会逐步长成整块画布式工作台。当前先保留总览、代办和自动化入口,共 {count} 项。",affairsWorkbenchEmpty:"当前还没有可展示的工作台内容。",affairsWorkbenchEmptyBody:"这一块后面会变成可摆放代办、自动化和 HTML 插件的画布。现在先用它收口旧入口,避免继续分散。",affairsWorkbenchEyebrow:"工作台预览",affairsWorkbenchDefaultTabTitle:"默认工作台",affairsWorkbenchDefaultTabShortTitle:"默认",affairsWorkbenchNewTabTitle:"工作台 {count}",affairsWorkbenchAddTabAction:"新建标签页",affairsWorkbenchRenameTabAction:"重命名标签页",affairsWorkbenchDeleteTabAction:"删除标签页",affairsWorkbenchCanvasTitle:"工作台画布",affairsWorkbenchCanvasDescription:"这块区域现在就是完整工作台画布。顶部切标签页,下面的块可以直接拖动位置,也可以直接拖拽调整大小。",affairsWorkbenchCanvasEmptyTitle:"这个标签页还没有块",affairsWorkbenchCanvasEmptyBody:"先在这里添加第一块,后面这里会变成可调整布局的正式画布。",affairsWorkbenchWidgetHtmlAppHint:"把工作区里的静态 HTML 页面直接钉进画布,适合常用工具或小应用。",affairsWorkbenchWidgetHtmlStatHint:"把 HTML 统计页面作为指标块固定在画布里,适合盯数据。",affairsWorkbenchWidgetHtmlEmbedHint:"把受控 HTML 页面嵌进工作台,适合展示页面块或只读页面。",affairsWorkbenchWidgetOpenTodoAction:"打开代办列表",affairsWorkbenchWidgetOpenAutomationAction:"打开自动化列表",affairsWorkbenchWidgetCountValue:"共 {count} 项",affairsWorkbenchWidgetTeableBadge:"Teable",affairsWorkbenchHtmlWidgetBadge:"HTML",affairsWorkbenchHtmlAppDefaultTitle:"HTML 应用",affairsWorkbenchHtmlStatDefaultTitle:"HTML 统计",affairsWorkbenchHtmlEmbedDefaultTitle:"HTML 页面",affairsWorkbenchCancelAction:"取消",affairsWorkbenchAddWidgetAction:"添加块",affairsWorkbenchResetLayoutAction:"恢复默认布局",affairsWorkbenchLockLayoutAction:"锁定布局",affairsWorkbenchUnlockLayoutAction:"解锁布局",affairsWorkbenchWidgetTypeTodo:"代办块",affairsWorkbenchWidgetTypeAutomation:"自动化块",affairsWorkbenchWidgetTypeTeable:"Teable 块",affairsWorkbenchWidgetTypeHtml:"HTML 块",affairsWorkbenchWidgetTypeHtmlApp:"HTML 应用块",affairsWorkbenchWidgetTypeHtmlStat:"HTML 统计块",affairsWorkbenchWidgetTypeHtmlEmbed:"HTML 页面块",affairsWorkbenchHtmlVariantField:"用途预设",affairsWorkbenchHtmlVariantHelper:"这里只是创建时的默认用途预设,主要影响默认标题、推荐尺寸和后续呈现语义。",affairsWorkbenchHtmlVariantApp:"应用",affairsWorkbenchHtmlVariantStat:"统计",affairsWorkbenchHtmlVariantEmbed:"页面",affairsWorkbenchWidgetTitleField:"块标题",affairsWorkbenchWidgetTitlePlaceholder:"不填就用默认标题",affairsWorkbenchHtmlSourceWorkspaceField:"来源工作区",affairsWorkbenchHtmlSourceWorkspaceHelper:"先选择代码工作区,再从这个工作区里选 HTML 文件。HTML 预览和权限会沿用该工作区。",affairsWorkbenchHtmlSourceWorkspaceCurrentLibraryOption:"当前文档库",affairsWorkbenchHtmlSourceWorkspaceCurrentLibraryHelper:"当前文档库路径:{path}。下面的文件列表直接来自这份全局文档库配置。",affairsWorkbenchHtmlSourceField:"HTML 文件路径",affairsWorkbenchHtmlSourcePlaceholder:"例如:tools/report/index.html",affairsWorkbenchHtmlSourceSelectField:"HTML 文件",affairsWorkbenchHtmlSourceSelectPlaceholder:"请选择一个 HTML 文件",affairsWorkbenchHtmlSourceHelper:"先选来源工作区,再从下面的文件列表里选 HTML 文件。",affairsWorkbenchHtmlSourceListFailed:"读取工作区 HTML 文件列表失败",affairsWorkbenchHtmlSourceInvalid:"只允许添加 .html 或 .htm 文件。",affairsWorkbenchHtmlSourceUnsupported:"这个文件当前不能作为工作台 HTML 来源。",affairsWorkbenchHtmlSourceMissing:"当前块还没有可用的 HTML 来源。",affairsWorkbenchHtmlSourceLoadFailed:"加载 HTML 页面失败",affairsWorkbenchConfirmAddWidgetAction:"确认添加",affairsWorkbenchAddWidgetFailed:"添加工作台块失败",affairsWorkbenchWidgetSizeGroup:"块尺寸",affairsWorkbenchWidgetSizeSmall:"小",affairsWorkbenchWidgetSizeMedium:"中",affairsWorkbenchWidgetSizeLarge:"大",affairsWorkbenchMoveWidgetBackwardAction:"向前移动",affairsWorkbenchMoveWidgetForwardAction:"向后移动",affairsWorkbenchDragWidgetAction:"拖动块",affairsWorkbenchResizeWidgetAction:"调整块大小",affairsWorkbenchRemoveWidgetAction:"删除块",affairsWorkbenchWidgetErrorTitle:"这个块加载失败了",affairsWorkbenchWidgetErrorBody:"先保留其他块继续用,再检查这个块的配置或来源。",affairsWorkbenchWidgetTodoViewLabel:"代办块视图",affairsWorkbenchWidgetCompactView:"紧凑",affairsWorkbenchWidgetDetailView:"明细",affairsWorkbenchWidgetAutomationViewLabel:"自动化块视图",affairsWorkbenchWidgetAutomationListView:"任务",affairsWorkbenchWidgetAutomationRecentView:"最近运行",affairsWorkbenchWidgetAutomationRunFallbackTitle:"自动化运行",affairsWorkbenchOpenHtmlAction:"新窗口打开",teableRuntimeDefaultBlockTitle:"Teable 数据",teableRuntimeTableField:"Teable 表",teableRuntimeViewField:"Teable 视图",teableRuntimeCreateFormViewField:"新建记录表单视图",teableRuntimeEditFormViewField:"编辑记录表单视图",teableRuntimeViewGrid:"表格",teableRuntimeViewForm:"表单",teableRuntimeViewCalendar:"日历",teableRuntimeViewKanban:"看板",teableRuntimeTablesLoadFailed:"读取 Teable 表失败",teableRuntimeViewsLoadFailed:"读取 Teable 视图失败",teableRuntimeTablesEmpty:"当前 Base 里还没有可选表。请先到 Teable 创建表,或检查连接设置。",teableRuntimeViewsEmpty:"这张表没有可用的表格、表单、日历或看板视图。",teableRuntimeFormViewsEmpty:"这张表没有可用的表单视图。请先在 Teable 里创建表单视图,再添加这个块。",teableRuntimeSelectionRequired:"请先选择 Teable 表和视图。",teableRuntimeBlockLoadFailed:"加载 Teable 数据失败",teableRuntimeConfigMissing:"这个 Teable 块缺少表配置。",teableRuntimeRefreshAction:"刷新记录",teableRuntimeRecordsEmpty:"当前视图还没有记录。",teableRuntimeEmptyValue:"空",teableRuntimePrimaryFieldMissing:"这张表没有可用的主字段。",teableRuntimeRecordDrawerTitle:"编辑记录",teableRuntimeRecordDrawerDescription:"普通字段可以编辑;公式、查找和汇总字段只读,由 Teable 计算。",teableRuntimeRecordFieldsTitle:"记录字段",teableRuntimeReadonlyHint:"保存后会重新读取记录,显示 Teable 计算后的最新值。",teableRuntimeSaveRecordAction:"保存记录",teableRuntimeDeleteRecordAction:"删除记录",teableRuntimeDeleteConfirm:"确定删除这条 Teable 记录吗?",teableRuntimeSaveFailed:"保存记录失败",teableRuntimeDeleteFailed:"删除记录失败",teableRuntimeCreateFailed:"新建记录失败",teableRuntimeCreateRecordAction:"新建记录",teableRuntimeCreateRecordModalTitle:"新建 Teable 记录",teableRuntimeCreateRecordModalDescription:"正在向「{table}」添加一条新记录。",teableRuntimeCreateRecordFieldsTitle:"填写记录内容",teableRuntimeCreateRecordFieldsDescription:"这里按 Teable 表单视图能读取到的字段顺序、可见字段和必填规则展示。",teableRuntimeNoWritableFields:"这张表没有可填写的字段。",teableRuntimeRequiredMark:" *",teableRuntimeRequiredFieldMissing:"请填写「{field}」。",teableRuntimeUnsupportedEditor:"暂不支持编辑,当前值:{value}",teableRuntimeLinkOptionsLoadFailed:"读取关联记录失败",teableRuntimeLinkFieldMissing:"这个关联字段缺少关联表配置。",teableRuntimeLinkEmptyOption:"不选择",teableRuntimeCalendarDateMissing:"日历视图需要一个日期字段。请在 Teable 视图或块设置里选择日期字段。",teableRuntimeKanbanGroupMissing:"看板视图需要一个单选字段。请在 Teable 视图或块设置里选择分组字段。",affairsShortcutRailTitle:"快捷应用",affairsShortcutRailDescription:"暂无",affairsShortcutRailEmpty:"暂无",affairsShortcutRailEditAction:"编辑",affairsShortcutRailDoneAction:"完成",affairsShortcutRailAddAction:"添加应用",affairsShortcutRailTitleField:"应用名称",affairsShortcutRailTitlePlaceholder:"不填就用文件名",affairsShortcutRailSourceSelectField:"文件",affairsShortcutRailSourceSelectPlaceholder:"请选择一个文件",affairsShortcutRailSourceHelper:"先选来源工作区,再从下面的文件列表里选一个文件。打开时会复用该工作区的预览和权限。",affairsShortcutRailSourceListFailed:"读取工作区文件列表失败",affairsShortcutRailSourceInvalid:"请选择一个文件。",affairsShortcutRailSourceUnsupported:"这个文件当前不能作为快捷应用打开。",affairsShortcutRailSourcePickerTitle:"选择文件",affairsShortcutRailSourcePickerDescription:"从工作区目录里选一个文件,保存后会作为快捷应用打开。",affairsShortcutRailSourcePickerCurrentField:"当前文件",affairsShortcutRailSourcePickerCurrentEmpty:"还没选文件",affairsShortcutRailSourcePickerTreeTitle:"工作区文件",affairsShortcutRailSourcePickerTreeEmpty:"当前没有可选文件",affairsShortcutRailSourcePickerTreeEmptyDescription:"先展开目录,再选一个能预览的文件。",affairsShortcutRailSourcePickerRetryAction:"重新加载",affairsShortcutRailSourcePickerConfirmAction:"使用这个文件",affairsShortcutRailConfirmAddAction:"添加到快捷应用",affairsShortcutRailConfirmEditAction:"保存快捷应用",affairsShortcutRailAddedTitle:"快捷应用已添加",affairsShortcutRailUpdatedTitle:"快捷应用已更新",affairsShortcutRailAddFailed:"添加快捷应用失败",affairsShortcutRailUpdateFailed:"更新快捷应用失败",affairsShortcutRailOpenAction:"打开",affairsShortcutRailOpenFailed:"打开快捷应用失败",affairsShortcutRailRemoveAction:"移除",affairsShortcutRailExpandAction:"展开",affairsShortcutRailCollapseAction:"收起",affairsShortcutRailLaunchAction:"打开快捷应用:{title}",affairsShortcutRailEditEntryAction:"编辑快捷应用:{title}",affairsShortcutRailPreviewEditDisabled:"快捷应用当前只支持预览,不支持直接编辑。",affairsWorkbenchDetailTitle:"工作台总览",affairsWorkbenchDetailDescription:"这里先展示工作台的标签页和画布方向,等块系统接完后,再把更多细节放进来。",affairsWorkbenchOverviewLabel:"总览",affairsWorkbenchOverviewSummary:"先收口 {todoCount} 条代办和 {automationCount} 个自动化,后面再接画布块。",affairsWorkbenchAssistantContextTitle:"当前工作台代办",affairsWorkbenchAssistantContextSummary:"当前筛选是 {scopeLabel},共 {count} 条代办。优先关注:{titles}",affairsWorkbenchAssistantContextSummaryCompact:"当前筛选是 {scopeLabel},共 {count} 条代办。",affairsWorkbenchAssistantContextEmpty:"当前筛选下还没有代办,先帮我判断下一步该补什么。",affairsWorkbenchStepTodoTitle:"先看代办",affairsWorkbenchStepTodoDescription:"代办先按来源收进工作台,后面会变成可拖拽的块。",affairsWorkbenchStepAutomationTitle:"再看自动化",affairsWorkbenchStepAutomationDescription:"自动化任务先保留现有列表,后面再接进画布。",affairsWorkbenchStepHtmlTitle:"最后接 HTML 块",affairsWorkbenchStepHtmlDescription:"静态 HTML 快捷应用和统计插件后面统一按工作台块接入。",affairsConversationNav:"对话",affairsConversationSummary:"这里把轻量会话和 Agent 会话放到正式主舞台里,不再只缩在右侧小面板。",affairsConversationSidebarTitle:"对话",affairsConversationSidebarListTitle:"会话列表",affairsConversationSidebarGroupModes:"创建入口",affairsConversationStageTitle:"事务对话",affairsConversationStageDescription:"先把事务对话入口和创建方式收口,后面再一条条接真实运行时。",affairsConversationEmpty:"当前还没有事务对话,先新建一条。",affairsConversationEmptyEyebrow:"开始",affairsConversationEmptyBody:"从这里新建一条事务对话,继续围绕当前文档库和事务对象往下做。",affairsConversationEmptyCreateTitle:"新建",affairsConversationEmptyCreateBody:"点击“新建对话”,选择轻量模式或助手模式后开始。",affairsConversationEmptyModeTitle:"先选会话模式",affairsConversationEmptyModeBody:"轻量模式适合快速问答和联网搜索,助手模式适合继续做完整 Agent 任务。",affairsConversationEmptySelectedTitle:"当前准备创建的会话",affairsConversationEmptyCompanionTitle:"右侧配合使用",affairsConversationEmptyCompanionBody:"需要对象详情、文档内容或事务助手时,再看右侧分区。",affairsConversationEmptyTip:"准备好后,从这里新建一条事务对话开始。",affairsConversationEmptyDescription:"这里复用正式聊天页样式,但先把创建入口、模式分组和 provider 选择钉住,避免后面越做越乱。",affairsConversationEntryBadge:"正式入口",affairsConversationCreateAction:"新建对话",affairsConversationCreateHint:"暂无会话",affairsConversationSidebarLoadingAll:"正在补全会话列表…",affairsConversationSidebarLoadingLightweight:"正在补全轻量会话…",affairsConversationSidebarLoadingAgent:"正在补全助手会话…",affairsConversationAgentSessionHint:"当前工作区还没有可复用的助手会话。",affairsConversationLightweightCapabilityHint:"轻量模式只支持快速问答、联网搜索和轻分析,不带本地工具。",affairsConversationLightweightLoadFailed:"读取轻量会话列表失败",affairsConversationAgentLoadFailed:"读取助手会话列表失败",affairsConversationCreateModalDescription:"先选会话模式,再选 provider。轻量模式只放轻能力 provider,助手模式复用完整 CLI provider。",affairsConversationCreateModalDescriptionWithWorkspace:"当前文档库:{workspace}。先选会话模式,再选 provider。",affairsConversationLightweightTitle:"轻量模式",affairsConversationLightweightDescription:"这里放快速问答、联网搜索、轻分析用的 LLM provider,不带完整本地工具。",affairsConversationAssistantTitle:"助手模式",affairsConversationAssistantDescription:"这里复用完整助手链路和 AGENTS.md 注入,适合继续做 Agent 任务。",affairsConversationModePickerTitle:"先选会话模式,再选 provider",affairsConversationModePickerDescription:"轻量和 Agent 说的是能力级别,Codex 和 Claude Code 说的是底层 provider,这两件事不能混。",affairsConversationBoundaryTitle:"这一页当前先定什么",affairsConversationBoundaryDescription:"这一步先把入口、壳层和边界钉住,不急着把所有运行时一次接完。",affairsConversationBoundaryLightweight:"轻量会话只做快速问答、联网搜索和轻分析,不带完整本地工具。",affairsConversationBoundaryAgent:"Agent 会话后面复用完整助手链路,围绕当前文档库和事务对象继续工作。",affairsConversationBoundaryProvider:"轻量模式和助手模式是两类会话,不是 provider 别名;provider 只负责底层模型来源。",affairsInitSubmit:"完成事务模式初始化",affairsInitSuccess:"事务模式已初始化完成",affairsInitFailed:"事务模式初始化失败",affairsInitPreviewRuleLabel:"事务助手方式",affairsInitLibraryTitle:"文档库设置",affairsInitLibraryDescription:"这里决定事务模式第一次进来时,要不要直接把文档库接上。",affairsInitLibraryEnabledLabel:"是否启用文档库",affairsInitLibraryEnabledHint:"启用后会在初始化完成后直接绑定文档库,并开始可用。",affairsInitLibraryPathHint:"这里填事务文档库根目录,后面还能在文档库设置里再改。",affairsInitLibraryPathRequired:"启用文档库时,必须先选择文档库路径",affairsInitRouteGuardHint:"事务模式还没完成初始化,文档库、待办和自动化都会先收口到这里。",affairsInitRouteGuardSidebarEmpty:"先完成初始化,左侧分区内容才会出现。",affairsInitRouteGuardAuxiliaryEmpty:"先完成初始化,右侧详情区才会展示对象内容。",affairsConnectionCheckingTitle:"正在连接事务服务",affairsConnectionCheckingDescription:"先确认 Host 是否可用,再决定是继续进入事务视图,还是提示你处理连接问题。",affairsConnectionCheckingSidebarEmpty:"正在检查连接状态,左侧分区稍后再加载。",affairsConnectionCheckingAuxiliaryEmpty:"正在检查连接状态,右侧详情区稍后再加载。",affairsHostUnavailableTitle:"暂时连不上事务服务",affairsHostUnavailableDescription:"现在不是事务模式没初始化,而是前端还连不上 Host。先把连接恢复,再回来继续。",affairsHostUnavailableRetryAction:"重新连接",affairsHostUnavailableRetryHint:"重试不会改你的初始化状态,只会重新检查 Host 是否恢复可用。",affairsHostUnavailableErrorTitle:"连接报错",affairsHostUnavailableSidebarEmpty:"连接恢复前,左侧分区内容暂时加载不出来。",affairsHostUnavailableAuxiliaryEmpty:"连接恢复前,右侧详情区暂时拿不到对象内容。",affairsConversationKindLightweight:"轻量会话",affairsConversationKindAgent:"Agent 会话",affairsConversationOptionLabel:"{kind} · {provider}",affairsConversationOptionSummaryLightweight:"用 {provider} 开一条轻量对话,优先做快速问答、联网搜索和轻分析。",affairsConversationOptionSummaryAgent:"用 {provider} 开一条助手对话,后面复用完整助手链路和当前事务上下文。",affairsTodoNav:"待办",affairsTodoSummary:"这里后面承接待办拆解、优先级和执行跟踪。",affairsAutomationNav:"自动化",affairsAutomationSummary:"这里后面承接自动化流程、浏览器任务和运维结果。",affairsPluginsNav:"插件",affairsPluginsSummary:"这里后面承接事务插件和对象级扩展入口。",affairsComingSoon:"这块先占位,后面按 spec 继续接。",affairsLibraryTitle:"文档库",affairsToolbarCount:"{count} 项",affairsToolbarSummary:"当前工作区:{workspaceName} · 共 {count} 个对象",affairsToolbarExpand:"展开工具区",affairsToolbarCollapse:"收起工具区",affairsToolbarPlaceholderNew:"新建",affairsToolbarPlaceholderSearch:"搜索",affairsToolbarPlaceholderFilter:"筛选",affairsLibraryResultTitle:"对象结果",affairsLibraryEmpty:"当前还没有可用对象,先从左侧切分区或回到代码视图沉淀内容。",affairsSectionPlaceholderBadge:"规划中",affairsTodoPlaceholderTitle:"待办区稍后接入",affairsTodoPlaceholderDescription:"这块先保留正式入口,后面把待办拆解、标签整理和执行跟踪接进来。",affairsAutomationPlaceholderTitle:"自动化区稍后接入",affairsAutomationPlaceholderDescription:"这块先保留正式入口,后面把浏览器任务、自动化流程和运维动作接进来。",affairsPluginsPlaceholderTitle:"插件区稍后接入",affairsPluginsPlaceholderDescription:"这块先保留正式入口,后面把事务插件和对象级扩展入口接进来。",affairsDetailTitle:"对象详情",affairsDetailEmpty:"先从中间选一个对象,右侧再给你详情和助手。",affairsObjectTypeDocument:"文档",affairsAssistantTitle:"事务助手",affairsAssistantDescription:"这里的助手先围绕当前对象工作,不再把代码会话当默认语境。",affairsAssistantPlaceholder:"围绕《{title}》继续处理文档、标签、待办或浏览器任务",affairsAssistantPlaceholderEmpty:"先选一个对象,再让助手围着它做事。",affairsAssistantContextFallback:"当前对象还没有更多摘要。",affairsAssistantPromptPreamble:`当前事务对象:{title}
42
+ 对象摘要:{summary}
43
+ 来源:{sourceRef}
44
+ 请围绕这个对象处理文档整理、标签、待办拆解、浏览器任务和导出建议。`,affairsAssistantPromptPreambleEmpty:"当前还没有选中事务对象,请先帮我判断应该先看什么,再给下一步建议。",affairsDocumentSummaryTemplate:"来自会话《{sessionTitle}》的文档对象占位,后面这里会接正式文档索引结果。",affairsSidebarMenuLabel:"事务视图分区菜单",affairsLibrarySidebarTitle:"收藏与标签",affairsLibrarySidebarDescription:"当前工作区共 {count} 份文档对象,已收口 {favorites} 个收藏、{tags} 个标签。",affairsLibraryAllFilter:"全部文档",affairsLibraryAllFilterSummary:"按当前工作区查看全部文档对象。",affairsLibraryFavoritesSummary:"优先看你已经标过星的内容。",affairsLibraryFavoritesEntry:"全部收藏",affairsLibraryTagSummary:"按标签筛当前文档结果。",affairsLibraryFoldersEntry:"目录",affairsLibraryFoldersSummary:"按目录浏览当前文档库。",affairsLibraryTagsEntry:"标签",affairsLibraryTagsSummary:"按标签浏览当前文档库。",affairsLibraryFolderNodeSummary:"按目录筛当前文档结果。",affairsLibraryTagNodeSummary:"按标签筛当前文档结果。",affairsLibraryRefreshAction:"刷新文档库",affairsLibraryRefreshQueued:"已开始刷新文档库",affairsLibraryRefreshQueuedDescription:"系统会在后台重新扫描文档并更新目录、标签和列表结果。",affairsLibraryRefreshFailed:"刷新文档库失败",affairsLibraryBindingTitle:"先绑定文档库路径",affairsLibraryBindingDescription:"给当前事务视图指定一个文档库根目录,后面左侧目录、收藏、标签和中间文档列表都基于这里显示。",affairsLibraryBindingFieldLabel:"文档库路径",affairsLibraryBindingFieldPlaceholder:"/Users/you/Documents/Knowledge",affairsLibraryBindingSubmitAction:"保存路径",affairsLibraryBindingBrowseAction:"选择目录",affairsLibraryBindingPickerTitle:"选择文档库目录",affairsLibraryBindingPickerDescription:"从真实目录里挑一个文档库根路径,事务视图会基于这里显示目录、收藏、标签和文档。",affairsLibraryBindingUseThisDirectory:"使用这个目录",affairsLibraryEnableLabel:"启用文档库",affairsLibraryEnableHint:"关闭后会停掉当前工作区的内置索引服务,重新开启后才会继续刷新索引。",affairsLibraryEnableAction:"启用",affairsLibraryDisableAction:"停用",affairsLibraryEnabledState:"已启用",affairsLibraryDisabledState:"未启用",affairsLibraryEnableSaveFailed:"更新文档库开关失败",affairsLibraryDisabledSummary:"文档库功能当前已关闭。重新启用后,内置索引服务才会继续工作。",affairsLibraryConfigTitle:"文档库设置",affairsLibraryConfigDescription:"这里补本地镜像路径、允许索引的文件类型,以及确实需要放行的隐藏路径。",affairsLibraryMirrorRootLabel:"本地镜像路径",affairsLibraryMirrorRootPlaceholder:"/Users/you/SynologyDrive",affairsLibraryMirrorRootBrowseAction:"选择本地目录",affairsLibraryMirrorRootDesktopOnlyHint:"选择目录只在桌面应用里生效,H5 端请直接手动填写路径。",affairsLibraryIncludedHiddenPathsLabel:"额外纳入的隐藏路径",affairsLibraryIncludedHiddenPathsHint:"默认会忽略 . 开头的文件和文件夹。只有你明确需要时,才在这里逐条填相对路径,例如 .obsidian 或 notes/.draft.md。",affairsLibraryIncludedHiddenPathsPlaceholder:`.obsidian
45
+ notes/.draft.md`,affairsLibraryAllowedExtensionsLabel:"索引文件类型",affairsLibraryAllowedExtensionsPlaceholder:".md, .pdf, .docx",affairsLibraryAllowedExtensionsHint:"多个后缀用逗号或空格分开。这里只是白名单,最终还要受索引器本身支持范围限制。",affairsLibraryAllowedExtensionsCustomPlaceholder:"手动添加后缀名,例如:.pages 或 .epub",affairsLibraryAllowedExtensionsCustomAddAction:"添加后缀",affairsLibraryAllowedExtensionsCustomInvalid:"请输入合法的后缀名,例如 .pages。",affairsLibraryCustomExtensionBadge:"自定义",affairsLibrarySettingsAction:"打开文档库设置",affairsLibraryConfigSaveAction:"保存设置",affairsLibraryConfigSaveFailed:"保存文档库设置失败",affairsLibraryConfigSaved:"文档库设置已保存",affairsLibraryConfigAppliedSuccess:"新白名单和镜像路径已经应用到索引器。",affairsLibraryConfigAppliedRunning:"设置已保存,索引器正在应用新配置。",affairsLibraryConfigAppliedFailed:"设置已保存,但索引器应用新配置失败。",affairsLibraryOpenLocalFileAction:"打开本地文件",affairsLibraryOpenWithLocalAppAction:"使用本地应用程序打开",affairsLibraryOpenLocalFileFailed:"打开本地文件失败",affairsLibraryRevealLocalFileAction:"在 Finder 中定位",affairsLibraryRevealLocalFileFailed:"打开所在目录失败",affairsLibraryLocateFolderAction:"定位目录",affairsLibraryContextLocate:"定位",affairsLibraryMirrorRootEmpty:"还没有设置本地镜像路径",affairsLibraryContextMenuLabel:"文档库操作菜单",affairsLibraryContextPreview:"预览",affairsLibraryContextOpen:"打开",affairsLibraryContextDownload:"下载",affairsLibraryContextNew:"新建",affairsLibraryContextNewDirectory:"目录",affairsLibraryContextNewMarkdown:"MD 文件",affairsLibraryContextNewText:"TXT 文件",affairsLibraryContextNewCustomFile:"自定义文件",affairsLibraryContextRefresh:"刷新",affairsLibraryContextCopy:"复制",affairsLibraryContextCopyFile:"文件",affairsLibraryContextCopyFileName:"文件名",affairsLibraryContextCopyAbsolutePath:"绝对路径",affairsLibraryContextCopyRelativePath:"相对路径",affairsLibraryContextCut:"剪切",affairsLibraryContextPaste:"粘贴",affairsLibraryContextDelete:"删除",affairsLibraryContextTags:"标签",affairsLibraryContextProperties:"属性",affairsLibraryRecentTagsEmpty:"还没有可用的最近标签",affairsLibraryActionFailed:"文档操作失败",affairsLibraryDownloadSuccess:"已下载 {name}",affairsLibraryDownloadFailed:"下载失败",affairsLibraryCopyFileSuccess:"已复制文件路径",affairsLibraryCopyFileNameSuccess:"已复制文件名",affairsLibraryCopyAbsolutePathSuccess:"已复制绝对路径",affairsLibraryCopyRelativePathSuccess:"已复制相对路径",affairsLibraryCopyFailed:"复制失败",affairsLibraryCutSuccess:"已剪切 {name}",affairsLibraryPasteSuccess:"已粘贴 {name}",affairsLibraryDeleteSuccess:"已删除 {name}",affairsLibraryDeleteConfirmTitle:"确认删除",affairsLibraryDeleteConfirmDescription:"删除会立刻生效,这里不能撤销。",affairsLibraryDeleteDocumentConfirm:"确定要删除文件“{path}”吗?",affairsLibraryDeleteFolderConfirm:"确定要删除目录“{path}”吗?目录里的内容也会一起删除。",affairsLibraryDeleteConfirmAction:"确认删除",affairsLibraryDeleteSubmitting:"删除中...",affairsLibraryCreateModalTitle:"新建内容",affairsLibraryCreateModalDescription:"会创建到 {path} 里。先把名字写清楚,再继续。",affairsLibraryCreateNameLabel:"名称",affairsLibraryCreateNamePlaceholder:"请输入名称",affairsLibraryCreateTypeHint:"当前准备新建:{type}",affairsLibraryCreateConfirmAction:"创建",affairsLibraryCreateFailed:"新建失败",affairsLibraryCreateSuccess:"已创建 {name}",affairsLibraryCreateNameRequired:"请先输入名称",affairsLibraryCreateDirectoryDefaultName:"新建目录",affairsLibraryCreateMarkdownDefaultName:"新建文档.md",affairsLibraryCreateTextDefaultName:"新建文档.txt",affairsLibraryCreateCustomDefaultName:"未命名文件",affairsLibraryCreateMarkdownHeading:"新文档",affairsLibraryAbsolutePathMissing:"当前文档库缺少可打开的本地路径",affairsLibraryUntitledFileName:"未命名文件",affairsFavoriteAddAction:"加入收藏",affairsFavoriteRemoveAction:"取消收藏",affairsFavoriteAdded:"已加入收藏",affairsFavoriteRemoved:"已取消收藏",affairsFavoritesEmpty:"还没有收藏。你可以先收藏常用文件夹或标签。",affairsLibraryBrowseModeLabel:"文档库浏览模式",affairsLibraryBrowseModeFolder:"文件夹",affairsLibraryBrowseModeTag:"标签",affairsLibrarySortLabel:"排序方式",affairsLibrarySortRecent:"最近",affairsLibrarySortName:"名称",affairsLibrarySortType:"类型",affairsLibrarySortSize:"大小",affairsLibrarySortCreatedAt:"创建时间",affairsLibraryViewModeLabel:"文档库显示方式",affairsLibraryViewModeGrid:"图标",affairsLibraryViewModeList:"列表",affairsLibraryTagTreeTitle:"标签树",affairsLibraryTagTreeShowMore:"显示更多标签",affairsLibraryTagTreeShowLess:"收起其他标签",affairsLibraryTagTreeReset:"重置筛选",affairsLibraryTagSearchAction:"查找标签",affairsLibraryTagSearchInputLabel:"查找标签",affairsLibraryTagSearchPlaceholder:"输入关键词或拼音",affairsLibraryTagSearchResultsLabel:"标签查找结果",affairsLibraryTagSearchEmpty:"没有匹配的标签",affairsLibraryPreparingMessage:"正在准备文档库对象,目录和标签会先出来,不再整页卡住。",affairsLibraryGoParentAction:"返回上级",affairsFinderColumnName:"名称",affairsFinderColumnSize:"大小",affairsFinderColumnUpdatedAt:"修改时间",affairsFinderColumnType:"类型",affairsFinderColumnCreatedAt:"创建时间",affairsFinderSortAction:"按{column}排序",affairsFinderSortCurrent:"{column},当前按{direction}排序",affairsFinderSortDirectionAsc:"升序",affairsFinderSortDirectionDesc:"降序",affairsFinderResizeColumn:"调整“{column}”列宽",affairsFinderDateToday:"今天",affairsFinderDateYesterday:"昨天",affairsFinderKindFolder:"文件夹",affairsFinderKindFile:"文件",affairsFinderKindMarkdown:"Markdown 文稿",affairsFinderKindText:"文本文档",affairsFinderKindHtml:"HTML 文稿",affairsFinderKindJson:"JSON 数据",affairsFinderKindXml:"XML 文稿",affairsFinderKindYaml:"YAML 配置",affairsFinderKindImage:"图片",affairsFinderKindPdf:"PDF 文稿",affairsFinderKindWord:"Word 文稿",affairsFinderKindExcel:"Excel 表格",affairsFinderKindPowerPoint:"PowerPoint 演示文稿",affairsFinderKindArchive:"压缩文件",affairsFinderKindCode:"代码文件",affairsFinderKindSql:"SQL 脚本",affairsFinderKindDatabase:"数据库文件",affairsFinderKindAudio:"音频文件",affairsFinderKindVideo:"视频文件",affairsFinderKindDesign:"设计文件",affairsFinderKindFont:"字体文件",affairsFinderKindEbook:"电子书",affairsFinderKindData:"数据文件",affairsLibraryFolderRootLabel:"根目录",affairsLibraryTagRootLabel:"全部标签",affairsLibraryFolderStageDescription:"当前目录:{path} · 子文件夹 {folderCount} 个 · 文档 {documentCount} 份",affairsLibraryTagStageDescription:"当前标签:{path} · 匹配文档 {count} 份",affairsLibraryFolderCardCount:"{count} 个对象",affairsLibraryFolderDetailTitle:"目录详情",affairsLibraryFolderDetailDescription:"这里显示当前目录的直接内容和整个子树规模。",affairsLibraryFolderDetailSummary:"当前目录是 {path}。这里有 {folderCount} 个直接子目录、{directDocumentCount} 份直接文档,整个目录树一共 {totalDocumentCount} 份文档。",affairsLibraryTagDetailTitle:"标签详情",affairsLibraryTagDetailDescription:"这里显示当前标签的命中范围,不影响右侧事务助手。",affairsLibraryDocumentDetailTitle:"文档详情",affairsLibraryDocumentSize:"文件大小",affairsLibraryDocumentCreatedAt:"创建时间",affairsLibraryDocumentUpdatedAt:"修改时间",affairsDocumentSummaryExpandAction:"展开全文",affairsDocumentSummaryCollapseAction:"收起详情",affairsLibraryFolderOpenBehaviorLabel:"文件夹打开方式",affairsLibraryFolderOpenBehaviorHint:"默认双击进入文件夹。需要更快的操作时,可以改成单击直接进入。",affairsLibraryFolderOpenBehaviorSwitchLabel:"单击进入文件夹",affairsLibraryFolderOpenBehaviorSingle:"单击打开",affairsLibraryFolderOpenBehaviorDouble:"双击打开",affairsDocumentTagsSectionTitle:"文档标签",affairsFolderTagsSectionTitle:"文件夹标签",affairsDocumentTagSourcesTitle:"标签来源",affairsDocumentTagSourcesEmpty:"当前文件还没有可解释的标签来源。",affairsTagSourceManualDocument:"手动分配",affairsTagSourceFolderBinding:"文件夹继承",affairsTagSourceSystemDerived:"系统推导",affairsTagDetailsLoading:"正在读取标签详情…",affairsDocumentTagAddLabel:"添加文档标签",affairsDocumentTagSearchPlaceholder:"输入标签名称或路径",affairsDocumentTagSuggestionsLabel:"可添加的文档标签",affairsDocumentTagNoMatch:"没有匹配的可添加标签",affairsDocumentTagsEmpty:"还没有手动添加的标签。",affairsDocumentTagRemoveAction:"移除标签 {tag}",affairsFolderTagAddLabel:"添加文件夹标签",affairsFolderTagSuggestionsLabel:"可分配给文件夹的标签",affairsFolderTagsEmpty:"这个文件夹还没有手动标签。",affairsTagQuickSearchPlaceholder:"输入标签名称或路径,回车即可分配",affairsTagQuickCreateAction:"创建并分配“{tag}”",affairsTagQuickCreateHint:"如果这个标签还不存在,会直接新建后分配。",affairsTagQuickAlreadyAssigned:"这个标签已经分配过了。",affairsTagQuickAssignModalTitle:"分配标签",affairsTagQuickAssignDocumentDescription:"给“{name}”分配标签。输入已有标签会直接匹配,没有就当场创建。",affairsTagQuickAssignFolderDescription:"给“{name}”分配标签。这个标签会同步到当前文件夹和后续新增文件。",affairsFolderTagTaskShortTitle:"{operation}标签",affairsFolderTagTaskTitle:"{operation}标签进度",affairsFolderTagTaskButtonLabel:"{folder} 的{operation}标签状态:{status},当前进度 {percent}%",affairsFolderTagTaskFolderLabel:"当前文件夹",affairsFolderTagTaskPhaseLabel:"当前阶段",affairsFolderTagTaskProgressLabel:"已处理文档",affairsFolderTagTaskProgressCount:"{current} / {total}",affairsFolderTagTaskPreparing:"正在准备",affairsFolderTagTaskSubmitting:"正在提交{operation}标签请求",affairsFolderTagTaskSubmittingDetail:"请求已经发出,正在等待任务开始。",affairsFolderTagTaskOperationAttach:"添加",affairsFolderTagTaskOperationRemove:"移除",affairsFolderTagTaskOperationUpdate:"更新",affairsFolderTagTaskStatusQueued:"排队中",affairsFolderTagTaskStatusRunning:"进行中",affairsFolderTagTaskStatusSucceeded:"已完成",affairsFolderTagTaskStatusFailed:"失败",affairsFolderTagTaskStatusCancelled:"已取消",affairsFolderTagTaskStatusTimeout:"超时",affairsFolderTagTaskPhasePrepare:"准备任务",affairsFolderTagTaskPhaseRecompute:"应用标签",affairsFolderTagTaskPhaseWrite:"写入结果",affairsFolderTagTaskPhaseExport:"刷新结果",affairsFolderTagTaskPhaseFinished:"处理完成",affairsTagTaskHistoryTitle:"最近标签任务",affairsTagTaskHistoryShortTitle:"标签任务",affairsTagTaskHistoryButtonLabel:"最近 {count} 条标签任务,当前为 {target} 的{operation}标签:{status},进度 {percent}%",affairsTagTaskHistoryCount:"最近 {count} 条",affairsTagTaskHistoryRunningCount:"处理中 {count}",affairsTagTaskDocumentLabel:"当前文档",affairsTagManagerAction:"管理标签",affairsTagManagerTitle:"标签管理",affairsTagManagerDescription:"这里用来整理标签树。左边点标签,右边直接编辑,并给需要自动命中的标签设置规则。",affairsTagManagerSectionTitle:"标签树和规则",affairsTagManagerSectionDescription:"左边选标签,右边新建、编辑或删除。",affairsTagBatchSectionTitle:"批量修改和批量删除",affairsTagBatchSectionDescription:"先勾选要一起处理的标签,再统一改上级、启停状态,或者一起删除。",affairsTagBatchEmpty:"还没有选中标签",affairsTagBatchEmptyDescription:"左边勾选两个或更多标签后,就可以在这里一起处理。",affairsTagBatchSelectionSummary:"已勾选 {count} 个标签",affairsTagBatchCheckboxLabel:"选择标签 {tag}",affairsTagBatchSelectAllAction:"全选",affairsTagBatchClearSelectionAction:"清空选择",affairsTagBatchParentLabel:"统一改到上级标签",affairsTagBatchParentKeepOption:"保持原来的上级",affairsTagBatchStatusLabel:"统一状态",affairsTagBatchStatusKeepOption:"保持原状态",affairsTagBatchStatusActiveOption:"统一启用",affairsTagBatchStatusDisabledOption:"统一停用",affairsTagBatchUpdateAction:"批量保存修改",affairsTagBatchDeleteAction:"批量删除",affairsTagBatchHint:"批量修改会把所选标签统一改到同一个上级,并统一启停状态,不会自动保留它们原来的父子层级。",affairsTagRecoverySectionTitle:"重新写回文件标签",affairsTagRecoverySectionDescription:"只有当文件上的标签结果没跟上最新标签树、文件夹标签或智能规则时,才需要在这里重跑。",affairsTagRecoveryStatusLabel:"当前状态",affairsTagRecoveryStatusIdle:"还没有开始",affairsTagRecoveryPhaseIdle:"等待发起",affairsTagRecoveryProgressIdle:"还没有开始处理",affairsTagRecoveryAction:"恢复文件标签结果",affairsTagRecoveryRunningAction:"正在恢复文件标签结果…",affairsTagRecoveryHint:"这会全量重跑手动标签、文件夹标签、智能标签和系统标签,把文件上的标签结果重新写回。",affairsTagRecoveryRunningHint:"恢复任务正在执行,完成后文件上的标签关联会自动补回。",affairsTagRecoveryStartedDescription:"恢复任务已经开始,处理完成后文件标签会逐步补回。",affairsTagRecoveryQueuedDescription:"已经有同一个恢复任务在排队或执行,等它完成就行。",affairsTagRecoveryFailed:"发起文件标签恢复失败,请稍后再试。",affairsTagRecoveryIdentityBindingLabel:"身份绑定",affairsTagRecoveryLegacyBindingLabel:"旧路径兼容数据",affairsTagRecoveryLegacyFallbackLabel:"仍在兼容层",affairsTagRecoveryCompatibilityHint:"主链路现在优先读“身份绑定”。当前还有 {count} 条旧路径绑定只留在兼容层,涉及 {documents} 份文档,后面会逐步退出主链路。",affairsTagRecoveryCleanHint:"当前没有需要兼容处理的旧数据。只有文件上的标签结果不对时,才需要手动重跑。",affairsTagRecoveryPendingHint:"还有 {documents} 份文档在用旧兼容数据。想把文件上的标签结果统一重写时,再点下面的按钮。",affairsTagBatchUpdateNoop:"请先选择要批量改什么,不然这一步没有任何变化。",affairsTagBatchUpdateSuccess:"批量修改已完成",affairsTagBatchUpdateSuccessDescription:"已更新 {count} 个标签。",affairsTagBatchUpdateFailed:"批量修改失败",affairsTagBatchDeleteConfirm:"确定删除这 {count} 个标签吗?如果里面有父标签,它下面的子标签也会一起删除。",affairsTagBatchDeleteSuccess:"批量删除已完成",affairsTagBatchDeleteSuccessDescription:"已删除 {count} 个标签。",affairsTagBatchDeleteFailed:"批量删除失败",affairsTagCreateAction:"新建标签",affairsTagTreeSectionTitle:"标签树",affairsTagTreeSectionDescription:"这里只显示可以手动管理的业务标签。",affairsTagTreeEmpty:"还没有业务标签",affairsTagTreeEmptyDescription:"先建一个根标签,再慢慢往下补子标签。",affairsTagTreeDocumentCount:"{count} 份文档",affairsTagCreateRootAction:"新建根标签",affairsTagCreateChildAction:"新建子标签",affairsTagEditorCreateRootTitle:"新建根标签",affairsTagEditorCreateRootDescription:"先把顶层分类建出来,后面再逐层往下细分。",affairsTagEditorCreateChildTitle:"新建子标签",affairsTagEditorCreateChildDescription:"这个新标签会放到“{tag}”下面。",affairsTagEditorEditTitle:"编辑标签",affairsTagEditorEditDescription:"这里改当前标签的名称和层级。文档数量也放在这里看,智能规则在下一块单独设置。",affairsTagEditorPathLabel:"标签路径",affairsTagEditorDocumentCountLabel:"命中文档",affairsTagSmartRulesSectionTitle:"智能标签规则",affairsTagSmartRulesSectionDescription:"规则会直接挂在当前标签上。命中后,系统会自动把这个标签分配给文件。",affairsTagSmartRulesEmpty:"还没有智能规则",affairsTagSmartRulesEmptyDescription:"如果这个标签需要自动命中条件,就在这里追加规则。",affairsTagSmartRuleAddAction:"添加规则",affairsTagSmartRuleRelationLabel:"关系",affairsTagSmartRuleRelationAnd:"与",affairsTagSmartRuleRelationOr:"或",affairsTagSmartRuleRelationNot:"非",affairsTagSmartRuleTypeLabel:"规则类型",affairsTagSmartRuleTypeFileNameContains:"文件名包含指定字符",affairsTagSmartRuleTypeFileContentContains:"文件内容包含指定字符",affairsTagSmartRuleTypeFileExtensionIn:"指定文件类型",affairsTagSmartRuleTypeModifiedTimeBetween:"文件修改时间范围",affairsTagSmartRuleTypeDocumentPathInFolder:"位于指定文件夹及子文件夹",affairsTagSmartRuleKeywordLabel:"关键词",affairsTagSmartRuleKeywordPlaceholder:"例如:合同、报价、付款",affairsTagSmartRuleExtensionsLabel:"文件类型",affairsTagSmartRuleExtensionsPlaceholder:"例如:pdf, docx, xlsx",affairsTagSmartRuleModifiedStartLabel:"开始时间",affairsTagSmartRuleModifiedEndLabel:"结束时间",affairsTagSmartRuleFolderPathLabel:"文件夹路径",affairsTagSmartRuleFolderPathPlaceholder:"例如:售前/方案,根目录可填 .",affairsTagSmartRuleEnabledLabel:"启用这条规则",affairsTagSmartRuleRemoveAction:"删除规则",affairsTagSmartRuleOrderHint:"第 {index} 条规则",affairsTagNameLabel:"标签名称",affairsTagNamePlaceholder:"例如:客户合同",affairsTagParentLabel:"上级标签",affairsTagParentRootOption:"放在标签树根部",affairsTagSaveAction:"保存标签",affairsTagSaveFailed:"保存标签失败",affairsTagSaveSuccess:"标签已保存",affairsTagSaveSuccessDescription:"标签树已经更新。",affairsTagCreateSubmitAction:"创建标签",affairsTagUpdateSubmitAction:"保存修改",affairsTagResetFormAction:"清空表单",affairsTagRevertAction:"恢复当前内容",affairsTagCloseAction:"关闭",affairsTagDangerZoneTitle:"删除标签",affairsTagDangerZoneDescription:"删除当前标签时,下面的子标签也会一起删掉。",affairsTagDeleteAction:"删除这个标签",affairsTagDeleteConfirm:"确定删除“{tag}”吗?它下面的子标签也会一起删除。",affairsTagDeleteFailed:"删除标签失败",affairsTagDeleteSuccess:"标签已删除",affairsTagDeleteSuccessDescription:"标签树已经更新,文档标签结果会跟着刷新。",affairsLibraryCurrentFolder:"当前目录",affairsLibraryCurrentTag:"当前标签",affairsLibraryDirectFolderCount:"直接子文件夹",affairsLibraryDirectDocumentCount:"直接文档数",affairsLibraryNestedDocumentCount:"子树文档数",affairsLibraryTagRootType:"标签根分类",affairsLibraryTagMultiTitle:"组合筛选",affairsLibraryTagMultiRootType:"多标签组合",affairsLibraryTagDocumentCount:"当前标签命中",affairsLibraryNestedTagDocumentCount:"标签子树命中",affairsLibraryBindingSaveFailed:"保存文档库路径失败",affairsLibraryStatusIdle:"未初始化",affairsLibraryStatusFresh:"已就绪",affairsLibraryStatusStale:"待刷新",affairsLibraryStatusQueued:"排队中",affairsLibraryStatusRunning:"刷新中",affairsLibraryStatusQueueTimeout:"排队超时",affairsLibraryStatusCooldown:"刚刷新完",affairsLibraryStatusFailed:"刷新失败",affairsLibraryStatusIndicatorAction:"文档库索引状态:{status}",affairsLibraryStatusIndicatorProgress:"已扫 {scanned}",affairsLibraryStatusPopoverTitle:"文档库索引器状态",affairsLibraryStatusSummaryTotalLabel:"索引总数",affairsLibraryStatusSummaryScannedLabel:"当前数量",affairsLibraryStatusSummaryUpdatedLabel:"更新数量",affairsLibraryStatusSummaryIssueLabel:"问题数量",affairsLibraryStatusPrimaryTitle:"当前概览",affairsLibraryStatusTechnicalToggle:"技术详情",affairsLibraryStatusSectionOverviewTitle:"运行细节",affairsLibraryStatusSectionTimelineTitle:"时间记录",affairsLibraryStatusSectionProgressTitle:"扫描细分",affairsLibraryStatusSectionDirectoryTitle:"目录结果",affairsLibraryStatusSectionWorkerTitle:"后台执行",affairsLibraryStatusCurrentLabel:"当前状态",affairsLibraryStatusLastRequestedAtLabel:"最近请求",affairsLibraryStatusLastStartedAtLabel:"最近启动",affairsLibraryStatusLastCompletedAtLabel:"最近完成",affairsLibraryStatusLastFailedAtLabel:"最近失败",affairsLibraryStatusNextAllowedAtLabel:"下次允许刷新",affairsLibraryStatusRunningTaskIdLabel:"运行任务",affairsLibraryStatusRunningStageLabel:"当前阶段",affairsLibraryStatusProgressScannedLabel:"已扫描文件",affairsLibraryStatusProgressIndexedLabel:"本轮已更新",affairsLibraryStatusProgressUnchangedLabel:"未变化跳过",affairsLibraryStatusProgressSkippedLabel:"解析跳过",affairsLibraryStatusProgressFailedLabel:"处理失败",affairsLibraryStatusProgressTotalLabel:"预计总数",affairsLibraryStatusDirtyReasonsLabel:"待处理原因",affairsLibraryStatusErrorSummaryLabel:"失败说明",affairsLibraryStatusStageQueued:"排队中",affairsLibraryStatusStageInit:"准备索引环境",affairsLibraryStatusStageApplyConfig:"应用配置",affairsLibraryStatusStageIndex:"更新索引",affairsLibraryStatusStageIncrementalIndex:"增量索引",affairsLibraryStatusStageRecomputeTags:"重算标签",affairsLibraryStatusStageExport:"导出结果",affairsLibraryStatusStageExportMetaDetail:"导出目录和文档",affairsLibraryStatusStageExportTag:"导出标签结果",affairsLibraryStatusStageExportRelation:"导出文档关系",affairsLibraryStatusStageExportSearch:"构建搜索索引",affairsLibraryStatusStageSqlite:"写入数据库",affairsLibraryDirectoryStatusPathLabel:"当前目录",affairsLibraryDirectoryStatusRootPath:"根目录",affairsLibraryDirectoryStatusStateLabel:"目录刷新状态",affairsLibraryDirectoryStatusSourceLabel:"目录结果来源",affairsLibraryDirectoryStatusLastRequestedAtLabel:"目录最近请求",affairsLibraryDirectoryStatusLastCompletedAtLabel:"目录最近完成",affairsLibraryDirectoryStatusLastFailedAtLabel:"目录最近失败",affairsLibraryDirectoryStatusRunningTaskIdLabel:"目录运行任务",affairsLibraryDirectoryStatusErrorSummaryLabel:"目录失败说明",affairsLibraryDirectoryStatusGeneratedAtLabel:"当前结果生成时间",affairsLibraryDirectoryStatusFilesystemObservedAtLabel:"最近扫盘时间",affairsLibraryDirectoryStatusStaleReasonLabel:"当前降级原因",affairsLibraryDirectoryStatusIdle:"未调度",affairsLibraryDirectoryStatusQueued:"排队中",affairsLibraryDirectoryStatusRunning:"刷新中",affairsLibraryDirectoryStatusQueueTimeout:"排队超时",affairsLibraryDirectoryStatusFresh:"已更新",affairsLibraryDirectoryStatusFailed:"刷新失败",affairsLibraryDirectoryStatusSourceLive:"实时目录",affairsLibraryDirectoryStatusSourceSnapshot:"导出快照",affairsLibraryDirectoryStatusSourceMixed:"实时目录 + 快照",affairsLibraryDirectoryStatusSourceStaleFallback:"保底旧结果",affairsLibraryWorkerHealthStateLabel:"Worker 状态",affairsLibraryWorkerHealthPidLabel:"Worker PID",affairsLibraryWorkerHealthLocalInflightLabel:"本地挂起数",affairsLibraryWorkerHealthRemoteInflightLabel:"远端挂起数",affairsLibraryWorkerHealthStartedAtLabel:"Worker 启动时间",affairsLibraryWorkerHealthHeartbeatLabel:"最近心跳",affairsLibraryWorkerHealthLastStartedAtLabel:"最近接任务",affairsLibraryWorkerHealthLastCompletedAtLabel:"最近完成任务",affairsLibraryWorkerHealthLastFailedAtLabel:"最近失败任务",affairsLibraryWorkerHealthSoftCancelAtLabel:"最近软取消",affairsLibraryWorkerHealthHardKillAtLabel:"最近强制回收",affairsLibraryWorkerHealthLastExitAtLabel:"最近退出",affairsLibraryWorkerHealthTerminationReasonLabel:"最近回收原因",affairsLibraryWorkerHealthStateIdle:"空闲",affairsLibraryWorkerHealthStateRunning:"运行中",affairsLibraryWorkerHealthStateTerminating:"正在回收",affairsLibraryWorkerHealthStateRecycled:"已回收",affairsLibraryEmptyRunning:"正在刷新文档库,稍等一会再看。",affairsAssistantWaitingDocument:"文档库已经绑定,但当前还没有可选文档。先刷新或换一个目录看看。",affairsSidebarGroupOverview:"总览",affairsSidebarGroupTags:"标签",affairsFavoriteBadge:"收藏",affairsLibraryStageDescription:"当前共有 {count} 组收藏 / 标签入口在驱动文档列表。",affairsTodoSidebarTitle:"代办来源",affairsTodoSidebarDescription:"这里汇总手动代办、待分析事项和会话跟进任务,共 {count} 项。",affairsTodoAllFilter:"全部代办",affairsTodoAllFilterSummary:"把当前工作区所有未完成事项先放在一起看。",affairsTodoInboxFilter:"待分析事项",affairsTodoInboxSummary:"来自助手收件箱,还没完全消化的事项。",affairsTodoFollowUpFilter:"会话跟进",affairsTodoFollowUpSummary:"来自代码会话的未完成跟进任务。",affairsTodoSidebarGroupSources:"来源分类",affairsTodoStageTitle:"代办列表",affairsTodoStageDescription:"当前共有 {count} 组代办来源在驱动主列表。",affairsTodoEmpty:"当前没有待处理的代办或会话跟进。",affairsTodoStatusPending:"待处理",affairsTodoStatusInProgress:"处理中",affairsTodoStatusClosed:"已关闭",affairsTodoStatusWaitingUser:"等待你确认",affairsTodoStatusCompleted:"已完成",affairsTodoStatusFailed:"已失败",affairsTodoStatusCancelled:"已取消",affairsTodoStatusActive:"进行中",affairsTodoDetailStatus:"当前状态",affairsTodoDetailSource:"来源会话",affairsTodoDetailNotes:"补充说明",affairsTodoDetailTotal:"当前筛选结果",affairsTodoDetailTotalValue:"共 {count} 项",affairsAutomationSidebarTitle:"自动化任务",affairsAutomationSidebarDescription:"这里直接复用助手自动化任务,共 {count} 条。",affairsAutomationStageTitle:"自动化任务",affairsAutomationStageDescription:"当前共有 {count} 条自动化任务可直接查看。",affairsAutomationEmpty:"当前没有可展示的自动化任务。",affairsAutomationUntitled:"未命名自动化",affairsAutomationPromptFallback:"这个自动化还没有可读说明。",affairsAutomationStatusActive:"运行中",affairsAutomationStatusPaused:"已暂停",affairsAutomationStatusCompleted:"已完成",affairsAutomationStatusCancelled:"已取消",affairsAutomationStatusFailed:"已失败",affairsAutomationTriggerOnce:"单次触发",affairsAutomationTriggerInterval:"定时轮询",affairsAutomationTriggerCron:"周期计划",affairsAutomationTriggerCondition:"条件触发",affairsAutomationTargetFallback:"当前没有绑定目标会话",affairsAutomationDetailTrigger:"触发方式",affairsAutomationDetailTarget:"目标会话",affairsAutomationDetailStatus:"任务状态",affairsAutomationRunsTitle:"最近执行",affairsAutomationRunsDescription:"这里直接看这条自动化最近跑成什么样。",affairsAutomationRunsEmpty:"最近还没有执行记录。",affairsAutomationRunsFallback:"这次运行还没有产出可读摘要。",affairsAutomationLastRunSummary:"最近一次:{summary}",affairsAutomationSidebarGroupTasks:"任务列表",affairsAutomationRunsStatusQueued:"排队中",affairsAutomationRunsStatusRunning:"执行中",affairsAutomationRunsStatusFinished:"已完成",affairsAutomationRunsStatusFailed:"已失败",affairsAutomationRunsStatusCancelled:"已取消",affairsAutomationRunsStatusSkipped:"已跳过",affairsAuxiliaryTabsLabel:"事务视图右侧标签页",affairsDetailMetaPath:"文档路径",affairsDetailMetaTags:"标签",butlerInitTitle:"初始化助手",butlerInitDescription:"先设置助手的称呼、provider 和工作方式。助手工作目录和第一版 AGENTS.md 会由系统自动创建。",butlerInitPreviewTitle:"当前预览",butlerInitPreviewDescription:"这不是花架子,下面这些选择会直接决定首版规则的语气和汇报方式。",butlerInitBasicsTitle:"基础设置",butlerInitBasicsDescription:"先把名字、provider 和规则载体定下来,别让初始化阶段长成配置地狱。",butlerInitPersonaTitle:"表达方式",butlerInitPersonaDescription:"语气、语言和总结风格决定它怎么说,不决定它会不会胡来。",butlerInitPreferenceTitle:"默认偏好",butlerInitPreferenceDescription:"这里控制它默认先盯什么风险、先汇报什么结果。",butlerInitRuleLabel:"规则载体",butlerInitTipAutoWorkspace:"系统会自动创建助手目录和首版 AGENTS.md,你现在只需要定默认偏好。",butlerInitTipProviderSwitch:"Provider 后续还能切,不用在第一次初始化时把自己困死。",butlerInitTipReportPriority:"汇报优先级会影响它先告诉你风险、阻塞,还是验证结果。",butlerDisplayNameLabel:"助手称呼",butlerDisplayNamePlaceholder:"例如:阿尔文、小助手",butlerDisplayNameHint:"这是助手的自称,系统会写入 AGENTS.md 首版规则。",butlerProviderLabel:"Provider",butlerWorkspacePathLabel:"助手工作目录",butlerWorkspacePathPlaceholder:"例如:/Users/you/WorkFile/butler-home",butlerAgentsModeLabel:"AGENTS 模式",butlerAgentsModeInline:"内联",butlerAgentsModeFile:"文件",butlerAgentsModeInlineDescription:"内联:系统按你的初始化选项生成规则,后续由系统管理为主。",butlerAgentsModeFileDescription:"文件:系统会在助手独立工作目录下写入 AGENTS.md,后续可以直接改这个文件。",butlerAgentsFilePathLabel:"AGENTS.md 文件路径",butlerAgentsFilePathPlaceholder:"例如:/Users/you/WorkFile/butler-home/AGENTS.md",butlerAgentsContentLabel:"AGENTS 规则内容",butlerAgentsContentPlaceholder:"输入助手的工作规则和解答风格",butlerAgentsContentHint:"这里维护助手的正式规则正文,保存后会直接回写 Butler 专用 AGENTS.md 或内联规则。",butlerPersonaToneLabel:"语气",butlerPersonaLanguageLabel:"使用语言",butlerPersonaSummaryStyleLabel:"总结风格",butlerFocusRiskPreferenceLabel:"风险倾向",butlerFocusReportPriorityLabel:"汇报优先级(逗号分隔)",butlerFocusReportPriorityPlaceholder:"例如:risk,blocker,verification",butlerToneDirect:"直接明确",butlerToneSteady:"稳健克制",butlerToneFriendly:"友好耐心",butlerLanguageZhCn:"中文优先",butlerLanguageEnUs:"英文优先",butlerLanguageBilingual:"中英双语",butlerSummaryBrief:"简明扫一眼",butlerSummaryStructured:"分段清晰",butlerSummaryThorough:"详细展开",butlerRiskConservative:"保守稳妥",butlerRiskBalanced:"推进/风险平衡",butlerRiskProactive:"主动预警",butlerReportPriorityPresetLabel:"汇报优先级",butlerReportRiskFirst:"风险优先",butlerReportBlockerFirst:"阻塞优先",butlerReportVerificationFirst:"验证优先",butlerReportProgressFirst:"进展优先",butlerSummaryDebounceLabel:"会话摘要防抖",butlerSummaryDebounceOption1Minute:"1 分钟",butlerSummaryDebounceOption3Minutes:"3 分钟",butlerSummaryDebounceOption5Minutes:"5 分钟(默认)",butlerSummaryDebounceOption10Minutes:"10 分钟",butlerSummaryDebounceOption15Minutes:"15 分钟",butlerSummaryDebounceOption30Minutes:"30 分钟",butlerSettingsTitle:"助手设置",butlerSettingsSaveAction:"保存设置",butlerSettingsSaving:"保存中...",butlerSettingsSaved:"助手设置已保存",butlerSettingsSaveFailed:"保存助手设置失败",butlerInitSubmitting:"初始化中...",butlerInitSubmit:"完成初始化",butlerInitSuccess:"助手初始化成功",butlerInitFailed:"助手初始化失败",butlerInitNameRequired:"请先输入助手称呼",butlerInitWorkspaceRequired:"请先填写助手工作目录",butlerInitAgentsFileRequired:"文件模式下请填写 AGENTS.md 路径",butlerWorkbenchTitle:"助手工作台",butlerWorkbenchSubtitle:"在这里与助手对话,并查看聚合上下文和动作事件。",butlerWorkspaceHint:"助手工作目录:{workspacePath}",butlerDisplayNameActiveHint:"当前助手称呼:{displayName}",butlerNewSessionAction:"新建会话",butlerNewSessionStarted:"已为助手新建会话",butlerNewSessionFailed:"新建助手会话失败",butlerRefreshAction:"刷新",butlerHistoryAction:"最近会话",butlerHistoryTitle:"最近会话",butlerHistoryDescription:"这里保留所有 Butler 会话,代办分析和普通聊天都会持久化保存。",butlerHistoryEmpty:"还没有助手历史会话。",butlerHistorySearchLabel:"搜索会话",butlerHistorySearchPlaceholder:"搜索会话标题或内容",butlerHistorySearchEmpty:"没有找到匹配的会话。",butlerHistoryActiveSection:"活跃会话",butlerHistoryInactiveSection:"较早会话",butlerHistoryOpenAction:"打开这条会话",butlerHistoryDeleteAction:"删除这条会话",butlerCurrentSessionBadge:"当前会话",butlerControlSessionKindChat:"普通聊天",butlerControlSessionKindTodoAnalysis:"代办分析",butlerLoadingTitle:"助手页面加载中",butlerLoadingDescription:"正在整理当前助手的会话、摘要和控制状态,请稍候。",butlerSidebarInfoTab:"信息",butlerSidebarAutomationTab:"自动化",butlerSidebarSettingsTab:"设置",butlerSidebarTabsLabel:"助手信息栏标签",butlerSidebarLoadFailed:"助手信息栏读取失败",butlerInfoContextTitle:"当前上下文",butlerInfoContextDescription:"这里先告诉你助手这一轮正在看什么,不把无关信息一股脑塞进来。",butlerInfoCurrentScopeLabel:"当前范围",butlerInfoCurrentScopeProject:"项目:{projectName}",butlerInfoCurrentScopeGlobal:"全局总览",butlerInfoManagedProjectsLabel:"已跟踪项目",butlerInfoManagedProjectsValue:"活跃 {activeCount} / 全部 {totalCount}",butlerInfoCurrentContextProjectHint:"当前已经切到 {projectName},助手后续补查会优先围绕这个项目展开。",butlerInfoCurrentContextGlobalHint:"当前还是全局视角,只有你点进项目或追问细节时,助手才继续补查更深的信息。",butlerInfoProjectSelectedAction:"当前已选中",butlerInfoProjectViewAction:"查看这个项目",butlerInfoProjectBlockedBadge:"有阻塞",butlerInfoProjectRiskBadge:"风险:{riskLevel}",butlerInfoProjectRiskShortBadge:"风险 {riskLevel}",butlerInfoProjectLastActivityBadge:"最近活跃:{updatedAt}",butlerInfoLatestSessionAction:"打开最近会话",butlerInfoProgressTitle:"当前进展",butlerInfoAttentionTitle:"需要留意",butlerInfoNextStepTitle:"建议下一步",butlerInfoFollowUpRecordsTitle:"会话跟进",butlerInfoFollowUpRecordsDescription:"这里只显示最近 5 条会话跟进状态,完整历史通过按钮展开查看。",butlerInfoFollowUpRecordsEmpty:"还没有会话跟进记录。",butlerInfoFollowUpUntitled:"未命名会话",butlerInfoFollowUpFallback:"最近更新时间:{updatedAt}",butlerFollowUpHistoryAction:"查看历史",butlerFollowUpHistoryTitle:"会话跟进历史",butlerFollowUpHistoryDescription:"这里查看完整的会话跟进状态历史,并可继续下钻轮次详情。",butlerInfoVerificationRecordsTitle:"会话验证",butlerInfoVerificationRecordsDescription:"这里看全局的功能验证记录。",butlerInfoVerificationRecordsEmpty:"还没有会话验证记录。",butlerInfoVerificationFallback:"当前状态:{status}",butlerVerificationHistoryTitle:"会话验证历史",butlerVerificationHistoryDescription:"这里只收口非进行中的验证记录,进行中的验证仍留在信息栏主列表。",butlerVerificationHistoryEmpty:"还没有可查看的历史验证记录。",butlerInfoTodoRecordsTitle:"代办进度",butlerInfoTodoRecordsDescription:"这里看当前汇总出来的代办推进情况。",butlerInfoTodoRecordsEmpty:"还没有代办进度记录。",butlerInfoShowCompletedAction:"显示已完成记录",butlerInfoTodoItemTitle:"代办 {index}",butlerInfoTodoPending:"待处理",butlerInfoTodoInProgress:"进行中",butlerInfoTodoClosed:"已关闭",butlerTodoLifecyclePending:"待分析",butlerTodoLifecycleAnalyzing:"分析中",butlerTodoLifecycleAnalyzed:"已生成提示词",butlerTodoLifecycleSessionCreated:"已创建会话",butlerTodoLifecycleFollowUpActive:"助手处理中",butlerTodoLifecycleCompleted:"已完成",butlerTodoLifecycleFailed:"处理失败",butlerTodoLifecycleEmpty:"这条代办还没有生成分析摘要。",butlerTodoPromptPreviewAction:"查看开发提示词",butlerTodoAnalyzeAction:"分析仓库",butlerTodoReanalyzeAction:"重新分析",butlerTodoAnalyzeRunning:"分析中...",butlerTodoAnalyzeQueued:"已加入后台分析队列",butlerTodoAnalyzeSucceeded:"已生成开发提示词",butlerTodoAnalyzeFailed:"代办仓库分析失败",butlerTodoAnalyzeFirstAction:"先分析代办",butlerTodoWaitForPromptAction:"等待分析完成",butlerTodoStartSessionAction:"创建会话",butlerTodoStartSessionRunning:"创建中...",butlerTodoCopyPromptAction:"复制提示词",butlerTodoOpenSessionAction:"打开会话",butlerTodoCopyPromptSucceeded:"开发提示词已复制",butlerTodoStartSessionSucceeded:"已为代办创建开发会话",butlerTodoStartSessionFailed:"代办会话创建失败",butlerAutomationTasksTitle:"自动化任务",butlerAutomationTasksDescription:"这里只看自动化任务本身:有哪些任务、现在什么状态、下一次什么时候运行。",butlerAutomationTasksEmpty:"当前还没有自动化任务。",butlerAutomationMobileOverviewDescription:"主列表只保留关键状态,点卡片再看完整配置和编辑项。",butlerAutomationRunsTitle:"最近运行记录",butlerAutomationRunsDescription:"这里只看自动化任务最近执行了什么,以及每次运行的结果。",butlerAutomationRunsEmpty:"最近还没有自动化运行记录。",butlerAutomationHistoryTitle:"自动化历史",butlerAutomationHistoryDescription:"这里只收口非进行中的自动化任务和历史运行记录,进行中的自动化继续留在主列表。",butlerAutomationHistoryEmpty:"还没有可查看的自动化历史记录。",butlerAutomationStatusActive:"进行中",butlerAutomationStatusWaitingUser:"等你决定",butlerAutomationStatusCompleted:"已完成",butlerAutomationStatusFailed:"失败",butlerAutomationStatusCancelled:"已取消",butlerAutomationTaskTypeLabel:"任务类型",butlerAutomationTaskTypeManual:"手动计划任务",butlerAutomationTaskTypeInterval:"定时计划任务",butlerAutomationTaskTypeCron:"Cron 计划任务",butlerAutomationTaskTypeFollowUp:"条件跟进任务",butlerAutomationTaskTypeControlTimer:"助手计时器",butlerAutomationTaskEnabled:"已启用",butlerAutomationTaskDisabled:"已停用",butlerAutomationStatusLabel:"当前状态",butlerAutomationTaskLastRunLabel:"最近运行",butlerAutomationTaskNextRunLabel:"下一次运行",butlerAutomationOpenDetailsAction:"查看配置",butlerAutomationCollapseDetailsAction:"收起详情",butlerAutomationDetailTitle:"自动化配置",butlerAutomationDetailDescription:"这里直接改触发条件和动作内容,保存后立刻生效。",butlerAutomationSaveAction:"保存配置",butlerAutomationSaving:"保存中...",butlerAutomationSaveSucceeded:"自动化配置已保存",butlerAutomationSaveFailed:"自动化配置保存失败",butlerAutomationTitleLabel:"自动化名称",butlerAutomationPromptLabel:"动作内容",butlerAutomationPromptRequired:"动作内容不能为空。",butlerAutomationIncludeTriggerContextLabel:"把触发上下文一并带给助手",butlerAutomationTargetSessionLabel:"目标会话",butlerAutomationDueAtLabel:"执行时间",butlerAutomationEverySecondsLabel:"每隔秒数",butlerAutomationEveryMinutesLabel:"每隔分钟",butlerAutomationEveryHoursLabel:"每隔小时",butlerAutomationStopAtLabel:"停止时间",butlerAutomationCronMinuteLabel:"Cron 分钟",butlerAutomationCronHourLabel:"Cron 小时",butlerAutomationCronDaysOfWeekLabel:"执行星期",butlerAutomationPollIntervalLabel:"轮询间隔(秒)",butlerAutomationExpiresAtLabel:"过期时间",butlerAutomationMaxChecksLabel:"最多检查次数",butlerAutomationInvalidDateSuffix:"格式不对,请重新填写时间。",butlerAutomationRequiredSuffix:"不能为空。",butlerAutomationInvalidNumberSuffix:"必须是整数。",butlerAutomationInvalidPositiveNumberSuffix:"必须大于 0。",butlerAutomationCronDaysValidation:"执行星期必须写成 0 到 6 的逗号分隔整数。",butlerAutomationRunSourceLabel:"来源",butlerAutomationRunSourcePatrol:"计划任务运行",butlerAutomationRunSourceFollowUp:"条件跟进运行",butlerAutomationRunSourceControlTimer:"助手定时续接",butlerAutomationRunSummaryLabel:"运行结果",butlerAutomationRunProcessedAtLabel:"运行时间",butlerAutomationRunEmptySummary:"本次运行没有返回摘要。",butlerAutomationPatrolRunTitle:"巡视任务运行",butlerControlTimerBannerTitle:"等待中的下一步",butlerControlTimerCountdownActive:"助手将在 {duration} 后继续下一步",butlerControlTimerCountdownDueNow:"助手即将继续下一步",butlerControlTimerCountdownLead:"助手将在",butlerControlTimerCountdownTail:"后继续下一步",butlerControlTimerCountdownDueLead:"助手即将",butlerControlTimerCountdownDueTail:"继续下一步",butlerControlTimerDueAtLabel:"预计时间:{time}",butlerControlTimerTypeOnce:"单次",butlerControlTimerTypeRepeat:"重复",butlerControlTimerTypeConditional:"条件",butlerControlTimerTypeOther:"其他",butlerControlTimerWorkspaceLabel:"目标工作区",butlerControlTimerSessionLabel:"目标会话",butlerControlTimerTargetSessionLabel:"目标会话:{sessionId}",butlerControlTimerDetailAction:"查看提示词详情",butlerControlTimerPromptTitle:"续接提示词",butlerControlTimerUnknownWorkspace:"未关联工作区",butlerControlTimerUnknownSession:"未关联会话",butlerControlTimerStopAction:"停止动作",butlerControlTimerCancelOperationAction:"取消操作",butlerControlTimerExecuteNowAction:"停止计时",butlerControlTimerExecutingNow:"立即执行中...",butlerControlTimerExecuteNowSucceeded:"已结束等待并立即执行这步动作",butlerControlTimerExecuteNowFailed:"结束等待并立即执行失败",butlerControlTimerActionNote:"停止动作:取消本轮自动续接。停止计时:结束等待并立刻执行。",butlerControlTimerCancelAction:"取消计时",butlerControlTimerCancelling:"取消中...",butlerControlTimerCancelSucceeded:"已取消这条助手计时器",butlerControlTimerCancelFailed:"取消助手计时器失败",butlerControlTimerRunCompletedSummary:"计时器已到点,助手已经继续下一步。",butlerControlTimerRunCancelledSummary:"这条计时器已手动取消。",butlerControlTimerRunFailedSummary:"计时器触发失败,请查看错误信息。",butlerControlTimerNoProject:"未关联项目",butlerAutomationObjectiveLabel:"当前目标",butlerAutomationLatestAssessmentLabel:"最近判断",butlerAutomationWaitingReasonLabel:"等你决定什么",butlerAutomationNextCheckLabel:"下一次查看",butlerAutomationFinishedAtLabel:"结束时间",butlerAutomationViewRoundsAction:"查看每轮详情",butlerAutomationRoundDetailsTitle:"跟进轮次详情",butlerAutomationRoundDetailsDescription:"查看这个跟进任务每一轮的判断和动作。",butlerAutomationRoundLoading:"正在读取跟进轮次详情...",butlerAutomationRoundLoadFailed:"读取跟进轮次详情失败",butlerAutomationRoundEmpty:"当前还没有可展示的跟进轮次详情。",butlerAutomationRoundLabel:"第 {round} 轮",butlerAutomationRoundProcessedAtLabel:"处理时间",butlerAutomationRoundStatusLabel:"任务状态",butlerAutomationRoundObservedStateLabel:"会话运行状态",butlerAutomationRoundSummaryLabel:"这一轮判断",butlerAutomationRoundWaitingReasonLabel:"等待原因",butlerAutomationRoundPromptLabel:"代理发送内容",butlerAutomationRoundKindStarted:"开始跟进",butlerAutomationRoundKindContinue:"已直接续接",butlerAutomationRoundKindQueued:"已进入消息队列",butlerAutomationRoundKindWaitingUser:"等待用户处理",butlerAutomationRoundKindCompleted:"确认完成",butlerAutomationRoundKindFailed:"跟进失败",butlerAutomationRoundKindCancelled:"手动终止",butlerAutomationRoundKindLimitReached:"达到轮数上限",butlerInboxAction:"收件箱",butlerInboxModalTitle:"收件箱",butlerInboxModalDescription:"在这里记录项目代办,并按项目维护当前推进情况。",butlerInboxLoading:"正在读取收件箱...",butlerInboxLoadFailed:"收件箱读取失败",butlerInboxProjectsEmpty:"还没有可绑定的项目,请先在管家里管理项目。",butlerInboxEmpty:"还没有收件箱记录。",butlerInboxCreateTitle:"新增代办",butlerInboxEditingTitle:"编辑代办",butlerInboxFormDescription:"每条代办都必须绑定到一个项目,后续助手才能围绕它继续跟进。",butlerInboxListTitle:"当前代办",butlerInboxListDescription:"这里会列出你管理的项目代办,方便统一收口处理。",butlerInboxShowClosedAction:"显示已关闭",butlerInboxQuickStatusLabel:"快速设置进度",butlerInboxProjectLabel:"绑定项目",butlerInboxTypeLabel:"类型",butlerInboxTitleLabel:"标题",butlerInboxTitlePlaceholder:"例如:登录页验证码收尾",butlerInboxContentLabel:"内容",butlerInboxContentPlaceholder:"写清楚当前问题、目标或你希望助手后续继续推进的点。",butlerInboxStatusLabel:"进度",butlerInboxTypeTask:"任务",butlerInboxTypeBug:"缺陷",butlerInboxTypeFeature:"新功能",butlerInboxTypeChange:"修改",butlerInboxStatusPending:"待处理",butlerInboxStatusInProgress:"进行中",butlerInboxStatusClosed:"已关闭",butlerInboxCreateAction:"新增代办",butlerInboxUpdateAction:"保存修改",butlerInboxCancelEditAction:"取消编辑",butlerInboxEditAction:"编辑",butlerInboxDeleteAction:"删除",butlerInboxCreated:"代办已新增",butlerInboxUpdated:"代办已更新",butlerInboxDeleted:"代办已删除",butlerInboxSaveFailed:"代办保存失败",butlerInboxDeleteFailed:"代办删除失败",butlerProviderSwitched:"Provider 已切换",butlerProviderSwitchedDescription:"已切换到 {provider},当前视图已重置并重新加载。",butlerProviderSwitchFailed:"Provider 切换失败",butlerAttachmentUnsupported:"助手对话暂不支持附件",butlerOverviewTitle:"整体情况",butlerOverviewDescription:"这里会先帮你整理当前最值得关注的内容。",butlerMetricProjectCount:"项目",butlerMetricBlockedCount:"阻塞",butlerMetricHighRiskCount:"高风险",butlerTopRisksTitle:"优先风险",butlerNextActionsTitle:"建议动作",butlerOverviewEmpty:"暂无",butlerOverviewLoading:"正在读取助手聚合摘要...",butlerEventsTitle:"最近操作",butlerEventsDescription:"助手最近帮你做过什么,这里会记下来。",butlerEventsEmpty:"暂无动作事件",butlerLoadFailed:"助手工作台加载失败",butlerContextStrategyTitle:"按需上下文",butlerContextStrategyDescription:"默认只给助手全局摘要,只有你点到某个项目时,才再向后端补拉该项目的会话、记忆、巡视和验证摘要。",butlerConversationTitle:"与助手对话",butlerConversationDescription:"这个对话窗口只属于 {displayName}。需要细节时,{displayName} 会先用聚合摘要回答,再按需直达后端补查具体项目、会话、巡视或验证信息。",butlerComposerPlaceholder:"直接对 {displayName} 说你现在想搞清楚什么",butlerProjectsTitle:"项目",butlerProjectsDescription:"选一个项目,助手就会继续帮你查它的进展和记录。",butlerProjectsEmpty:"暂无可下钻的项目",butlerProjectWorkspaceLabel:"所属工作区:{workspaceId}",butlerProjectSummaryEmpty:"暂无可用摘要",butlerProjectOpenDetailAction:"查看详情",butlerProjectSyncAction:"同步到时间线",butlerProjectSyncSucceeded:"已把项目 {projectName} 同步到助手时间线",butlerProjectActionRequiresSession:"先和助手说一句话,然后再让它继续处理项目。",butlerProjectContextTitle:"当前项目",butlerProjectContextDescription:"这里会显示这个项目的会话、记录和结果。",butlerProjectContextEmpty:"先从上面的项目列表或动作事件里选一个项目。",butlerProjectContextLoading:"正在读取项目关联信息...",butlerProjectContextMeta:"项目状态:{status} · 风险级别:{riskLevel}",butlerProjectActionSucceeded:"助手动作已执行",butlerProjectActionFailed:"助手动作失败",butlerProjectActionPending:"处理中...",butlerProjectSessionsTitle:"项目会话",butlerProjectMemoriesTitle:"项目记忆",butlerProjectPatrolsTitle:"巡视记录",butlerProjectVerificationsTitle:"验证记录",butlerProjectOpenConversationAction:"打开真实会话",butlerProjectResumeAction:"续接会话",butlerProjectResumeSucceeded:"已续接会话:{sessionTitle}",butlerProjectStartPatrolAction:"发起巡视",butlerProjectPatrolSucceeded:"已为 {projectName} 发起巡视",butlerProjectStartVerificationAction:"发起验证",butlerProjectVerificationSucceeded:"已为 {projectName} 发起验证",butlerProjectMemoryMeta:"类型:{memoryType} · 状态:{status}",butlerProjectSessionMeta:"角色:{role} · 状态:{status}",butlerProjectPatrolMeta:"状态:{status} · 风险:{riskLevel}",butlerProjectVerificationMeta:"类型:{verificationType} · 状态:{status}",butlerProjectRunSummaryEmpty:"暂无摘要",butlerProjectFocusAction:"定位这条记录",butlerProjectUpdatedAtLabel:"更新时间:{updatedAt}",butlerFocusedBadge:"当前定位",searchModalTitle:"搜索",searchModalDescription:"输入关键词后,选择要搜代码、事务,还是全部一起搜。",searchPlaceholder:"输入会话、代码、文档、标签或代办关键词",searchHint:"先输入关键词,然后选择搜代码、搜事务,或者全部一起搜。",searchChooseActionHint:"请选择下面的搜索范围。",searchActionLabel:"搜索范围",searchActionCode:"搜索代码",searchActionAffairs:"搜索事务",searchActionAll:"搜索全部",searchClearAction:"清除",searchLoading:"正在搜索...",searchEmpty:"没找到匹配的结果。",searchSessionsGroup:"会话",searchCodeGroup:"代码",searchModeLabel:"搜索模式",searchModeSessions:"会话",searchModeCode:"代码",searchModeAffairs:"事务",searchKeywordLabel:"关键词",searchWorkspaceLabel:"工作区",searchSessionPlaceholder:"输入会话名称、工作区或 provider",searchCodePlaceholder:"输入文件名或路径片段",searchAffairsPlaceholder:"输入文档名、标签、代办或对话关键词",searchSessionHint:"输入关键词后,这里会立即列出匹配的会话。",searchCodeHint:"选一个工作区,然后搜文件名或路径。",searchAffairsHint:"输入关键词后,这里会列出事务模式下所有工作区的文档、标签、代办和对话。",searchAffairsLoading:"正在搜事务内容...",searchSessionEmpty:"没找到匹配的会话。",searchCodeEmpty:"没找到匹配的文件。",searchAffairsEmpty:"没找到匹配的事务内容。",searchCodeFailed:"代码搜索失败,请稍后重试。",searchAffairsFailed:"事务搜索失败,请稍后重试。",searchAffairsWorkspaceMissing:"当前没有可用的事务工作区。",searchAffairsDocumentsGroup:"文档",searchAffairsTagsGroup:"标签",searchAffairsConversationsGroup:"对话",searchAffairsTodosGroup:"代办",searchSortLabel:"排序方式",searchSortRelevance:"相关度优先",searchSortUpdated:"最近更新优先",searchSortTitle:"标题/名称优先",searchResultTypeSession:"会话",searchResultTypeCode:"代码",searchResultTypeDocument:"文档",searchResultTypeAffairsTag:"文档库标签",searchResultTypeTodo:"代办",searchResultLocateDocument:"定位",searchResultLocateDocumentTitle:"定位到文档所在目录",searchSubmit:"开始搜索",filesEntry:"文件",gitEntry:"GIT",terminalManagerEntry:"调试",workspaceSectionTitle:"工作区",goBack:"后退",goForward:"前进",workspaceCount:"项目",sessionCount:"会话",manageWorkspaceAction:"管理项目",manageWorkspaceTitle:"管理项目",manageWorkspaceDescription:"默认只列出当前已加载的项目,展开后可以查看路径、Git 摘要、代码类型组成,也可以从当前工作台列表里移除。",manageWorkspaceImportAction:"导入项目",manageWorkspaceCloneAction:"Clone项目",manageWorkspaceEmpty:"当前没有可管理的项目。",manageWorkspaceLoading:"正在读取项目详情...",manageWorkspaceLoadFailed:"项目详情加载失败",manageWorkspacePathLabel:"路径",manageWorkspaceGitCommitCount:"Git 提交版本数",manageWorkspaceGitInfoLabel:"Git 仓库信息",manageWorkspaceRepoRoot:"仓库根目录",manageWorkspaceCurrentBranch:"当前分支",manageWorkspaceRemoteLabel:"远程",manageWorkspaceNoRemote:"未配置远程",manageWorkspaceNotGit:"当前项目不是 Git 仓库。",manageWorkspaceCodeCompositionLabel:"代码类型组成",manageWorkspaceCodeCompositionFiles:"文件",manageWorkspaceCodeCompositionOther:"其他",manageWorkspaceNoCodeComposition:"暂时没有识别到可统计的代码文件。",manageWorkspaceCodeTruncated:"文件过多,只统计了前 {count} 个可识别文件。",manageWorkspaceColorLabel:"背景颜色",manageWorkspaceColorSelectSwatch:"使用颜色 {color}",manageWorkspaceColorClearAction:"清除颜色",manageWorkspaceColorUnset:"未设置,当前使用默认颜色",manageWorkspaceColorSaveFailed:"工作区颜色保存失败",manageWorkspaceRemoveAction:"移除项目",manageWorkspaceRemoving:"移除中...",manageWorkspaceRemoveSuccess:"项目已从当前工作台移除",manageWorkspaceRemoveFailed:"移除项目失败",manageWorkspaceRemoveConfirmTitle:"确认移除项目",manageWorkspaceRemoveConfirmDescription:"这只会把项目从当前工作台列表移除,不会删除任何磁盘数据或历史记录。后续重新加载同一路径时,旧记录会直接恢复显示。",manageWorkspaceRemoveConfirmTarget:"确定移除「{name}」吗?",manageWorkspaceRemoveConfirmAction:"确认移除",importWorkspaceTitle:"添加项目",importWorkspaceHint:"导入本地代码目录",importExpand:"展开",importCollapse:"收起",importPathLabel:"项目路径",importPathPlaceholder:"输入项目文件夹路径",importNameLabel:"项目名称",importNamePlaceholder:"可选",importSubmit:"添加项目",importSubmitting:"添加中...",importChooseFolder:"选择文件夹",importPickFolderFailed:"打开文件夹选择器失败",importDesktopDropHint:"支持把本地项目文件夹直接拖到这个区域",importHint:"输入本地代码目录后就能开始工作",importServerDirectoryHint:"浏览并选择运行服务器上的项目目录",importBrowserTitle:"选择服务器目录",importBrowserDescription:"这里浏览的是项目运行所在服务器上的目录,不是当前设备的本地目录。",importBrowserCurrentPath:"当前目录",importBrowserRoots:"根目录",importBrowserOpenParent:"返回上一级",importBrowserOpenPath:"打开路径",importBrowserCreateDirectory:"新建文件夹",importBrowserCreateDirectoryTitle:"新建文件夹",importBrowserCreateDirectoryDescription:"只在当前服务器目录下新建一层子文件夹,不接受带路径的输入。",importBrowserCreateDirectoryLabel:"文件夹名称",importBrowserCreateDirectoryPlaceholder:"输入新文件夹名称",importBrowserCreateDirectorySuccess:"文件夹已创建",importBrowserCreateDirectoryFailed:"新建文件夹失败",importBrowserCreateDirectorySubmit:"确认新建",importBrowserCreatingDirectory:"新建中...",importBrowserEmpty:"当前目录下没有可选的子目录",importBrowserBrowseFailed:"加载服务器目录失败",importBrowserSubmit:"导入当前目录",importPathRequired:"请输入项目路径",importSuccess:"项目已添加",importFailed:"添加失败",cloneWorkspaceTitle:"Clone项目",cloneWorkspaceHint:"从 Git 仓库拉取代码到服务端目录,完成后直接加入项目列表。",cloneSubmit:"Clone项目",cloneSubmitting:"Clone 中...",cloneRepositoryLabel:"Git 仓库地址",cloneRepositoryPlaceholder:"例如:https://github.com/org/repo.git",cloneParentPathLabel:"目标父目录",cloneParentPathPlaceholder:"选择后端服务上已存在的目录",cloneDirectoryNameLabel:"新项目目录名",cloneDirectoryNamePlaceholder:"留空时默认使用仓库名",clonePickDirectory:"选择目录",cloneAuthModeLabel:"认证方式",cloneAuthModeNone:"无认证",cloneAuthModeBasic:"用户名 + 密码",cloneAuthModeToken:"Token",cloneUsernameLabel:"用户名",cloneUsernamePlaceholder:"输入 Git 用户名",clonePasswordLabel:"密码",clonePasswordPlaceholder:"输入 Git 密码",cloneTokenLabel:"Token",cloneTokenPlaceholder:"输入 access token",cloneTokenUsernamePlaceholder:"可选,留空时默认使用 git",cloneRepoRequired:"请输入 Git 仓库地址",clonePathRequired:"请选择目标父目录",cloneSuccess:"项目已成功 Clone",cloneFailed:"Clone 失败",cloneHint:"目标父目录必须已经存在,Clone 时会在这个目录下新建仓库文件夹。",cloneBrowserTitle:"选择 Clone 目标父目录",cloneBrowserDescription:"这里选的是服务端已存在的父目录,Clone 时会在其下新建一个项目文件夹。",cloneBrowserSubmit:"使用当前目录",refreshNavigation:"刷新",desktopChromeLabel:"桌面工作台",windowMinimize:"最小化窗口",windowMaximize:"最大化或还原窗口",windowClose:"关闭窗口",contextOpenSession:"打开会话",navigationLoadFailed:"加载失败,请重试",emptyNavigationTitle:"还没有项目",emptyNavigationBody:"添加本地代码目录开始工作",emptyWorkspaceSessions:"暂无会话",favoriteSectionTitle:"收藏会话",favoriteSectionEmpty:"收藏后的会话会固定放在这里,方便你快速回到常用链路。",worktreeSectionTitle:"子工作树",worktreeSectionExpand:"展开子工作树",worktreeSectionCollapse:"收起子工作树",worktreeMergePanelLabel:"工作树合并",worktreeMergePanelTitle:"合回直接父工作区",worktreeMergeExpandDetails:"展开详情",worktreeMergeCollapseDetails:"收起详情",worktreeMergePreviewAction:"预检",worktreeMergePreviewRefresh:"预检",worktreeMergePreviewIdle:"尚未预检",worktreeMergePreviewLoading:"预检中...",worktreeMergeReady:"可以合并",worktreeMergeBlocked:"当前不能合并",worktreeMergeApplying:"合并中...",worktreeMergeApplyAction:"合并",worktreeMergeApplySuccess:"子工作树已经合回直接父工作区",worktreeMergeApplyFailed:"合并子工作树失败",worktreeMergePreviewFailed:"读取工作树合并预检失败",worktreeMergeAlreadyMerged:"已合回直接父工作区",worktreeMergeMergedHint:"代码已经合回直接父工作区,下一步可以继续做清理。",worktreeMergeMergedDirtyHint:"提交历史已经同步到父工作区,但当前子工作树还有未处理事项,暂时不能清理。",worktreeMergeChecklistTitle:"合并检查清单",worktreeMergeChecklistSourceState:"工作树状态正常",worktreeMergeChecklistSourceStateBlocked:"当前子工作树状态异常,系统暂时没有把它当作活跃工作树",worktreeMergeChecklistSourceClean:"子工作区已清理",worktreeMergeChecklistSourceCleanBlocked:"当前子工作树存在未提交改动,请先提交",worktreeMergeChecklistTargetClean:"父工作区可接收合并",worktreeMergeChecklistTargetCleanBlocked:"直接父工作区存在未提交改动,不能接收合并",worktreeMergeChecklistChildren:"没有活跃子工作树",worktreeMergeChecklistChildrenBlocked:"当前子工作树下面还有活跃子节点,必须先从叶子节点开始回收",worktreeMergeChecklistCommits:"存在待合并提交",worktreeMergeChecklistCommitsBlocked:"当前子工作树没有领先父工作区的提交",worktreeMergeChecklistConflicts:"合并不会产生冲突",worktreeMergeChecklistConflictsBlocked:"检测到合并冲突,先处理冲突后再继续",worktreeMergeChecklistResultPending:"等待预检结果",worktreeMergeChecklistResultReady:"可以执行合并",worktreeMergeChecklistResultReadyDetail:"所有条件已满足,可以开始合并",worktreeMergeChecklistResultBlocked:"暂时不能执行合并",worktreeMergeChecklistResultBlockedDetail:"上面的阻塞项解决后,才可以继续",worktreeMergeChecklistResultMerged:"已完成合并,可继续清理",worktreeMergeCompactPending:"待预检",worktreeMergeCompactChecking:"预检中",worktreeMergeCompactReady:"可合并",worktreeMergeCompactBlocked:"受阻",worktreeMergeCompactMerged:"已合并",worktreeMergeCompactMerging:"合并中",worktreeMergeCompactCleaning:"清理中",worktreeMergeCompactInactive:"状态异常",worktreeMergeCompactDirty:"未提交",worktreeMergeCompactTargetDirty:"父区脏",worktreeMergeCompactConflict:"有冲突",worktreeMergeCompactChildren:"有子树",worktreeMergeCompactNoCommits:"无提交",worktreeCleanupAction:"清理",worktreeCleanupRunning:"清理中...",worktreeCleanupSuccess:"工作树已经清理完成",worktreeCleanupFailed:"清理工作树失败",worktreeCleanupModalTitle:"确认清理工作树",worktreeCleanupModalDescription:"默认只清理工作树目录和系统记录。只有分支已经合并进父分支后,才允许额外删除分支。",worktreeCleanupConfirm:"确认清理 {name} 吗?默认会保留 git 分支。",worktreeCleanupDeleteBranchLabel:"同时删除分支 {branch}",worktreeCleanupDeleteBranchHint:"只有分支已经合并进父分支后,才允许删除分支。",worktreeCleanupDeleteBranchAction:"清理并删除分支",worktreeCleanupDeleteBranchSuccess:"工作树和分支 {branch} 已清理完成",worktreeCleanupDeleteBranchPartialFailed:"工作树已清理,但分支 {branch} 删除失败",worktreeMergeCurrentBranch:"当前分支:{branch}",worktreeMergeParentBranch:"父分支:{branch}",worktreeMergeTargetWorkspace:"目标父工作区:{name}",worktreeMergeAheadBehindPending:"提交差异:待预检",worktreeMergeAheadBehind:"提交差异:领先 {ahead} / 落后 {behind}",worktreeMergeBaseCommit:"merge base:{commit}",worktreeMergeConflictLabel:"冲突文件",favoriteAction:"收藏会话",unfavoriteAction:"取消收藏",favoriteAdded:"会话已加入收藏",favoriteRemoved:"会话已取消收藏",favoriteToggleFailed:"收藏状态更新失败",sessionMoreAction:"更多操作",deleteSessionAction:"删除会话",deleteSessionConfirmTitle:"确认删除会话",deleteSessionConfirmDescription:"删除后,这条会话会从助手历史和工作区列表里消失,真实会话记录也会一并清掉,不能恢复。",deleteSessionSuccess:"会话已删除",deleteSessionFailed:"删除会话失败",sessionStateInferred:"推断",renameAction:"重命名",renameSuccess:"会话名称已更新",renameFailed:"会话重命名失败",renameModalTitle:"重命名会话",renameModalDescription:"改成你自己能一眼认出来的名字,只改标题,不改消息内容。",renameInputLabel:"会话名称",renameInputPlaceholder:"输入新的会话名称",renamingSession:"保存中...",archiveFolderLabel:"归档会话",archiveFolderAction:"打开归档文件夹",archiveAction:"归档会话",archiveCurrentSessionAction:"归档当前会话",archiveAdded:"会话已归档",archiveConfirmTitle:"确认归档会话",archiveConfirmDescription:"归档后,这条会话会从当前工作区主列表里隐藏,你仍然可以在归档区恢复它。",unarchiveAction:"取消归档",archiveRestored:"会话已恢复到主列表",archiveModalTitle:"归档会话",archiveModalDescription:"这里列出当前项目暂时隐藏的会话,需要时可以恢复到主列表。",archiveEmpty:"这个项目还没有归档会话。",archiveSearchAction:"搜索",archiveSearchLabel:"搜索归档会话",archiveSearchPlaceholder:"按会话名称或摘要搜索",archiveSearchEmpty:"没有找到匹配的归档会话。",archiveSearchSummaryLoading:"正在补全归档会话摘要...",archiveSearchSummaryFailed:"部分归档会话摘要暂时读取失败,当前只能先按名称搜索。",archiveViewAction:"查看归档会话",parallelCreateAction:"新建并行会话",parallelCreateModalTitle:"创建并行会话",parallelCreateModalDescription:"先定下这组并行会话要解决什么问题,再分别补充每个会话的设置。",parallelCreateSharedPromptLabel:"本次并行会话的目标是",parallelCreateSharedPromptPlaceholder:"例如:围绕同一个需求分别给出不同实现方案、技术路线或问题排查方向。",parallelCreateCountLabel:"并行数量",parallelCreateMembersTitle:"分别设置每个会话",parallelCreateMembersDescription:"每个会话都是真实独立成员,可以单独选择供应商、模型和是否启用临时隔离工作区。",parallelCreateMemberTitle:"成员 {index}",parallelCreateModelLabel:"模型",parallelCreateMemberPromptLabel:"还有特殊的要求吗?",parallelCreateMemberPromptPlaceholder:"例如:更保守、偏重重构、优先排查性能问题,或限定技术栈与输出形式。",parallelCreateIsolationLabel:"启用临时隔离工作区",parallelCreateIsolationHint:"只对需要独立代码目录的成员开启,升级成功前不会进入正式子工作区体系。",parallelCreateProvidersLoading:"正在读取已安装供应商…",parallelCreateNoAvailableProviders:"当前工作区还没有可用的模型供应商,请先安装并接入后再创建并行会话。",parallelCreateNoModelsAvailable:"当前供应商没有可选模型",parallelCreatePromptRequired:"公共提示词不能为空",parallelCreatePartialFailure:"已成功创建 {successCount} 个成员,另有 {failureCount} 个成员未创建成功。",parallelCreateAllFailed:"{failureCount} 个成员都创建失败了,请直接修改对应成员配置后重试。",parallelCreateContinuePartial:"继续查看已创建分屏",parallelCreateMemberSucceeded:"已创建",parallelCreateMemberFailed:"未创建",parallelCreateMemberErrorTitle:"这一条成员没有创建成功",parallelCreateSubmit:"开始并行创建",parallelCreateSubmitting:"正在创建并行会话…",parallelCreateSucceeded:"并行会话已创建",parallelAppendAction:"追加并行会话",parallelAppendModalTitle:"追加并行会话",parallelAppendModalDescription:"沿用这组并行会话最初的用户消息,只补充这次新加成员的设置。",parallelAppendSharedPromptLabel:"本组最初的用户消息",parallelAppendSharedPromptDescription:"这段内容来自当前并行会话组的起始消息,追加成员时不能修改。",parallelAppendCountLabel:"新增数量",parallelAppendSubmit:"追加并行会话",parallelAppendSubmitting:"正在追加并行会话…",parallelAppendSucceeded:"并行会话已追加",parallelAppendNoRemainingSlots:"当前并行会话组已经有 4 个成员,不能继续追加。",parallelGroupBadge:"并行",parallelGroupAnchorBadge:"锚点",parallelGroupMemberBadge:"成员",parallelWorkspacePromotedBadge:"已升级工作区",parallelGroupLoadFailed:"读取并行会话组失败",parallelGroupEmpty:"这组并行会话还没有可展示的成员。",parallelPaneOpenAction:"打开会话",parallelPaneToolsAction:"工具",parallelPanePinAction:"钉住浮窗",parallelPaneDetachAction:"独立窗口",parallelPaneResizeAction:"调整浮窗尺寸",parallelPaneMoreAction:"更多选项",parallelPaneInfoAction:"查看信息",parallelPaneProcessesEntry:"进程",parallelPaneTerminalEntryDescription:"终端更适合输入密集和滚动密集的操作,这里保留独立入口,不硬塞进浮层里。",parallelPaneTerminalOpenAction:"打开终端",parallelPaneInfoTitle:"会话信息",parallelPaneModelFallback:"默认模型",parallelPaneIsolatedWorkspaceTitle:"临时隔离工作区",parallelPanePromptFallback:"未补充特殊要求",parallelPaneColorPaletteLabel:"色板",parallelPaneColorPaletteDescription:"调整这个并行会话 pane 的分色,方便你快速区分不同分支。",parallelPaneColorPaletteReset:"恢复默认分色",parallelPaneRemoveAction:"移除并行会话",parallelPaneRemoveDescription:"移除后,这个并行会话会从当前并行组里消失;如果它仍在临时隔离工作区中,对应工作区和分支也会一起清掉。",parallelPaneRemovePromotedDescription:"移除后,这个并行会话会从当前并行组里消失;已升级为正式子工作区的目录和分支会保留。",parallelPanePromoteAction:"升级为正式子工作区",parallelPanePromoteDescription:"确认这个临时工作区已经值得长期保留后,再把它升级成正式子工作区。",parallelPanePromoting:"正在升级…",parallelPaneRemoving:"正在移除…",subagentBadge:"子代理",sessionForkSession:"会话分叉",sessionForkMessage:"消息分叉",sessionForkReconstructed:"重建分叉",subagentExpand:"展开子代理列表",subagentCollapse:"收起子代理列表",subagentExpandMore:"展开更多子会话",favoriteExpandMore:"显示更多收藏",sessionExpandMore:"显示更多会话",archiveExpandMore:"查看更多归档会话",worktreeCollapse:"收起工作树",worktreeExpand:"展开工作树",workspaceCollapse:"收起项目",workspaceExpand:"展开项目",reorderWorkspace:"拖拽调整项目顺序",switchWorkspace:"切换到此项目",workspaceReorderFailed:"项目排序保存失败",workspaceCollapseStateSaveFailed:"项目折叠状态保存失败",workspaceHomeSwitcherLabel:"切换工作区",workspaceHomeSwitcherTitle:"工作区",hostWorkspaceSwitcherTitle:"HOST 与工作区",hostSwitcherAriaLabel:"切换 HOST",hostSwitcherTitle:"HOST 切换",hostSwitcherSavedSection:"手动保存",hostSwitcherDiscoveredSection:"自动发现",hostSwitcherCurrentBadge:"当前",hostSwitcherDiscoveredBadge:"自动发现",hostSwitcherNodeBadge:"HOST",hostSwitcherAddAction:"新增 HOST",hostSwitcherNameLabel:"HOST 名称",hostSwitcherNamePlaceholder:"例如:办公室 Host",hostSwitcherUrlLabel:"HOST 地址",hostSwitcherUrlPlaceholder:"例如:http://192.168.1.20:3002",hostSwitcherSaveAction:"保存 HOST",hostSwitcherSwitching:"切换中",hostSwitcherDetailAction:"详情",hostSwitcherDetailAriaLabel:"查看 HOST {name} 连接详情",hostSwitcherDetailTitle:"连接详情",hostSwitcherDetailStatusLabel:"连接状态",hostSwitcherDetailStatusRelay:"CodingNS Connect",hostSwitcherDetailStatusDirect:"直连",hostSwitcherDetailRouteLabel:"当前链路",hostSwitcherDetailAddressLabel:"当前地址",hostSwitcherDetailLatencyLabel:"CodingNS Connect 链路延时",hostSwitcherDetailLatencyLoading:"检测中...",hostSwitcherDetailTrafficLabel:"本次会话流量",hostSwitcherDetailResourceTitle:"主机资源",hostSwitcherDetailCpuLabel:"CPU",hostSwitcherDetailCpuValue:"{usage} · {cores} 核",hostSwitcherDetailMemoryLabel:"内存",hostSwitcherDetailDiskLabel:"磁盘",hostSwitcherDetailUnavailable:"暂时无法获取",hostSwitcherWorkspaceCount:"{count} 个工作区",hostSwitcherWorkspaceCountWithUser:"{username} · {count} 个工作区",hostSwitchFailed:"切换 HOST 失败",hostSwitchUnreachable:"{name} 当前不可达",hostSwitchMissing:"目标 HOST 不存在",hostDeleteAction:"删除 HOST",hostDeleteAriaLabel:"删除 HOST {name}",hostDeleteBusy:"删除中",hostDeleteConfirmAction:"确认删除",hostDeleteConfirm:"确定删除 HOST “{name}”吗?已保存的登录信息也会一起清理。",hostDeleteSuccess:"已删除 HOST:{name}",hostDeleteFailed:"删除 HOST 失败:{name}",hostAddIncompleteCredentials:"用户名和密码要么都填写,要么都留空",hostAddInvalidUrl:"HOST 地址无效",hostAddDuplicate:"这个 HOST 已经存在",hostAddFailed:"新增 HOST 失败",hostAddSuccess:"已新增 HOST:{name}",hostDiscoveryRefreshing:"正在扫描本机 HOST…",hostDiscoveryFailed:"本机 HOST 扫描失败",mobileWorktreeBadge:"工作树",workspaceHomeStatusSectionTitle:"当前工作区",workspaceHomeViewAllAction:"查看全部会话",workspaceHomeMetricActive:"活动",workspaceHomeMetricUnread:"通知",workspaceHomeMetricTerminal:"终端",workspaceHomeMetricChanges:"变更",workspaceHomeActiveSessionsSectionTitle:"活动会话",workspaceHomeQuickLaunchStatusLabel:"快捷调试",workspaceHomeQuickLaunchRunning:"运行中",workspaceHomeQuickLaunchStopped:"未运行",workspaceHomeWaitingInputLabel:"等待输入",workspaceHomeButlerLabel:"助手",mobileButlerEntry:"助手",mobileConversationToolCloseAction:"返回对话",mobileConversationToolTabsLabel:"文件、Git 与调试标签",mobileConversationToolProcessesTab:"调试",mobileButlerEmptyTitle:"助手还没准备好",mobileButlerEmptyBody:"当前还没有完成助手初始化,先在桌面端做完首轮初始化,再回到手机端看跟进和自动化。",butlerProjectSyncEmptyState:"直接给助手一句明确目标,它就会在这里继续推进当前工作。",mobileButlerSummaryTitle:"当前工作区摘要",mobileButlerSummaryProjects:"项目",mobileButlerSummaryFollowUps:"进行中任务",mobileButlerSummaryWaitingUser:"待你处理",mobileButlerSummaryInbox:"未完成代办",mobileButlerAssistantWorkspaceLabel:"助手工作目录",mobileButlerAssistantToneLabel:"沟通风格",mobileButlerAssistantLanguageLabel:"工作语言",mobileButlerAssistantUpdatedAtLabel:"最近更新",workspaceOverviewTitle:"把项目入口放到看得见的地方",workspaceOverviewBody:"先选项目,再决定是继续已有会话,还是开一条新的工作链路。",workspaceListBody:"这里保留当前工作台里的全部项目,并把高频操作直接放到首页。",workspaceDetailTitle:"项目详情",workspaceDetailSummaryTitle:"项目概览",workspaceDetailSummaryBody:"先看当前项目路径、Git 摘要和代码规模,再决定下一步去哪做事。",workspaceDetailMissingTitle:"没找到这个项目",workspaceDetailMissingBody:"这个项目可能已经被移除,或者当前快照还没加载到它。",workspaceDetailDebugTitle:"服务状态",manageWorkspaceDebugDescription:"查看当前项目里的服务识别结果、最近一次启动情况和支持说明。",workspaceDetailDebugAnalyzeFailed:"读取服务状态失败",workspaceDetailDebugFrameworkLabel:"识别类型",workspaceDetailDebugConfidenceLabel:"识别把握",workspaceDetailDebugCompatibilityLabel:"可用程度",workspaceDetailDebugInjectionLabel:"推荐处理方式",workspaceDetailDebugRuntimeStatusLabel:"当前状态",workspaceDetailDebugFailureStageLabel:"卡住位置",workspaceDetailDebugServiceDiscoveryLabel:"服务地址处理",workspaceDetailDebugHmrLabel:"热更新处理",workspaceDetailDebugCallbackLabel:"回调处理",workspaceDetailDebugAiFallbackLabel:"人工处理策略",workspaceDetailDebugFrameworkNoteLabel:"说明",workspaceDetailDebugReasonsLabel:"当前说明",workspaceDetailDebugFilesLabel:"参考文件",workspaceDetailDebugFailureStageEmpty:"暂无",workspaceDetailDebugRuntimeEmpty:"当前还没有运行记录。",workspaceDetailDebugFrameworkNoteEmpty:"当前没有额外兼容说明。",workspaceDetailDebugEmptyReasons:"暂无",workspaceDetailDebugEmptyFiles:"暂无",workspaceDetailDebugConfidenceHigh:"高",workspaceDetailDebugConfidenceMedium:"中",workspaceDetailDebugConfidenceLow:"低",workspaceDetailDebugCompatibilitySupported:"可以直接使用",workspaceDetailDebugCompatibilityConditional:"需要补充处理",workspaceDetailDebugCompatibilityUnsupported:"暂不建议直接使用",workspaceDetailDebugCompatibilityUnknown:"未知",workspaceDetailDebugInjectionCli:"启动参数",workspaceDetailDebugInjectionEnv:"环境变量",workspaceDetailDebugInjectionOverride:"调整启动命令",workspaceDetailDebugInjectionAiFallback:"需要人工辅助",workspaceDetailDebugInjectionNone:"暂不自动处理",workspaceDetailDebugRuntimePreparing:"准备中",workspaceDetailDebugRuntimeRunning:"运行中",workspaceDetailDebugRuntimeFailed:"启动失败",workspaceDetailDebugRuntimeStopped:"已停止",workspaceDetailDebugRuntimeNotStarted:"未启动",workspaceDetailDebugRequirementRequired:"需要补充",workspaceDetailDebugRequirementNotRequired:"不需要补充",workspaceDetailDebugAiPolicyNever:"不建议自动处理",workspaceDetailDebugAiPolicyConditional:"视情况处理",workspaceDetailDebugAiPolicyAllowed:"可以处理",workspaceDetailDebugRuntimeServicesTitle:"最近一次启动",workspaceDetailDebugRuntimeHistoryTitle:"最近几次启动记录",workspaceDetailDebugRuntimeHistoryTimeLabel:"启动时间",workspaceDetailDebugRuntimeHistoryServiceLabel:"涉及服务",workspaceDetailDebugRuntimeHistoryResultLabel:"结果",workspaceDetailDebugRuntimeHistoryTitleWithIndex:"启动记录 #{id}",workspaceDetailDebugRuntimeHistoryFailedSummary:"这次启动里,{services} 没有正常启动。",workspaceDetailDebugRuntimeHistoryGenericSummary:"这里保留最近几次启动结果,方便回看问题是否重复出现。",workspaceDetailDebugRuntimeHistoryNoServices:"暂无",workspaceDetailDebugRuntimeHistoryResultRunning:"仍在运行",workspaceDetailDebugRuntimeHistoryResultFailed:"启动失败",workspaceDetailDebugRuntimeHistoryResultStopped:"已结束",workspaceDetailDebugRuntimeHistoryResultPreparing:"准备中",workspaceDetailDebugRuntimeServicePortLabel:"分配端口",workspaceDetailDebugRuntimeServiceBindingLabel:"端口状态",workspaceDetailDebugRuntimeServiceProcessLabel:"服务进程",workspaceDetailDebugRuntimeServiceFailureLabel:"问题位置",workspaceDetailDebugRuntimeServiceAiLabel:"人工处理记录",workspaceDetailDebugDetectedServicesTitle:"识别到的服务",workspaceDetailDebugServicePathLabel:"所在位置",workspaceDetailDebugServiceFrameworkLabel:"识别结果",workspaceDetailDebugServiceCommandLabel:"启动方式",workspaceDetailDebugServiceRequirementsLabel:"需要补充处理",workspaceDetailDebugServiceActionLabel:"建议动作",workspaceDetailDebugOpenPageAction:"服务",workspaceDetailDebugPageTitle:"服务",workspaceDetailDebugPageDescription:"查看启动项和当前状态。",workspaceDetailRegisteredDebugPageHeroEyebrow:"已注册启动项",workspaceDetailRegisteredDebugPageDescription:"只看已登记的启动项和状态。",workspaceDetailRegisteredDebugLoadFailed:"读取已注册启动项失败",workspaceDetailRegisteredDebugOverallStatusReady:"可启动",workspaceDetailRegisteredDebugOverallStatusPartial:"需处理",workspaceDetailRegisteredDebugOverallStatusEmpty:"未配置",workspaceDetailRegisteredDebugOverallSummary:"{runnable} 可启动 · {orchestrated} 需调整 · {blocked} 阻断",workspaceDetailRegisteredDebugSummaryRegisteredCountLabel:"启动项",workspaceDetailRegisteredDebugSummaryConfiguredPortLabel:"已配置端口",workspaceDetailRegisteredDebugSummaryRunnableCountLabel:"可直接启动",workspaceDetailRegisteredDebugSummaryOrchestratedCountLabel:"需调整",workspaceDetailRegisteredDebugSummaryBlockedCountLabel:"阻断",workspaceDetailRegisteredDebugSummaryLastRefreshLabel:"更新时间",workspaceDetailRegisteredDebugChipRegisteredOnly:"只认调试登记项",workspaceDetailRegisteredDebugChipNoGuessing:"不再猜框架和命令",workspaceDetailRegisteredDebugChipPortDriven:"运行态只按端口占用判断",workspaceDetailRegisteredDebugAnalysisTitle:"项目识别",workspaceDetailRegisteredDebugAnalysisDescription:"查看项目信息。",workspaceDetailRegisteredDebugAnalysisReadonlyNote:"仅供查看",workspaceDetailRegisteredDebugAnalysisDisplayOnlyHint:"仅供查看",workspaceDetailRegisteredDebugAnalysisRoleLabel:"类型",workspaceDetailRegisteredDebugAnalysisNoService:"暂无识别结果。",workspaceDetailRegisteredDebugAnalysisSourceSummary:"分析来源:{sourceType}",workspaceDetailRegisteredDebugTemplatesTitle:"启动项",workspaceDetailRegisteredDebugTemplatesDescription:"这里只显示已登记的启动项。",workspaceDetailRegisteredDebugTemplatesEmpty:"还没有启动项,请先到调试里添加。",workspaceDetailRegisteredDebugOpenProcessManagerAction:"打开调试",workspaceDetailRegisteredDebugActionSyncTemplates:"刷新",workspaceDetailRegisteredDebugActionSyncingTemplates:"刷新中…",workspaceDetailRegisteredDebugActionSyncTemplatesSuccess:"已经同步调试里的启动项",workspaceDetailRegisteredDebugActionSyncTemplatesFailed:"刷新启动项失败",workspaceDetailRegisteredDebugActionRunRegistered:"启动",workspaceDetailRegisteredDebugActionRunningRegistered:"启动中…",workspaceDetailRegisteredDebugActionRunRegisteredSuccess:"已提交可启动项",workspaceDetailRegisteredDebugActionRunRegisteredFailed:"启动已注册项失败",workspaceDetailRegisteredDebugActionRunRegisteredSkipped:"当前没有可启动项,请先处理阻断。",workspaceDetailRegisteredDebugActionPlanHint:"先看方案",workspaceDetailDebugPageHeroEyebrow:"项目服务概览",workspaceDetailDebugOverallStatusLabel:"整体状态",workspaceDetailDebugOverallSummaryLabel:"整体说明",workspaceDetailDebugOverallStatusSupported:"可以直接启动",workspaceDetailDebugOverallStatusConditional:"部分服务还要补充设置",workspaceDetailDebugOverallStatusBlocked:"当前不建议整体直接启动",workspaceDetailDebugOverallSummaryEmpty:"暂时还没拿到可用的服务检查结果。",workspaceDetailDebugOverallSummaryMixed:"当前识别到 {webCount} 个网页服务,以及 {desktopCount} 个桌面壳服务。桌面壳服务会单独展示,不参与网页服务的自动处理。",workspaceDetailDebugOverallSummaryDesktopOnly:"当前识别到 {count} 个桌面壳服务,还没有明确识别出网页服务。",workspaceDetailDebugOverallSummaryWebOnly:"当前识别到 {count} 个可以参与网页调试的服务。",workspaceDetailDebugSummaryServiceCountLabel:"分析条目数",workspaceDetailDebugSummaryWebCountLabel:"网页服务",workspaceDetailDebugSummaryDesktopShellCountLabel:"桌面壳服务",workspaceDetailDebugSummaryWebServicesChip:"{count} 个网页服务",workspaceDetailDebugSummaryDesktopShellChip:"{count} 个桌面壳",workspaceDetailDebugSummaryUnsupportedChip:"{count} 个阻断项",workspaceDetailDebugAutoInjectionEligible:"当前网页服务已经满足自动处理条件",workspaceDetailDebugAutoInjectionBlocked:"当前还不建议把整个项目当成可自动处理目标",workspaceDetailDebugDesktopShellSummaryHint:"桌面壳服务单独识别,不参与网页服务协调",workspaceDetailDebugCompatibilityBreakdown:"可直接使用 {supported} / 需要补充 {conditional} / 暂不建议 {unsupported}",workspaceDetailDebugLastAnalyzedAtLabel:"最近检查时间",workspaceDetailDebugTargetSourceRepo:"检查范围:仓库根目录",workspaceDetailDebugTargetSourceWorktree:"检查范围:当前工作树",workspaceDetailDebugRequirementsNone:"目前没有额外要求",workspaceDetailDebugServiceSectionDescription:"把项目拆成单个服务来看,方便确认哪些可以直接启动,哪些还要补充设置。",workspaceDetailDebugRuntimeSectionDescription:"这里只显示最近一次启动结果,方便快速确认是哪一个服务没有正常跑起来。",workspaceDetailDebugMatrixSectionDescription:"这里展示不同类型服务的默认支持情况,帮助你判断下一步怎么处理。",workspaceDetailDebugMatrixTitle:"支持说明",workspaceDetailDebugMatrixOpenAction:"查看支持矩阵",workspaceDetailDebugMatrixModalDescription:"把不同服务类型的默认支持情况放到一张矩阵里,别再靠长列表硬扫。",workspaceDetailDebugMatrixFrameworkHeader:"框架",workspaceDetailDebugMatrixCompatibilityHeader:"支持",workspaceDetailDebugMatrixInjectionHeader:"方式",workspaceDetailDebugMatrixDiscoveryHeader:"发现",workspaceDetailDebugMatrixHmrHeader:"HMR",workspaceDetailDebugMatrixCallbackHeader:"回调",workspaceDetailDebugMatrixAiHeader:"人工",workspaceDetailDebugMatrixNotesHeader:"说明",workspaceDetailDebugMatrixCompatibilitySupportedShort:"可直接",workspaceDetailDebugMatrixCompatibilityConditionalShort:"先补充",workspaceDetailDebugMatrixCompatibilityUnsupportedShort:"不建议",workspaceDetailDebugMatrixCompatibilityUnknownShort:"未知",workspaceDetailDebugMatrixInjectionCliShort:"参数",workspaceDetailDebugMatrixInjectionEnvShort:"环境",workspaceDetailDebugMatrixInjectionOverrideShort:"改命令",workspaceDetailDebugMatrixInjectionAiFallbackShort:"人工",workspaceDetailDebugMatrixInjectionNoneShort:"无",workspaceDetailDebugMatrixRequirementRequiredShort:"需处理",workspaceDetailDebugMatrixRequirementNotRequiredShort:"无需",workspaceDetailDebugMatrixAiNeverShort:"不处理",workspaceDetailDebugMatrixAiConditionalShort:"视情况",workspaceDetailDebugMatrixAiAllowedShort:"可处理",workspaceDetailDebugMatrixLegendSummary:"表格里的图标含义是:勾表示默认可过,警示表示启动前还要补设置,叉表示当前不建议自动处理。下面把短表头补成人话,省得你猜。",workspaceDetailDebugMatrixDiscoveryNote:"服务地址、代理、rewrites 这一类处理。",workspaceDetailDebugMatrixHmrNote:"热更新、前端开发长连这类处理。",workspaceDetailDebugMatrixCallbackNote:"登录回调、OAuth、Webhook 这类回调入口。",workspaceDetailDebugMatrixAiNote:"遇到边界情况时,是否允许转人工辅助。",workspaceDetailDebugActionAnalyze:"重新分析",workspaceDetailDebugActionPlan:"生成方案",workspaceDetailDebugActionRun:"开始运行",workspaceDetailDebugActionRefresh:"刷新状态",workspaceDetailDebugActionAnalyzing:"分析中…",workspaceDetailDebugActionPlanning:"生成中…",workspaceDetailDebugActionRunning:"运行中…",workspaceDetailDebugActionRefreshing:"刷新中…",workspaceDetailDebugActionAnalyzeSuccess:"已经重新读取服务分析结果",workspaceDetailDebugActionPlanSuccess:"已生成启动方案",workspaceDetailDebugActionRunSuccess:"已经提交启动命令,正在刷新最新运行态",workspaceDetailDebugActionRefreshSuccess:"已刷新状态",workspaceDetailDebugActionWorkspaceMissing:"当前工作区信息不完整,暂时不能执行这个操作。",workspaceDetailDebugActionTargetMissing:"当前还没有可用的调试目标,请先完成分析。",workspaceDetailDebugActionAnalyzeFailed:"重新分析失败",workspaceDetailDebugActionPlanFailed:"生成启动方案失败",workspaceDetailDebugActionRunFailed:"启动服务失败",workspaceDetailDebugActionRefreshFailed:"刷新运行态失败",workspaceDetailDebugLaunchPlanTitle:"启动方案",workspaceDetailDebugLaunchPlanDescription:"查看本次生成的方案。",workspaceDetailRegisteredDebugLaunchPlanDescription:"查看本次方案。",workspaceDetailRegisteredDebugLaunchPlanGeneratedAtLabel:"时间",workspaceDetailRegisteredDebugLaunchPlanRunnableLabel:"可直接启动",workspaceDetailRegisteredDebugLaunchPlanOrchestratedLabel:"需调整",workspaceDetailRegisteredDebugLaunchPlanBlockedLabel:"阻断",workspaceDetailRegisteredDebugLaunchPlanNote:"按当前设置生成。",workspaceDetailDebugLaunchPlanRuntimeIdLabel:"准备记录",workspaceDetailDebugLaunchPlanAutoStartLabel:"结果",workspaceDetailDebugLaunchPlanAutoStartAllowed:"可直接运行",workspaceDetailDebugLaunchPlanAutoStartBlocked:"需先处理",workspaceDetailDebugLaunchPlanSideEffectNote:"注意:当前“检查启动方案”不是纯预览,后端会生成一条准备记录。",workspaceDetailDebugLaunchPlanServicePortLabel:"计划端口",workspaceDetailDebugLaunchPlanServiceAdapterLabel:"处理方式",workspaceDetailDebugLaunchPlanServiceFailureLabel:"阻断位置",workspaceDetailDebugLaunchPlanServiceRequirementsLabel:"缺少条件",workspaceDetailDebugLaunchPlanServiceAttemptsLabel:"处理链路",workspaceDetailDebugLaunchPlanServiceAiLabel:"人工兜底",workspaceDetailDebugLaunchPlanServiceAllowedFilesLabel:"允许触达文件",workspaceDetailDebugLaunchPlanServiceNoRequirements:"当前没有额外阻断条件",workspaceDetailDebugLaunchPlanServiceNoEnvPatch:"没有额外环境变量补丁",workspaceDetailDebugLaunchPlanServiceEnvPatchLabel:"环境变量补丁",workspaceDetailDebugLaunchPlanDismissAction:"清空方案",workspaceDetailDebugFailureStageServiceDiscovery:"还缺少服务地址相关处理",workspaceDetailDebugFailureStageHmr:"还缺少热更新相关处理",workspaceDetailDebugFailureStageCallback:"还缺少回调处理",workspaceDetailDebugFailureStageAiFallbackRequired:"需要转人工处理",workspaceDetailDebugFailureStageAdapterSelection:"还没找到合适的启动方式",workspaceDetailDebugFailureStageLaunchRequirements:"启动前还有条件没有满足",workspaceDetailDebugFailureStageCommandExecution:"启动命令没有正常执行",workspaceDetailDebugFailureStageProcessExit:"服务启动后很快退出了",workspaceDetailDebugFailureStageProcessRuntimeError:"服务运行时出现错误",workspaceDetailDebugFailureStageStaleRuntimeBinding:"这次启动记录已经失效",workspaceDetailDebugFailureStageUnknown:"未知阶段({code})",workspaceDetailDebugBindingAllocated:"已分配",workspaceDetailDebugBindingListening:"可访问",workspaceDetailDebugBindingFailed:"未就绪",workspaceDetailDebugBindingReleased:"已释放",workspaceDetailDebugBindingUnknown:"未知",workspaceDetailDebugProcessCreating:"启动中",workspaceDetailDebugProcessRunning:"运行中",workspaceDetailDebugProcessClosed:"已结束",workspaceDetailDebugProcessError:"异常",workspaceDetailDebugProcessUnknown:"未知",workspaceDetailDebugPortEmpty:"暂无",workspaceDetailRegisteredDebugTemplatePortMissing:"未配置",workspaceDetailRegisteredDebugTemplatePathLabel:"登记位置",workspaceDetailRegisteredDebugTemplatePortLabel:"端口",workspaceDetailRegisteredDebugTemplateRuntimeTypeLabel:"运行时",workspaceDetailRegisteredDebugTemplateSourceLabel:"来源",workspaceDetailRegisteredDebugTemplateSourceManual:"手动添加",workspaceDetailRegisteredDebugTemplateSourceDebugService:"自动生成",workspaceDetailRegisteredDebugTemplateSourceManaged:"系统生成",workspaceDetailRegisteredDebugTemplateProxyLabel:"代理",workspaceDetailRegisteredDebugTemplateProxyEnabled:"已开启",workspaceDetailRegisteredDebugTemplateProxyDisabled:"未开启",workspaceDetailRegisteredDebugTemplateInjectionModeLabel:"端口注入方式",workspaceDetailRegisteredDebugTemplateInjectionModeUnknown:"未标注",workspaceDetailRegisteredDebugTemplateServiceDiscoveryLabel:"服务地址联动",workspaceDetailRegisteredDebugTemplateServiceDiscoverySameOrigin:"同源访问",workspaceDetailRegisteredDebugTemplateServiceDiscoveryApiBaseUrl:"注入 API_BASE_URL",workspaceDetailRegisteredDebugTemplateServiceDiscoveryNone:"不额外处理",workspaceDetailRegisteredDebugTemplateServiceDiscoveryUnknown:"未标注",workspaceDetailRegisteredDebugTemplateStatusOccupied:"占用中",workspaceDetailRegisteredDebugTemplateStatusIdle:"空闲",workspaceDetailRegisteredDebugTemplateStatusUntracked:"未判断",workspaceDetailRegisteredDebugPlanItemCommandLabel:"命令",workspaceDetailRegisteredDebugPlanItemRuntimeLabel:"运行时",workspaceDetailRegisteredDebugPlanItemActionLabel:"结果",workspaceDetailRegisteredDebugPlanItemReasonLabel:"说明",workspaceDetailRegisteredDebugPlanActionStart:"直接启动",workspaceDetailRegisteredDebugPlanActionOrchestrated:"调整后启动",workspaceDetailRegisteredDebugPlanActionBlocked:"暂不能启动",workspaceDetailRegisteredDebugPlanReasonPortMissing:"未设置端口",workspaceDetailRegisteredDebugPlanReasonDuplicatePort:"存在重复登记端口,当前不能自动启动。",workspaceDetailRegisteredDebugPlanReasonDuplicatePortWillOrchestrate:"端口冲突,将自动分配新端口",workspaceDetailRegisteredDebugPlanReasonPortOccupied:"端口已占用",workspaceDetailRegisteredDebugPlanReasonPortOccupiedWillOrchestrate:"端口已占用,将自动分配新端口",workspaceDetailRegisteredDebugPlanReasonPortOrchestrated:"将改用端口 {port}",workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryInjected:"已自动完成地址联动",workspaceDetailRegisteredDebugPlanReasonAnalysisMissing:"缺少可用的项目识别结果,请先刷新启动项后再生成方案",workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryMissing:"缺少可联动的后端启动项,请先到调试里补登记;端口会自动注入,不需要手动改项目",workspaceDetailRegisteredDebugPlanReasonCallbackMissing:"当前回调场景还不能自动处理,请先手动确认启动方式",workspaceDetailRegisteredDebugPlanReasonRunnable:"可以直接启动",workspaceDetailRegisteredDebugLaunchPlanServiceDiscoveryHelp:"如果这里提示缺少地址联动,去调试里补登记后端启动项即可。端口会在启动时自动改配,不需要手动修改项目。",workspaceDetailRegisteredDebugRuntimeScopeNote:"未配端口的不计入。",workspaceDetailRegisteredDebugRuntimeIdle:"当前空闲",workspaceDetailRegisteredDebugRuntimeUnknown:"暂无状态",workspaceDetailRegisteredDebugRuntimeProcessLabel:"进程",workspaceDetailRegisteredDebugRuntimeCommandLabel:"进程命令行",workspaceDetailDebugRoleFrontend:"网页服务",workspaceDetailDebugRoleBackend:"后端服务",workspaceDetailDebugRoleWorker:"后台任务",workspaceDetailDebugRoleMock:"模拟服务",workspaceDetailDebugRoleDesktopShell:"桌面壳服务",workspaceDetailDebugRoleCustom:"自定义",workspaceDetailDebugServiceOverviewSupported:"这个服务已经识别清楚,按推荐方式处理后通常可以直接启动。",workspaceDetailDebugServiceOverviewConditional:"这个服务已经识别出来,但启动前还需要补充一些设置或配套处理。",workspaceDetailDebugServiceOverviewUnsupported:"这个服务目前不建议直接自动处理,建议先手动确认启动方式。",workspaceDetailDebugServiceOverviewUnknown:"这个服务还没有识别清楚,先保留结果,后续再补充判断。",workspaceDetailDebugServiceOverviewDesktopShell:"这是桌面壳服务,会单独展示,不参与网页服务的自动端口处理。",workspaceDetailDebugServiceActionSupported:"可直接启动",workspaceDetailDebugServiceActionConditional:"先补配置",workspaceDetailDebugServiceActionUnsupported:"建议手动处理",workspaceDetailDebugServiceActionUnknown:"先确认服务类型",workspaceDetailDebugServiceActionDesktopShell:"按桌面壳方式单独处理",workspaceDetailDebugAiEditEmpty:"无",workspaceDetailDebugAiEditPending:"待处理",workspaceDetailDebugAiEditApplied:"已应用",workspaceDetailDebugAiEditRolledBack:"已回滚",workspaceDetailDebugAiEditRejected:"已拒绝",workspaceSessionListBody:"项目里的会话、收藏和归档操作都收在这里,不再让你先去翻侧栏。",recentSessionsSectionTitle:"最近会话",recentSessionsSectionBody:"先回到最近在做的事情,别让手机端还要你猜入口。",currentWorkspaceSectionTitle:"当前项目会话",currentWorkspaceSectionBody:"当前项目下的会话都集中在这里,方便继续刚才的上下文。",sessionIndexTitle:"会话入口单独成页",sessionIndexBody:"最近、收藏、当前项目三块分开看,手机上找会话别再靠侧栏折叠。",toolsMoreAction:"更多",toolsSwipeHint:"左右滑动切换文件管理和 Git 管理",toolsSwipePosition:"{current} / {total}",toolFilesBody:"查看项目文件、变更文件和代码上下文,不再靠桌面右栏概念。",toolGitBody:"把当前项目的 Git 状态、提交和分支操作收进一个明确入口。",toolTerminalsBody:"进入终端主页面,处理输入密集和滚动密集的操作。",toolProcessesBody:"查看当前项目的终端模板、运行状态和调试入口。",toolsWorkspaceRequiredBody:"先选一个项目,再打开对应的工具页。",createSession:"新建会话",createSessionModalTitle:"选择新会话类型",createSessionModalDescription:"先选会话类型,再启动真正的会话进程。",createSessionWorkspaceLabel:"选择工作区",createSessionProviderLabel:"选择供应商",createSessionTarget:"当前项目",createWorktreeSectionTitle:"子工作区",createWorktreeSectionDescription:"先从当前项目分出子工作区,再决定用哪个供应商开新会话。",createWorktreeAction:"新增子工作区",createWorktreeCollapseAction:"收起子工作区表单",createWorktreeBranchLabel:"分支名",createWorktreeBranchPlaceholder:"例如:feat/login-codex",createWorktreeBranchRequired:"请先输入子工作区分支名",createWorktreeBranchInvalid:"分支名只能包含英文、数字、-、_、/,并且不能以 / 开头、结尾或连续出现 /",createWorktreeDisplayNameLabel:"显示名称(可选)",createWorktreeDisplayNamePlaceholder:"默认沿用分支名",createWorktreeBaseRefLabel:"从哪个分支/提交创建(可选)",createWorktreeBaseRefPlaceholder:"默认沿用当前分支",createWorktreeBaseRefHint:"可选当前仓库的本地分支 {localCount} 个、远端分支 {remoteCount} 个、标签 {tagCount} 个;也可以手填 commit hash。",createWorktreeBaseRefLoading:"正在读取当前仓库的分支和标签...",createWorktreeBaseRefLoadFailed:"分支和标签列表读取失败,仍然可以手动输入分支、标签或 commit hash。",createWorktreeBaseRefLocalGroup:"本地分支",createWorktreeBaseRefRemoteGroup:"远端分支",createWorktreeBaseRefTagGroup:"标签",createWorktreeBaseRefCurrentBadge:"当前分支",createWorktreeBaseRefRecommendedBadge:"推荐",createWorktreeBaseRefEmpty:"没有找到匹配项。你也可以直接输入想使用的分支、标签或 commit hash。",createWorktreeBaseRefToggle:"展开可选分支和标签",createWorktreeHelpAction:"填写说明",createWorktreeHelpTitle:"这三个内容怎么填",createWorktreeHelpBranchTitle:"分支名",createWorktreeHelpBranchBody:"这是新子工作区自己的名字,后面在列表里也会用它区分。一般填类似 feat/login 这种短名字就够了。",createWorktreeHelpDisplayNameTitle:"显示名称",createWorktreeHelpDisplayNameBody:"如果你想让列表里更好认,可以填一个更直白的名字。不填也没关系,系统会直接用分支名。",createWorktreeHelpBaseRefTitle:"从哪个分支/提交创建",createWorktreeHelpBaseRefBody:"这决定新子工作区从哪里开始。大多数时候保持默认就行;只有你想从别的分支、标签,或者某次提交继续时再改。",createWorktreeSubmit:"创建子工作区",createWorktreeSubmitting:"创建中...",createWorktreeSucceeded:"子工作区已创建:{name}",createWorktreeFailed:"创建子工作区失败",providerClaudeCode:"Claude Code",providerLegnaCode:"Legna Code",providerCodexDescription:"创建 Codex 会话,适合继续当前默认工作流。",providerClaudeDescription:"创建 Claude Code 会话,适合切换另一条会话链路。",providerLegnaDescription:"创建 Legna Code 会话,底层复用 Claude 兼容 runtime,但使用独立会话存储路径。",providerOpenCodeDescription:"创建 OpenCode 会话,适合通过 OpenCode server 延续当前上下文。",providerGeminiDescription:"创建 Gemini 会话,适合接入 Gemini CLI 的原生工作流。",providerKimiDescription:"创建 Kimi 会话,适合接入 Kimi CLI 的原生工作流。",createSessionPresetLabel:"会话配置",createSessionPresetHint:"默认沿用当前全局 preset;只对 Codex、Claude Code、Gemini 开放会话级 preset。",createSessionPresetDefault:"使用当前默认 preset",createSessionPresetLoading:"正在读取 cc-switch preset...",createSessionPresetUnavailable:"暂时无法读取 cc-switch preset,先按默认配置创建。",createSessionStartAction:"进入会话草稿",providerChecking:"检查中...",startClaude:"Claude",startCodex:"Codex",startingSession:"创建中...",startClaudeSuccess:"Claude 会话已创建",startCodexSuccess:"Codex 会话已创建",startSessionFailed:"创建失败",auxiliaryTitle:"信息",auxiliarySubtitle:"文件与 Git 状态",expandAuxiliary:"展开",collapseAuxiliary:"收起",auxiliaryEmptyTitle:"选择一个会话",auxiliaryEmptyBody:"会话文件和 Git 信息将显示在这里",batchSelectSessions:"批量选择会话",batchSelectionMode:"批量选择",selectAllSessions:"全选",clearSelectedSessions:"清空选择",batchArchiveAction:"归档已选",batchArchiving:"归档中...",batchArchiveSuccess:"已归档选中的会话",batchArchivePartialFailed:"部分会话归档失败,请重试",batchArchiveFailed:"批量归档失败",batchDeleteAction:"删除已选",batchDeleting:"删除中...",batchDeleteSuccess:"已删除选中的会话",batchDeletePartialFailed:"部分会话删除失败,请重试",batchDeleteFailed:"批量删除失败",batchDeleteConfirmTitle:"确认删除已选会话",batchDeleteConfirmDescription:"删除后,选中的 {count} 条会话会从助手历史和工作区列表里消失,真实会话记录也会一并清掉,不能恢复。",batchDeleteSelectionSummary:"已选择 {count} 条会话",hideSessionSidebar:"隐藏会话列表",showSessionSidebar:"显示会话列表",hideInfoSidebar:"隐藏信息栏",showInfoSidebar:"显示信息栏",centerTabsLabel:"中间区域标签",infoTabsLabel:"信息栏标签",leftResizerLabel:"调整左侧宽度",rightResizerLabel:"调整右侧宽度",filesPanelEmpty:"先导入或选中一个项目,文件管理才能显示。",gitPanelEmpty:"先导入或选中一个工作区,Git 信息才能显示。",infoPanelDeferred:"左侧会话列表优先加载,右侧附属面板稍后再挂载。"},workbench:{emptyEyebrow:"开始",emptyTitle:"先选一个会话",emptyBody:"从左侧继续之前的内容,或新建一个会话。",emptyResumeTitle:"继续",emptyResumeBody:"回到上次停下的地方。",emptyNewTitle:"新建",emptyNewBody:"把新问题放进新会话。",emptyCompanionTitle:"查看辅助信息",emptyCompanionBody:"需要文件、Git 或终端时,再看右侧。",emptyTip:"准备好后,从左侧选一个会话开始。"},conversation:{resendButton:"重发",historyLoading:"加载中...",historyLoadingOlder:"加载更早的消息...",historyLoadFailed:"加载失败",inheritedContextLoading:"正在整理从父会话继承的上下文...",inheritedContextMessageLabel:"继承自某条消息之前的上下文",inheritedContextSessionLabel:"继承自主会话的上下文",inheritedContextSummary:"已默认折叠从“{parentTitle}”继承的 {count} 条消息。",actionInheritedSelectionSummary:"已默认折叠来自“{parentTitle}”的一段选中文本。",inheritedContextExpand:"展开完整上文",inheritedContextCollapse:"收起继承上文",inheritedContextParentFallback:"父会话",timelineEmpty:"开始对话",composerPlaceholder:"把下一步交代清楚,剩下的交给这条会话继续跑。",sendButton:"发送消息",attachFiles:"附加文件",attachmentSourceSheetTitle:"添加附件",attachmentSourceSheetDescription:"可以从文件中选择一个或多个文件,也可以直接拍照。",attachmentTakePhoto:"拍照",attachmentTakePhotoHint:"直接打开相机添加一张照片",attachmentChooseFromLibrary:"从文件中选择",attachmentChooseFromLibraryHint:"通过系统文件选择器添加一个或多个文件",pasteImagesHint:"支持直接粘贴文件",attachmentImageOnly:"当前只支持图片附件",attachmentReadFailed:"附件读取失败,请重试",attachmentPreviewAlt:"已选图片预览",attachmentPreviewOpen:"打开附件",attachmentPreviewClose:"关闭预览",attachmentPreviewLoading:"附件加载中",attachmentPreviewUnavailable:"附件暂时不可用",attachmentDownload:"下载附件",toolWebSearch:"联网搜索",toolWebSearchQueryLabel:"搜索词",toolWebSearchSourcesLabel:"来源",toolWebSearchUntitledSource:"未命名来源",attachmentDropHint:"拖拽文件到这里即可添加",imageAttachmentLabel:"图片附件",fileAttachmentLabel:"文件附件",imagePreviewTitle:"图片预览",imagePreviewHint:"点击遮罩或按 Esc 可以关闭预览",removeAttachment:"移除附件",selectionTodoAction:"代办",selectionActionButton:"操作",selectionActionSubmit:"新开操作子会话",selectionActionPromptLabel:"你想让它做什么",selectionActionPromptPlaceholder:"比如:解释这段话、整理成笔记,或调用指定接口处理它",selectionActionIncludeContext:"包含当前上下文",selectionActionContextUnavailable:"当前选区跨了多条消息,没法安全继承上下文,只能按无上下文新建子会话。",selectionActionDefaultPrompt:"请处理这段内容。",selectionActionPreviewLabel:"已选内容",selectionActionTargetLabel:"新会话设置",selectionActionQuotedLabel:"选中文本",selectionActionFailed:"创建操作子会话失败。",actionSessionBadge:"操作",modelSelectorLabel:"选择模型",modelUseCliDefault:"默认",deploymentDefaultPreset:"默认",deploymentConfigColumn:"配置文件",deploymentModelColumn:"模型",deploymentLoading:"正在读取部署...",deploymentModelLoading:"正在加载模型...",deploymentModelEmpty:"这个配置文件下暂时没有可选模型",modelUseCodexConfig:"跟随当前 Codex 配置",modelUseOpenCodeConfig:"跟随当前 OpenCode 配置",reasoningSelectorLabel:"选择推理强度",reasoningLow:"低",reasoningMedium:"中",reasoningHigh:"高",reasoningMaximum:"极高",slashMenu:"命令",slashMenuTitle:"快捷命令",slashCommandPlan:"先让对方给出执行路线",slashCommandReview:"直接进入代码审查模式",slashCommandExplain:"要求用更清楚的方式解释",mentionMenuTitle:"@ 检索",mentionLoading:"正在查找可用的技能和最近改动的文件…",mentionEmpty:"没找到匹配项,换个名字试试。",mentionSkillTag:"技能",mentionFileTag:"文件",mentionSelectedListLabel:"已选中的 skill 和文件",mentionActivateSkill:"回显 skill:{name}",mentionActivateFile:"定位文件:{name}",mentionRemoveSkill:"删除 skill:{name}",mentionRemoveFile:"删除文件:{name}",toolInputLabel:"输入",toolResultLabel:"结果",toolResultEmpty:"暂无输出",toolPreviewCommand:"命令",toolPreviewTerminal:"终端",toolViewImageActiveLabel:"AI正在查看图片",toolStatusRunning:"运行中",toolStatusFailed:"已失败",toolStatusCompleted:"已完成",runtimeThinkingPlaceholder:"{provider} 正在思考...",applyPatchEditedLabel:"已编辑",applyPatchAddedLabel:"已新增",applyPatchDeletedLabel:"已删除",applyPatchDialogTitle:"Patch 变更预览",applyPatchDialogDescription:"这里按文件显示 apply_patch 将要执行的变更。",applyPatchOpenDiff:"查看 diff",applyPatchEditedStat:"已编辑",applyPatchAddedStat:"新增",applyPatchRemovedStat:"减少",applyPatchEmpty:"这个 patch 暂时没有可展示的文件变更。",titleFallback:"继续对话",draftTitleCodex:"New Codex session",draftTitleClaude:"New Claude Code session",draftTitleLegna:"New LegnaCode session",draftTitleOpenCode:"New OpenCode session",draftTitleGemini:"New Gemini session",draftTitleKimi:"New Kimi session",headerWorkspace:"工作区",headerWorkspaceUnknown:"未知工作区",headerProvider:"Provider",headerConnection:"连接",headerRuntime:"运行态",providerCodex:"Codex",branchTreeAction:"分支树",branchTreeTitle:"分支树",branchTreeDescription:"这里只看当前会话所在的父子链,不把整个工作区会话列表混进来。",branchTreeUpstreamLabel:"上游链路",branchTreeCurrentLabel:"当前会话",branchTreeChildrenLabel:"下游分支",branchTreeCurrentBadge:"当前",branchTreeArchivedBadge:"已归档",branchTreeEmpty:"这条会话当前还没有下游分支。",branchTreeMapTitle:"分支关系图",branchTreeMapDescription:"这里会把当前会话所在主干和所有关联分支一起展开。",branchTreePreviewTitle:"会话预览",branchTreePreviewDescription:"点一下节点就会浮出最近几条消息,再决定要不要切过去。",branchTreePreviewLoading:"正在读取这条会话的最近消息...",branchTreePreviewFailed:"会话预览读取失败。",branchTreePreviewEmpty:"这条会话最近没有可预览的消息。",branchTreeResizeHandle:"调整分支树宽度",branchTreeZoomInAction:"放大分支图",branchTreeZoomOutAction:"缩小分支图",branchTreeZoomResetAction:"重置分支图缩放",branchTreeSwitchAction:"切换到这个会话",branchTreeCurrentAction:"已在当前会话",branchTreeToolMessageFallback:"工具消息",branchTreeMessageEmpty:"这条消息当前没有可展示的正文。",moreSessionActions:"更多会话操作",branchAction:"分支",moreSessionActionsTitle:"更多会话操作",moreSessionActionsDescription:"分支树和助手入口统一收在这里,避免移动端标题栏被按钮挤满。",branchTreeTab:"分支树",aiAssistantTab:"助手",aiAssistantTabDescription:"这里保留当前会话的助手入口,需要继续跟进或发起验证时直接点下面这个按钮。",providerClaude:"Claude",providerLegna:"Legna",providerOpenCode:"OpenCode",providerGemini:"Gemini",providerKimi:"Kimi",capabilitySend:"可发送",queueTitle:"待发队列",queueDescription:"当前运行结束后,会按顺序自动继续处理下面的消息。",queueOrderPrefix:"等待顺序",queueStatusQueued:"等待中",queueStatusFailed:"续跑失败",queueDelete:"删除",queueDeleting:"删除中",permissionRequestSectionTitle:"待处理审批",permissionRequestSectionDescription:"这里把供应商原生的权限申请统一收口,不再让你面对三套不同的确认框。",permissionRequestToastTitle:"需要审批",backgroundPermissionToastDescription:"{title} · {requestTitle}",backgroundCompletionToastTitle:"会话已完成",backgroundCompletionToastDescription:"{title}",backgroundFailureToastTitle:"会话异常",backgroundFailureToastDescription:"{title} · {detail}",permissionRequestReplyFailed:"回复权限申请失败。",permissionRequestSubmitting:"提交中...",permissionRequestReasonLabel:"原因",permissionRequestCommandLabel:"命令",permissionRequestToolLabel:"工具",permissionRequestCwdLabel:"工作目录",permissionRequestPathsLabel:"相关路径",permissionRequestPermissionsLabel:"申请权限",permissionRequestReadLabel:"读取",permissionRequestWriteLabel:"写入",permissionRequestNetworkLabel:"网络",permissionRequestQuestionsLabel:"补充问题",permissionRequestDetailLabel:"详情",permissionRequestEmpty:"无",permissionRequestUnknown:"未知",permissionRequestKindCommand:"命令",permissionRequestKindFileChange:"文件改动",permissionRequestKindPermissions:"权限扩展",permissionRequestKindUserInput:"补充输入",permissionRequestKindToolCall:"工具调用",queueImageOnly:"只包含图片附件",sendGuidanceButton:"追加指导",queueGuidanceButton:"加入队列",capabilityDenied:"受限",capabilitySendDisabled:"发送受限",connectionConnected:"实时已连接",connectionReconnecting:"正在重连",connectionReconnectFailed:"重连失败",connectionClosed:"连接已关闭",runtimeIdle:"空闲",runtimeStarting:"启动中",runtimeRunning:"运行中",runtimeReconnecting:"恢复中",runtimeStale:"运行待确认",runtimeUnknown:"状态待确认",runtimeCompleted:"已完成",runtimeInterrupted:"已中断",runtimeFailed:"失败",rulesMessageTitle:"规则信息",rulesMessageHint:"这是一段会话启动规则,默认折叠显示,需要时再展开查看。",rulesMessageExpand:"展开规则",rulesMessageCollapse:"收起规则",skillContextTitle:"助手 Skill",skillContextHint:"这是 Claude Code 会话启动时注入的 Skill 上下文,默认折叠显示,需要时再展开查看。",skillContextExpand:"展开 Skill",skillContextCollapse:"收起 Skill",systemPromptTitle:"系统提示",systemPromptHint:"这是 Kimi 会话开头的系统提示词,默认折叠显示,需要时再展开查看。",systemPromptExpand:"展开提示词",systemPromptCollapse:"收起提示词",taskProgressButton:"任务进度({count})",taskProgressModalTitle:"任务进度",taskProgressModalDescription:"当前会话已记录 {count} 条任务,这里直接看最新进度。",taskProgressExplanationTitle:"本轮更新说明",taskProgressSummaryTotal:"总数",taskProgressStatusPending:"待处理",taskProgressStatusInProgress:"进行中",taskProgressStatusCompleted:"已完成",taskProgressStatusFailed:"已失败",taskProgressStatusCancelled:"已取消",taskCardPlanTitle:"计划更新",taskCardTodoTitle:"任务更新",taskCardPlanUpdated:"最新计划",taskCardTodoUpdated:"最新任务列表",taskCardRawExpand:"展开原始调用",taskCardRawCollapse:"收起原始调用",taskCardSummaryTotal:"共 {count} 项",taskCardSummaryInProgress:"进行中 {count}",taskCardSummaryPending:"待处理 {count}",taskCardSummaryCompleted:"已完成 {count}",taskCardSummaryFailed:"已失败 {count}",butlerActionButton:"助手",butlerActionModalTitle:"助手动作",butlerActionModalDescription:"让助手继续跟进当前开发会话,或发起一次开发验证。",butlerActionLoading:"正在连接助手记录...",butlerActionLoadFailed:"读取助手动作信息失败",butlerActionProjectLabel:"当前项目",butlerActionSessionLabel:"当前会话",butlerFollowUpAction:"继续跟进",butlerFollowUpActionDescription:"让助手持续盯住这条开发会话,并在结束或阻塞后继续推动。",butlerFollowUpProviderLabel:"跟进助手",butlerFollowUpProviderHint:"选择由哪种 CLI 助手负责这条跟进会话。后续每轮跟进都会复用这条可见助手会话。",butlerFollowUpObjectiveLabel:"跟进目标",butlerFollowUpObjectivePlaceholder:"例如:帮我把这个会话的功能真正做完,若 spec 还有未完成项就继续补齐。",butlerFollowUpCompletionCriteriaLabel:"结束条件",butlerFollowUpCompletionCriteriaPlaceholder:"例如:只有当当前功能按既定需求完成,且不再存在必须继续推进的未完成项时,才停止自动跟进。",butlerFollowUpCompletionCriteriaRequired:"请先选择或填写明确的结束条件,助手必须知道什么时候停下",butlerCompletionTemplateSectionLabel:"结束模板",butlerCompletionTemplateSectionHint:"请选择一条明确模板;模板会直接覆盖结束条件,且必须在达到轮数上限后停止自动续接。",butlerCompletionTemplateRecommendedLabel:"标准收口",butlerCompletionTemplateRecommendedDescription:"功能完成并验证通过后结束",butlerCompletionTemplateRecommendedValue:"只有当当前功能已经按本次需求完成、已完成一次开发验证或人工确认,且不存在必须继续推进的阻塞项时,才停止自动跟进;如果 AI 推荐的下一步相对于核心目标不是必选项,也必须停止;达到自动跟进轮数上限后也必须停止,不再无限续接会话。",butlerCompletionTemplateSpecLabel:"Spec 收尾",butlerCompletionTemplateSpecDescription:"把当前 spec 的必做项收干净",butlerCompletionTemplateSpecValue:"只有当当前 spec 的必做任务已经完成,相关代码、文档和必要验证已补齐,且没有必须继续推进的阻塞项时,才停止自动跟进;如果 AI 推荐的下一步相对于核心目标不是必选项,也必须停止;不主动扩展到新的需求范围;达到自动跟进轮数上限后也必须停止。",butlerCompletionTemplateBugfixLabel:"问题修复",butlerCompletionTemplateBugfixDescription:"问题修复并确认没有高优先级回归",butlerCompletionTemplateBugfixValue:"只有当这次问题已经定位并修复,相关验证已经通过,且没有新的高优先级回归需要立即处理时,才停止自动跟进;如果 AI 推荐的下一步相对于核心目标不是必选项,也必须停止;优化建议和后续想法不算必须继续推进的理由;达到自动跟进轮数上限后也必须停止。",butlerFollowUpRoundLimitLabel:"最多自动跟进轮数",butlerFollowUpRoundLimitHint:"达到上限后,助手会停止自动续接,避免无限扩展会话。",butlerCurrentFollowUpLabel:"当前跟进任务",butlerCurrentFollowUpProgress:"已自动推进 {current} / {max} 轮",butlerFollowUpStopping:"正在停止跟进...",butlerStopFollowUpAction:"停止当前跟进",butlerFollowUpObjectiveRequired:"请先写清楚这次希望助手持续推动的目标",butlerCurrentVerificationLabel:"当前验证任务",butlerStopVerificationAction:"停止当前验证",butlerVerificationAction:"开始验证",butlerVerificationActionDescription:"让助手从用户视角对当前会话对应功能发起一次验证。",butlerFollowUpStarted:"已交给助手继续跟进",butlerFollowUpStartedDescription:"助手会继续跟进 {projectName} 的当前开发会话。",butlerFollowUpFailed:"助手跟进启动失败",butlerFollowUpStopped:"已停止当前助手跟进",butlerFollowUpStoppedDescription:"当前会话的自动跟进已经停止,不会继续自动续接。",butlerFollowUpStopFailed:"停止助手跟进失败",butlerVerificationStarted:"已发起开发验证",butlerVerificationStartedDescription:"助手会对 {projectName} 发起一次开发验证。",butlerVerificationFailed:"开发验证启动失败",butlerVerificationStopping:"正在停止验证...",butlerVerificationStopped:"已停止当前开发验证",butlerVerificationStoppedDescription:"当前会话的验证已经停止,并且关联自动化执行也已一并结束。",butlerVerificationStopFailed:"停止开发验证失败",butlerAnalysisTitle:"助手分析过程",butlerAnalysisLoadFailed:"读取助手分析失败",butlerAnalysisObjectiveLabel:"当前目标",butlerAnalysisStatusLabel:"当前判断",butlerAnalysisSummaryLabel:"最近分析",butlerAnalysisWaitingReasonLabel:"等待原因",butlerAnalysisEmpty:"当前还没有可展示的助手分析记录。",butlerProxyMessageBadge:"代理发送",butlerOriginDetailTitle:"对应的助手跟进",butlerOriginDetailLoading:"正在读取对应的助手跟进记录...",butlerOriginDetailLoadFailed:"读取对应的助手跟进记录失败",butlerOriginDetailObjectiveLabel:"跟进目标",butlerOriginDetailStatusLabel:"当前状态",butlerOriginDetailSummaryLabel:"最近分析",butlerOriginDetailWaitingReasonLabel:"等待原因",assistantCapabilityBadgeSession:"助手会话",assistantCapabilityBadgeAutomation:"助手自动化",assistantCapabilityBadgeTerminal:"助手终端",assistantCapabilityBadgeWorkspace:"助手工作区",assistantCapabilityBadgeDebug:"助手调试",assistantCapabilityBadgeQuery:"助手查询",assistantCapabilityProjectSessionStartTitle:"新建会话",assistantCapabilitySessionSendTitle:"会话发送",assistantCapabilitySessionForkTitle:"会话分叉",assistantCapabilityTimerCreateTitle:"创建自动化",assistantCapabilityTimerCancelTitle:"取消自动化",assistantCapabilityTerminalInputTitle:"终端输入",assistantCapabilityTerminalCloseTitle:"关闭终端",assistantCapabilityWorkspaceDirectoryCreateTitle:"创建目录",assistantCapabilityWorkspaceImportTitle:"导入工作区",assistantCapabilityWorkspaceCloneTitle:"克隆工作区",assistantCapabilityWorkspaceNavigationUpdateTitle:"更新工作区视图",assistantCapabilityWorkspaceRemoveTitle:"移除工作区",assistantCapabilityWorktreeCreateTitle:"创建工作树",assistantCapabilityWorktreeMergeTitle:"合并工作树",assistantCapabilityWorktreeCleanupTitle:"清理工作树",assistantCapabilityDebugRunTitle:"启动调试",assistantCapabilitySessionReadTitle:"读取会话信息",assistantCapabilityAutomationReadTitle:"读取自动化信息",assistantCapabilityTerminalReadTitle:"读取终端信息",assistantCapabilityWorkspaceReadTitle:"读取工作区信息",assistantCapabilityDebugReadTitle:"读取调试信息",assistantCapabilityQueryTitle:"助手操作",assistantCapabilitySummarySessionStart:"已按当前助手配置创建真实会话。",assistantCapabilitySummarySessionSend:"消息已提交到目标真实会话。",assistantCapabilitySummarySessionFork:"已从当前上下文分叉出新会话。",assistantCapabilitySummaryTimerCreate:"已创建后续自动继续动作。",assistantCapabilitySummaryTimerCancel:"已取消等待中的自动继续动作。",assistantCapabilitySummaryTerminalInput:"输入已发送到目标终端。",assistantCapabilitySummaryTerminalClose:"目标终端已关闭。",assistantCapabilitySummaryWorkspace:"工作区相关操作已执行。",assistantCapabilitySummaryWorktree:"工作树相关操作已执行。",assistantCapabilitySummaryDebug:"调试动作已触发。",assistantCapabilitySummaryRead:"助手已完成这次读取操作。",assistantCliSummaryHelp:"已查询对应的助手命令帮助。",assistantCliSummaryCommand:"已发起助手命令调用。",assistantCliHelpRootTitle:"查看助手帮助",assistantCliHelpSessionsTitle:"查看会话帮助",assistantCliHelpSessionActionTitle:"查看会话动作帮助:{action}",assistantCliHelpTimersTitle:"查看自动化帮助",assistantCliHelpTerminalsTitle:"查看终端帮助",assistantCliHelpWorkspacesTitle:"查看工作区帮助",assistantCliHelpGenericTitle:"查看 {group} 帮助",assistantCapabilityRawExpand:"查看原始",assistantCapabilityRawCollapse:"收起原始",assistantCapabilityLabelWorkspace:"工作区",assistantCapabilityLabelSession:"会话",assistantCapabilityLabelTerminal:"终端",assistantCapabilityLabelTimer:"自动化",assistantCapabilityLabelProvider:"Provider",assistantCapabilityLabelDueAt:"时间",assistantCapabilityLabelStatus:"状态",assistantCapabilityLabelPath:"路径",assistantCapabilityLabelBranch:"分支",assistantCapabilityLabelRuntime:"运行实例",assistantCapabilityLabelCount:"数量",assistantCapabilityLabelDebugTarget:"调试目标",assistantCliLabelScope:"范围",assistantCliLabelAction:"动作",assistantCliLabelProject:"项目",assistantCliLabelMessage:"消息",assistantCliLabelInput:"输入",assistantCliLabelDelay:"延迟",assistantCliScopeRoot:"根命令",assistantCapabilityNavigationCollapsed:"已折叠",assistantCapabilityNavigationExpanded:"已展开",assistantCapabilityStatusActive:"进行中",assistantCapabilityStatusCompleted:"已完成",assistantCapabilityStatusCancelled:"已取消",assistantCapabilityStatusFailed:"已失败",thinkingLabel:"思考中",filePanelWorkspaceTab:"工作区",filePanelSessionTab:"本次会话",filePanelSessionViewLabel:"本次会话视图",filePanelSessionTreeView:"树状",filePanelSessionListView:"列表",filePanelSessionLoading:"正在整理本次会话修改的文件...",filePanelSessionEmpty:"这条会话还没识别到可暂存的修改文件。",filePanelSessionNoSession:"当前只选中了项目,还没选中会话,无法查看“本次会话”文件。",filePanelSessionStageAll:"全部暂存",filePanelSessionStageSuccess:"已把本次会话的修改加入暂存区。",filePanelSessionLoadFailed:"本次会话修改文件加载失败。",filePanelSessionSummary:"已识别文件",filePanelSessionUnstagedSummary:"未暂存",filePanelSessionDeleted:"已删除",filePanelOpenExternalWindow:"在新窗口打开",filePanelOpenExternalFailed:"打开文件外部窗口失败。"},desktopWindow:{invalidWindowId:"缺少窗口 ID,无法加载外部窗口。",loadDescriptorFailed:"读取窗口描述失败。",unsupportedKind:"暂不支持渲染 {kind} 窗口。",invalidFilePreviewTarget:"缺少要预览的文件,无法打开文件预览窗口。",invalidAffairsTarget:"缺少事务工作区所需的工作区信息,无法打开事务窗口。",invalidCodeTarget:"缺少要打开的代码路径,无法打开代码窗口。"},git:{recentVersionsTitle:"最近版本",stagedChangesTitle:"暂存的更改",expandRecentVersions:"展开最近版本",collapseRecentVersions:"折叠最近版本",stagedLabel:"暂存区",workingTreeLabel:"工作区",changeTreeHint:"按目录层级展示当前变更",discard:"放弃改动",discardFailed:"放弃改动失败",operationMenu:"操作菜单",currentBranch:"当前分支",resizePanels:"调整文件区和最近版本高度",switchBranchTo:"切换到",undoLastCommit:"撤销上次提交",undoLastCommitFailed:"撤销上次提交失败",undoLastCommitSuccess:"已撤销上次提交",historyKindLocal:"本地",historyKindRemote:"远程",historyKindShared:"已同步",pushNow:"推送",commitNow:"提交",refreshNow:"刷新",openExternalWindow:"在新窗口打开 Git",openExternalFailed:"打开 Git 外部窗口失败。",stageAll:"暂存全部",unstageAll:"取消暂存全部",discardAll:"放弃全部改动",selectedFiles:"已选文件",clearSelection:"清空选中",selectFile:"选中文件",discardConfirm:"确认放弃这些改动吗?{path}",historyItemMenu:"版本操作",copyCommitHash:"复制 Commit Hash",copyCommitHashSuccess:"Commit Hash 已复制。",copyCommitSubject:"复制提交标题",copyCommitSubjectSuccess:"提交标题已复制。"},terminalManager:{workspaceField:"当前工作区",refresh:"刷新列表",loadFailed:"终端管理面板加载失败",shellLoadFailed:"终端 Shell 列表加载失败",emptyWorkspaceBody:"还没有可用工作区。",noCurrentWorkspaceBody:"先选中一条会话,进程管理才能绑定对应的工作区。",emptyTerminalBody:"当前工作区还没有终端实例。",emptyTemplateBody:"还没有快捷启动项,可以先保存一条命令或脚本。",shellField:"新终端 Shell",shellUnavailable:"当前不可用",cwdField:"启动目录",cwdLabel:"目录",cwdPlaceholder:"留空时默认使用工作区根目录",modeField:"启动方式",commandMode:"命令",scriptMode:"脚本",quickLaunchDescription:"先保存启动方式,需要时一键拉起到新终端。",desktopPanelDescription:"默认只看启动决策所需的信息,路径和命令行收进详情层。",openExternalWindow:"在新窗口打开",openExternalFailed:"打开进程管理外部窗口失败。",runningCountLabel:"运行中",portWatchCountLabel:"已监控端口",terminalCountLabel:"终端数",templateSectionTitle:"启动项",templateSectionDescription:"右侧优先显示启动项的端口状态,看清楚是否已被占用。",openWorkspaceDebugAction:"调试服务",openCreateModalAction:"添加快捷启动项",createModalTitle:"添加快捷启动项",createModalDescription:"在这里保存命令或脚本,可以附带端口,后面就能一键启动并判断是否在跑。",editAction:"编辑启动项",editModalTitle:"编辑快捷启动项",editModalDescription:"直接修改这条快捷启动的名称、命令、目录和端口配置。",saveTemplateChangesAction:"保存修改",templateUpdating:"保存修改中...",templateUpdateSuccess:"快捷启动项已更新。",templateUpdateFailed:"快捷启动项更新失败",removeAction:"移除启动项",templateRemoving:"移除中...",removeConfirmTitle:"确认移除启动项",removeConfirmAction:"确认移除",removeConfirmTarget:"确认移除“{name}”吗?移除后将不再出现在快捷启动列表中。",removeRunningConfirmTarget:"“{name}”对应的进程还在跑。现在移除的是启动项配置,不会自动结束已经运行的进程。确认继续吗?",templateDeleteSuccess:"快捷启动项已移除。",templateDeleteFailed:"快捷启动项移除失败",terminalSectionTitle:"终端实例",terminalSectionDescription:"这里显示当前工作区由 CodingNS 托管的终端。",closeAction:"关闭终端",closing:"关闭中...",closeSuccess:"终端关闭请求已提交。",closeFailed:"终端关闭失败",createTerminalAction:"新建空终端",creatingTerminal:"创建中...",createTerminalSuccess:"新终端已创建。",createTerminalFailed:"新终端创建失败",defaultTerminalName:"工作终端",templateNameField:"名称",templateNamePlaceholder:"留空时会自动生成",commandField:"启动命令",commandPlaceholder:"例如:npm",scriptPathField:"脚本路径",scriptPathPlaceholder:"例如:scripts/dev.ps1 或 scripts/dev.sh",argsField:"参数",argsPlaceholder:"例如:run dev 或 --watch",portField:"监听端口",portLabel:"端口",portPlaceholder:"例如:3000",proxyField:"反向代理",proxyToggleLabel:"开启反向代理",proxyEnabled:"代理已启用",proxyEnabledDescription:"开启后会生成随机 URL 码,可通过 /proxy/地址访问当前开发服务。",proxyDisabledDescription:"未开启反向代理",proxyPortRequired:"开启反向代理时,必须同时配置端口",openProxyUrlAction:"在浏览器打开代理地址",openProxyUrlFailed:"打开代理地址失败",invalidPort:"端口必须是 1 到 65535 的整数",saveLaunchAction:"保存为快速启动",templateSaving:"保存中...",templateSaveSuccess:"快捷启动项已保存。",templateSaveFailed:"快捷启动项保存失败",runTemplateAction:"启动到新终端",runningTemplate:"启动中...",templateRunSuccess:"快捷启动已发送到新终端。",templateRunFailed:"快捷启动执行失败",showDetailsAction:"显示详细信息",hideDetailsAction:"隐藏详细信息",detailsSectionTitle:"启动项详情",commandPreviewLabel:"启动命令",processIdLabel:"监听进程 PID",processGroupIdLabel:"进程组 PGID",processCommandLabel:"监听命令行",parentProcessIdLabel:"父进程 PID",parentProcessCommandLabel:"父进程命令行",terminationScopeLabel:"结束范围",terminationScopeProcess:"仅监听进程",terminationScopeProcessGroup:"整个进程组",stopProcessAction:"结束进程",stoppingProcess:"结束中...",stopProcessSuccess:"监听进程或所属进程组已结束。",stopProcessFailed:"结束监听进程或进程组失败",defaultCommandName:"新启动命令",defaultScriptName:"新启动脚本",lastActiveAt:"最近活跃",updatedAt:"最后更新",processCommandFallback:"这个进程没有暴露命令行",portUnset:"未配置端口",portUnsetDescription:"没有端口时,只能启动,不能自动判断服务是否在跑。",portOccupied:"进程已启动",portAvailable:"端口暂未被占用",portAvailableDescription:"这个启动项对应的端口目前还没有监听进程。",statusRunning:"运行中",statusStopped:"未运行",exitCode:"Exit Code",runningValue:"运行中"},theme:{light:"浅色",dark:"深色",skyBlue:"赛博",eyeGreen:"护眼",switchLabel:"主题"}},rb={common:{close:"Close",cancel:"Cancel",copy:"Copy",copyFailed:"Copy failed",enabled:"Enabled",disabled:"Disabled",logout:"Log out",language:"Language",none:"None"},locale:{zhCN:"Simplified Chinese",enUS:"English"},settings:{title:"Settings",appearance:"Appearance",language:"Language",languageDescription:"Choose the display language used by the interface. The page updates immediately.",theme:"Theme",themeDescription:"Choose the color theme that fits the way you work.",connection:"Connection & Updates",serverAddress:"Server Address",serverDescription:"Desktop and H5 both work through this host entry.",releaseChannel:"Release Channel",releaseChannelDescription:"Stable or beta",releaseStable:"Stable",releaseBeta:"Beta",autoReconnect:"Auto Reconnect",autoReconnectDescription:"Retry HTTP and WebSocket links automatically when Host is briefly unavailable.",autoCheckUpdate:"Auto Check Client Updates",autoCheckUpdateDescription:"Clients only",notificationSettings:"Notifications",notificationSettingsDescription:"Control each session-related system notification independently.",notifyOnPermissionRequest:"Notify on permission requests",notifyOnPermissionRequestDescription:"Notify when a background session needs a new permission approval.",notifyOnSessionCompleted:"Notify when sessions complete",notifyOnSessionCompletedDescription:"Notify when a background session finishes.",notifyOnSessionFailed:"Notify when sessions fail",notifyOnSessionFailedDescription:"Notify when a background session fails.",enabled:"Enabled",disabled:"Disabled",serverUpdate:"Server Update",serverUpdateDescription:"",clientUpdate:"Client Update",clientUpdateDescription:"",serverCurrentVersion:"Server Current Version",serverTargetVersion:"Server Target Version",serverPackageName:"npm Package",serverUpdateCommand:"Upgrade Command",serverCheckNow:"Check Server",serverInstallNow:"Install",serverOpenPage:"Open npm",serverLatestUnknown:"Unavailable",serverUpdateReady:"New version found",serverUpToDate:"Up to date",serverCheckFailed:"Check failed",serverInstallWarning:"Installing the update will restart the CodingNS service through PM2 and briefly interrupt the connection.",serverInstallConfirmTitle:"Install Server Update",serverInstallConfirmDescription:"Continuing will install the new version first, then let PM2 restart the current CodingNS service automatically.",serverInstallConfirmAction:"Install And Restart",serverRestarting:"Update installed. Restarting the CodingNS service",serverInstallQueued:"Queued",serverInstalling:"Installing update",serverInstallSucceeded:"Update completed",serverInstallFailed:"Install failed",serverInstallCancelled:"Install cancelled",serverInstallTimeout:"Install timed out",serverRestartRequired:"New version installed. Restart Host to apply it.",serverOpenPageFailed:"Failed to open page",runtimePlatform:"Runtime Platform",runtimePlatformDescription:"Shows whether the app is running in Web/H5, Desktop, iOS, or Android.",platformDesktop:"Desktop",platformWeb:"Web",platformIos:"iOS",platformAndroid:"Android",releaseDesktopOnly:"Desktop updates are not available in the current Web/H5 runtime.",releaseCurrentVersion:"Current Version",releaseTargetVersion:"Target Version",releaseUnknownVersion:"Unknown",releaseNotes:"What's New",releaseNotesEmpty:"No details",releaseCheckNow:"Check Client",releaseInstallNow:"Install",releaseOpenPage:"Open Release",releaseManualOnly:"This version requires manual installation",releaseUpdateBadge:"Update",releaseUpdateReady:"New version found",releaseUpToDate:"Up to date",releaseCheckFailed:"Check failed",releaseInstallStarted:"Install started",releaseInstallFailed:"Install failed",releasePageOpenFailed:"Failed to open release page",androidInstallerStarted:"Handed off to the Android installer. You can still cancel there.",androidInstallPermissionRequired:"Allow installs from this source before retrying.",androidInstallCancelled:"Install was cancelled or not completed. You can try again.",androidInstallSucceeded:"The new version has been detected as installed.",clientUpdateUnsupported:"Install updates are not supported here",account:"Account",logout:"Log out",logoutDescription:"Sign out of the current account and return to the login page.",advancedSettings:"Advanced Settings",parallelTaskDebug:"Parallel Task Debug",parallelTaskDebugDescription:"Runtime sampling stays off until you open this panel. Use it to inspect background tasks, schedulers, and main-thread pressure in real time.",debugPortPool:"Debug Port Pool",debugPortPoolDescription:"Assign available ports to registered launchers in child workspaces. All debug services now share one port range instead of separate pools per role.",debugPortPoolRangeLabel:"Port Range",debugPortPoolRangeHint:"Frontend, backend, worker, mock, and custom services all draw ports from this shared range",debugPortPoolStart:"Start",debugPortPoolEnd:"End",debugPortPoolRangeSeparator:"to",debugPortPoolSaveAction:"Save Port Pool",debugPortPoolSaved:"Port pool saved",debugPortPoolSaveFailed:"Failed to save the port pool",debugPortPoolValidationInteger:"Port pool bounds must be integers",debugPortPoolValidationRange:"Port pools must stay within 1024-65535 and start must be smaller than end",debugPortPoolValidationOverlap:"Port pool ranges must not overlap",debugPortPoolRoleFrontend:"Frontend",debugPortPoolRoleBackend:"Backend",debugPortPoolRoleWorker:"Worker",debugPortPoolRoleMock:"Mock",debugPortPoolRoleCustom:"Custom",debugPortPoolRoleHint:"{role} launchers will draw ports from this range",parallelTaskDebugAction:"Open Debug Panel",parallelTaskDebugModalTitle:"Parallel Task Debug",parallelTaskDebugModalDescription:"Task activity and event loop sampling only stay active while this window is open. Closing it stops collection immediately.",parallelTaskDebugClose:"Close parallel task debug",parallelTaskDebugLoading:"Opening observability session and loading runtime snapshot...",parallelTaskDebugLoadFailed:"Failed to load parallel task debug information",parallelTaskDebugEmpty:"No execution records are available right now.",parallelTaskDebugStatusActive:"Collecting",parallelTaskDebugStatusError:"Collection Error",parallelTaskDebugObservedAt:"Last Updated",parallelTaskDebugSessionExpireAt:"Session Expires At",parallelTaskDebugSessionTtl:"Session TTL",parallelTaskDebugCollectorState:"Collector State",parallelTaskDebugCollectorEnabled:"Enabled",parallelTaskDebugCollectorDisabled:"Disabled",parallelTaskDebugAutoRefresh:"Auto refresh every second",parallelTaskDebugCountersTitle:"Overall Counters",parallelTaskDebugRegisteredTasksTitle:"Registered Tasks",parallelTaskDebugRegisteredTasksEmpty:"No registered tasks are available right now.",parallelTaskDebugTaskMetricsTitle:"Recent Active Task Metrics",parallelTaskDebugActiveTaskMetricsEmpty:"No active task metrics were collected in this session yet.",parallelTaskDebugSchedulerTitle:"Scheduler Metrics",parallelTaskDebugEventLoopTitle:"Event Loop",parallelTaskDebugRecentActivitiesTitle:"Recent Execution Records",parallelTaskDebugWaitAvg:"Average Wait",parallelTaskDebugRunAvg:"Average Run",parallelTaskDebugRunMax:"Longest Run",parallelTaskDebugStartedCount:"Started",parallelTaskDebugFinishedCount:"Finished",parallelTaskDebugFailedCount:"Failed",parallelTaskDebugCacheHitCount:"Cache Hits",parallelTaskDebugIdle:"Idle",parallelTaskDebugBusy:"Busy",parallelTaskDebugTickTotal:"Tick Total",parallelTaskDebugIdleTickTotal:"Idle Ticks",parallelTaskDebugTaskCountTotal:"Task Hits",parallelTaskDebugSchedulerErrorTotal:"Errors",parallelTaskDebugLastDuration:"Last Duration",parallelTaskDebugNextDelay:"Next Delay",parallelTaskDebugEventLoopResolution:"Resolution",parallelTaskDebugEventLoopMean:"Mean Delay",parallelTaskDebugEventLoopP95:"P95 Delay",parallelTaskDebugEventLoopP99:"P99 Delay",parallelTaskDebugEventLoopMax:"Max Delay",parallelTaskDebugTaskTimeout:"Timeout",parallelTaskDebugTaskConcurrency:"Concurrency",parallelTaskDebugTaskRetry:"Retry Attempts",parallelTaskDebugTaskCategory:"Task Type",parallelTaskDebugTaskCategoryBuiltinIndexer:"Built-in Indexer",parallelTaskDebugTaskCategoryGeneric:"General Background Task",parallelTaskDebugTaskRuntime:"Runtime",parallelTaskDebugTaskRuntimeBuiltinHelper:"Host Built-in Helper",parallelTaskDebugTaskRuntimeHelperProcess:"Generic Helper Process",parallelTaskDebugTaskRuntimeHostBackground:"Host Background Runtime",parallelTaskDebugTaskRuntimeExternalProcess:"External Process",parallelTaskDebugTaskRuntimeMainThread:"Request Main Thread",parallelTaskDebugTaskHelper:"Helper Handler",parallelTaskDebugTaskKey:"Task Key",parallelTaskDebugStatus:"Status",parallelTaskDebugAttempt:"Attempt",parallelTaskDebugWaitMs:"Wait",parallelTaskDebugRunMs:"Run",parallelTaskDebugSource:"Source",parallelTaskDebugError:"Error",parallelTaskDebugMetricEnqueue:"Enqueue",parallelTaskDebugMetricDedupe:"Dedupe",parallelTaskDebugMetricStarted:"Started",parallelTaskDebugMetricFinished:"Finished",parallelTaskDebugMetricFailed:"Failed",parallelTaskDebugMetricCancelled:"Cancelled",parallelTaskDebugMetricTimeout:"Timeout",parallelTaskDebugMetricCacheHit:"Cache Hit",parallelTaskDebugLaneRequestMainThread:"Request Main Thread",parallelTaskDebugLaneHostBackground:"Host Background",parallelTaskDebugLaneHelperProcess:"Helper Process",parallelTaskDebugLaneExternalProcess:"External Process",parallelTaskDebugEventEnqueued:"Enqueued",parallelTaskDebugEventDeduped:"Deduped",parallelTaskDebugEventStarted:"Started",parallelTaskDebugEventFinished:"Finished",parallelTaskDebugEventFailed:"Failed",parallelTaskDebugEventCancelled:"Cancelled",parallelTaskDebugEventTimeout:"Timeout",parallelTaskDebugEventCacheHit:"Cache Hit",parallelTaskDebugTaskStatusQueued:"Queued",parallelTaskDebugTaskStatusRunning:"Running",parallelTaskDebugTaskStatusSucceeded:"Succeeded",parallelTaskDebugTaskStatusFailed:"Failed",parallelTaskDebugTaskStatusCancelled:"Cancelled",parallelTaskDebugTaskStatusTimeout:"Timeout",opencliSectionTitle:"OpenCLI Access",opencliSectionDescription:"Manage which OpenCLI CLI skills are exposed inside CodingNS sessions without touching the global installation on this machine.",opencliEnableAction:"Enable",opencliRefreshAction:"Refresh",opencliSaveAction:"Save",opencliLoading:"Loading OpenCLI status...",opencliLoadFailed:"Failed to load OpenCLI status",opencliSummaryInstallState:"Install State",opencliSummaryCatalogCount:"Catalog Count",opencliSummaryEnabledCount:"Enabled Now",opencliSummaryBrowserCount:"Browser-Dependent",opencliProviderToggleLabel:"Enable OpenCLI in new sessions",opencliProviderHint:"This only controls CodingNS-managed sessions. It does not rewrite the global opencli in your own terminal.",opencliVersionLabel:"Version",opencliCatalogSourceLabel:"Catalog Source",opencliLastCheckedLabel:"Last Check",opencliCatalogRefreshedLabel:"Last Refresh",opencliInstallPathLabel:"Install Path",opencliInstallInstalled:"Installed",opencliInstallBroken:"Broken Install",opencliInstallMissing:"Not Installed",opencliHealthReady:"Runnable",opencliHealthBridgeMissing:"Browser Bridge Missing",opencliHealthBinaryReady:"Binary Ready",opencliHealthRuntimeBuildFailed:"Runtime Build Failed",opencliHealthUnknown:"Unchecked",opencliCatalogSourceManifest:"Installed manifest",opencliCatalogSourceCliList:"opencli list",opencliCatalogSourceLocalManifest:"Local manifest",opencliCatalogSourceCache:"Retained cache",opencliRuntimeReady:"Trimmed runtime ready",opencliRuntimeFailed:"Trimmed runtime failed",opencliRuntimePending:"Trimmed runtime building",opencliRuntimeStale:"Trimmed runtime stale",opencliRuntimeIdle:"No runtime yet",opencliRefreshDone:"OpenCLI status refreshed",opencliRefreshReady:"OpenCLI status refreshed and the current runtime is ready for new sessions",opencliRefreshCacheRetained:"Refresh failed. The latest successful catalog cache was kept.",opencliRefreshUnavailable:"OpenCLI catalog is unavailable right now",opencliSaveReady:"OpenCLI settings saved. New sessions will use the rebuilt trimmed runtime.",opencliSaveEnabled:"OpenCLI settings saved, but the runtime is not ready yet.",opencliSaveDisabled:"OpenCLI has been disabled for new sessions",opencliEmpty:"There is no OpenCLI catalog to display right now.",opencliEmptyNotInstalled:"OpenCLI is not installed on this machine yet. Install it first, then refresh.",opencliCatalogGridTitle:"CLI Skill Catalog",opencliCatalogGridDescription:"Filter first, then use site cards to inspect and switch individual commands.",opencliDetailAction:"Details",opencliDetailTitle:"OpenCLI Details",opencliDetailStatusHeading:"Current Status",opencliDetailRuntimeIdLabel:"Runtime ID",opencliDetailRuntimeRootLabel:"Runtime Root",opencliDetailErrorHeading:"Recent Errors",opencliEnabledStateLabel:"Enabled in New Sessions",opencliEnabledStateOn:"Enabled",opencliEnabledStateOff:"Disabled",opencliFilterTabsLabel:"OpenCLI CLI skill filters",opencliFilterAll:"All",opencliFilterEnabled:"Enabled",opencliFilterBrowser:"Browser",opencliFilterDirect:"Direct",opencliFilterStrategy:"Strategy {strategy}",opencliFilteredEmpty:"No CLI skills match the current filter.",opencliSiteToggleLabel:"Toggle site {site}",opencliSiteSummary:"{enabled}/{total} enabled, with {browser} commands depending on the browser bridge.",opencliSiteSummaryCompact:"{enabled}/{total} enabled",opencliSiteBrowserCompact:"{count} browser-dependent",opencliSiteDirectCompact:"No browser bridge",opencliSiteCommandCount:"{count} commands",opencliSiteDescriptionEmpty:"This site does not provide an extra summary yet. Open the command list below to keep filtering.",opencliSiteViewAction:"View",opencliSiteSelectedAction:"Viewing",opencliSiteEnableAction:"Enable",opencliSiteDetailTitle:"{site} Commands",opencliSiteDetailDescription:"{count} commands match the current filter, out of {total} total commands for this site.",opencliSiteDescriptionHeading:"Site Summary",opencliCommandModalFallbackTitle:"Command List",opencliCommandModalEmpty:"No commands are available for this CLI skill site under the current filter.",opencliCommandSearchLabel:"Search Commands",opencliCommandSearchPlaceholder:"Filter by command name, description, or strategy",opencliCommandSortLabel:"Sort",opencliCommandSortStatus:"By Status",opencliCommandSortBrowser:"Browser First",opencliCommandSortName:"By Name",opencliCommandResultCount:"{count} visible",opencliCommandToggleLabel:"Toggle command {commandId}",opencliBrowserTag:"Browser Bridge",opencliHttpTag:"HTTP",opencliCommandDescriptionEmpty:"This catalog entry does not provide an extra description.",opencliStrategyUnknown:"Unknown strategy",opencliStrategyLabel:"Type: {strategy}",opencliStrategyShortLabel:"{strategy}",opencliStrategyCookie:"Cookie",opencliStrategyHeader:"Header",opencliStrategyIntercept:"Intercept",opencliStrategyLocal:"Local",opencliStrategyPublic:"Public",opencliStrategyUi:"UI",skillConfigTabsLabel:"Skill manager tabs",skillConfigTabSkills:"SKILL",skillConfigTabOpenCli:"OpenCLI",skillOnlyOfficeStatusLabel:"Office Integration",skillOnlyOfficeSectionTitle:"ONLYOFFICE Integration",skillOnlyOfficeSectionDescription:"Configure the external ONLYOFFICE service URL here. Leaving it disabled does not affect normal use.",skillOnlyOfficeSectionEmpty:"There is no ONLYOFFICE configuration yet.",skillOnlyOfficeEnabledLabel:"Enable ONLYOFFICE document preview and editing",skillOnlyOfficeServerUrlLabel:"ONLYOFFICE Service URL",skillOnlyOfficeServerUrlPlaceholder:"For example: http://127.0.0.1:8088",skillOnlyOfficePublicBaseUrlLabel:"CodingNS Public URL",skillOnlyOfficePublicBaseUrlPlaceholder:"For example: http://host.docker.internal:3002",skillOnlyOfficeCallbackBaseUrlLabel:"Callback URL (Optional)",skillOnlyOfficeCallbackBaseUrlPlaceholder:"Leave empty to reuse the CodingNS public URL",skillOnlyOfficeUserDisplayNameLabel:"ONLYOFFICE Display Name (Optional)",skillOnlyOfficeUserDisplayNameDescription:"Leave empty to use the current signed-in username: {username}",skillOnlyOfficeUserDisplayNamePlaceholder:"Leave empty to use the current signed-in username",skillOnlyOfficeUserAvatarUrlLabel:"ONLYOFFICE Avatar URL (Optional)",skillOnlyOfficeUserAvatarUrlDescription:"Leave empty to omit the avatar. If provided, it will be shown in collaborator info.",skillOnlyOfficeUserAvatarUrlPlaceholder:"For example: https://example.com/avatar.png",skillOnlyOfficeJwtSecretLabel:"JWT Secret (Optional)",skillOnlyOfficeJwtSecretPlaceholder:"Use the same secret if ONLYOFFICE JWT is enabled",skillOnlyOfficeJwtSecretKeepPlaceholder:"A JWT secret is already saved. Leave empty to keep it unchanged.",skillOnlyOfficeClearJwtSecretLabel:"Clear the current JWT secret",skillOnlyOfficeOpenSettingsAction:"Settings",skillOnlyOfficeModalTitle:"Configure ONLYOFFICE",skillOnlyOfficeModalDescription:"Set the ONLYOFFICE service URL, the CodingNS public URL, and the callback URL here. Saving affects docx, xlsx, and pptx preview and write-back.",skillOnlyOfficeSaveAction:"Save Configuration",skillOnlyOfficeCheckAction:"Check Again",skillOnlyOfficeSaveSuccess:"The ONLYOFFICE configuration has been saved.",skillOnlyOfficeCheckSuccess:"The ONLYOFFICE status has been refreshed.",skillOnlyOfficeStatusReady:"Ready",skillOnlyOfficeStatusWarning:"Warning",skillOnlyOfficeStatusError:"Unavailable",skillOnlyOfficeStatusMisconfigured:"Misconfigured",skillOnlyOfficeStatusDisabled:"Disabled",skillOnlyOfficeStatusUnknown:"Unknown",skillOnlyOfficeCheckPass:"Pass",skillOnlyOfficeCheckWarn:"Warning",skillOnlyOfficeCheckFail:"Fail",skillOnlyOfficeCheckSkip:"Skip",skillWorkspaceSessionMcpStatusAction:"View MCP Status",skillWorkspaceSessionMcpModalTitle:"Workspace Session MCP Status",skillWorkspaceSessionMcpModalDescription:"Check the current workspace session runtime, global CLI installation state, and whether each CLI is actually ready to call office MCP tools.",skillWorkspaceSessionMcpLoading:"Loading MCP status...",skillWorkspaceSessionMcpRuntimeTitle:"Current Session Runtime",skillWorkspaceSessionMcpRuntimeDescription:"Start by checking whether the workspace session's dedicated runtime under the global CodingNS directory has really materialized the scoped auth file, instruction file, and dedicated skill. Codex injects office MCP at startup from these runtime artifacts instead of writing to the global home.",skillWorkspaceSessionMcpReadyCliCount:"Ready to Call",skillWorkspaceSessionMcpConfiguredCliCount:"Configured / Injected",skillWorkspaceSessionMcpTotalCliCount:"CLI Count",skillWorkspaceSessionMcpOverallLabel:"Overall",skillWorkspaceSessionMcpCurrentSessionLabel:"Current Session",skillWorkspaceSessionMcpCodexLabel:"Codex",skillWorkspaceSessionMcpRuntimeHomeLabel:"Runtime Directory",skillWorkspaceSessionMcpAuthFileLabel:"Scoped Auth File",skillWorkspaceSessionMcpInstructionFileLabel:"Composed Instruction File",skillWorkspaceSessionMcpSkillDirLabel:"Workspace Session Skill Directory",skillWorkspaceSessionMcpCommandTitle:"CLI Command Status",skillWorkspaceSessionMcpCommandDescription:"This separates whether the repo already contains the implementation from whether the globally installed CLI on this machine has actually been upgraded.",skillWorkspaceSessionMcpGlobalCodingnsLabel:"Global codingns",skillWorkspaceSessionMcpGlobalStandaloneLabel:"Global codingns-workspace-office-mcp",skillWorkspaceSessionMcpGlobalStandaloneMissing:"This machine does not have the standalone command installed yet.",skillWorkspaceSessionMcpRepoCodingnsLabel:"Repo codingns.mjs",skillWorkspaceSessionMcpCliTitle:"Per-CLI Call Status",skillWorkspaceSessionMcpCliDescription:"This checks each CLI by its actual integration path: Codex uses runtime injection, while Claude Code and OpenCode still rely on runtime config files.",skillWorkspaceSessionMcpRefreshAction:"Refresh MCP Status",skillWorkspaceSessionMcpStateReady:"Ready",skillWorkspaceSessionMcpStatePartial:"Partial",skillWorkspaceSessionMcpStateMissing:"Missing",skillWorkspaceSessionMcpBrowserBridgeLabel:"Real Browser Debug",skillWorkspaceSessionMcpBrowserBridgeDetail:"This means browser.opencli_bridge. It is not a profile-based task, so you do not need to list or create a browser profile first.",skillWorkspaceSessionMcpRecommendedPathLabel:"Recommended Path",skillWorkspaceSessionMcpValueMissing:"No path available right now",skillWorkspaceSessionMcpEmptyTitle:"No MCP status yet",skillWorkspaceSessionMcpEmptyDescription:"Make sure you are inside a normal workspace session and that this session has already materialized its dedicated runtime under the global CodingNS directory."},shell:{title:"Workbench",subtitle:"Manage AI sessions inside code projects",mobileWorkspacesEntry:"Workspaces",mobileTerminalsEntry:"Terminal",mobileSessionsEntry:"Conversation",mobileToolsEntry:"Tools",mobileSettingsEntry:"Settings",mobileNavigationAction:"Open workbench menu",mobileSearchAction:"Open search",mobileAuxiliaryAction:"Open tools panel",mobileRevealNavigationAction:"Show primary navigation",mobileHideNavigationAction:"Hide primary navigation",mobileConversationPreviewTitle:"Quick Preview",mobileConversationCurrentWorkspaceSection:"Current Workspace",mobileConversationCollapsePreviewAction:"Hide Preview",mobileConversationRestorePreviewAction:"Restore Session Preview",iosMoreAction:"More actions",androidMoreAction:"More actions",conversationEntry:"Conversation",terminalsEntry:"Terminal",butlerEntry:"Assistant",skillsEntry:"Skills",globalNotificationsAction:"Notifications",globalNotificationsUnreadAria:"{count} unread notifications",globalNotificationsPanelTitle:"Notification Center",globalNotificationsPanelDescription:"Review items waiting for your decision, todo analysis results, follow-up updates, and failed verifications.",globalNotificationsEmpty:"There are no new global notifications right now.",globalNotificationsShowArchived:"Show archived notifications",globalNotificationsArchiveAction:"Archive",globalNotificationsRemoveArchiveAction:"Remove Archive",globalNotificationsArchiveFailed:"Failed to update notification archive state",globalNotificationKindWaitingUser:"Waiting for You",globalNotificationKindTodoAnalyzed:"Todo Analyzed",globalNotificationKindTodoAnalyzeFailed:"Todo Analysis Failed",globalNotificationKindFollowUpFailed:"Follow-up Failed",globalNotificationKindFollowUpCompleted:"Follow-up Completed",globalNotificationKindVerificationFailed:"Verification Failed",globalNotificationTodoAnalyzedTitle:"Todo analysis completed: {title}",globalNotificationTodoAnalyzeFailedTitle:"Todo analysis failed: {title}",globalNotificationFollowUpWaitingTitle:"Needs your decision: {title}",globalNotificationFollowUpFailedTitle:"Follow-up failed: {title}",globalNotificationFollowUpCompletedTitle:"Follow-up completed: {title}",globalNotificationVerificationFailedTitle:"Verification failed: {title}",globalNotificationVerificationFailedFallback:"The latest verification did not pass. Please review it soon.",searchEntry:"Search",workbenchModeTabsLabel:"Workbench Modes",workbenchModeCode:"Code",workbenchModeAffairs:"Affairs",workbenchModeCodeOpenInNewWindow:"Open Code in New Window",workbenchModeAffairsOpenInNewWindow:"Open Affairs in New Window",affairsSectionGroupPrimary:"Sections",affairsSectionGroupFavorites:"Pinned",affairsSectionGroupRecent:"Recent",affairsNavigationDescription:"This area collects sections, pinned items, and recent objects instead of scattering them.",affairsLibraryNav:"Documents",affairsLibraryNavSummary:"Start by landing document objects and related actions here.",affairsLibrarySummary:"Document objects stay in the main stage first, while the right side focuses on detail and assistance.",affairsWorkbenchNav:"Workbench",affairsWorkbenchSummary:"Bring todos, automations, and HTML tools into one unified workbench.",affairsWorkbenchSidebarTitle:"Workbench",affairsWorkbenchSidebarDescription:"Keep todos and automations together here first, then hand the full right side to the canvas. Right now it has {todoCount} todos and {automationCount} automations.",affairsWorkbenchSidebarGroupOverview:"Overview",affairsWorkbenchStageTitle:"Workbench",affairsWorkbenchStageDescription:"This area will grow into a full-canvas workbench. For now it keeps the overview, todo, and automation entry points together across {count} items.",affairsWorkbenchEmpty:"There is no workbench content to show yet.",affairsWorkbenchEmptyBody:"This area will later become the canvas for todos, automations, and HTML widgets. Right now it just collects the old entry points in one place.",affairsWorkbenchEyebrow:"Workbench preview",affairsWorkbenchDefaultTabTitle:"Default workbench",affairsWorkbenchDefaultTabShortTitle:"Default",affairsWorkbenchNewTabTitle:"Workbench {count}",affairsWorkbenchAddTabAction:"New tab",affairsWorkbenchRenameTabAction:"Rename tab",affairsWorkbenchDeleteTabAction:"Delete tab",affairsWorkbenchCanvasTitle:"Workbench canvas",affairsWorkbenchCanvasDescription:"This area is now the full workbench canvas. Tabs stay on top, while blocks below can be dragged to move and resized directly.",affairsWorkbenchCanvasEmptyTitle:"This tab does not have any widgets yet",affairsWorkbenchCanvasEmptyBody:"Add the first widget here. This area will become the formal resizable canvas next.",affairsWorkbenchWidgetHtmlAppHint:"Pin a workspace static HTML page to the canvas as a small app or tool.",affairsWorkbenchWidgetHtmlStatHint:"Keep an HTML metric page on the canvas as a focused stats block.",affairsWorkbenchWidgetHtmlEmbedHint:"Embed a controlled HTML page into the workbench canvas as a page block.",affairsWorkbenchWidgetOpenTodoAction:"Open todo list",affairsWorkbenchWidgetOpenAutomationAction:"Open automation list",affairsWorkbenchWidgetCountValue:"{count} items",affairsWorkbenchWidgetTeableBadge:"Teable",affairsWorkbenchHtmlWidgetBadge:"HTML",affairsWorkbenchHtmlAppDefaultTitle:"HTML app",affairsWorkbenchHtmlStatDefaultTitle:"HTML stats",affairsWorkbenchHtmlEmbedDefaultTitle:"HTML page",affairsWorkbenchCancelAction:"Cancel",affairsWorkbenchAddWidgetAction:"Add block",affairsWorkbenchResetLayoutAction:"Reset layout",affairsWorkbenchLockLayoutAction:"Lock layout",affairsWorkbenchUnlockLayoutAction:"Unlock layout",affairsWorkbenchWidgetTypeTodo:"Todo block",affairsWorkbenchWidgetTypeAutomation:"Automation block",affairsWorkbenchWidgetTypeTeable:"Teable block",affairsWorkbenchWidgetTypeHtml:"HTML block",affairsWorkbenchWidgetTypeHtmlApp:"HTML app block",affairsWorkbenchWidgetTypeHtmlStat:"HTML stats block",affairsWorkbenchWidgetTypeHtmlEmbed:"HTML page block",affairsWorkbenchHtmlVariantField:"Purpose preset",affairsWorkbenchHtmlVariantHelper:"This only sets the starting preset for creation. It mainly affects the default title, suggested size, and later display semantics.",affairsWorkbenchHtmlVariantApp:"App",affairsWorkbenchHtmlVariantStat:"Stats",affairsWorkbenchHtmlVariantEmbed:"Page",affairsWorkbenchWidgetTitleField:"Block title",affairsWorkbenchWidgetTitlePlaceholder:"Leave blank to use the default title",affairsWorkbenchHtmlSourceWorkspaceField:"Source workspace",affairsWorkbenchHtmlSourceWorkspaceHelper:"Choose the code workspace first, then pick an HTML file from that workspace. Preview and permissions will follow that workspace.",affairsWorkbenchHtmlSourceWorkspaceCurrentLibraryOption:"Current library",affairsWorkbenchHtmlSourceWorkspaceCurrentLibraryHelper:"Current library path: {path}. The file list below comes directly from this global library binding.",affairsWorkbenchHtmlSourceField:"HTML file path",affairsWorkbenchHtmlSourcePlaceholder:"For example: tools/report/index.html",affairsWorkbenchHtmlSourceSelectField:"HTML file",affairsWorkbenchHtmlSourceSelectPlaceholder:"Choose an HTML file",affairsWorkbenchHtmlSourceHelper:"Choose the source workspace first, then pick an HTML file from the list below.",affairsWorkbenchHtmlSourceListFailed:"Failed to load workspace HTML files",affairsWorkbenchHtmlSourceInvalid:"Only .html or .htm files are allowed here.",affairsWorkbenchHtmlSourceUnsupported:"This file cannot be used as a workbench HTML source right now.",affairsWorkbenchHtmlSourceMissing:"This block does not have a usable HTML source yet.",affairsWorkbenchHtmlSourceLoadFailed:"Failed to load the HTML page",affairsWorkbenchConfirmAddWidgetAction:"Add block",affairsWorkbenchAddWidgetFailed:"Failed to add the workbench block",affairsWorkbenchWidgetSizeGroup:"Block size",affairsWorkbenchWidgetSizeSmall:"S",affairsWorkbenchWidgetSizeMedium:"M",affairsWorkbenchWidgetSizeLarge:"L",affairsWorkbenchMoveWidgetBackwardAction:"Move earlier",affairsWorkbenchMoveWidgetForwardAction:"Move later",affairsWorkbenchDragWidgetAction:"Drag block",affairsWorkbenchResizeWidgetAction:"Resize block",affairsWorkbenchRemoveWidgetAction:"Remove block",affairsWorkbenchWidgetErrorTitle:"This block failed to load",affairsWorkbenchWidgetErrorBody:"Keep using the rest of the canvas first, then check this block's source or config.",affairsWorkbenchWidgetTodoViewLabel:"Todo block view",affairsWorkbenchWidgetCompactView:"Compact",affairsWorkbenchWidgetDetailView:"Detail",affairsWorkbenchWidgetAutomationViewLabel:"Automation block view",affairsWorkbenchWidgetAutomationListView:"Tasks",affairsWorkbenchWidgetAutomationRecentView:"Recent runs",affairsWorkbenchWidgetAutomationRunFallbackTitle:"Automation run",affairsWorkbenchOpenHtmlAction:"Open in new window",teableRuntimeDefaultBlockTitle:"Teable data",teableRuntimeTableField:"Teable table",teableRuntimeViewField:"Teable view",teableRuntimeCreateFormViewField:"Create record form view",teableRuntimeEditFormViewField:"Edit record form view",teableRuntimeViewGrid:"Grid",teableRuntimeViewForm:"Form",teableRuntimeViewCalendar:"Calendar",teableRuntimeViewKanban:"Kanban",teableRuntimeTablesLoadFailed:"Failed to load Teable tables",teableRuntimeViewsLoadFailed:"Failed to load Teable views",teableRuntimeTablesEmpty:"No table is available in the current Base. Create one in Teable first, or check the connection settings.",teableRuntimeViewsEmpty:"This table has no usable grid, form, calendar, or kanban view.",teableRuntimeFormViewsEmpty:"This table has no usable form view. Create a form view in Teable before adding this block.",teableRuntimeSelectionRequired:"Choose a Teable table and view first.",teableRuntimeBlockLoadFailed:"Failed to load Teable data",teableRuntimeConfigMissing:"This Teable block is missing table settings.",teableRuntimeRefreshAction:"Refresh records",teableRuntimeRecordsEmpty:"This view has no records yet.",teableRuntimeEmptyValue:"Empty",teableRuntimePrimaryFieldMissing:"This table has no usable primary field.",teableRuntimeRecordDrawerTitle:"Edit record",teableRuntimeRecordDrawerDescription:"Regular fields are editable. Formula, lookup, and rollup fields stay read-only and are calculated by Teable.",teableRuntimeRecordFieldsTitle:"Record fields",teableRuntimeReadonlyHint:"After saving, records are loaded again so Teable-calculated values are up to date.",teableRuntimeSaveRecordAction:"Save record",teableRuntimeDeleteRecordAction:"Delete record",teableRuntimeDeleteConfirm:"Delete this Teable record?",teableRuntimeSaveFailed:"Failed to save the record",teableRuntimeDeleteFailed:"Failed to delete the record",teableRuntimeCreateFailed:"Failed to create the record",teableRuntimeCreateRecordAction:"Create record",teableRuntimeCreateRecordModalTitle:"Create Teable record",teableRuntimeCreateRecordModalDescription:'Add a new record to "{table}".',teableRuntimeCreateRecordFieldsTitle:"Record details",teableRuntimeCreateRecordFieldsDescription:"Fields are shown using the order, visibility, and required settings that can be read from the Teable form view.",teableRuntimeNoWritableFields:"This table has no writable fields.",teableRuntimeRequiredMark:" *",teableRuntimeRequiredFieldMissing:'Fill in "{field}".',teableRuntimeUnsupportedEditor:"Editing is not supported yet. Current value: {value}",teableRuntimeLinkOptionsLoadFailed:"Failed to load linked records",teableRuntimeLinkFieldMissing:"This link field has no linked table setting.",teableRuntimeLinkEmptyOption:"None",teableRuntimeCalendarDateMissing:"Calendar view needs a date field. Choose one in the Teable view or block settings.",teableRuntimeKanbanGroupMissing:"Kanban view needs a single-select field. Choose a group field in the Teable view or block settings.",affairsShortcutRailTitle:"Quick apps",affairsShortcutRailDescription:"None",affairsShortcutRailEmpty:"None",affairsShortcutRailEditAction:"Edit",affairsShortcutRailDoneAction:"Done",affairsShortcutRailAddAction:"Add app",affairsShortcutRailTitleField:"App name",affairsShortcutRailTitlePlaceholder:"Leave blank to use the file name",affairsShortcutRailSourceSelectField:"File",affairsShortcutRailSourceSelectPlaceholder:"Choose a file",affairsShortcutRailSourceHelper:"Choose the source workspace first, then pick a file from the list below. Opening will reuse that workspace's preview and permissions.",affairsShortcutRailSourceListFailed:"Failed to load workspace files",affairsShortcutRailSourceInvalid:"Choose a file.",affairsShortcutRailSourceUnsupported:"This file cannot be opened as a quick app right now.",affairsShortcutRailSourcePickerTitle:"Choose a file",affairsShortcutRailSourcePickerDescription:"Pick a file from the workspace tree and save it as a quick app.",affairsShortcutRailSourcePickerCurrentField:"Current file",affairsShortcutRailSourcePickerCurrentEmpty:"No file selected yet",affairsShortcutRailSourcePickerTreeTitle:"Workspace files",affairsShortcutRailSourcePickerTreeEmpty:"No files available right now",affairsShortcutRailSourcePickerTreeEmptyDescription:"Expand a folder, then choose a file that can be previewed.",affairsShortcutRailSourcePickerRetryAction:"Reload",affairsShortcutRailSourcePickerConfirmAction:"Use this file",affairsShortcutRailConfirmAddAction:"Add to quick apps",affairsShortcutRailConfirmEditAction:"Save quick app",affairsShortcutRailAddedTitle:"Quick app added",affairsShortcutRailUpdatedTitle:"Quick app updated",affairsShortcutRailAddFailed:"Failed to add the quick app",affairsShortcutRailUpdateFailed:"Failed to update the quick app",affairsShortcutRailOpenAction:"Open",affairsShortcutRailOpenFailed:"Failed to open the quick app",affairsShortcutRailRemoveAction:"Remove",affairsShortcutRailExpandAction:"Expand",affairsShortcutRailCollapseAction:"Collapse",affairsShortcutRailLaunchAction:"Open quick app: {title}",affairsShortcutRailEditEntryAction:"Edit quick app: {title}",affairsShortcutRailPreviewEditDisabled:"Quick apps are preview-only right now and cannot be edited directly.",affairsWorkbenchDetailTitle:"Workbench overview",affairsWorkbenchDetailDescription:"This panel introduces the tab and canvas direction first. More detail will land here after the widget system is wired in.",affairsWorkbenchOverviewLabel:"Overview",affairsWorkbenchOverviewSummary:"Start by collecting {todoCount} todos and {automationCount} automations, then wire canvas blocks in later.",affairsWorkbenchAssistantContextTitle:"Current workbench todos",affairsWorkbenchAssistantContextSummary:"The current filter is {scopeLabel} with {count} todos. Focus on: {titles}",affairsWorkbenchAssistantContextSummaryCompact:"The current filter is {scopeLabel} with {count} todos.",affairsWorkbenchAssistantContextEmpty:"There are no todos in the current filter yet. Help me decide what to add next.",affairsWorkbenchStepTodoTitle:"Review todos first",affairsWorkbenchStepTodoDescription:"Todos are grouped into the workbench first and will later become draggable blocks.",affairsWorkbenchStepAutomationTitle:"Then review automations",affairsWorkbenchStepAutomationDescription:"Automation tasks keep the current list for now and will move into the canvas later.",affairsWorkbenchStepHtmlTitle:"Add HTML blocks later",affairsWorkbenchStepHtmlDescription:"Static HTML shortcuts and metric widgets will later be added through the same workbench block system.",affairsConversationNav:"Conversation",affairsConversationSummary:"This page gives lightweight and agent conversations a formal main stage instead of leaving them in the small right-side panel.",affairsConversationSidebarTitle:"Conversation",affairsConversationSidebarListTitle:"Sessions",affairsConversationSidebarGroupModes:"Create entry",affairsConversationStageTitle:"Affairs conversations",affairsConversationStageDescription:"Lock down the affairs conversation entry and creation flow first, then wire the actual runtimes in.",affairsConversationEmpty:"There is no affairs conversation yet. Start by creating one.",affairsConversationEmptyEyebrow:"Start",affairsConversationEmptyBody:"Create an affairs conversation here and continue working around the current library and affairs object.",affairsConversationEmptyCreateTitle:"Create",affairsConversationEmptyCreateBody:"Click New conversation, then choose lightweight mode or assistant mode to start.",affairsConversationEmptyModeTitle:"Choose the mode first",affairsConversationEmptyModeBody:"Lightweight mode is for quick Q&A and web search, while assistant mode is for full agent work.",affairsConversationEmptySelectedTitle:"Current creation draft",affairsConversationEmptyCompanionTitle:"Use the right side when needed",affairsConversationEmptyCompanionBody:"Open the right-side panels when you need object details, document content, or the affairs assistant.",affairsConversationEmptyTip:"When you're ready, start by creating an affairs conversation here.",affairsConversationEmptyDescription:"This page already uses the formal chat layout, but the first job is to lock down the entry, grouping, and provider choice.",affairsConversationEntryBadge:"Formal entry",affairsConversationCreateAction:"New conversation",affairsConversationCreateHint:"No conversations yet",affairsConversationSidebarLoadingAll:"Loading more conversations…",affairsConversationSidebarLoadingLightweight:"Loading lightweight conversations…",affairsConversationSidebarLoadingAgent:"Loading assistant conversations…",affairsConversationAgentSessionHint:"There is no reusable assistant session in this workspace yet.",affairsConversationLightweightCapabilityHint:"Lightweight mode only supports quick Q&A, web search, and light analysis without local tools.",affairsConversationLightweightLoadFailed:"Failed to load lightweight conversations",affairsConversationAgentLoadFailed:"Failed to load assistant conversations",affairsConversationCreateModalDescription:"Choose the mode first, then the provider. Lightweight mode only shows lightweight providers, while assistant mode reuses full CLI providers.",affairsConversationCreateModalDescriptionWithWorkspace:"Current library: {workspace}. Choose the mode first, then the provider.",affairsConversationLightweightTitle:"Lightweight mode",affairsConversationLightweightDescription:"These LLM providers are for quick Q&A, web search, and light analysis without the full local tool stack.",affairsConversationAssistantTitle:"Assistant mode",affairsConversationAssistantDescription:"This reuses the full assistant chain and AGENTS.md injection for agent work.",affairsConversationModePickerTitle:"Choose the mode first, then the provider",affairsConversationModePickerDescription:"Lightweight and agent describe capability level. Codex and Claude Code describe the provider. These must stay separate.",affairsConversationBoundaryTitle:"What this page locks down first",affairsConversationBoundaryDescription:"This step fixes the entry, shell, and boundaries first instead of pretending every runtime is already complete.",affairsConversationBoundaryLightweight:"Lightweight conversations only cover quick Q&A, web search, and light analysis without the full local tool stack.",affairsConversationBoundaryAgent:"Agent conversations will later reuse the full assistant chain around the current library and affairs object.",affairsConversationBoundaryProvider:"Lightweight and assistant are conversation modes, not provider aliases. Providers only describe the backend model source.",affairsInitSubmit:"Finish affairs setup",affairsInitSuccess:"Affairs mode is ready",affairsInitFailed:"Failed to initialize affairs mode",affairsInitPreviewRuleLabel:"Affairs assistant mode",affairsInitLibraryTitle:"Library setup",affairsInitLibraryDescription:"Decide whether affairs mode should connect the document library during the first setup.",affairsInitLibraryEnabledLabel:"Enable document library",affairsInitLibraryEnabledHint:"When enabled, the library will be bound and ready right after setup finishes.",affairsInitLibraryPathHint:"Set the library root here. You can still change it later in library settings.",affairsInitLibraryPathRequired:"Choose a library path before enabling the document library",affairsInitRouteGuardHint:"Affairs mode is not set up yet, so library, todo, and automation all return here first.",affairsInitRouteGuardSidebarEmpty:"Finish setup before the left-side sections appear.",affairsInitRouteGuardAuxiliaryEmpty:"Finish setup before the detail panel shows object content.",affairsConnectionCheckingTitle:"Checking affairs service",affairsConnectionCheckingDescription:"The frontend is checking whether Host is reachable before deciding whether affairs mode should open or show a connection problem.",affairsConnectionCheckingSidebarEmpty:"The left-side sections will load after the connection check finishes.",affairsConnectionCheckingAuxiliaryEmpty:"The detail panel will load after the connection check finishes.",affairsHostUnavailableTitle:"Affairs service is unavailable",affairsHostUnavailableDescription:"This is not an initialization problem. The frontend cannot reach Host right now, so affairs mode cannot load yet.",affairsHostUnavailableRetryAction:"Retry connection",affairsHostUnavailableRetryHint:"Retry only checks whether Host is reachable again. It does not change your setup state.",affairsHostUnavailableErrorTitle:"Connection error",affairsHostUnavailableSidebarEmpty:"The left-side sections cannot load until the connection is restored.",affairsHostUnavailableAuxiliaryEmpty:"The detail panel cannot load object content until the connection is restored.",affairsConversationKindLightweight:"Lightweight",affairsConversationKindAgent:"Agent",affairsConversationOptionLabel:"{kind} · {provider}",affairsConversationOptionSummaryLightweight:"Start a lightweight conversation with {provider} for quick Q&A, web search, and light analysis.",affairsConversationOptionSummaryAgent:"Start an assistant conversation with {provider} and later reuse the full assistant chain with current affairs context.",affairsTodoNav:"Todo",affairsTodoSummary:"This area will hold breakdowns, priorities, and follow-up later.",affairsAutomationNav:"Automation",affairsAutomationSummary:"This area will hold browser jobs, automations, and ops results later.",affairsPluginsNav:"Plugins",affairsPluginsSummary:"This area will hold affairs plugins and object-level extensions later.",affairsComingSoon:"Reserved for the next phase.",affairsLibraryTitle:"Document Library",affairsToolbarCount:"{count} items",affairsToolbarSummary:"Workspace: {workspaceName} · {count} objects",affairsToolbarExpand:"Expand Tools",affairsToolbarCollapse:"Collapse Tools",affairsToolbarPlaceholderNew:"New",affairsToolbarPlaceholderSearch:"Search",affairsToolbarPlaceholderFilter:"Filter",affairsLibraryResultTitle:"Objects",affairsLibraryEmpty:"There are no objects yet. Switch sections on the left or go back to code view first.",affairsSectionPlaceholderBadge:"Planned",affairsTodoPlaceholderTitle:"Todo is landing next",affairsTodoPlaceholderDescription:"Keep the official entry here first, then wire in breakdowns, tags, and execution tracking.",affairsAutomationPlaceholderTitle:"Automation is landing next",affairsAutomationPlaceholderDescription:"Keep the official entry here first, then wire in browser jobs, automation flows, and ops actions.",affairsPluginsPlaceholderTitle:"Plugins are landing next",affairsPluginsPlaceholderDescription:"Keep the official entry here first, then wire in affairs plugins and object-level extensions.",affairsDetailTitle:"Object Detail",affairsDetailEmpty:"Pick an object from the center first.",affairsObjectTypeDocument:"Document",affairsAssistantTitle:"Affairs Assistant",affairsAssistantDescription:"The assistant works around the current object instead of assuming a coding session.",affairsAssistantPlaceholder:"Keep working on {title} and help with docs, tags, todos, or browser tasks",affairsAssistantPlaceholderEmpty:"Pick an object first, then ask the assistant to work on it.",affairsAssistantContextFallback:"No additional summary is available yet.",affairsAssistantPromptPreamble:`Current affairs object: {title}
46
+ Summary: {summary}
47
+ Source: {sourceRef}
48
+ Work around this object for document cleanup, tags, todos, browser tasks, and export suggestions.`,affairsAssistantPromptPreambleEmpty:"There is no selected affairs object yet. Help decide what to inspect first and suggest the next step.",affairsDocumentSummaryTemplate:"Placeholder document object derived from session {sessionTitle}. This will be replaced by the formal document index later.",affairsSidebarMenuLabel:"Affairs sections",affairsLibrarySidebarTitle:"Favorites and tags",affairsLibrarySidebarDescription:"This workspace currently shows {count} document objects, with {favorites} favorites and {tags} tags collected here.",affairsLibraryAllFilter:"All documents",affairsLibraryAllFilterSummary:"Browse every document object in this workspace.",affairsLibraryFavoritesSummary:"Start from the documents you already starred.",affairsLibraryFavoritesEntry:"All pinned",affairsLibraryTagSummary:"Filter the current document list by tag.",affairsLibraryFoldersEntry:"Folders",affairsLibraryFoldersSummary:"Browse the current library by folder.",affairsLibraryTagsEntry:"Tags",affairsLibraryTagsSummary:"Browse the current library by tag.",affairsLibraryFolderNodeSummary:"Filter the current document list by folder.",affairsLibraryTagNodeSummary:"Filter the current document list by tag.",affairsLibraryRefreshAction:"Refresh library",affairsLibraryRefreshQueued:"Library refresh started",affairsLibraryRefreshQueuedDescription:"The app is rescanning documents in the background and will update folders, tags, and list results.",affairsLibraryRefreshFailed:"Failed to refresh the library",affairsLibraryBindingTitle:"Bind a document library first",affairsLibraryBindingDescription:"Pick a root directory for this affairs view. The left sidebar, favorites, tags, and the middle document list will all come from it.",affairsLibraryBindingFieldLabel:"Library path",affairsLibraryBindingFieldPlaceholder:"/Users/you/Documents/Knowledge",affairsLibraryBindingSubmitAction:"Save path",affairsLibraryBindingBrowseAction:"Choose folder",affairsLibraryBindingPickerTitle:"Choose a document library folder",affairsLibraryBindingPickerDescription:"Pick a real directory as the library root. The affairs view will show folders, favorites, tags, and documents from it.",affairsLibraryBindingUseThisDirectory:"Use this folder",affairsLibraryEnableLabel:"Enable library",affairsLibraryEnableHint:"When disabled, the built-in indexer for this workspace stops running until you turn it back on.",affairsLibraryEnableAction:"Enable",affairsLibraryDisableAction:"Disable",affairsLibraryEnabledState:"Enabled",affairsLibraryDisabledState:"Disabled",affairsLibraryEnableSaveFailed:"Failed to update the library switch",affairsLibraryDisabledSummary:"The library is currently disabled. Turn it back on before the built-in indexer can resume.",affairsLibraryConfigTitle:"Library settings",affairsLibraryConfigDescription:"Set the local mirror path, allowed file types, and any hidden paths that really need to be included.",affairsLibraryMirrorRootLabel:"Local mirror path",affairsLibraryMirrorRootPlaceholder:"/Users/you/SynologyDrive",affairsLibraryMirrorRootBrowseAction:"Choose local folder",affairsLibraryMirrorRootDesktopOnlyHint:"Directory picker only works in the desktop app. On the web, enter the path manually.",affairsLibraryIncludedHiddenPathsLabel:"Extra hidden paths to include",affairsLibraryIncludedHiddenPathsHint:"Dot-prefixed files and folders are ignored by default. Add relative paths here only when you really want them indexed, for example .obsidian or notes/.draft.md.",affairsLibraryIncludedHiddenPathsPlaceholder:`.obsidian
49
+ notes/.draft.md`,affairsLibraryAllowedExtensionsLabel:"Indexed file types",affairsLibraryAllowedExtensionsPlaceholder:".md, .pdf, .docx",affairsLibraryAllowedExtensionsHint:"Separate multiple suffixes with commas or spaces. This is only a whitelist. The indexer still decides what it can really parse.",affairsLibraryAllowedExtensionsCustomPlaceholder:"Add a custom suffix, for example .pages or .epub",affairsLibraryAllowedExtensionsCustomAddAction:"Add suffix",affairsLibraryAllowedExtensionsCustomInvalid:"Enter a valid suffix such as .pages.",affairsLibraryCustomExtensionBadge:"Custom",affairsLibrarySettingsAction:"Open library settings",affairsLibraryConfigSaveAction:"Save settings",affairsLibraryFolderOpenBehaviorLabel:"Folder open behavior",affairsLibraryFolderOpenBehaviorHint:"Folders open on double click by default. Switch to single click if you want faster navigation.",affairsLibraryFolderOpenBehaviorSwitchLabel:"Open folders on single click",affairsLibraryFolderOpenBehaviorSingle:"Open on single click",affairsLibraryFolderOpenBehaviorDouble:"Open on double click",affairsLibraryConfigSaveFailed:"Failed to save the library settings",affairsLibraryConfigSaved:"Library settings saved",affairsLibraryConfigAppliedSuccess:"The new mirror path and whitelist have been applied to the indexer.",affairsLibraryConfigAppliedRunning:"Settings saved. The indexer is applying the new configuration.",affairsLibraryConfigAppliedFailed:"Settings saved, but the indexer failed to apply the new configuration.",affairsLibraryOpenLocalFileAction:"Open local file",affairsLibraryOpenWithLocalAppAction:"Open with local application",affairsLibraryOpenLocalFileFailed:"Failed to open the local file",affairsLibraryRevealLocalFileAction:"Reveal in Finder",affairsLibraryRevealLocalFileFailed:"Failed to reveal the file in Finder",affairsLibraryLocateFolderAction:"Go to folder",affairsLibraryContextLocate:"Locate",affairsLibraryMirrorRootEmpty:"No local mirror path is configured yet",affairsLibraryContextMenuLabel:"Document library action menu",affairsLibraryContextPreview:"Preview",affairsLibraryContextOpen:"Open",affairsLibraryContextDownload:"Download",affairsLibraryContextNew:"New",affairsLibraryContextNewDirectory:"Folder",affairsLibraryContextNewMarkdown:"Markdown file",affairsLibraryContextNewText:"Text file",affairsLibraryContextNewCustomFile:"Custom file",affairsLibraryContextRefresh:"Refresh",affairsLibraryContextCopy:"Copy",affairsLibraryContextCopyFile:"File",affairsLibraryContextCopyFileName:"File name",affairsLibraryContextCopyAbsolutePath:"Absolute path",affairsLibraryContextCopyRelativePath:"Relative path",affairsLibraryContextCut:"Cut",affairsLibraryContextPaste:"Paste",affairsLibraryContextDelete:"Delete",affairsLibraryContextTags:"Tags",affairsLibraryContextProperties:"Properties",affairsLibraryRecentTagsEmpty:"No recent tags available",affairsLibraryActionFailed:"Document action failed",affairsLibraryDownloadSuccess:"Downloaded {name}",affairsLibraryDownloadFailed:"Download failed",affairsLibraryCopyFileSuccess:"File path copied",affairsLibraryCopyFileNameSuccess:"File name copied",affairsLibraryCopyAbsolutePathSuccess:"Absolute path copied",affairsLibraryCopyRelativePathSuccess:"Relative path copied",affairsLibraryCopyFailed:"Copy failed",affairsLibraryCutSuccess:"Cut {name}",affairsLibraryPasteSuccess:"Pasted {name}",affairsLibraryDeleteSuccess:"Deleted {name}",affairsLibraryDeleteConfirmTitle:"Confirm deletion",affairsLibraryDeleteConfirmDescription:"Deletion happens immediately and cannot be undone here.",affairsLibraryDeleteDocumentConfirm:'Are you sure you want to delete the file "{path}"?',affairsLibraryDeleteFolderConfirm:'Are you sure you want to delete the folder "{path}"? Everything inside it will be removed too.',affairsLibraryDeleteConfirmAction:"Delete",affairsLibraryDeleteSubmitting:"Deleting...",affairsLibraryCreateModalTitle:"Create item",affairsLibraryCreateModalDescription:"This will be created in {path}. Give it a clear name first.",affairsLibraryCreateNameLabel:"Name",affairsLibraryCreateNamePlaceholder:"Enter a name",affairsLibraryCreateTypeHint:"You are about to create: {type}",affairsLibraryCreateConfirmAction:"Create",affairsLibraryCreateFailed:"Failed to create the item",affairsLibraryCreateSuccess:"Created {name}",affairsLibraryCreateNameRequired:"Enter a name first",affairsLibraryCreateDirectoryDefaultName:"New Folder",affairsLibraryCreateMarkdownDefaultName:"Untitled.md",affairsLibraryCreateTextDefaultName:"Untitled.txt",affairsLibraryCreateCustomDefaultName:"Untitled file",affairsLibraryCreateMarkdownHeading:"Untitled",affairsLibraryAbsolutePathMissing:"This library item has no local path to open",affairsLibraryUntitledFileName:"Untitled file",affairsFavoriteAddAction:"Add to favorites",affairsFavoriteRemoveAction:"Remove from favorites",affairsFavoriteAdded:"Added to favorites",affairsFavoriteRemoved:"Removed from favorites",affairsLibraryBrowseModeLabel:"Library browse mode",affairsLibraryBrowseModeFolder:"Folders",affairsLibraryBrowseModeTag:"Tags",affairsLibrarySortLabel:"Sort order",affairsLibrarySortRecent:"Recent",affairsLibrarySortName:"Name",affairsLibrarySortType:"Type",affairsLibrarySortSize:"Size",affairsLibrarySortCreatedAt:"Date Added",affairsLibraryViewModeLabel:"Library view mode",affairsLibraryViewModeGrid:"Grid",affairsLibraryViewModeList:"List",affairsLibraryTagTreeTitle:"Tag Tree",affairsLibraryTagTreeShowMore:"Show More Tags",affairsLibraryTagTreeShowLess:"Show Fewer Tags",affairsLibraryTagTreeReset:"Reset Filters",affairsLibraryTagSearchAction:"Find tag",affairsLibraryTagSearchInputLabel:"Find tag",affairsLibraryTagSearchPlaceholder:"Enter keyword or pinyin",affairsLibraryTagSearchResultsLabel:"Tag search results",affairsLibraryTagSearchEmpty:"No matching tags",affairsDocumentTagsSectionTitle:"Document tags",affairsFolderTagsSectionTitle:"Folder tags",affairsDocumentTagSourcesTitle:"Tag sources",affairsDocumentTagSourcesEmpty:"This file has no explainable tag source yet.",affairsTagSourceManualDocument:"Manual",affairsTagSourceFolderBinding:"Folder",affairsTagSourceRuleMatch:"Smart match",affairsTagSourceSystemDerived:"System",affairsTagDetailsLoading:"Loading tag details…",affairsDocumentTagAddLabel:"Add document tag",affairsDocumentTagSearchPlaceholder:"Type a tag name or path",affairsDocumentTagSuggestionsLabel:"Document tags you can add",affairsDocumentTagNoMatch:"No matching tag can be added",affairsDocumentTagsEmpty:"No manual tags yet.",affairsDocumentTagRemoveAction:"Remove tag {tag}",affairsFolderTagAddLabel:"Add folder tag",affairsFolderTagSuggestionsLabel:"Tags you can assign to this folder",affairsFolderTagsEmpty:"This folder has no manual tags yet.",affairsTagQuickSearchPlaceholder:"Type a tag name or path, then press Enter to assign",affairsTagQuickCreateAction:"Create and assign “{tag}”",affairsTagQuickCreateHint:"If this tag does not exist yet, it will be created immediately.",affairsTagQuickAlreadyAssigned:"This tag is already assigned.",affairsTagQuickAssignModalTitle:"Assign tags",affairsTagQuickAssignDocumentDescription:"Assign tags to “{name}”. Existing tags match immediately. Missing tags are created on the spot.",affairsTagQuickAssignFolderDescription:"Assign tags to “{name}”. The tag will apply to this folder and future files added under it.",affairsFolderTagTaskShortTitle:"{operation} tags",affairsFolderTagTaskTitle:"{operation} tag progress",affairsFolderTagTaskButtonLabel:"{operation} tags for {folder}: {status}, {percent}% complete",affairsFolderTagTaskFolderLabel:"Current folder",affairsFolderTagTaskPhaseLabel:"Current stage",affairsFolderTagTaskProgressLabel:"Processed documents",affairsFolderTagTaskProgressCount:"{current} / {total}",affairsFolderTagTaskPreparing:"Preparing",affairsFolderTagTaskSubmitting:"Submitting {operation} tag request",affairsFolderTagTaskSubmittingDetail:"The request has been sent. Waiting for the task to start.",affairsFolderTagTaskOperationAttach:"Add",affairsFolderTagTaskOperationRemove:"Remove",affairsFolderTagTaskOperationUpdate:"Update",affairsFolderTagTaskStatusQueued:"Queued",affairsFolderTagTaskStatusRunning:"Running",affairsFolderTagTaskStatusSucceeded:"Completed",affairsFolderTagTaskStatusFailed:"Failed",affairsFolderTagTaskStatusCancelled:"Cancelled",affairsFolderTagTaskStatusTimeout:"Timed out",affairsFolderTagTaskPhasePrepare:"Preparing task",affairsFolderTagTaskPhaseRecompute:"Applying tags",affairsFolderTagTaskPhaseWrite:"Writing results",affairsFolderTagTaskPhaseExport:"Refreshing results",affairsFolderTagTaskPhaseFinished:"Finished",affairsTagTaskHistoryTitle:"Recent tag tasks",affairsTagTaskHistoryShortTitle:"Tag tasks",affairsTagTaskHistoryButtonLabel:"Recent {count} tag tasks. Current: {operation} tags for {target}: {status}, {percent}% complete",affairsTagTaskHistoryCount:"Recent {count}",affairsTagTaskHistoryRunningCount:"{count} active",affairsTagTaskDocumentLabel:"Current document",affairsTagManagerAction:"Manage tags",affairsTagManagerTitle:"Tag management",affairsTagManagerDescription:"Use this panel to organize the tag tree. Pick a tag on the left, edit it on the right, and add rules for tags that should match automatically.",affairsTagManagerSectionTitle:"Tag tree and rules",affairsTagManagerSectionDescription:"Pick a tag on the left, then create, edit, or delete it on the right.",affairsTagBatchSectionTitle:"Bulk edit and bulk delete",affairsTagBatchSectionDescription:"Select the tags you want to handle together, then move, enable, disable, or delete them in one pass.",affairsTagBatchEmpty:"No tags selected yet",affairsTagBatchEmptyDescription:"Check two or more tags on the left to manage them together here.",affairsTagBatchSelectionSummary:"{count} tags selected",affairsTagBatchCheckboxLabel:"Select tag {tag}",affairsTagBatchSelectAllAction:"Select all",affairsTagBatchClearSelectionAction:"Clear selection",affairsTagBatchParentLabel:"Move all to parent tag",affairsTagBatchParentKeepOption:"Keep current parents",affairsTagBatchStatusLabel:"Unified status",affairsTagBatchStatusKeepOption:"Keep current status",affairsTagBatchStatusActiveOption:"Enable all",affairsTagBatchStatusDisabledOption:"Disable all",affairsTagBatchUpdateAction:"Save bulk changes",affairsTagBatchDeleteAction:"Delete selected",affairsTagBatchHint:"Bulk edits move all selected tags under the same parent and unify their status. Their original parent-child structure is not preserved automatically.",affairsTagRecoverySectionTitle:"Rewrite document tag results",affairsTagRecoverySectionDescription:"Only rerun this when document tag results have not caught up with the latest tag tree, folder tags, or smart rules.",affairsTagRecoveryStatusLabel:"Current status",affairsTagRecoveryStatusIdle:"Not started",affairsTagRecoveryPhaseIdle:"Waiting to start",affairsTagRecoveryProgressIdle:"Nothing has been processed yet",affairsTagRecoveryAction:"Recover document tag results",affairsTagRecoveryRunningAction:"Recovering document tag results…",affairsTagRecoveryHint:"This reruns manual tags, folder tags, smart tags, and system tags to write tag results back to documents.",affairsTagRecoveryRunningHint:"The recovery task is running. Document tag links will recover automatically when it finishes.",affairsTagRecoveryStartedDescription:"The recovery task has started. Document tag results will recover as it finishes.",affairsTagRecoveryQueuedDescription:"A recovery task is already queued or running. Wait for that one to finish.",affairsTagRecoveryFailed:"Failed to start document tag recovery. Please try again later.",affairsTagRecoveryIdentityBindingLabel:"Identity bindings",affairsTagRecoveryLegacyBindingLabel:"Legacy path data",affairsTagRecoveryLegacyFallbackLabel:"Still on compatibility layer",affairsTagRecoveryCompatibilityHint:"The primary path now reads identity bindings first. There are still {count} legacy path bindings left only in the compatibility layer across {documents} documents, and they will be phased out gradually.",affairsTagRecoveryCleanHint:"There is no compatibility-only legacy data right now. Rerun this only when document tag results look wrong.",affairsTagRecoveryPendingHint:"{documents} documents are still using compatibility-only legacy data. Use the button below when you want to rewrite all document tag results together.",affairsTagBatchUpdateNoop:"Choose at least one batch change first. Otherwise nothing will change.",affairsTagBatchUpdateSuccess:"Bulk update completed",affairsTagBatchUpdateSuccessDescription:"Updated {count} tags.",affairsTagBatchUpdateFailed:"Bulk update failed",affairsTagBatchDeleteConfirm:"Delete these {count} tags? If a parent tag is included, its child tags will be removed too.",affairsTagBatchDeleteSuccess:"Bulk delete completed",affairsTagBatchDeleteSuccessDescription:"Deleted {count} tags.",affairsTagBatchDeleteFailed:"Bulk delete failed",affairsTagCreateAction:"New tag",affairsTagTreeSectionTitle:"Tag tree",affairsTagTreeSectionDescription:"Only manually managed business tags are shown here.",affairsTagTreeEmpty:"No business tags yet",affairsTagTreeEmptyDescription:"Start with one root tag, then split it into child tags later.",affairsTagTreeDocumentCount:"{count} documents",affairsTagCreateRootAction:"New root tag",affairsTagCreateChildAction:"New child tag",affairsTagEditorCreateRootTitle:"Create root tag",affairsTagEditorCreateRootDescription:"Create the top-level category first, then refine it layer by layer.",affairsTagEditorCreateChildTitle:"Create child tag",affairsTagEditorCreateChildDescription:"This new tag will be created under “{tag}”.",affairsTagEditorEditTitle:"Edit tag",affairsTagEditorEditDescription:"Update the current tag's name and place in the tree here. The document count also lives here, and smart rules are edited in the next section.",affairsTagEditorPathLabel:"Tag path",affairsTagEditorDocumentCountLabel:"Matched documents",affairsTagSmartRulesSectionTitle:"Smart tag rules",affairsTagSmartRulesSectionDescription:"Rules live on the current tag. When a file matches them, the tag is assigned automatically.",affairsTagSmartRulesEmpty:"No smart rules yet",affairsTagSmartRulesEmptyDescription:"Add rules here if this tag should be assigned automatically.",affairsTagSmartRuleAddAction:"Add rule",affairsTagSmartRuleRelationLabel:"Relation",affairsTagSmartRuleRelationAnd:"AND",affairsTagSmartRuleRelationOr:"OR",affairsTagSmartRuleRelationNot:"NOT",affairsTagSmartRuleTypeLabel:"Rule type",affairsTagSmartRuleTypeFileNameContains:"File name contains text",affairsTagSmartRuleTypeFileContentContains:"File content contains text",affairsTagSmartRuleTypeFileExtensionIn:"File type matches",affairsTagSmartRuleTypeModifiedTimeBetween:"Modified time range",affairsTagSmartRuleTypeDocumentPathInFolder:"Inside a folder and its subfolders",affairsTagSmartRuleKeywordLabel:"Keyword",affairsTagSmartRuleKeywordPlaceholder:"For example: contract, quote, payment",affairsTagSmartRuleExtensionsLabel:"File types",affairsTagSmartRuleExtensionsPlaceholder:"For example: pdf, docx, xlsx",affairsTagSmartRuleModifiedStartLabel:"Start time",affairsTagSmartRuleModifiedEndLabel:"End time",affairsTagSmartRuleFolderPathLabel:"Folder path",affairsTagSmartRuleFolderPathPlaceholder:"For example: presales/proposals, or . for root",affairsTagSmartRuleEnabledLabel:"Enable this rule",affairsTagSmartRuleRemoveAction:"Remove rule",affairsTagSmartRuleOrderHint:"Rule {index}",affairsTagNameLabel:"Tag name",affairsTagNamePlaceholder:"For example: Customer contracts",affairsTagParentLabel:"Parent tag",affairsTagParentRootOption:"Place at the tag tree root",affairsTagSaveAction:"Save tag",affairsTagSaveFailed:"Failed to save the tag",affairsTagSaveSuccess:"Tag saved",affairsTagSaveSuccessDescription:"The tag tree was updated.",affairsTagCreateSubmitAction:"Create tag",affairsTagUpdateSubmitAction:"Save changes",affairsTagResetFormAction:"Reset form",affairsTagRevertAction:"Revert",affairsTagCloseAction:"Close",affairsTagDangerZoneTitle:"Delete tag",affairsTagDangerZoneDescription:"Deleting this tag will also remove all of its child tags.",affairsTagDeleteAction:"Delete this tag",affairsTagDeleteConfirm:"Delete “{tag}”? All child tags under it will also be removed.",affairsTagDeleteFailed:"Failed to delete the tag",affairsTagDeleteSuccess:"Tag deleted",affairsTagDeleteSuccessDescription:"The tag tree was updated and document tag results will refresh.",affairsFinderColumnName:"Name",affairsFinderColumnSize:"Size",affairsFinderColumnUpdatedAt:"Date Modified",affairsFinderColumnType:"Kind",affairsFinderColumnCreatedAt:"Date Added",affairsFinderSortAction:"Sort by {column}",affairsFinderSortCurrent:"{column}, currently sorted {direction}",affairsFinderSortDirectionAsc:"ascending",affairsFinderSortDirectionDesc:"descending",affairsFinderResizeColumn:"Resize {column} column",affairsFinderDateToday:"Today",affairsFinderDateYesterday:"Yesterday",affairsFinderKindFolder:"Folder",affairsFinderKindFile:"File",affairsFinderKindMarkdown:"Markdown document",affairsFinderKindText:"Text document",affairsFinderKindHtml:"HTML document",affairsFinderKindJson:"JSON data",affairsFinderKindXml:"XML document",affairsFinderKindYaml:"YAML config",affairsFinderKindImage:"Image",affairsFinderKindPdf:"PDF document",affairsFinderKindWord:"Word document",affairsFinderKindExcel:"Excel spreadsheet",affairsFinderKindPowerPoint:"PowerPoint presentation",affairsFinderKindArchive:"Archive",affairsFinderKindCode:"Code file",affairsFinderKindSql:"SQL script",affairsFinderKindDatabase:"Database file",affairsFinderKindAudio:"Audio file",affairsFinderKindVideo:"Video file",affairsFinderKindDesign:"Design file",affairsFinderKindFont:"Font file",affairsFinderKindEbook:"E-book",affairsFinderKindData:"Data file",affairsLibraryTagMultiTitle:"Combined Filters",affairsLibraryTagMultiRootType:"Multiple tags",affairsLibraryBindingSaveFailed:"Failed to save the document library path",affairsLibraryStatusIdle:"Not ready",affairsLibraryStatusFresh:"Ready",affairsLibraryStatusStale:"Needs refresh",affairsLibraryStatusQueued:"Queued",affairsLibraryStatusRunning:"Refreshing",affairsLibraryStatusQueueTimeout:"Queue timeout",affairsLibraryStatusCooldown:"Just refreshed",affairsLibraryStatusFailed:"Refresh failed",affairsLibraryStatusIndicatorAction:"Document library index status: {status}",affairsLibraryStatusIndicatorProgress:"Scanned {scanned}",affairsLibraryStatusPopoverTitle:"Document library indexer status",affairsLibraryStatusSummaryTotalLabel:"Indexed total",affairsLibraryStatusSummaryScannedLabel:"Current count",affairsLibraryStatusSummaryUpdatedLabel:"Updated",affairsLibraryStatusSummaryIssueLabel:"Issues",affairsLibraryStatusPrimaryTitle:"Current overview",affairsLibraryStatusTechnicalToggle:"Technical details",affairsLibraryStatusSectionOverviewTitle:"Run details",affairsLibraryStatusSectionTimelineTitle:"Timeline",affairsLibraryStatusSectionProgressTitle:"Scan details",affairsLibraryStatusSectionDirectoryTitle:"Directory result",affairsLibraryStatusSectionWorkerTitle:"Background worker",affairsLibraryStatusCurrentLabel:"Current status",affairsLibraryStatusLastRequestedAtLabel:"Last requested",affairsLibraryStatusLastStartedAtLabel:"Last started",affairsLibraryStatusLastCompletedAtLabel:"Last completed",affairsLibraryStatusLastFailedAtLabel:"Last failed",affairsLibraryStatusNextAllowedAtLabel:"Next allowed refresh",affairsLibraryStatusRunningTaskIdLabel:"Running task",affairsLibraryStatusRunningStageLabel:"Current stage",affairsLibraryStatusProgressScannedLabel:"Files scanned",affairsLibraryStatusProgressIndexedLabel:"Updated this run",affairsLibraryStatusProgressUnchangedLabel:"Unchanged skipped",affairsLibraryStatusProgressSkippedLabel:"Parser skipped",affairsLibraryStatusProgressFailedLabel:"Failed",affairsLibraryStatusProgressTotalLabel:"Estimated total",affairsLibraryStatusDirtyReasonsLabel:"Pending reasons",affairsLibraryStatusErrorSummaryLabel:"Failure summary",affairsLibraryStatusStageQueued:"Queued",affairsLibraryStatusStageInit:"Preparing index environment",affairsLibraryStatusStageApplyConfig:"Applying config",affairsLibraryStatusStageIndex:"Updating index",affairsLibraryStatusStageIncrementalIndex:"Incremental index",affairsLibraryStatusStageRecomputeTags:"Recomputing tags",affairsLibraryStatusStageExport:"Exporting results",affairsLibraryStatusStageExportMetaDetail:"Exporting folders and documents",affairsLibraryStatusStageExportTag:"Exporting tag results",affairsLibraryStatusStageExportRelation:"Exporting document relations",affairsLibraryStatusStageExportSearch:"Building search index",affairsLibraryStatusStageSqlite:"Writing SQLite metadata",affairsLibraryDirectoryStatusPathLabel:"Current directory",affairsLibraryDirectoryStatusRootPath:"Root directory",affairsLibraryDirectoryStatusStateLabel:"Directory refresh status",affairsLibraryDirectoryStatusSourceLabel:"Directory result source",affairsLibraryDirectoryStatusLastRequestedAtLabel:"Directory last requested",affairsLibraryDirectoryStatusLastCompletedAtLabel:"Directory last completed",affairsLibraryDirectoryStatusLastFailedAtLabel:"Directory last failed",affairsLibraryDirectoryStatusRunningTaskIdLabel:"Directory task",affairsLibraryDirectoryStatusErrorSummaryLabel:"Directory failure summary",affairsLibraryDirectoryStatusGeneratedAtLabel:"Result generated",affairsLibraryDirectoryStatusFilesystemObservedAtLabel:"Filesystem observed",affairsLibraryDirectoryStatusStaleReasonLabel:"Fallback reason",affairsLibraryDirectoryStatusIdle:"Idle",affairsLibraryDirectoryStatusQueued:"Queued",affairsLibraryDirectoryStatusRunning:"Refreshing",affairsLibraryDirectoryStatusQueueTimeout:"Queue timeout",affairsLibraryDirectoryStatusFresh:"Updated",affairsLibraryDirectoryStatusFailed:"Refresh failed",affairsLibraryDirectoryStatusSourceLive:"Live directory",affairsLibraryDirectoryStatusSourceSnapshot:"Export snapshot",affairsLibraryDirectoryStatusSourceMixed:"Live + snapshot",affairsLibraryDirectoryStatusSourceStaleFallback:"Stale fallback",affairsLibraryWorkerHealthStateLabel:"Worker state",affairsLibraryWorkerHealthPidLabel:"Worker PID",affairsLibraryWorkerHealthLocalInflightLabel:"Local inflight",affairsLibraryWorkerHealthRemoteInflightLabel:"Remote inflight",affairsLibraryWorkerHealthStartedAtLabel:"Worker started",affairsLibraryWorkerHealthHeartbeatLabel:"Last heartbeat",affairsLibraryWorkerHealthLastStartedAtLabel:"Last task started",affairsLibraryWorkerHealthLastCompletedAtLabel:"Last task completed",affairsLibraryWorkerHealthLastFailedAtLabel:"Last task failed",affairsLibraryWorkerHealthSoftCancelAtLabel:"Last soft cancel",affairsLibraryWorkerHealthHardKillAtLabel:"Last hard kill",affairsLibraryWorkerHealthLastExitAtLabel:"Last exit",affairsLibraryWorkerHealthTerminationReasonLabel:"Last termination reason",affairsLibraryWorkerHealthStateIdle:"Idle",affairsLibraryWorkerHealthStateRunning:"Running",affairsLibraryWorkerHealthStateTerminating:"Terminating",affairsLibraryWorkerHealthStateRecycled:"Recycled",affairsLibraryEmptyRunning:"The document library is refreshing. Check back in a moment.",affairsAssistantWaitingDocument:"The library is bound, but there is no selectable document yet. Refresh it or choose another directory.",affairsSidebarGroupOverview:"Overview",affairsSidebarGroupTags:"Tags",affairsFavoriteBadge:"Pinned",affairsLibraryStageDescription:"The document list is currently driven by {count} favorite/tag entries.",affairsTodoSidebarTitle:"Todo sources",affairsTodoSidebarDescription:"This area merges manual todos, inbox items, and follow-up tasks. {count} items in total.",affairsTodoAllFilter:"All todos",affairsTodoAllFilterSummary:"See every unfinished item in the current workspace together.",affairsTodoInboxFilter:"Inbox items",affairsTodoInboxSummary:"Items from the assistant inbox that still need to be processed.",affairsTodoFollowUpFilter:"Session follow-up",affairsTodoFollowUpSummary:"Unfinished follow-up tasks recognized from coding sessions.",affairsTodoSidebarGroupSources:"Source groups",affairsTodoStageTitle:"Todo list",affairsTodoStageDescription:"The main list is currently driven by {count} todo sources.",affairsTodoEmpty:"There are no pending todos or follow-up tasks right now.",affairsTodoStatusPending:"Pending",affairsTodoStatusInProgress:"In progress",affairsTodoStatusClosed:"Closed",affairsTodoStatusWaitingUser:"Waiting for you",affairsTodoStatusCompleted:"Completed",affairsTodoStatusFailed:"Failed",affairsTodoStatusCancelled:"Cancelled",affairsTodoStatusActive:"Active",affairsTodoDetailStatus:"Status",affairsTodoDetailSource:"Source session",affairsTodoDetailNotes:"Notes",affairsTodoDetailTotal:"Current result",affairsTodoDetailTotalValue:"{count} items",affairsAutomationSidebarTitle:"Automation tasks",affairsAutomationSidebarDescription:"This area directly reuses assistant automation tasks. {count} items total.",affairsAutomationStageTitle:"Automation tasks",affairsAutomationStageDescription:"There are currently {count} automation tasks available here.",affairsAutomationEmpty:"There are no automation tasks to show right now.",affairsAutomationUntitled:"Untitled automation",affairsAutomationPromptFallback:"This automation does not have a readable summary yet.",affairsAutomationStatusActive:"Running",affairsAutomationStatusPaused:"Paused",affairsAutomationStatusCompleted:"Completed",affairsAutomationStatusCancelled:"Cancelled",affairsAutomationStatusFailed:"Failed",affairsAutomationTriggerOnce:"Run once",affairsAutomationTriggerInterval:"Interval",affairsAutomationTriggerCron:"Schedule",affairsAutomationTriggerCondition:"Condition",affairsAutomationTargetFallback:"No target session is bound yet",affairsAutomationDetailTrigger:"Trigger",affairsAutomationDetailTarget:"Target session",affairsAutomationDetailStatus:"Status",affairsAutomationRunsTitle:"Recent runs",affairsAutomationRunsDescription:"Review how this automation has been running recently.",affairsAutomationRunsEmpty:"There are no recent runs yet.",affairsAutomationRunsFallback:"This run did not produce a readable summary.",affairsAutomationLastRunSummary:"Last run: {summary}",affairsAutomationSidebarGroupTasks:"Task list",affairsAutomationRunsStatusQueued:"Queued",affairsAutomationRunsStatusRunning:"Running",affairsAutomationRunsStatusFinished:"Finished",affairsAutomationRunsStatusFailed:"Failed",affairsAutomationRunsStatusCancelled:"Cancelled",affairsAutomationRunsStatusSkipped:"Skipped",affairsAuxiliaryTabsLabel:"Affairs auxiliary tabs",affairsDetailMetaPath:"Document path",affairsDetailMetaTags:"Tags",butlerInitTitle:"Initialize Assistant",butlerInitDescription:"Set the Butler name, provider, and work style first. The dedicated workspace and first AGENTS.md will be created automatically.",butlerInitPreviewTitle:"Live Preview",butlerInitPreviewDescription:"These choices directly shape the first rule set, so show the result instead of dumping a plain form.",butlerInitBasicsTitle:"Basics",butlerInitBasicsDescription:"Lock in the name, provider, and rule storage first so initialization does not become config soup.",butlerInitPersonaTitle:"Expression Style",butlerInitPersonaDescription:"Tone, language, and summary style decide how Butler speaks, not whether it gets to be sloppy.",butlerInitPreferenceTitle:"Default Priorities",butlerInitPreferenceDescription:"This decides which risks Butler watches first and what it surfaces first in reports.",butlerInitRuleLabel:"Rule Format",butlerInitTipAutoWorkspace:"The system creates the Butler workspace and first AGENTS.md automatically, so you only set the defaults here.",butlerInitTipProviderSwitch:"You can switch provider later, so do not overthink the first initialization pass.",butlerInitTipReportPriority:"Report priority changes whether Butler leads with risk, blockers, or verification results.",butlerDisplayNameLabel:"Butler Name",butlerDisplayNamePlaceholder:"Example: Arvin, Butler",butlerDisplayNameHint:"This is the Butler's self-name. The system writes it into the first generated AGENTS.md.",butlerProviderLabel:"Provider",butlerWorkspacePathLabel:"Butler Workspace Path",butlerWorkspacePathPlaceholder:"Example: /Users/you/WorkFile/butler-home",butlerAgentsModeLabel:"AGENTS Mode",butlerAgentsModeInline:"Inline",butlerAgentsModeFile:"File",butlerAgentsModeInlineDescription:"Inline: the system generates rules from your initialization choices and manages them for you.",butlerAgentsModeFileDescription:"File: the system writes AGENTS.md into the Butler workspace so you can edit the file directly later.",butlerAgentsFilePathLabel:"AGENTS.md File Path",butlerAgentsFilePathPlaceholder:"Example: /Users/you/WorkFile/butler-home/AGENTS.md",butlerAgentsContentLabel:"AGENTS Instructions",butlerAgentsContentPlaceholder:"Describe the Butler's work rules and response style",butlerAgentsContentHint:"Maintain Butler's formal rules here. Saving will write back to the dedicated AGENTS.md or inline instructions.",butlerPersonaToneLabel:"Tone",butlerPersonaLanguageLabel:"Language",butlerPersonaSummaryStyleLabel:"Summary Style",butlerFocusRiskPreferenceLabel:"Risk Preference",butlerFocusReportPriorityLabel:"Report Priorities (comma-separated)",butlerFocusReportPriorityPlaceholder:"Example: risk,blocker,verification",butlerToneDirect:"Direct and Clear",butlerToneSteady:"Steady and Controlled",butlerToneFriendly:"Friendly and Patient",butlerLanguageZhCn:"Chinese First",butlerLanguageEnUs:"English First",butlerLanguageBilingual:"Bilingual",butlerSummaryBrief:"Brief",butlerSummaryStructured:"Structured",butlerSummaryThorough:"Thorough",butlerRiskConservative:"Conservative",butlerRiskBalanced:"Balanced",butlerRiskProactive:"Proactive",butlerReportPriorityPresetLabel:"Report Priority",butlerReportRiskFirst:"Risk First",butlerReportBlockerFirst:"Blockers First",butlerReportVerificationFirst:"Verification First",butlerReportProgressFirst:"Progress First",butlerSummaryDebounceLabel:"Session Summary Debounce",butlerSummaryDebounceOption1Minute:"1 minute",butlerSummaryDebounceOption3Minutes:"3 minutes",butlerSummaryDebounceOption5Minutes:"5 minutes (default)",butlerSummaryDebounceOption10Minutes:"10 minutes",butlerSummaryDebounceOption15Minutes:"15 minutes",butlerSummaryDebounceOption30Minutes:"30 minutes",butlerSettingsTitle:"Butler Settings",butlerSettingsSaveAction:"Save Settings",butlerSettingsSaving:"Saving...",butlerSettingsSaved:"Butler settings saved",butlerSettingsSaveFailed:"Failed to save Butler settings",butlerInitSubmitting:"Initializing...",butlerInitSubmit:"Initialize Butler",butlerInitSuccess:"Assistant initialized",butlerInitFailed:"Failed to initialize Assistant",butlerInitNameRequired:"Assistant name is required",butlerInitWorkspaceRequired:"Assistant workspace path is required",butlerInitAgentsFileRequired:"AGENTS.md path is required in file mode",butlerWorkbenchTitle:"Assistant Workbench",butlerWorkbenchSubtitle:"Chat with Butler here and review aggregated context with action events.",butlerWorkspaceHint:"Butler workspace: {workspacePath}",butlerDisplayNameActiveHint:"Current Butler name: {displayName}",butlerNewSessionAction:"New Session",butlerNewSessionStarted:"Started a fresh Butler session",butlerNewSessionFailed:"Failed to start a fresh Butler session",butlerRefreshAction:"Refresh",butlerHistoryAction:"Recent Sessions",butlerHistoryTitle:"Recent Sessions",butlerHistoryDescription:"All assistant sessions are kept here, including todo analysis runs and regular chats.",butlerHistoryEmpty:"There is no assistant history yet.",butlerHistorySearchLabel:"Search sessions",butlerHistorySearchPlaceholder:"Search by title or preview",butlerHistorySearchEmpty:"No matching sessions found.",butlerHistoryActiveSection:"Active",butlerHistoryInactiveSection:"Earlier",butlerHistoryOpenAction:"Open Session",butlerHistoryDeleteAction:"Delete Session",butlerCurrentSessionBadge:"Current",butlerControlSessionKindChat:"Chat",butlerControlSessionKindTodoAnalysis:"Todo Analysis",butlerLoadingTitle:"Loading Butler",butlerLoadingDescription:"Pulling the current assistant session, summaries, and control state. Please wait a moment.",butlerSidebarInfoTab:"Info",butlerSidebarAutomationTab:"Automation",butlerSidebarSettingsTab:"Settings",butlerSidebarTabsLabel:"Butler sidebar tabs",butlerSidebarLoadFailed:"Failed to load Butler sidebar",butlerInfoContextTitle:"Current Context",butlerInfoContextDescription:"Show only what the Butler is using in this round, without flooding the panel with unrelated details.",butlerInfoCurrentScopeLabel:"Current Scope",butlerInfoCurrentScopeProject:"Project: {projectName}",butlerInfoCurrentScopeGlobal:"Global Overview",butlerInfoManagedProjectsLabel:"Tracked Projects",butlerInfoManagedProjectsValue:"Active {activeCount} / Total {totalCount}",butlerInfoCurrentContextProjectHint:"{projectName} is selected, so follow-up lookups will stay centered on this project first.",butlerInfoCurrentContextGlobalHint:"The Butler is still in global view. It only drills down when you pick a project or ask for details.",butlerInfoProjectSelectedAction:"Currently Selected",butlerInfoProjectViewAction:"View Project",butlerInfoProjectBlockedBadge:"Blocked",butlerInfoProjectRiskBadge:"Risk: {riskLevel}",butlerInfoProjectRiskShortBadge:"Risk {riskLevel}",butlerInfoProjectLastActivityBadge:"Active: {updatedAt}",butlerInfoLatestSessionAction:"Open Latest Session",butlerInfoProgressTitle:"Current Progress",butlerInfoAttentionTitle:"Watch For",butlerInfoNextStepTitle:"Next Step",butlerInfoFollowUpRecordsTitle:"Follow-up Records",butlerInfoFollowUpRecordsDescription:"Only the latest 5 follow-up states are shown here; open the full history for more.",butlerInfoFollowUpRecordsEmpty:"No follow-up records yet.",butlerInfoFollowUpUntitled:"Untitled Session",butlerInfoFollowUpFallback:"Last updated: {updatedAt}",butlerFollowUpHistoryAction:"View History",butlerFollowUpHistoryTitle:"Follow-up History",butlerFollowUpHistoryDescription:"Review the complete follow-up status history and continue drilling into round details.",butlerInfoVerificationRecordsTitle:"Verification Records",butlerInfoVerificationRecordsDescription:"A global view of feature verification records.",butlerInfoVerificationRecordsEmpty:"No verification records yet.",butlerInfoVerificationFallback:"Current status: {status}",butlerVerificationHistoryTitle:"Verification History",butlerVerificationHistoryDescription:"Only non-active verification records are collected here. Active verifications stay in the main info list.",butlerVerificationHistoryEmpty:"There are no historical verification records yet.",butlerInfoTodoRecordsTitle:"Todo Progress",butlerInfoTodoRecordsDescription:"A global view of current todo progress.",butlerInfoTodoRecordsEmpty:"No todo progress records yet.",butlerInfoShowCompletedAction:"Show completed",butlerInfoTodoItemTitle:"Todo {index}",butlerInfoTodoPending:"Pending",butlerInfoTodoInProgress:"In Progress",butlerInfoTodoClosed:"Closed",butlerTodoLifecyclePending:"Pending analysis",butlerTodoLifecycleAnalyzing:"Analyzing",butlerTodoLifecycleAnalyzed:"Prompt ready",butlerTodoLifecycleSessionCreated:"Session created",butlerTodoLifecycleFollowUpActive:"Assistant working",butlerTodoLifecycleCompleted:"Completed",butlerTodoLifecycleFailed:"Failed",butlerTodoLifecycleEmpty:"No analysis summary has been generated for this todo yet.",butlerTodoPromptPreviewAction:"View prompt",butlerTodoAnalyzeAction:"Analyze repo",butlerTodoReanalyzeAction:"Analyze again",butlerTodoAnalyzeRunning:"Analyzing...",butlerTodoAnalyzeQueued:"Queued for background analysis",butlerTodoAnalyzeSucceeded:"Development prompt generated",butlerTodoAnalyzeFailed:"Failed to analyze the todo repository context",butlerTodoAnalyzeFirstAction:"Analyze first",butlerTodoWaitForPromptAction:"Waiting for prompt",butlerTodoStartSessionAction:"Create session",butlerTodoStartSessionRunning:"Creating...",butlerTodoCopyPromptAction:"Copy prompt",butlerTodoOpenSessionAction:"Open session",butlerTodoCopyPromptSucceeded:"Prompt copied",butlerTodoStartSessionSucceeded:"Created a development session for the todo",butlerTodoStartSessionFailed:"Failed to create a development session for the todo",butlerAutomationTasksTitle:"Automation Tasks",butlerAutomationTasksDescription:"Only automation tasks live here: what exists, what state it is in, and when it runs next.",butlerAutomationTasksEmpty:"No automation tasks yet.",butlerAutomationMobileOverviewDescription:"The main list only keeps the signals worth scanning. Open a card to view and edit the full configuration.",butlerAutomationRunsTitle:"Recent Automation Runs",butlerAutomationRunsDescription:"This view only shows recent automation executions and their outcomes.",butlerAutomationRunsEmpty:"No automation run records yet.",butlerAutomationHistoryTitle:"Automation History",butlerAutomationHistoryDescription:"Only non-active automation tasks and completed run records are collected here. Active automation stays in the main list.",butlerAutomationHistoryEmpty:"There are no automation history records yet.",butlerAutomationStatusActive:"Running",butlerAutomationStatusWaitingUser:"Waiting for You",butlerAutomationStatusCompleted:"Completed",butlerAutomationStatusFailed:"Failed",butlerAutomationStatusCancelled:"Cancelled",butlerAutomationTaskTypeLabel:"Task type",butlerAutomationTaskTypeManual:"Manual plan task",butlerAutomationTaskTypeInterval:"Scheduled plan task",butlerAutomationTaskTypeCron:"Cron plan task",butlerAutomationTaskTypeFollowUp:"Conditional follow-up task",butlerAutomationTaskTypeControlTimer:"Assistant timer",butlerAutomationTaskEnabled:"Enabled",butlerAutomationTaskDisabled:"Disabled",butlerAutomationStatusLabel:"Status",butlerAutomationTaskLastRunLabel:"Last run",butlerAutomationTaskNextRunLabel:"Next run",butlerAutomationOpenDetailsAction:"Open Details",butlerAutomationCollapseDetailsAction:"Hide Details",butlerAutomationDetailTitle:"Automation Config",butlerAutomationDetailDescription:"Edit the trigger rules and action content here. Changes apply immediately after saving.",butlerAutomationSaveAction:"Save Changes",butlerAutomationSaving:"Saving...",butlerAutomationSaveSucceeded:"Automation config saved",butlerAutomationSaveFailed:"Failed to save automation config",butlerAutomationTitleLabel:"Automation name",butlerAutomationPromptLabel:"Action content",butlerAutomationPromptRequired:"Action content is required.",butlerAutomationIncludeTriggerContextLabel:"Include trigger context in the assistant message",butlerAutomationTargetSessionLabel:"Target session",butlerAutomationDueAtLabel:"Run at",butlerAutomationEverySecondsLabel:"Every seconds",butlerAutomationEveryMinutesLabel:"Every minutes",butlerAutomationEveryHoursLabel:"Every hours",butlerAutomationStopAtLabel:"Stop at",butlerAutomationCronMinuteLabel:"Cron minute",butlerAutomationCronHourLabel:"Cron hour",butlerAutomationCronDaysOfWeekLabel:"Days of week",butlerAutomationPollIntervalLabel:"Poll interval (seconds)",butlerAutomationExpiresAtLabel:"Expires at",butlerAutomationMaxChecksLabel:"Max checks",butlerAutomationInvalidDateSuffix:" has an invalid datetime value.",butlerAutomationRequiredSuffix:" is required.",butlerAutomationInvalidNumberSuffix:" must be an integer.",butlerAutomationInvalidPositiveNumberSuffix:" must be greater than 0.",butlerAutomationCronDaysValidation:"Days of week must be comma-separated integers from 0 to 6.",butlerAutomationRunSourceLabel:"Source",butlerAutomationRunSourcePatrol:"Plan task run",butlerAutomationRunSourceFollowUp:"Conditional follow-up run",butlerAutomationRunSourceControlTimer:"Assistant timed resume",butlerAutomationRunSummaryLabel:"Outcome",butlerAutomationRunProcessedAtLabel:"Processed at",butlerAutomationRunEmptySummary:"No summary was returned for this run.",butlerAutomationPatrolRunTitle:"Patrol Task Run",butlerControlTimerBannerTitle:"Next timed step",butlerControlTimerCountdownActive:"The assistant will continue in {duration}",butlerControlTimerCountdownDueNow:"The assistant is about to continue",butlerControlTimerCountdownLead:"The assistant will",butlerControlTimerCountdownTail:"before continuing",butlerControlTimerCountdownDueLead:"The assistant is about to",butlerControlTimerCountdownDueTail:"continue",butlerControlTimerDueAtLabel:"Scheduled for: {time}",butlerControlTimerTypeOnce:"One-time",butlerControlTimerTypeRepeat:"Repeating",butlerControlTimerTypeConditional:"Conditional",butlerControlTimerTypeOther:"Other",butlerControlTimerWorkspaceLabel:"Target workspace",butlerControlTimerSessionLabel:"Target session",butlerControlTimerTargetSessionLabel:"Target session: {sessionId}",butlerControlTimerDetailAction:"View prompt details",butlerControlTimerPromptTitle:"Resume prompt",butlerControlTimerUnknownWorkspace:"No workspace linked",butlerControlTimerUnknownSession:"No session linked",butlerControlTimerStopAction:"Stop action",butlerControlTimerCancelOperationAction:"Cancel action",butlerControlTimerExecuteNowAction:"Stop timer",butlerControlTimerExecutingNow:"Executing now...",butlerControlTimerExecuteNowSucceeded:"The wait ended and the next action started immediately",butlerControlTimerExecuteNowFailed:"Failed to end the wait and execute immediately",butlerControlTimerActionNote:"Stop action cancels this timed continuation. Stop timer ends the wait and runs it now.",butlerControlTimerCancelAction:"Cancel timer",butlerControlTimerCancelling:"Cancelling...",butlerControlTimerCancelSucceeded:"The assistant timer was cancelled",butlerControlTimerCancelFailed:"Failed to cancel the assistant timer",butlerControlTimerRunCompletedSummary:"The timer fired and the assistant continued the next step.",butlerControlTimerRunCancelledSummary:"This timer was cancelled manually.",butlerControlTimerRunFailedSummary:"The timer failed to resume the assistant.",butlerControlTimerNoProject:"No linked project",butlerAutomationViewRoundsAction:"View Round Details",butlerAutomationRoundDetailsTitle:"Follow-up Round Details",butlerAutomationRoundDetailsDescription:"Review each Butler follow-up round for this task.",butlerAutomationRoundLoading:"Loading follow-up round details...",butlerAutomationRoundLoadFailed:"Failed to load follow-up round details",butlerAutomationRoundEmpty:"There are no follow-up round details yet.",butlerAutomationRoundLabel:"Round {round}",butlerAutomationRoundProcessedAtLabel:"Processed at",butlerAutomationRoundStatusLabel:"Task status",butlerAutomationRoundObservedStateLabel:"Session runtime state",butlerAutomationRoundSummaryLabel:"Round decision",butlerAutomationRoundWaitingReasonLabel:"Waiting reason",butlerAutomationRoundPromptLabel:"Proxy-sent content",butlerAutomationRoundKindStarted:"Follow-up started",butlerAutomationRoundKindContinue:"Resumed immediately",butlerAutomationRoundKindQueued:"Queued for send",butlerAutomationRoundKindWaitingUser:"Waiting for user",butlerAutomationRoundKindCompleted:"Marked completed",butlerAutomationRoundKindFailed:"Follow-up failed",butlerAutomationRoundKindCancelled:"Stopped manually",butlerAutomationRoundKindLimitReached:"Round limit reached",butlerInboxAction:"Inbox",butlerInboxModalTitle:"Inbox",butlerInboxModalDescription:"Track project todos here and keep their current progress tied to real projects.",butlerInboxLoading:"Loading inbox...",butlerInboxLoadFailed:"Failed to load inbox",butlerInboxProjectsEmpty:"No managed project is available to bind yet.",butlerInboxEmpty:"No inbox records yet.",butlerInboxCreateTitle:"Add Todo",butlerInboxEditingTitle:"Edit Todo",butlerInboxFormDescription:"Every todo must be bound to a project so the assistant can keep following it later.",butlerInboxListTitle:"Current Todos",butlerInboxListDescription:"This list shows todos across your managed projects so you can handle them in one place.",butlerInboxShowClosedAction:"Show closed",butlerInboxQuickStatusLabel:"Quick status update",butlerInboxProjectLabel:"Project",butlerInboxTypeLabel:"Type",butlerInboxTitleLabel:"Title",butlerInboxTitlePlaceholder:"For example: Finish login captcha flow",butlerInboxContentLabel:"Details",butlerInboxContentPlaceholder:"Describe the current issue, target, or what you want the assistant to keep pushing forward.",butlerInboxStatusLabel:"Progress",butlerInboxTypeTask:"Task",butlerInboxTypeBug:"Bug",butlerInboxTypeFeature:"Feature",butlerInboxTypeChange:"Change",butlerInboxStatusPending:"Pending",butlerInboxStatusInProgress:"In Progress",butlerInboxStatusClosed:"Closed",butlerInboxCreateAction:"Add Todo",butlerInboxUpdateAction:"Save Changes",butlerInboxCancelEditAction:"Cancel Edit",butlerInboxEditAction:"Edit",butlerInboxDeleteAction:"Delete",butlerInboxCreated:"Todo created",butlerInboxUpdated:"Todo updated",butlerInboxDeleted:"Todo deleted",butlerInboxSaveFailed:"Failed to save todo",butlerInboxDeleteFailed:"Failed to delete todo",butlerProviderSwitched:"Provider switched",butlerProviderSwitchedDescription:"Switched to {provider}. The current view was reset and reloaded.",butlerProviderSwitchFailed:"Failed to switch provider",butlerAttachmentUnsupported:"Attachments are not supported in Butler chat yet",butlerOverviewTitle:"Overview",butlerOverviewDescription:"This area pulls together the most important things to pay attention to right now.",butlerMetricProjectCount:"Projects",butlerMetricBlockedCount:"Blocked",butlerMetricHighRiskCount:"High Risk",butlerTopRisksTitle:"Top Risks",butlerNextActionsTitle:"Next Actions",butlerOverviewEmpty:"No data",butlerOverviewLoading:"Loading Butler context summary...",butlerEventsTitle:"Recent Actions",butlerEventsDescription:"Anything Butler just helped you do is listed here.",butlerEventsEmpty:"No action events yet",butlerLoadFailed:"Failed to load Butler workbench",butlerContextStrategyTitle:"Context On Demand",butlerContextStrategyDescription:"Butler only receives the global summary by default. Project sessions, memories, patrols, and verifications are fetched from the backend only after you drill into a specific project.",butlerConversationTitle:"Talk to Assistant",butlerConversationDescription:"This conversation belongs to {displayName} only. When details are needed, {displayName} answers from the aggregated summary first, then pulls the relevant project, session, patrol, or verification data from the backend on demand.",butlerComposerPlaceholder:"Tell {displayName} what you want to inspect or decide next",butlerProjectsTitle:"Projects",butlerProjectsDescription:"Pick a project here and Butler will continue with its latest progress and records.",butlerProjectsEmpty:"No projects available for drilldown",butlerProjectWorkspaceLabel:"Workspace: {workspaceId}",butlerProjectSummaryEmpty:"No summary available yet",butlerProjectOpenDetailAction:"Open Details",butlerProjectSyncAction:"Sync to Timeline",butlerProjectSyncSucceeded:"Project {projectName} was synced into Butler's timeline",butlerProjectActionRequiresSession:"Send Butler a message first, then ask it to continue working on a project.",butlerProjectContextTitle:"Current Project",butlerProjectContextDescription:"This area shows the sessions, records, and results tied to the project you selected.",butlerProjectContextEmpty:"Pick a project from the list or action events first.",butlerProjectContextLoading:"Loading project-related context...",butlerProjectContextMeta:"Project status: {status} · Risk level: {riskLevel}",butlerProjectActionSucceeded:"Butler action completed",butlerProjectActionFailed:"Butler action failed",butlerProjectActionPending:"Processing...",butlerProjectSessionsTitle:"Project Sessions",butlerProjectMemoriesTitle:"Project Memories",butlerProjectPatrolsTitle:"Patrol Runs",butlerProjectVerificationsTitle:"Verification Runs",butlerProjectOpenConversationAction:"Open Real Session",butlerProjectResumeAction:"Resume Session",butlerProjectResumeSucceeded:"Session resumed: {sessionTitle}",butlerProjectStartPatrolAction:"Start Patrol",butlerProjectPatrolSucceeded:"Started a patrol for {projectName}",butlerProjectStartVerificationAction:"Start Verification",butlerProjectVerificationSucceeded:"Started a verification for {projectName}",butlerProjectMemoryMeta:"Type: {memoryType} · Status: {status}",butlerProjectSessionMeta:"Role: {role} · Status: {status}",butlerProjectPatrolMeta:"Status: {status} · Risk: {riskLevel}",butlerProjectVerificationMeta:"Type: {verificationType} · Status: {status}",butlerProjectRunSummaryEmpty:"No summary yet",butlerProjectFocusAction:"Focus This Record",butlerProjectUpdatedAtLabel:"Updated: {updatedAt}",butlerFocusedBadge:"Focused",searchModalTitle:"Search",searchModalDescription:"Enter a keyword, then choose whether to search code, affairs, or everything.",searchPlaceholder:"Search sessions, code, documents, tags, or todos",searchHint:"Type a keyword first, then choose code, affairs, or all.",searchChooseActionHint:"Choose a search scope below.",searchActionLabel:"Search scope",searchActionCode:"Search Code",searchActionAffairs:"Search Affairs",searchActionAll:"Search All",searchClearAction:"Clear",searchLoading:"Searching...",searchEmpty:"No matching results found.",searchSessionsGroup:"Sessions",searchCodeGroup:"Code",searchModeLabel:"Search mode",searchModeSessions:"Sessions",searchModeCode:"Code",searchModeAffairs:"Affairs",searchKeywordLabel:"Keyword",searchWorkspaceLabel:"Workspace",searchSessionPlaceholder:"Search by session title, workspace, or provider",searchCodePlaceholder:"Search by file name or path fragment",searchAffairsPlaceholder:"Search by document, tag, todo, or conversation keyword",searchSessionHint:"Type a keyword to instantly filter matching sessions.",searchCodeHint:"Pick a workspace, then search by file name or path.",searchAffairsHint:"Type a keyword to search documents, tags, todos, and conversations across all affairs workspaces.",searchAffairsLoading:"Searching affairs content...",searchSessionEmpty:"No matching sessions found.",searchCodeEmpty:"No matching files found.",searchAffairsEmpty:"No matching affairs content found.",searchCodeFailed:"Code search failed. Please try again later.",searchAffairsFailed:"Affairs search failed. Please try again later.",searchAffairsWorkspaceMissing:"No affairs workspace is available right now.",searchAffairsDocumentsGroup:"Documents",searchAffairsTagsGroup:"Tags",searchAffairsConversationsGroup:"Conversations",searchAffairsTodosGroup:"Todos",searchSortLabel:"Sort by",searchSortRelevance:"Relevance first",searchSortUpdated:"Recently updated first",searchSortTitle:"Title or name first",searchResultTypeSession:"Session",searchResultTypeCode:"Code",searchResultTypeDocument:"Document",searchResultTypeAffairsTag:"Library tag",searchResultTypeTodo:"Todo",searchResultLocateDocument:"Locate",searchResultLocateDocumentTitle:"Locate this file in the document library",searchSubmit:"Search",filesEntry:"Files",gitEntry:"GIT",terminalManagerEntry:"Debug",workspaceSectionTitle:"Workspaces",goBack:"Back",goForward:"Forward",workspaceCount:"Projects",sessionCount:"Sessions",manageWorkspaceAction:"Manage Projects",manageWorkspaceTitle:"Manage Projects",manageWorkspaceDescription:"The list starts with the currently loaded projects. Expand one to inspect its path, Git summary, and code composition, or remove it from the current workbench list.",manageWorkspaceImportAction:"Import Project",manageWorkspaceCloneAction:"Clone Project",manageWorkspaceEmpty:"There are no projects to manage right now.",manageWorkspaceLoading:"Loading project details...",manageWorkspaceLoadFailed:"Failed to load project details.",manageWorkspacePathLabel:"Path",manageWorkspaceGitCommitCount:"Git Commit Count",manageWorkspaceGitInfoLabel:"Git Repository Info",manageWorkspaceRepoRoot:"Repository Root",manageWorkspaceCurrentBranch:"Current Branch",manageWorkspaceRemoteLabel:"Remote",manageWorkspaceNoRemote:"No remote configured",manageWorkspaceNotGit:"This project is not a Git repository.",manageWorkspaceCodeCompositionLabel:"Code Composition",manageWorkspaceCodeCompositionFiles:"files",manageWorkspaceCodeCompositionOther:"Other",manageWorkspaceNoCodeComposition:"No recognizable code files were found for composition stats.",manageWorkspaceCodeTruncated:"The project is large, so only the first {count} recognizable files were counted.",manageWorkspaceColorLabel:"Background Color",manageWorkspaceColorSelectSwatch:"Use color {color}",manageWorkspaceColorClearAction:"Clear Color",manageWorkspaceColorUnset:"Not set. The default worktree color is in use.",manageWorkspaceColorSaveFailed:"Failed to save the workspace color.",manageWorkspaceRemoveAction:"Remove Project",manageWorkspaceRemoving:"Removing...",manageWorkspaceRemoveSuccess:"Project removed from the current workbench list",manageWorkspaceRemoveFailed:"Failed to remove the project",manageWorkspaceRemoveConfirmTitle:"Confirm Project Removal",manageWorkspaceRemoveConfirmDescription:"This only removes the project from the current workbench list. It does not delete any files on disk or historical records. If you load the same path again later, the old records will appear again.",manageWorkspaceRemoveConfirmTarget:'Remove "{name}" from the current workbench?',manageWorkspaceRemoveConfirmAction:"Remove Project",importWorkspaceTitle:"Add Project",importWorkspaceHint:"Import a local code directory",importExpand:"Expand",importCollapse:"Collapse",importPathLabel:"Project Path",importPathPlaceholder:"Enter the project folder path",importNameLabel:"Project Name",importNamePlaceholder:"Optional",importSubmit:"Add Project",importSubmitting:"Adding...",importChooseFolder:"Choose Folder",importPickFolderFailed:"Failed to open the folder picker",importDesktopDropHint:"You can drag a local project folder directly into this area",importHint:"Enter a local code directory and start working",importServerDirectoryHint:"Browse and select the project directory on the server",importBrowserTitle:"Select Server Directory",importBrowserDescription:"You are browsing directories on the server, not on the current device.",importBrowserCurrentPath:"Current Path",importBrowserRoots:"Root Directories",importBrowserOpenParent:"Go Up",importBrowserOpenPath:"Open Path",importBrowserCreateDirectory:"New Folder",importBrowserCreateDirectoryTitle:"New Folder",importBrowserCreateDirectoryDescription:"Create a single child folder in the current server path. Path separators are not accepted.",importBrowserCreateDirectoryLabel:"Folder Name",importBrowserCreateDirectoryPlaceholder:"Enter the new folder name",importBrowserCreateDirectorySuccess:"Folder created",importBrowserCreateDirectoryFailed:"Failed to create folder",importBrowserCreateDirectorySubmit:"Create Folder",importBrowserCreatingDirectory:"Creating...",importBrowserEmpty:"No subdirectory is available in the current path",importBrowserBrowseFailed:"Failed to load server directories",importBrowserSubmit:"Import Current Directory",importPathRequired:"Enter the project path",importSuccess:"Project added",importFailed:"Failed to add project",cloneWorkspaceTitle:"Clone Project",cloneWorkspaceHint:"Clone a Git repository into a server directory and add it to the project list.",cloneSubmit:"Clone Project",cloneSubmitting:"Cloning...",cloneRepositoryLabel:"Git Repository URL",cloneRepositoryPlaceholder:"For example: https://github.com/org/repo.git",cloneParentPathLabel:"Target Parent Directory",cloneParentPathPlaceholder:"Choose an existing directory on the backend server",cloneDirectoryNameLabel:"New Project Directory Name",cloneDirectoryNamePlaceholder:"Defaults to the repository name when left empty",clonePickDirectory:"Choose Directory",cloneAuthModeLabel:"Authentication",cloneAuthModeNone:"No Authentication",cloneAuthModeBasic:"Username + Password",cloneAuthModeToken:"Token",cloneUsernameLabel:"Username",cloneUsernamePlaceholder:"Enter Git username",clonePasswordLabel:"Password",clonePasswordPlaceholder:"Enter Git password",cloneTokenLabel:"Token",cloneTokenPlaceholder:"Enter access token",cloneTokenUsernamePlaceholder:"Optional, defaults to git when left empty",cloneRepoRequired:"Enter the Git repository URL",clonePathRequired:"Select the target parent directory",cloneSuccess:"Project cloned successfully",cloneFailed:"Clone failed",cloneHint:"The target parent directory must already exist. Clone creates a new repository folder under it.",cloneBrowserTitle:"Select Clone Parent Directory",cloneBrowserDescription:"Choose an existing server-side parent directory. Clone will create a new project folder under it.",cloneBrowserSubmit:"Use Current Directory",refreshNavigation:"Refresh",desktopChromeLabel:"Desktop Workbench",windowMinimize:"Minimize Window",windowMaximize:"Maximize or Restore Window",windowClose:"Close Window",contextOpenSession:"Open Session",navigationLoadFailed:"Load failed. Retry.",emptyNavigationTitle:"No project yet",emptyNavigationBody:"Add a local code directory to start working",emptyWorkspaceSessions:"No sessions",favoriteSectionTitle:"Pinned Sessions",favoriteSectionEmpty:"Pinned sessions stay here for quick access.",worktreeSectionTitle:"Child Worktrees",worktreeSectionExpand:"Expand Child Worktrees",worktreeSectionCollapse:"Collapse Child Worktrees",worktreeMergePanelLabel:"Worktree Merge",worktreeMergePanelTitle:"Merge Into Direct Parent",worktreeMergePreviewAction:"Preview",worktreeMergePreviewRefresh:"Preview",worktreeMergePreviewIdle:"Preview not loaded",worktreeMergePreviewLoading:"Checking...",worktreeMergeReady:"Ready to merge",worktreeMergeBlocked:"Merge blocked",worktreeMergeApplying:"Merging...",worktreeMergeApplyAction:"Merge",worktreeMergeApplySuccess:"The worktree has been merged into its direct parent",worktreeMergeApplyFailed:"Failed to merge worktree",worktreeMergePreviewFailed:"Failed to load merge preview",worktreeMergeAlreadyMerged:"Already merged into parent",worktreeMergeMergedHint:"The code is already back in the parent. Cleanup can be done next.",worktreeMergeMergedDirtyHint:"Committed history is already in the parent, but this worktree still has pending work and cannot be cleaned up yet.",worktreeMergeChecklistTitle:"Merge Checklist",worktreeMergeChecklistSourceState:"Worktree state is valid",worktreeMergeChecklistSourceStateBlocked:"The worktree state is inconsistent. The system is not treating it as an active worktree yet.",worktreeMergeChecklistSourceClean:"Source worktree is clean",worktreeMergeChecklistSourceCleanBlocked:"The source worktree still has uncommitted changes. Commit them first.",worktreeMergeChecklistTargetClean:"Parent workspace is clean",worktreeMergeChecklistTargetCleanBlocked:"The direct parent workspace has uncommitted changes and cannot receive the merge.",worktreeMergeChecklistChildren:"No active child worktrees",worktreeMergeChecklistChildrenBlocked:"There are still active child worktrees under this node. Clean leaf nodes first.",worktreeMergeChecklistCommits:"There are commits to merge",worktreeMergeChecklistCommitsBlocked:"This worktree has no commits ahead of the parent workspace.",worktreeMergeChecklistConflicts:"No merge conflicts detected",worktreeMergeChecklistConflictsBlocked:"Merge conflicts were detected. Resolve them before continuing.",worktreeMergeChecklistResultPending:"Waiting for preview",worktreeMergeChecklistResultReady:"Merge can proceed",worktreeMergeChecklistResultReadyDetail:"All checks passed. You can start the merge now.",worktreeMergeChecklistResultBlocked:"Merge cannot proceed yet",worktreeMergeChecklistResultBlockedDetail:"Resolve the blockers above before continuing.",worktreeMergeChecklistResultMerged:"Merged. Cleanup can continue",worktreeMergeCompactPending:"Pending",worktreeMergeCompactChecking:"Checking",worktreeMergeCompactReady:"Ready",worktreeMergeCompactBlocked:"Blocked",worktreeMergeCompactMerged:"Merged",worktreeMergeCompactMerging:"Merging",worktreeMergeCompactCleaning:"Cleaning",worktreeMergeCompactInactive:"State Error",worktreeMergeCompactDirty:"Dirty",worktreeMergeCompactTargetDirty:"Parent Dirty",worktreeMergeCompactConflict:"Conflict",worktreeMergeCompactChildren:"Has Children",worktreeMergeCompactNoCommits:"No Commits",worktreeCleanupAction:"Cleanup",worktreeCleanupRunning:"Cleaning...",worktreeCleanupSuccess:"The worktree has been cleaned up",worktreeCleanupFailed:"Failed to clean up worktree",worktreeCleanupModalTitle:"Confirm Worktree Cleanup",worktreeCleanupModalDescription:"Cleanup removes the worktree directory and app metadata by default. Deleting the branch is only available after it has been merged into the parent branch.",worktreeCleanupConfirm:"Clean up {name}? The git branch will be kept by default.",worktreeCleanupDeleteBranchLabel:"Also delete branch {branch}",worktreeCleanupDeleteBranchHint:"Branch deletion is only available after the branch has been merged into the parent branch.",worktreeCleanupDeleteBranchAction:"Cleanup and Delete Branch",worktreeCleanupDeleteBranchSuccess:"The worktree and branch {branch} have been cleaned up",worktreeCleanupDeleteBranchPartialFailed:"The worktree was cleaned up, but branch {branch} could not be deleted",worktreeMergeCurrentBranch:"Current branch: {branch}",worktreeMergeParentBranch:"Parent branch: {branch}",worktreeMergeTargetWorkspace:"Target parent: {name}",worktreeMergeAheadBehind:"Commit delta: ahead {ahead} / behind {behind}",worktreeMergeBaseCommit:"merge base: {commit}",worktreeMergeConflictLabel:"Conflicting files",favoriteAction:"Pin Session",unfavoriteAction:"Unpin",favoriteAdded:"Session pinned",favoriteRemoved:"Session unpinned",favoriteToggleFailed:"Failed to update pinned state",sessionMoreAction:"More Actions",deleteSessionAction:"Delete Session",deleteSessionConfirmTitle:"Delete This Session",deleteSessionConfirmDescription:"Deleting a session removes it from assistant history and workspace lists, and also clears the real session record. This cannot be undone.",deleteSessionSuccess:"Session deleted",deleteSessionFailed:"Failed to delete session",sessionStateInferred:"Inferred",renameAction:"Rename",renameSuccess:"Session name updated",renameFailed:"Failed to rename session",renameModalTitle:"Rename Session",renameModalDescription:"Use a name you can recognize at a glance. This changes only the title, not the content.",renameInputLabel:"Session Name",renameInputPlaceholder:"Enter a new session name",renamingSession:"Saving...",archiveFolderLabel:"Archived Sessions",archiveFolderAction:"Open Archive Folder",archiveAction:"Archive Session",archiveCurrentSessionAction:"Archive Current Session",archiveAdded:"Session archived",archiveConfirmTitle:"Archive This Session",archiveConfirmDescription:"After archiving, this session will be hidden from the main list for the current workspace, and you can still restore it from archive.",unarchiveAction:"Restore from Archive",archiveRestored:"Session restored to the main list",archiveModalTitle:"Archived Sessions",archiveModalDescription:"This list shows sessions temporarily hidden in the current project. Restore them when needed.",archiveEmpty:"There are no archived sessions in this project yet.",archiveSearchAction:"Search",archiveSearchLabel:"Search Archived Sessions",archiveSearchPlaceholder:"Search by session name or summary",archiveSearchEmpty:"No archived sessions match your search.",archiveSearchSummaryLoading:"Loading archived session summaries...",archiveSearchSummaryFailed:"Some archived summaries could not be loaded yet, so search currently falls back to titles.",archiveViewAction:"View Archived Sessions",parallelCreateAction:"Create Parallel Session",parallelCreateModalTitle:"Create Parallel Sessions",parallelCreateModalDescription:"Set the goal for this parallel run first, then adjust each session separately.",parallelCreateSharedPromptLabel:"The goal for this parallel run is",parallelCreateSharedPromptPlaceholder:"For example: explore multiple implementation paths, compare technical directions, or split the same debugging task into parallel angles.",parallelCreateCountLabel:"Parallel Count",parallelCreateMembersTitle:"Configure Each Session",parallelCreateMembersDescription:"Each pane is a real session member, with its own provider, model, and temporary workspace choice.",parallelCreateMemberTitle:"Member {index}",parallelCreateModelLabel:"Model",parallelCreateMemberPromptLabel:"Any special requirement?",parallelCreateMemberPromptPlaceholder:"For example: be more conservative, focus on refactoring, prioritize performance investigation, or constrain the stack and output style.",parallelCreateIsolationLabel:"Use Temporary Isolated Workspace",parallelCreateIsolationHint:"Only enable this for members that need an independent code directory. It stays out of formal worktrees until promotion succeeds.",parallelCreateProvidersLoading:"Loading installed providers...",parallelCreateNoAvailableProviders:"No available model provider is installed for this workspace yet.",parallelCreateNoModelsAvailable:"No models are available for this provider",parallelCreatePromptRequired:"The shared prompt cannot be empty",parallelCreatePartialFailure:"{successCount} members were created, and {failureCount} members failed to start.",parallelCreateAllFailed:"All {failureCount} members failed to start. Adjust the failed member settings and try again.",parallelCreateContinuePartial:"Open Created Split View",parallelCreateMemberSucceeded:"Created",parallelCreateMemberFailed:"Failed",parallelCreateMemberErrorTitle:"This member was not created",parallelCreateSubmit:"Create Parallel Sessions",parallelCreateSubmitting:"Creating parallel sessions...",parallelCreateSucceeded:"Parallel sessions created",parallelAppendAction:"Add Parallel Session",parallelAppendModalTitle:"Add Parallel Sessions",parallelAppendModalDescription:"Reuse the original user prompt for this group and only configure the newly added members.",parallelAppendSharedPromptLabel:"Original User Prompt",parallelAppendSharedPromptDescription:"This comes from the first user message in the current parallel group and cannot be edited here.",parallelAppendCountLabel:"Add Count",parallelAppendSubmit:"Add Parallel Sessions",parallelAppendSubmitting:"Adding parallel sessions...",parallelAppendSucceeded:"Parallel sessions added",parallelAppendNoRemainingSlots:"This parallel group already has 4 members and cannot accept more.",parallelGroupBadge:"Parallel",parallelGroupAnchorBadge:"Anchor",parallelGroupMemberBadge:"Member",parallelWorkspacePromotedBadge:"Promoted Workspace",parallelGroupLoadFailed:"Failed to load the parallel session group",parallelGroupEmpty:"No parallel members are available yet.",parallelPaneOpenAction:"Open Session",parallelPaneToolsAction:"Tools",parallelPanePinAction:"Pin Panel",parallelPaneDetachAction:"Open in Window",parallelPaneResizeAction:"Resize Panel",parallelPaneMoreAction:"More Options",parallelPaneInfoAction:"View Info",parallelPaneProcessesEntry:"Processes",parallelPaneTerminalEntryDescription:"Terminal work is input-heavy and scroll-heavy, so it stays as a dedicated entry instead of being forced into this floating panel.",parallelPaneTerminalOpenAction:"Open Terminal",parallelPaneInfoTitle:"Session Info",parallelPaneModelFallback:"Default Model",parallelPaneIsolatedWorkspaceTitle:"Temporary Isolated Workspace",parallelPanePromptFallback:"No special requirement",parallelPaneColorPaletteLabel:"Palette",parallelPaneColorPaletteDescription:"Adjust this pane color so it is easier to tell branches apart at a glance.",parallelPaneColorPaletteReset:"Use Default Split Colors",parallelPaneRemoveAction:"Remove Parallel Session",parallelPaneRemoveDescription:"Removing this session takes it out of the current parallel group. If it is still using a temporary isolated workspace, the workspace and branch are cleaned up too.",parallelPaneRemovePromotedDescription:"Removing this session takes it out of the current parallel group. Promoted child worktrees and branches are kept.",parallelPanePromoteAction:"Promote to Formal Worktree",parallelPanePromoteDescription:"Only promote this temporary workspace after you are sure it should be kept as a formal child worktree.",parallelPanePromoting:"Promoting...",parallelPaneRemoving:"Removing...",subagentBadge:"Sub-agent",sessionForkSession:"Session Fork",sessionForkMessage:"Message Fork",sessionForkReconstructed:"Reconstructed Fork",subagentExpand:"Expand Sub-agent List",subagentCollapse:"Collapse Sub-agent List",subagentExpandMore:"Show More Sub-agents",favoriteExpandMore:"Show More Pinned",sessionExpandMore:"Show More Sessions",archiveExpandMore:"Show More Archived Sessions",worktreeCollapse:"Collapse Worktree",worktreeExpand:"Expand Worktree",workspaceCollapse:"Collapse Project",workspaceExpand:"Expand Project",reorderWorkspace:"Drag to Reorder Projects",switchWorkspace:"Switch to Project",workspaceReorderFailed:"Failed to save project order.",workspaceCollapseStateSaveFailed:"Failed to save project collapse state.",workspaceHomeSwitcherLabel:"Switch Workspace",workspaceHomeSwitcherTitle:"Workspace",hostWorkspaceSwitcherTitle:"Hosts and Workspaces",hostSwitcherAriaLabel:"Switch Host",hostSwitcherTitle:"Hosts",hostSwitcherSavedSection:"Saved",hostSwitcherDiscoveredSection:"Discovered",hostSwitcherCurrentBadge:"Current",hostSwitcherDiscoveredBadge:"Auto",hostSwitcherNodeBadge:"HOST",hostSwitcherAddAction:"Add Host",hostSwitcherNameLabel:"Host Name",hostSwitcherNamePlaceholder:"For example: Office Host",hostSwitcherUrlLabel:"Host URL",hostSwitcherUrlPlaceholder:"For example: http://192.168.1.20:3002",hostSwitcherSaveAction:"Save Host",hostSwitcherSwitching:"Switching",hostSwitcherDetailAction:"Details",hostSwitcherDetailAriaLabel:"View connection details for host {name}",hostSwitcherDetailTitle:"Connection Details",hostSwitcherDetailStatusLabel:"Connection Status",hostSwitcherDetailStatusRelay:"CodingNS Connect",hostSwitcherDetailStatusDirect:"Direct",hostSwitcherDetailRouteLabel:"Current Route",hostSwitcherDetailAddressLabel:"Current Address",hostSwitcherDetailLatencyLabel:"CodingNS Connect Latency",hostSwitcherDetailLatencyLoading:"Checking...",hostSwitcherDetailTrafficLabel:"Session Traffic",hostSwitcherDetailResourceTitle:"Host Resources",hostSwitcherDetailCpuLabel:"CPU",hostSwitcherDetailCpuValue:"{usage} · {cores} cores",hostSwitcherDetailMemoryLabel:"Memory",hostSwitcherDetailDiskLabel:"Disk",hostSwitcherDetailUnavailable:"Unavailable",hostSwitcherWorkspaceCount:"{count} workspaces",hostSwitcherWorkspaceCountWithUser:"{username} · {count} workspaces",hostSwitchFailed:"Failed to switch host.",hostSwitchUnreachable:"{name} is unreachable right now.",hostSwitchMissing:"The target host no longer exists.",hostDeleteAction:"Delete Host",hostDeleteAriaLabel:"Delete host {name}",hostDeleteBusy:"Removing",hostDeleteConfirmAction:"Confirm",hostDeleteConfirm:'Delete host "{name}"? Saved sign-in info will also be cleared.',hostDeleteSuccess:"Removed host: {name}",hostDeleteFailed:"Failed to remove host: {name}",hostAddIncompleteCredentials:"Fill in both the username and password, or leave both blank.",hostAddInvalidUrl:"The host URL is invalid.",hostAddDuplicate:"This host already exists.",hostAddFailed:"Failed to add the host.",hostAddSuccess:"Added host: {name}",hostDiscoveryRefreshing:"Scanning local hosts...",hostDiscoveryFailed:"Failed to scan local hosts.",mobileWorktreeBadge:"Worktree",workspaceHomeStatusSectionTitle:"Current Workspace",workspaceHomeViewAllAction:"View All Sessions",workspaceHomeMetricActive:"Active",workspaceHomeMetricUnread:"Notifications",workspaceHomeMetricTerminal:"Terminals",workspaceHomeMetricChanges:"Changes",workspaceHomeActiveSessionsSectionTitle:"Active Sessions",workspaceHomeQuickLaunchStatusLabel:"Quick Debug",workspaceHomeQuickLaunchRunning:"Running",workspaceHomeQuickLaunchStopped:"Stopped",workspaceHomeWaitingInputLabel:"Waiting Input",workspaceHomeButlerLabel:"Assistant",mobileButlerEntry:"Assistant",mobileConversationToolCloseAction:"Back to Conversation",mobileConversationToolTabsLabel:"Files, Git, and Debug Tabs",mobileConversationToolProcessesTab:"Debug",mobileButlerEmptyTitle:"Assistant is not ready yet",mobileButlerEmptyBody:"The first assistant setup has not been completed yet. Finish the initial setup on desktop, then come back on mobile to review follow-ups and automations.",butlerProjectSyncEmptyState:"Give the assistant a concrete goal and it will continue the work here.",mobileButlerSummaryTitle:"Workspace Summary",mobileButlerSummaryProjects:"Projects",mobileButlerSummaryFollowUps:"Active Tasks",mobileButlerSummaryWaitingUser:"Waiting on You",mobileButlerSummaryInbox:"Open Todos",mobileButlerAssistantWorkspaceLabel:"Butler Workspace",mobileButlerAssistantToneLabel:"Tone",mobileButlerAssistantLanguageLabel:"Language",mobileButlerAssistantUpdatedAtLabel:"Updated",workspaceOverviewTitle:"Put project entry points where you can actually see them",workspaceOverviewBody:"Choose a project first, then decide whether to continue or start a new session.",workspaceListBody:"Keep every loaded project here and surface the frequent actions on the page.",workspaceDetailTitle:"Project Details",workspaceDetailSummaryTitle:"Project Overview",workspaceDetailSummaryBody:"See the path, Git summary, and code footprint first, then jump into the right tool.",workspaceDetailMissingTitle:"Project not found",workspaceDetailMissingBody:"This project may have been removed, or the current snapshot has not loaded it yet.",workspaceDetailDebugTitle:"Service Status",manageWorkspaceDebugDescription:"Review detected services, recent start status, and support guidance for the current project.",workspaceDetailDebugAnalyzeFailed:"Failed to load service status",workspaceDetailDebugFrameworkLabel:"Detected Type",workspaceDetailDebugConfidenceLabel:"Confidence",workspaceDetailDebugCompatibilityLabel:"Readiness",workspaceDetailDebugInjectionLabel:"Recommended Handling",workspaceDetailDebugRuntimeStatusLabel:"Current Status",workspaceDetailDebugFailureStageLabel:"Blocked At",workspaceDetailDebugServiceDiscoveryLabel:"Service Address Handling",workspaceDetailDebugHmrLabel:"Hot Reload Handling",workspaceDetailDebugCallbackLabel:"Callback Handling",workspaceDetailDebugAiFallbackLabel:"Manual Handling Policy",workspaceDetailDebugFrameworkNoteLabel:"Notes",workspaceDetailDebugReasonsLabel:"Summary",workspaceDetailDebugFilesLabel:"Reference Files",workspaceDetailDebugFailureStageEmpty:"None",workspaceDetailDebugRuntimeEmpty:"No runtime record yet.",workspaceDetailDebugFrameworkNoteEmpty:"No extra compatibility note.",workspaceDetailDebugEmptyReasons:"None",workspaceDetailDebugEmptyFiles:"None",workspaceDetailDebugConfidenceHigh:"High",workspaceDetailDebugConfidenceMedium:"Medium",workspaceDetailDebugConfidenceLow:"Low",workspaceDetailDebugCompatibilitySupported:"Ready to Use",workspaceDetailDebugCompatibilityConditional:"Needs More Setup",workspaceDetailDebugCompatibilityUnsupported:"Not Recommended Yet",workspaceDetailDebugCompatibilityUnknown:"Unknown",workspaceDetailDebugInjectionCli:"Startup Args",workspaceDetailDebugInjectionEnv:"Environment",workspaceDetailDebugInjectionOverride:"Adjust Command",workspaceDetailDebugInjectionAiFallback:"Needs Manual Help",workspaceDetailDebugInjectionNone:"Do Not Auto Handle Yet",workspaceDetailDebugRuntimePreparing:"Preparing",workspaceDetailDebugRuntimeRunning:"Running",workspaceDetailDebugRuntimeFailed:"Start Failed",workspaceDetailDebugRuntimeStopped:"Stopped",workspaceDetailDebugRuntimeNotStarted:"Not Started",workspaceDetailDebugRequirementRequired:"Needs Extra Setup",workspaceDetailDebugRequirementNotRequired:"No Extra Setup",workspaceDetailDebugAiPolicyNever:"Do Not Auto Handle",workspaceDetailDebugAiPolicyConditional:"Case by Case",workspaceDetailDebugAiPolicyAllowed:"Allowed",workspaceDetailDebugRuntimeServicesTitle:"Most Recent Start",workspaceDetailDebugRuntimeHistoryTitle:"Recent Starts",workspaceDetailDebugRuntimeHistoryTimeLabel:"Started At",workspaceDetailDebugRuntimeHistoryServiceLabel:"Services",workspaceDetailDebugRuntimeHistoryResultLabel:"Result",workspaceDetailDebugRuntimeHistoryTitleWithIndex:"Run #{id}",workspaceDetailDebugRuntimeHistoryFailedSummary:"{services} did not start correctly in this run.",workspaceDetailDebugRuntimeHistoryGenericSummary:"Recent start records are kept here so repeated failures are easier to spot.",workspaceDetailDebugRuntimeHistoryNoServices:"None",workspaceDetailDebugRuntimeHistoryResultRunning:"Still Running",workspaceDetailDebugRuntimeHistoryResultFailed:"Start Failed",workspaceDetailDebugRuntimeHistoryResultStopped:"Stopped",workspaceDetailDebugRuntimeHistoryResultPreparing:"Preparing",workspaceDetailDebugRuntimeServicePortLabel:"Assigned Port",workspaceDetailDebugRuntimeServiceBindingLabel:"Port State",workspaceDetailDebugRuntimeServiceProcessLabel:"Process",workspaceDetailDebugRuntimeServiceFailureLabel:"Issue Stage",workspaceDetailDebugRuntimeServiceAiLabel:"Manual Handling Record",workspaceDetailDebugDetectedServicesTitle:"Detected Services",workspaceDetailDebugServicePathLabel:"Location",workspaceDetailDebugServiceFrameworkLabel:"Detected As",workspaceDetailDebugServiceCommandLabel:"Start Command",workspaceDetailDebugServiceRequirementsLabel:"Extra Setup Needed",workspaceDetailDebugServiceActionLabel:"Recommended Action",workspaceDetailDebugOpenPageAction:"Services",workspaceDetailDebugPageTitle:"Services",workspaceDetailDebugPageDescription:"View launchers and current status.",workspaceDetailRegisteredDebugPageHeroEyebrow:"Registered Launchers",workspaceDetailRegisteredDebugPageDescription:"Shows registered launchers and status only.",workspaceDetailRegisteredDebugLoadFailed:"Failed to load registered launchers",workspaceDetailRegisteredDebugOverallStatusReady:"Ready",workspaceDetailRegisteredDebugOverallStatusPartial:"Needs Attention",workspaceDetailRegisteredDebugOverallStatusEmpty:"Not Set",workspaceDetailRegisteredDebugOverallSummary:"{runnable} ready · {orchestrated} adjust · {blocked} blocked",workspaceDetailRegisteredDebugSummaryRegisteredCountLabel:"Launchers",workspaceDetailRegisteredDebugSummaryConfiguredPortLabel:"Port Configured",workspaceDetailRegisteredDebugSummaryRunnableCountLabel:"Runnable Now",workspaceDetailRegisteredDebugSummaryOrchestratedCountLabel:"Needs Adjust",workspaceDetailRegisteredDebugSummaryBlockedCountLabel:"Blocked",workspaceDetailRegisteredDebugSummaryLastRefreshLabel:"Updated",workspaceDetailRegisteredDebugChipRegisteredOnly:"Only Debug entries",workspaceDetailRegisteredDebugChipNoGuessing:"No framework guessing",workspaceDetailRegisteredDebugChipPortDriven:"Runtime is port-driven only",workspaceDetailRegisteredDebugAnalysisTitle:"Project Info",workspaceDetailRegisteredDebugAnalysisDescription:"Shows project info.",workspaceDetailRegisteredDebugAnalysisReadonlyNote:"View only",workspaceDetailRegisteredDebugAnalysisDisplayOnlyHint:"View only",workspaceDetailRegisteredDebugAnalysisRoleLabel:"Type",workspaceDetailRegisteredDebugAnalysisNoService:"No result yet.",workspaceDetailRegisteredDebugAnalysisSourceSummary:"Analysis Source: {sourceType}",workspaceDetailRegisteredDebugTemplatesTitle:"Launchers",workspaceDetailRegisteredDebugTemplatesDescription:"Shows registered launchers only.",workspaceDetailRegisteredDebugTemplatesEmpty:"No launcher yet. Add one in Debug.",workspaceDetailRegisteredDebugOpenProcessManagerAction:"Open Debug",workspaceDetailRegisteredDebugActionSyncTemplates:"Refresh",workspaceDetailRegisteredDebugActionSyncingTemplates:"Refreshing…",workspaceDetailRegisteredDebugActionSyncTemplatesSuccess:"Registered launchers were synced from Debug",workspaceDetailRegisteredDebugActionSyncTemplatesFailed:"Failed to refresh registered launchers",workspaceDetailRegisteredDebugActionRunRegistered:"Start",workspaceDetailRegisteredDebugActionRunningRegistered:"Starting…",workspaceDetailRegisteredDebugActionRunRegisteredSuccess:"Runnable items were dispatched",workspaceDetailRegisteredDebugActionRunRegisteredFailed:"Failed to start registered items",workspaceDetailRegisteredDebugActionRunRegisteredSkipped:"Nothing is ready yet. Clear blockers first.",workspaceDetailRegisteredDebugActionPlanHint:"Check plan first",workspaceDetailDebugPageHeroEyebrow:"Service Overview",workspaceDetailDebugOverallStatusLabel:"Overall Status",workspaceDetailDebugOverallSummaryLabel:"Summary",workspaceDetailDebugOverallStatusSupported:"Ready to Start",workspaceDetailDebugOverallStatusConditional:"Some Services Need More Setup",workspaceDetailDebugOverallStatusBlocked:"Do Not Start Everything Yet",workspaceDetailDebugOverallSummaryEmpty:"No usable service check result is available yet.",workspaceDetailDebugOverallSummaryMixed:"Detected {webCount} web services and {desktopCount} desktop-shell services. Desktop shells are shown separately and excluded from web auto handling.",workspaceDetailDebugOverallSummaryDesktopOnly:"Detected {count} desktop-shell services and no clear web service yet.",workspaceDetailDebugOverallSummaryWebOnly:"Detected {count} web services that can join the web debug flow.",workspaceDetailDebugSummaryServiceCountLabel:"Analysis Items",workspaceDetailDebugSummaryWebCountLabel:"Web Services",workspaceDetailDebugSummaryDesktopShellCountLabel:"Desktop Shells",workspaceDetailDebugSummaryWebServicesChip:"{count} web services",workspaceDetailDebugSummaryDesktopShellChip:"{count} desktop shells",workspaceDetailDebugSummaryUnsupportedChip:"{count} blocking items",workspaceDetailDebugAutoInjectionEligible:"Current web services are ready for automatic handling",workspaceDetailDebugAutoInjectionBlocked:"Do not treat this whole project as auto-ready yet",workspaceDetailDebugDesktopShellSummaryHint:"Desktop shell services are shown separately from web service handling",workspaceDetailDebugCompatibilityBreakdown:"Ready {supported} / Needs setup {conditional} / Not recommended {unsupported}",workspaceDetailDebugLastAnalyzedAtLabel:"Last Check",workspaceDetailDebugTargetSourceRepo:"Scope: Repository Root",workspaceDetailDebugTargetSourceWorktree:"Scope: Current Worktree",workspaceDetailDebugRequirementsNone:"No extra setup required",workspaceDetailDebugServiceSectionDescription:"View the project one service at a time so you can tell what is ready and what still needs setup.",workspaceDetailDebugRuntimeSectionDescription:"This only shows the most recent start result so you can quickly see which service failed to come up.",workspaceDetailDebugMatrixSectionDescription:"This section explains the default support level for each detected service type.",workspaceDetailDebugMatrixTitle:"Support Guidance",workspaceDetailDebugMatrixOpenAction:"Open Support Matrix",workspaceDetailDebugMatrixModalDescription:"Use a real matrix table so people can scan support rules without reading a wall of cards.",workspaceDetailDebugMatrixFrameworkHeader:"Framework",workspaceDetailDebugMatrixCompatibilityHeader:"Support",workspaceDetailDebugMatrixInjectionHeader:"Mode",workspaceDetailDebugMatrixDiscoveryHeader:"Discovery",workspaceDetailDebugMatrixHmrHeader:"HMR",workspaceDetailDebugMatrixCallbackHeader:"Callback",workspaceDetailDebugMatrixAiHeader:"Manual",workspaceDetailDebugMatrixNotesHeader:"Notes",workspaceDetailDebugMatrixCompatibilitySupportedShort:"Ready",workspaceDetailDebugMatrixCompatibilityConditionalShort:"Needs Setup",workspaceDetailDebugMatrixCompatibilityUnsupportedShort:"Avoid",workspaceDetailDebugMatrixCompatibilityUnknownShort:"Unknown",workspaceDetailDebugMatrixInjectionCliShort:"CLI",workspaceDetailDebugMatrixInjectionEnvShort:"ENV",workspaceDetailDebugMatrixInjectionOverrideShort:"CMD",workspaceDetailDebugMatrixInjectionAiFallbackShort:"Manual",workspaceDetailDebugMatrixInjectionNoneShort:"None",workspaceDetailDebugMatrixRequirementRequiredShort:"Needs Work",workspaceDetailDebugMatrixRequirementNotRequiredShort:"Not Needed",workspaceDetailDebugMatrixAiNeverShort:"Do Not Use",workspaceDetailDebugMatrixAiConditionalShort:"Conditional",workspaceDetailDebugMatrixAiAllowedShort:"Allowed",workspaceDetailDebugMatrixLegendSummary:"Icon meanings: check means the default path is clear, warning means you still need setup, and cross means this path is not recommended for automatic handling yet.",workspaceDetailDebugMatrixDiscoveryNote:"Service address handling such as proxy, rewrites, and discovery.",workspaceDetailDebugMatrixHmrNote:"Hot reload and other long-lived frontend dev connections.",workspaceDetailDebugMatrixCallbackNote:"Callback-style entries such as OAuth, login callback, or webhook.",workspaceDetailDebugMatrixAiNote:"Whether edge cases are allowed to fall back to manual help.",workspaceDetailDebugActionAnalyze:"Reanalyze",workspaceDetailDebugActionPlan:"Create Plan",workspaceDetailDebugActionRun:"Start Services",workspaceDetailDebugActionRefresh:"Refresh Status",workspaceDetailDebugActionAnalyzing:"Analyzing…",workspaceDetailDebugActionPlanning:"Creating…",workspaceDetailDebugActionRunning:"Starting…",workspaceDetailDebugActionRefreshing:"Refreshing…",workspaceDetailDebugActionAnalyzeSuccess:"Service analysis has been refreshed",workspaceDetailDebugActionPlanSuccess:"Launch plan created",workspaceDetailDebugActionRunSuccess:"Start command was dispatched and the latest runtime is being refreshed",workspaceDetailDebugActionRefreshSuccess:"Status refreshed",workspaceDetailDebugActionWorkspaceMissing:"The current workspace information is incomplete, so this action cannot run yet.",workspaceDetailDebugActionTargetMissing:"No usable debug target is available yet. Finish analysis first.",workspaceDetailDebugActionAnalyzeFailed:"Failed to refresh analysis",workspaceDetailDebugActionPlanFailed:"Failed to create the launch plan",workspaceDetailDebugActionRunFailed:"Failed to start services",workspaceDetailDebugActionRefreshFailed:"Failed to refresh runtime",workspaceDetailDebugLaunchPlanTitle:"Launch Plan",workspaceDetailDebugLaunchPlanDescription:"View the current plan.",workspaceDetailRegisteredDebugLaunchPlanDescription:"Shows the latest plan.",workspaceDetailRegisteredDebugLaunchPlanGeneratedAtLabel:"Time",workspaceDetailRegisteredDebugLaunchPlanRunnableLabel:"Ready",workspaceDetailRegisteredDebugLaunchPlanOrchestratedLabel:"Adjust",workspaceDetailRegisteredDebugLaunchPlanBlockedLabel:"Blocked",workspaceDetailRegisteredDebugLaunchPlanNote:"Built from current settings.",workspaceDetailDebugLaunchPlanRuntimeIdLabel:"Preparation Record",workspaceDetailDebugLaunchPlanAutoStartLabel:"Result",workspaceDetailDebugLaunchPlanAutoStartAllowed:"Ready to run",workspaceDetailDebugLaunchPlanAutoStartBlocked:"Needs attention",workspaceDetailDebugLaunchPlanSideEffectNote:"Note: “Check Launch Plan” is not a pure preview right now. The backend will create a preparation record.",workspaceDetailDebugLaunchPlanServicePortLabel:"Planned Port",workspaceDetailDebugLaunchPlanServiceAdapterLabel:"Handling Mode",workspaceDetailDebugLaunchPlanServiceFailureLabel:"Blocked At",workspaceDetailDebugLaunchPlanServiceRequirementsLabel:"Missing Requirements",workspaceDetailDebugLaunchPlanServiceAttemptsLabel:"Resolution Chain",workspaceDetailDebugLaunchPlanServiceAiLabel:"Manual Fallback",workspaceDetailDebugLaunchPlanServiceAllowedFilesLabel:"Allowed Files",workspaceDetailDebugLaunchPlanServiceNoRequirements:"No extra blocking requirement right now",workspaceDetailDebugLaunchPlanServiceNoEnvPatch:"No additional environment patch",workspaceDetailDebugLaunchPlanServiceEnvPatchLabel:"Environment Patch",workspaceDetailDebugLaunchPlanDismissAction:"Clear Plan",workspaceDetailDebugFailureStageServiceDiscovery:"Still needs service address handling",workspaceDetailDebugFailureStageHmr:"Still needs hot reload handling",workspaceDetailDebugFailureStageCallback:"Still needs callback handling",workspaceDetailDebugFailureStageAiFallbackRequired:"Needs manual review",workspaceDetailDebugFailureStageAdapterSelection:"No suitable start method was found",workspaceDetailDebugFailureStageLaunchRequirements:"Some launch requirements are still missing",workspaceDetailDebugFailureStageCommandExecution:"The start command did not run correctly",workspaceDetailDebugFailureStageProcessExit:"The service exited right after start",workspaceDetailDebugFailureStageProcessRuntimeError:"The service hit a runtime error",workspaceDetailDebugFailureStageStaleRuntimeBinding:"This start record is no longer valid",workspaceDetailDebugFailureStageUnknown:"Unknown stage ({code})",workspaceDetailDebugBindingAllocated:"Assigned",workspaceDetailDebugBindingListening:"Reachable",workspaceDetailDebugBindingFailed:"Not Ready",workspaceDetailDebugBindingReleased:"Released",workspaceDetailDebugBindingUnknown:"Unknown",workspaceDetailDebugProcessCreating:"Starting",workspaceDetailDebugProcessRunning:"Running",workspaceDetailDebugProcessClosed:"Stopped",workspaceDetailDebugProcessError:"Error",workspaceDetailDebugProcessUnknown:"Unknown",workspaceDetailDebugPortEmpty:"None",workspaceDetailRegisteredDebugTemplatePortMissing:"Not Set",workspaceDetailRegisteredDebugTemplatePathLabel:"Registered Path",workspaceDetailRegisteredDebugTemplatePortLabel:"Port",workspaceDetailRegisteredDebugTemplateRuntimeTypeLabel:"Runtime",workspaceDetailRegisteredDebugTemplateSourceLabel:"Source",workspaceDetailRegisteredDebugTemplateSourceManual:"Manual",workspaceDetailRegisteredDebugTemplateSourceDebugService:"Auto",workspaceDetailRegisteredDebugTemplateSourceManaged:"Generated by System",workspaceDetailRegisteredDebugTemplateProxyLabel:"Proxy",workspaceDetailRegisteredDebugTemplateProxyEnabled:"Enabled",workspaceDetailRegisteredDebugTemplateProxyDisabled:"Disabled",workspaceDetailRegisteredDebugTemplateInjectionModeLabel:"Port Injection",workspaceDetailRegisteredDebugTemplateInjectionModeUnknown:"Not Marked",workspaceDetailRegisteredDebugTemplateServiceDiscoveryLabel:"Service Address Sync",workspaceDetailRegisteredDebugTemplateServiceDiscoverySameOrigin:"Same Origin",workspaceDetailRegisteredDebugTemplateServiceDiscoveryApiBaseUrl:"Inject API_BASE_URL",workspaceDetailRegisteredDebugTemplateServiceDiscoveryNone:"No Extra Handling",workspaceDetailRegisteredDebugTemplateServiceDiscoveryUnknown:"Not Marked",workspaceDetailRegisteredDebugTemplateStatusOccupied:"Busy",workspaceDetailRegisteredDebugTemplateStatusIdle:"Idle",workspaceDetailRegisteredDebugTemplateStatusUntracked:"Unknown",workspaceDetailRegisteredDebugPlanItemCommandLabel:"Command",workspaceDetailRegisteredDebugPlanItemRuntimeLabel:"Runtime",workspaceDetailRegisteredDebugPlanItemActionLabel:"Status",workspaceDetailRegisteredDebugPlanItemReasonLabel:"Reason",workspaceDetailRegisteredDebugPlanActionStart:"Start Directly",workspaceDetailRegisteredDebugPlanActionOrchestrated:"Start After Adjust",workspaceDetailRegisteredDebugPlanActionBlocked:"Cannot Start",workspaceDetailRegisteredDebugPlanReasonPortMissing:"Port is not set",workspaceDetailRegisteredDebugPlanReasonDuplicatePort:"Multiple launchers are registered with the same port, so auto-start is blocked.",workspaceDetailRegisteredDebugPlanReasonDuplicatePortWillOrchestrate:"Port conflict, a new port will be assigned",workspaceDetailRegisteredDebugPlanReasonPortOccupied:"Port is occupied",workspaceDetailRegisteredDebugPlanReasonPortOccupiedWillOrchestrate:"Port is occupied, a new port will be assigned",workspaceDetailRegisteredDebugPlanReasonPortOrchestrated:"Will switch to port {port}",workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryInjected:"Address sync is ready",workspaceDetailRegisteredDebugPlanReasonAnalysisMissing:"Project analysis is missing. Refresh launchers and create the plan again.",workspaceDetailRegisteredDebugPlanReasonServiceDiscoveryMissing:"A backend launcher is required for address sync. Register it in Debug. Ports will be injected automatically.",workspaceDetailRegisteredDebugPlanReasonCallbackMissing:"This callback flow is not handled automatically yet. Confirm the startup flow manually.",workspaceDetailRegisteredDebugPlanReasonRunnable:"Ready to start",workspaceDetailRegisteredDebugLaunchPlanServiceDiscoveryHelp:"If address sync is missing, register the backend launcher in Debug. Ports are adjusted automatically at start time.",workspaceDetailRegisteredDebugRuntimeScopeNote:"Items without a port are skipped.",workspaceDetailRegisteredDebugRuntimeIdle:"Idle",workspaceDetailRegisteredDebugRuntimeUnknown:"No status",workspaceDetailRegisteredDebugRuntimeProcessLabel:"Process",workspaceDetailRegisteredDebugRuntimeCommandLabel:"Process Command Line",workspaceDetailDebugRoleFrontend:"Web Service",workspaceDetailDebugRoleBackend:"Backend Service",workspaceDetailDebugRoleWorker:"Background Worker",workspaceDetailDebugRoleMock:"Mock Service",workspaceDetailDebugRoleDesktopShell:"Desktop Shell",workspaceDetailDebugRoleCustom:"Custom",workspaceDetailDebugServiceOverviewSupported:"This service is clearly identified and is usually ready to start once you follow the recommended handling.",workspaceDetailDebugServiceOverviewConditional:"This service is identified, but still needs a few extra setup steps before it can start cleanly.",workspaceDetailDebugServiceOverviewUnsupported:"This service is not recommended for direct automatic handling yet. Confirm the start flow manually first.",workspaceDetailDebugServiceOverviewUnknown:"This service has not been identified clearly yet. The current result is kept for later review.",workspaceDetailDebugServiceOverviewDesktopShell:"This is a desktop shell service. It is shown separately and does not participate in automatic web-port handling.",workspaceDetailDebugServiceActionSupported:"Start Directly",workspaceDetailDebugServiceActionConditional:"Complete Setup First",workspaceDetailDebugServiceActionUnsupported:"Handle Manually",workspaceDetailDebugServiceActionUnknown:"Confirm Service Type First",workspaceDetailDebugServiceActionDesktopShell:"Handle as Desktop Shell",workspaceDetailDebugAiEditEmpty:"None",workspaceDetailDebugAiEditPending:"Pending",workspaceDetailDebugAiEditApplied:"Applied",workspaceDetailDebugAiEditRolledBack:"Rolled Back",workspaceDetailDebugAiEditRejected:"Rejected",workspaceSessionListBody:"Project sessions, favorites, and archive actions live here instead of hiding in a sidebar.",recentSessionsSectionTitle:"Recent Sessions",recentSessionsSectionBody:"Jump back into the work you touched most recently.",currentWorkspaceSectionTitle:"Current Project Sessions",currentWorkspaceSectionBody:"Keep the sessions for the current project together so the context stays obvious.",sessionIndexTitle:"Sessions deserve their own page",sessionIndexBody:"Recent, favorites, and current-project sessions are split into clear sections for mobile.",toolsMoreAction:"More",toolsSwipeHint:"Swipe left or right to switch between files and Git",toolsSwipePosition:"{current} / {total}",toolFilesBody:"Browse project files, changed files, and code context without relying on a desktop sidebar.",toolGitBody:"Open a clear Git entry for status, commits, and branches in the current project.",toolTerminalsBody:"Open the full terminal page for input-heavy and scroll-heavy tasks.",toolProcessesBody:"Review terminal templates, runtime status, and debug entry points for the current project.",toolsWorkspaceRequiredBody:"Pick a project before opening this tool page.",createSession:"New Session",createSessionModalTitle:"Choose Session Type",createSessionModalDescription:"Pick the session type first, then start the actual session process.",createSessionWorkspaceLabel:"Choose Workspace",createSessionProviderLabel:"Choose Provider",createSessionTarget:"Current Project",createWorktreeSectionTitle:"Child Workspace",createWorktreeSectionDescription:"Create a child workspace from the current project first, then choose the provider for the new session.",createWorktreeAction:"Add Child Workspace",createWorktreeCollapseAction:"Hide Child Workspace Form",createWorktreeBranchLabel:"Branch Name",createWorktreeBranchPlaceholder:"For example: feat/login-codex",createWorktreeBranchRequired:"Enter the child workspace branch name first.",createWorktreeBranchInvalid:"Branch names may only contain letters, numbers, -, _, and /. They cannot start or end with / or contain //.",createWorktreeDisplayNameLabel:"Display Name (Optional)",createWorktreeDisplayNamePlaceholder:"Defaults to the branch name",createWorktreeBaseRefLabel:"Create From Branch/Commit (Optional)",createWorktreeBaseRefPlaceholder:"Defaults to the current branch",createWorktreeBaseRefHint:"You can choose from {localCount} local branches, {remoteCount} remote branches, and {tagCount} tags, or enter a commit hash manually.",createWorktreeBaseRefLoading:"Loading branches and tags from the current repository...",createWorktreeBaseRefLoadFailed:"Failed to load branches and tags. You can still enter a branch, tag, or commit hash manually.",createWorktreeBaseRefLocalGroup:"Local Branches",createWorktreeBaseRefRemoteGroup:"Remote Branches",createWorktreeBaseRefTagGroup:"Tags",createWorktreeBaseRefCurrentBadge:"Current",createWorktreeBaseRefRecommendedBadge:"Recommended",createWorktreeBaseRefEmpty:"No matches found. You can still enter a branch, tag, or commit hash manually.",createWorktreeBaseRefToggle:"Show available branches and tags",createWorktreeHelpAction:"How to Fill This",createWorktreeHelpTitle:"What These Fields Mean",createWorktreeHelpBranchTitle:"Branch Name",createWorktreeHelpBranchBody:"This is the name of the new child workspace. It is also what you will see in the list later. A short name like feat/login is usually enough.",createWorktreeHelpDisplayNameTitle:"Display Name",createWorktreeHelpDisplayNameBody:"Use this if you want a clearer name in the list. If you leave it empty, the branch name will be used automatically.",createWorktreeHelpBaseRefTitle:"Create From Branch/Commit",createWorktreeHelpBaseRefBody:"This decides where the new child workspace starts from. Most of the time, you can keep the default. Only change it if you want to start from another branch, tag, or specific commit.",createWorktreeSubmit:"Create Child Workspace",createWorktreeSubmitting:"Creating...",createWorktreeSucceeded:"Child workspace created: {name}",createWorktreeFailed:"Failed to create child workspace",providerClaudeCode:"Claude Code",providerLegnaCode:"Legna Code",providerCodexDescription:"Create a Codex session for the current default workflow.",providerClaudeDescription:"Create a Claude Code session when you want to switch to another conversation chain.",providerLegnaDescription:"Create a Legna Code session that reuses the Claude-compatible runtime with an independent session store.",providerOpenCodeDescription:"Create an OpenCode session to continue context via the OpenCode service.",providerGeminiDescription:"Create a Gemini session for the native Gemini CLI workflow.",providerKimiDescription:"Create a Kimi session for the native Kimi CLI workflow.",createSessionPresetLabel:"Session Config",createSessionPresetHint:"The default follows the current global preset. Session-level presets are only available for Codex, Claude Code, and Gemini.",createSessionPresetDefault:"Use current default preset",createSessionPresetLoading:"Loading cc-switch presets...",createSessionPresetUnavailable:"cc-switch presets are unavailable right now. You can still start with the default config.",createSessionStartAction:"Open Draft Session",providerChecking:"Checking...",startClaude:"Claude",startCodex:"Codex",startingSession:"Creating...",startClaudeSuccess:"Claude session created",startCodexSuccess:"Codex session created",startSessionFailed:"Failed to create session",auxiliaryTitle:"Info",auxiliarySubtitle:"Files and Git status",expandAuxiliary:"Expand",collapseAuxiliary:"Collapse",auxiliaryEmptyTitle:"Select a session",auxiliaryEmptyBody:"Session files and Git info will appear here",batchSelectSessions:"Select Sessions in Bulk",batchSelectionMode:"Batch Selection",selectAllSessions:"Select All",clearSelectedSessions:"Clear Selection",batchArchiveAction:"Archive Selected",batchArchiving:"Archiving...",batchArchiveSuccess:"Selected sessions archived",batchArchivePartialFailed:"Some sessions failed to archive. Retry.",batchArchiveFailed:"Batch archive failed",batchDeleteAction:"Delete Selected",batchDeleting:"Deleting...",batchDeleteSuccess:"Selected sessions deleted",batchDeletePartialFailed:"Some sessions failed to delete. Retry.",batchDeleteFailed:"Batch delete failed",batchDeleteConfirmTitle:"Delete Selected Sessions",batchDeleteConfirmDescription:"The selected {count} sessions will be removed from the assistant history and workspace list, and the underlying records will be deleted permanently.",batchDeleteSelectionSummary:"{count} sessions selected",hideSessionSidebar:"Hide Session List",showSessionSidebar:"Show Session List",hideInfoSidebar:"Hide Info Sidebar",showInfoSidebar:"Show Info Sidebar",centerTabsLabel:"Center Area Tabs",infoTabsLabel:"Info Sidebar Tabs",leftResizerLabel:"Resize Left Sidebar",rightResizerLabel:"Resize Right Sidebar",filesPanelEmpty:"Import or select a workspace first to use file management.",gitPanelEmpty:"Import or select a workspace first to view Git info.",infoPanelDeferred:"The left session list loads first. The right auxiliary panel mounts slightly later."},workbench:{emptyEyebrow:"Start",emptyTitle:"Choose a session first",emptyBody:"Continue from the left, or create a new session.",emptyResumeTitle:"Continue",emptyResumeBody:"Go back to where you stopped.",emptyNewTitle:"New session",emptyNewBody:"Put a new question into a clean session.",emptyCompanionTitle:"Side details",emptyCompanionBody:"Open files, Git, or terminal on the right when needed.",emptyTip:"When you are ready, pick a session from the left."},conversation:{resendButton:"Resend",historyLoading:"Loading...",historyLoadingOlder:"Loading older messages...",historyLoadFailed:"Load failed",inheritedContextLoading:"Preparing inherited context from the parent session...",inheritedContextMessageLabel:"Inherited context before the forked message",inheritedContextSessionLabel:"Inherited context from the parent session",inheritedContextSummary:'Collapsed {count} inherited messages from "{parentTitle}" by default.',actionInheritedSelectionSummary:'Collapsed the selected text from "{parentTitle}" by default.',inheritedContextExpand:"Show inherited context",inheritedContextCollapse:"Hide inherited context",inheritedContextParentFallback:"Parent session",timelineEmpty:"Start Conversation",composerPlaceholder:"State the next step clearly. Let the session continue from there.",sendButton:"Send Message",attachFiles:"Attach File",attachmentSourceSheetTitle:"Add Files",attachmentSourceSheetDescription:"Choose one or more files from the system picker, or capture a photo.",attachmentTakePhoto:"Take Photo",attachmentTakePhotoHint:"Open the camera and attach a new photo",attachmentChooseFromLibrary:"Choose Files",attachmentChooseFromLibraryHint:"Open the system file picker and add one or more files",pasteImagesHint:"Supports pasting files directly",attachmentImageOnly:"Only image attachments are supported right now",attachmentReadFailed:"Failed to read attachment. Retry.",attachmentPreviewAlt:"Selected image preview",attachmentPreviewOpen:"Open attachment",attachmentPreviewClose:"Close preview",attachmentPreviewLoading:"Loading attachment...",attachmentPreviewUnavailable:"Attachment unavailable",attachmentDownload:"Download attachment",toolWebSearch:"Web search",toolWebSearchQueryLabel:"Query",toolWebSearchSourcesLabel:"Sources",toolWebSearchUntitledSource:"Untitled source",attachmentDropHint:"Drop files here to attach them",imageAttachmentLabel:"Image Attachment",fileAttachmentLabel:"File Attachment",imagePreviewTitle:"Image Preview",imagePreviewHint:"Click the backdrop or press Esc to close the preview",removeAttachment:"Remove Attachment",selectionTodoAction:"Todo",selectionActionButton:"Action",selectionActionSubmit:"Open action child session",selectionActionPromptLabel:"What should it do",selectionActionPromptPlaceholder:"For example: explain this, turn it into notes, or send it to a specific API",selectionActionIncludeContext:"Include current context",selectionActionContextUnavailable:"This selection spans multiple messages, so context inheritance is disabled for safety.",selectionActionDefaultPrompt:"Please process this content.",selectionActionPreviewLabel:"Selected content",selectionActionTargetLabel:"New session settings",selectionActionQuotedLabel:"Selected text",selectionActionFailed:"Failed to create the action child session.",actionSessionBadge:"Action",modelSelectorLabel:"Model",modelUseCliDefault:"Default",deploymentDefaultPreset:"Default",deploymentConfigColumn:"Config",deploymentModelColumn:"Model",deploymentLoading:"Loading deployments...",deploymentModelLoading:"Loading models...",deploymentModelEmpty:"No models are available for this config yet.",modelUseCodexConfig:"Follow current Codex config",modelUseOpenCodeConfig:"Follow current OpenCode config",reasoningSelectorLabel:"Reasoning Effort",reasoningLow:"Low",reasoningMedium:"Medium",reasoningHigh:"High",reasoningMaximum:"Maximum",slashMenu:"Commands",slashMenuTitle:"Quick Commands",slashCommandPlan:"Ask for an execution plan first",slashCommandReview:"Switch directly to code review mode",slashCommandExplain:"Ask for a clearer explanation",toolInputLabel:"Input",toolResultLabel:"Result",toolResultEmpty:"No output yet",toolPreviewCommand:"Command",toolPreviewTerminal:"Terminal",toolViewImageActiveLabel:"AI is viewing an image",toolStatusRunning:"Running",toolStatusFailed:"Failed",toolStatusCompleted:"Completed",runtimeThinkingPlaceholder:"{provider} is thinking...",applyPatchEditedLabel:"Edited",applyPatchAddedLabel:"Added",applyPatchDeletedLabel:"Deleted",applyPatchDialogTitle:"Patch Change Preview",applyPatchDialogDescription:"This shows the file-level changes that apply_patch is about to perform.",applyPatchOpenDiff:"View Diff",applyPatchEditedStat:"Edited",applyPatchAddedStat:"Added",applyPatchRemovedStat:"Removed",applyPatchEmpty:"This patch does not contain any file change that can be displayed right now.",titleFallback:"Continue Conversation",draftTitleCodex:"New Codex session",draftTitleClaude:"New Claude Code session",draftTitleLegna:"New LegnaCode session",draftTitleOpenCode:"New OpenCode session",draftTitleGemini:"New Gemini session",draftTitleKimi:"New Kimi session",headerWorkspace:"Workspace",headerWorkspaceUnknown:"Unknown Workspace",headerProvider:"Provider",headerConnection:"Connection",headerRuntime:"Runtime",providerCodex:"Codex",branchTreeAction:"Branch Tree",branchTreeTitle:"Branch Tree",branchTreeDescription:"This panel only shows the parent-child chain around the current session.",branchTreeUpstreamLabel:"Upstream Chain",branchTreeCurrentLabel:"Current Session",branchTreeChildrenLabel:"Child Branches",branchTreeCurrentBadge:"Current",branchTreeArchivedBadge:"Archived",branchTreeEmpty:"This session does not have any child branches yet.",branchTreeMapTitle:"Branch Map",branchTreeMapDescription:"This view expands the full branch family around the current session.",branchTreePreviewTitle:"Session Preview",branchTreePreviewDescription:"Click a node to float its latest messages before switching.",branchTreePreviewLoading:"Loading recent messages for this session...",branchTreePreviewFailed:"Failed to load the session preview.",branchTreePreviewEmpty:"There are no recent messages to preview for this session.",branchTreeResizeHandle:"Resize branch tree width",branchTreeZoomInAction:"Zoom in branch map",branchTreeZoomOutAction:"Zoom out branch map",branchTreeZoomResetAction:"Reset branch map zoom",branchTreeSwitchAction:"Switch to This Session",branchTreeCurrentAction:"Already Current",branchTreeToolMessageFallback:"tool message",branchTreeMessageEmpty:"This message does not have visible text.",moreSessionActions:"More session actions",branchAction:"Branch",moreSessionActionsTitle:"More Session Actions",moreSessionActionsDescription:"Branch navigation and assistant actions live here so the mobile header stays clean.",branchTreeTab:"Branch Tree",aiAssistantTab:"Assistant",aiAssistantTabDescription:"Use the assistant entry here when you want to continue follow-up or start verification for this session.",providerClaude:"Claude",providerLegna:"Legna",providerOpenCode:"OpenCode",providerGemini:"Gemini",providerKimi:"Kimi",capabilitySend:"Send Enabled",queueTitle:"Queued Messages",queueDescription:"After the current run finishes, these messages will be processed automatically in order.",queueOrderPrefix:"Queue Position",queueStatusQueued:"Queued",queueStatusFailed:"Dispatch Failed",queueDelete:"Delete",queueDeleting:"Deleting",permissionRequestSectionTitle:"Pending approvals",permissionRequestSectionDescription:"Provider-side approvals are unified here so you do not need to learn three different dialogs.",permissionRequestToastTitle:"Approval needed",backgroundPermissionToastDescription:"{title} · {requestTitle}",backgroundCompletionToastTitle:"Session completed",backgroundCompletionToastDescription:"{title}",backgroundFailureToastTitle:"Session failed",backgroundFailureToastDescription:"{title} · {detail}",permissionRequestReplyFailed:"Failed to reply to the approval request.",permissionRequestSubmitting:"Submitting...",permissionRequestReasonLabel:"Reason",permissionRequestCommandLabel:"Command",permissionRequestToolLabel:"Tool",permissionRequestCwdLabel:"Working directory",permissionRequestPathsLabel:"Related paths",permissionRequestPermissionsLabel:"Requested permissions",permissionRequestReadLabel:"Read",permissionRequestWriteLabel:"Write",permissionRequestNetworkLabel:"Network",permissionRequestQuestionsLabel:"Questions",permissionRequestDetailLabel:"Details",permissionRequestEmpty:"None",permissionRequestUnknown:"Unknown",permissionRequestKindCommand:"Command",permissionRequestKindFileChange:"File Change",permissionRequestKindPermissions:"Permissions",permissionRequestKindUserInput:"User Input",permissionRequestKindToolCall:"Tool Call",queueImageOnly:"Image attachments only",sendGuidanceButton:"Add Guidance",queueGuidanceButton:"Queue Guidance",capabilityDenied:"Restricted",capabilitySendDisabled:"Sending disabled",connectionConnected:"Realtime connected",connectionReconnecting:"Reconnecting",connectionReconnectFailed:"Reconnect failed",connectionClosed:"Connection closed",runtimeIdle:"Idle",runtimeStarting:"Starting",runtimeRunning:"Running",runtimeReconnecting:"Recovering",runtimeStale:"Awaiting confirmation",runtimeUnknown:"Status pending",runtimeCompleted:"Completed",runtimeInterrupted:"Interrupted",runtimeFailed:"Failed",rulesMessageTitle:"Rules",rulesMessageHint:"This is the startup rule block for the session. It is collapsed by default and can be expanded when needed.",rulesMessageExpand:"Expand Rules",rulesMessageCollapse:"Collapse Rules",skillContextTitle:"Assistant Skill",skillContextHint:"This is the Skill context injected at Claude Code session startup. It is collapsed by default and can be expanded when needed.",skillContextExpand:"Expand Skill",skillContextCollapse:"Collapse Skill",systemPromptTitle:"System Prompt",systemPromptHint:"This is the Kimi startup system prompt for the session. It is collapsed by default and can be expanded when needed.",systemPromptExpand:"Expand Prompt",systemPromptCollapse:"Collapse Prompt",taskProgressButton:"Task Progress ({count})",taskProgressModalTitle:"Task Progress",taskProgressModalDescription:"This session has recorded {count} tasks. Check the latest progress here.",taskProgressExplanationTitle:"Latest Update Note",taskProgressSummaryTotal:"Total",taskProgressStatusPending:"Pending",taskProgressStatusInProgress:"In Progress",taskProgressStatusCompleted:"Completed",taskProgressStatusFailed:"Failed",taskProgressStatusCancelled:"Cancelled",taskCardPlanTitle:"Plan Update",taskCardTodoTitle:"Task Update",taskCardPlanUpdated:"Latest Plan",taskCardTodoUpdated:"Latest Task List",taskCardRawExpand:"Show Raw Call",taskCardRawCollapse:"Hide Raw Call",taskCardSummaryTotal:"{count} total",taskCardSummaryInProgress:"{count} in progress",taskCardSummaryPending:"{count} pending",taskCardSummaryCompleted:"{count} completed",taskCardSummaryFailed:"{count} failed",butlerActionButton:"Assistant",butlerActionModalTitle:"Butler Actions",butlerActionModalDescription:"Ask Butler to continue this development session or start a development verification run.",butlerActionLoading:"Loading Butler action context...",butlerActionLoadFailed:"Failed to load Butler action context",butlerActionProjectLabel:"Project",butlerActionSessionLabel:"Session",butlerFollowUpAction:"Continue Follow-up",butlerFollowUpActionDescription:"Let Butler keep watching this session and continue pushing it after each stop or blocker.",butlerFollowUpProviderLabel:"Follow-up Assistant",butlerFollowUpProviderHint:"Choose which CLI-backed assistant should own this follow-up session. Later rounds reuse the same visible assistant session.",butlerFollowUpObjectiveLabel:"Follow-up Goal",butlerFollowUpObjectivePlaceholder:"Example: finish this feature for me; if the spec still has unfinished work, keep going.",butlerFollowUpCompletionCriteriaLabel:"Finish Conditions",butlerFollowUpCompletionCriteriaPlaceholder:"Example: only stop once the current feature is finished against the agreed requirements.",butlerFollowUpCompletionCriteriaRequired:"Choose or write an explicit stop condition first so Butler knows exactly when to stop",butlerCompletionTemplateSectionLabel:"Stop Templates",butlerCompletionTemplateSectionHint:"Pick one explicit template. It replaces the stop condition and must still stop when the round limit is reached.",butlerCompletionTemplateRecommendedLabel:"Standard Finish",butlerCompletionTemplateRecommendedDescription:"Stop after the feature is done and verified",butlerCompletionTemplateRecommendedValue:"Stop only when the current feature is complete for this request, one development verification or manual confirmation has finished, and there is no blocking item that must still be pushed forward; if the next step recommended by AI is not required for the core goal, it must also stop; once the auto-continue round limit is reached, it must also stop and must not keep extending the session.",butlerCompletionTemplateSpecLabel:"Spec Wrap-up",butlerCompletionTemplateSpecDescription:"Finish the must-do items in the current spec",butlerCompletionTemplateSpecValue:"Stop only when the must-do tasks in the current spec are complete, the related code, docs, and required verification are all in place, and there is no blocking item that still must be pushed forward; if the next step recommended by AI is not required for the core goal, it must also stop; do not expand into new scope; once the auto-continue round limit is reached, it must also stop.",butlerCompletionTemplateBugfixLabel:"Bug Fix",butlerCompletionTemplateBugfixDescription:"Fix the issue and confirm there is no high-priority regression",butlerCompletionTemplateBugfixValue:"Stop only when this issue has been diagnosed and fixed, the related verification has passed, and there is no new high-priority regression that needs immediate work; if the next step recommended by AI is not required for the core goal, it must also stop; follow-up ideas and optimizations are not valid reasons to keep pushing; once the auto-continue round limit is reached, it must also stop.",butlerFollowUpRoundLimitLabel:"Max Auto Follow-up Rounds",butlerFollowUpRoundLimitHint:"Once the limit is reached, Butler stops auto-resuming so the session does not expand forever.",butlerCurrentFollowUpLabel:"Current Follow-up",butlerCurrentFollowUpProgress:"Auto-continued {current} / {max} rounds",butlerFollowUpStopping:"Stopping follow-up...",butlerStopFollowUpAction:"Stop Current Follow-up",butlerFollowUpObjectiveRequired:"Please describe the goal you want Butler to keep pushing",butlerCurrentVerificationLabel:"Current Verification",butlerStopVerificationAction:"Stop Current Verification",butlerVerificationAction:"Start Verification",butlerVerificationActionDescription:"Let Butler start a user-facing verification run for the feature behind this session.",butlerFollowUpStarted:"Butler follow-up started",butlerFollowUpStartedDescription:"Butler will continue following the current development session for {projectName}.",butlerFollowUpFailed:"Failed to start Butler follow-up",butlerFollowUpStopped:"Current Butler follow-up stopped",butlerFollowUpStoppedDescription:"Automatic follow-up for the current session has been stopped and will not auto-resume.",butlerFollowUpStopFailed:"Failed to stop Butler follow-up",butlerVerificationStarted:"Development verification started",butlerVerificationStartedDescription:"Butler will start a development verification run for {projectName}.",butlerVerificationFailed:"Failed to start development verification",butlerVerificationStopping:"Stopping verification...",butlerVerificationStopped:"Current development verification stopped",butlerVerificationStoppedDescription:"The current verification has been stopped, and the linked automation has been ended as well.",butlerVerificationStopFailed:"Failed to stop development verification",butlerAnalysisTitle:"Butler Analysis",butlerAnalysisLoadFailed:"Failed to load Butler analysis",butlerAnalysisObjectiveLabel:"Objective",butlerAnalysisStatusLabel:"Decision",butlerAnalysisSummaryLabel:"Latest analysis",butlerAnalysisWaitingReasonLabel:"Waiting reason",butlerAnalysisEmpty:"There is no Butler analysis record yet.",butlerProxyMessageBadge:"Sent by Butler",butlerOriginDetailTitle:"Related Butler Follow-up",butlerOriginDetailLoading:"Loading the related Butler follow-up...",butlerOriginDetailLoadFailed:"Failed to load the related Butler follow-up",butlerOriginDetailObjectiveLabel:"Objective",butlerOriginDetailStatusLabel:"Status",butlerOriginDetailSummaryLabel:"Latest analysis",butlerOriginDetailWaitingReasonLabel:"Waiting reason",assistantCapabilityBadgeSession:"Assistant Session",assistantCapabilityBadgeAutomation:"Assistant Automation",assistantCapabilityBadgeTerminal:"Assistant Terminal",assistantCapabilityBadgeWorkspace:"Assistant Workspace",assistantCapabilityBadgeDebug:"Assistant Debug",assistantCapabilityBadgeQuery:"Assistant Query",assistantCapabilityProjectSessionStartTitle:"Create Session",assistantCapabilitySessionSendTitle:"Send Message",assistantCapabilitySessionForkTitle:"Fork Session",assistantCapabilityTimerCreateTitle:"Create Automation",assistantCapabilityTimerCancelTitle:"Cancel Automation",assistantCapabilityTerminalInputTitle:"Send Terminal Input",assistantCapabilityTerminalCloseTitle:"Close Terminal",assistantCapabilityWorkspaceDirectoryCreateTitle:"Create Directory",assistantCapabilityWorkspaceImportTitle:"Import Workspace",assistantCapabilityWorkspaceCloneTitle:"Clone Workspace",assistantCapabilityWorkspaceNavigationUpdateTitle:"Update Workspace View",assistantCapabilityWorkspaceRemoveTitle:"Remove Workspace",assistantCapabilityWorktreeCreateTitle:"Create Worktree",assistantCapabilityWorktreeMergeTitle:"Merge Worktree",assistantCapabilityWorktreeCleanupTitle:"Clean Up Worktree",assistantCapabilityDebugRunTitle:"Start Debug Run",assistantCapabilitySessionReadTitle:"Read Session Info",assistantCapabilityAutomationReadTitle:"Read Automation Info",assistantCapabilityTerminalReadTitle:"Read Terminal Info",assistantCapabilityWorkspaceReadTitle:"Read Workspace Info",assistantCapabilityDebugReadTitle:"Read Debug Info",assistantCapabilityQueryTitle:"Assistant Action",assistantCapabilitySummarySessionStart:"A real session was created with the current assistant settings.",assistantCapabilitySummarySessionSend:"The message was submitted to the target real session.",assistantCapabilitySummarySessionFork:"A new session was forked from the current context.",assistantCapabilitySummaryTimerCreate:"A follow-up automation was created.",assistantCapabilitySummaryTimerCancel:"The pending follow-up automation was cancelled.",assistantCapabilitySummaryTerminalInput:"Input was sent to the target terminal.",assistantCapabilitySummaryTerminalClose:"The target terminal was closed.",assistantCapabilitySummaryWorkspace:"The workspace action has been executed.",assistantCapabilitySummaryWorktree:"The worktree action has been executed.",assistantCapabilitySummaryDebug:"The debug action has been triggered.",assistantCapabilitySummaryRead:"The assistant finished this read operation.",assistantCliSummaryHelp:"The matching assistant help command has been queried.",assistantCliSummaryCommand:"The assistant command has been issued.",assistantCliHelpRootTitle:"View Assistant Help",assistantCliHelpSessionsTitle:"View Session Help",assistantCliHelpSessionActionTitle:"View Session Action Help: {action}",assistantCliHelpTimersTitle:"View Automation Help",assistantCliHelpTerminalsTitle:"View Terminal Help",assistantCliHelpWorkspacesTitle:"View Workspace Help",assistantCliHelpGenericTitle:"View {group} Help",assistantCapabilityRawExpand:"View Raw",assistantCapabilityRawCollapse:"Hide Raw",assistantCapabilityLabelWorkspace:"Workspace",assistantCapabilityLabelSession:"Session",assistantCapabilityLabelTerminal:"Terminal",assistantCapabilityLabelTimer:"Automation",assistantCapabilityLabelProvider:"Provider",assistantCapabilityLabelDueAt:"Time",assistantCapabilityLabelStatus:"Status",assistantCapabilityLabelPath:"Path",assistantCapabilityLabelBranch:"Branch",assistantCapabilityLabelRuntime:"Runtime",assistantCapabilityLabelCount:"Count",assistantCapabilityLabelDebugTarget:"Debug Target",assistantCliLabelScope:"Scope",assistantCliLabelAction:"Action",assistantCliLabelProject:"Project",assistantCliLabelMessage:"Message",assistantCliLabelInput:"Input",assistantCliLabelDelay:"Delay",assistantCliScopeRoot:"Root Command",assistantCapabilityNavigationCollapsed:"Collapsed",assistantCapabilityNavigationExpanded:"Expanded",assistantCapabilityStatusActive:"Active",assistantCapabilityStatusCompleted:"Completed",assistantCapabilityStatusCancelled:"Cancelled",assistantCapabilityStatusFailed:"Failed",thinkingLabel:"Thinking",filePanelWorkspaceTab:"Workspace",filePanelSessionTab:"Session",filePanelSessionViewLabel:"Session File View",filePanelSessionTreeView:"Tree",filePanelSessionListView:"List",filePanelSessionLoading:"Collecting files changed in this session...",filePanelSessionEmpty:"No cacheable changed files have been detected in this session yet.",filePanelSessionNoSession:"Only the workspace is selected right now. Pick a session before viewing session-scoped files.",filePanelSessionStageAll:"Stage All",filePanelSessionStageSuccess:"Changes from this session have been added to the staging area.",filePanelSessionLoadFailed:"Failed to load changed files for this session.",filePanelSessionSummary:"Detected Files",filePanelSessionUnstagedSummary:"Unstaged",filePanelSessionDeleted:"Deleted",filePanelOpenExternalWindow:"Open in New Window",filePanelOpenExternalFailed:"Failed to open the file window externally."},desktopWindow:{invalidWindowId:"The external window is missing a window id.",loadDescriptorFailed:"Failed to load the window descriptor.",unsupportedKind:"Rendering the {kind} window is not supported yet.",invalidFilePreviewTarget:"The file preview window is missing its file target.",invalidAffairsTarget:"The affairs window is missing its workspace target.",invalidCodeTarget:"The code window is missing its route target."},git:{recentVersionsTitle:"Recent Versions",stagedChangesTitle:"Staged Changes",expandRecentVersions:"Expand Recent Versions",collapseRecentVersions:"Collapse Recent Versions",stagedLabel:"Staged",workingTreeLabel:"Working Tree",changeTreeHint:"Show current changes by directory hierarchy",discard:"Discard Changes",discardFailed:"Failed to discard changes",operationMenu:"Actions",currentBranch:"Current Branch",resizePanels:"Resize file and recent-version panels",switchBranchTo:"Switch To",undoLastCommit:"Undo Last Commit",undoLastCommitFailed:"Failed to undo last commit",undoLastCommitSuccess:"Last commit undone",historyKindLocal:"Local",historyKindRemote:"Remote",historyKindShared:"Synced",pushNow:"Push",commitNow:"Commit",refreshNow:"Refresh",openExternalWindow:"Open Git in New Window",openExternalFailed:"Failed to open the Git window externally.",stageAll:"Stage All",unstageAll:"Unstage All",discardAll:"Discard All Changes",selectedFiles:"Selected Files",clearSelection:"Clear Selection",selectFile:"Select File",discardConfirm:"Discard these changes? {path}",historyItemMenu:"Commit Actions",copyCommitHash:"Copy Commit Hash",copyCommitHashSuccess:"Commit hash copied.",copyCommitSubject:"Copy Commit Title",copyCommitSubjectSuccess:"Commit title copied."},terminalManager:{workspaceField:"Current Workspace",refresh:"Refresh List",loadFailed:"Failed to load the terminal management panel",shellLoadFailed:"Failed to load the terminal shell list",emptyWorkspaceBody:"There is no available workspace yet.",noCurrentWorkspaceBody:"Select a session first so process management can bind to its workspace.",emptyTerminalBody:"There is no terminal instance in the current workspace yet.",emptyTemplateBody:"There is no quick launch item yet. Save a command or script first.",shellField:"Shell for New Terminal",shellUnavailable:"Unavailable",cwdField:"Startup Directory",cwdLabel:"Directory",cwdPlaceholder:"Defaults to the workspace root when left empty",modeField:"Launch Mode",commandMode:"Command",scriptMode:"Script",quickLaunchDescription:"Save a launch preset here so you can start it in a new terminal with one click later.",desktopPanelDescription:"Keep the default view focused on launch decisions, while paths and command lines stay inside the details layer.",openExternalWindow:"Open in New Window",openExternalFailed:"Failed to open the process management window externally.",runningCountLabel:"Running",portWatchCountLabel:"Watched Ports",terminalCountLabel:"Terminals",templateSectionTitle:"Launch Items",templateSectionDescription:"The right side prioritizes the port status of launch items so you can see whether a service is already in use.",openWorkspaceDebugAction:"Debug Services",openCreateModalAction:"Add Quick Launch Item",createModalTitle:"Add Quick Launch Item",createModalDescription:"Save a command or script here. You can attach a port and then start it with one click while checking whether it is already running.",editAction:"Edit Launch Item",editModalTitle:"Edit Quick Launch Item",editModalDescription:"Update the name, command, directory, and port for this quick launch item.",saveTemplateChangesAction:"Save Changes",templateUpdating:"Saving changes...",templateUpdateSuccess:"Quick launch item updated.",templateUpdateFailed:"Failed to update quick launch item",removeAction:"Remove Launch Item",templateRemoving:"Removing...",removeConfirmTitle:"Remove Quick Launch Item",removeConfirmAction:"Remove Item",removeConfirmTarget:'Remove "{name}"? It will disappear from the quick launch list after removal.',removeRunningConfirmTarget:'"{name}" is still running. Removing it only deletes the launch item configuration and will not stop the active process. Continue?',templateDeleteSuccess:"Quick launch item removed.",templateDeleteFailed:"Failed to remove quick launch item",terminalSectionTitle:"Terminal Instances",terminalSectionDescription:"This area shows terminals currently managed by CodingNS for the workspace.",closeAction:"Close Terminal",closing:"Closing...",closeSuccess:"Terminal close request submitted.",closeFailed:"Failed to close terminal",createTerminalAction:"New Empty Terminal",creatingTerminal:"Creating...",createTerminalSuccess:"New terminal created.",createTerminalFailed:"Failed to create a new terminal",defaultTerminalName:"Workspace Terminal",templateNameField:"Name",templateNamePlaceholder:"Generated automatically when left empty",commandField:"Launch Command",commandPlaceholder:"For example: npm",scriptPathField:"Script Path",scriptPathPlaceholder:"For example: scripts/dev.ps1 or scripts/dev.sh",argsField:"Arguments",argsPlaceholder:"For example: run dev or --watch",portField:"Listening Port",portLabel:"Port",portPlaceholder:"For example: 3000",proxyField:"Reverse Proxy",proxyToggleLabel:"Enable Reverse Proxy",proxyEnabled:"Proxy Enabled",proxyEnabledDescription:"When enabled, the system generates a random URL code and exposes your dev service under /proxy/.",proxyDisabledDescription:"Reverse proxy is disabled",proxyPortRequired:"A listening port is required when reverse proxy is enabled",openProxyUrlAction:"Open Proxy URL",openProxyUrlFailed:"Failed to open proxy URL",invalidPort:"Port must be an integer between 1 and 65535",saveLaunchAction:"Save as Quick Launch",templateSaving:"Saving...",templateSaveSuccess:"Quick launch item saved.",templateSaveFailed:"Failed to save quick launch item",runTemplateAction:"Run in New Terminal",runningTemplate:"Starting...",templateRunSuccess:"Quick launch item sent to a new terminal.",templateRunFailed:"Failed to run quick launch item",showDetailsAction:"Show details",hideDetailsAction:"Hide details",detailsSectionTitle:"Launch item details",commandPreviewLabel:"Launch Command",processIdLabel:"Listener PID",processGroupIdLabel:"Process Group PGID",processCommandLabel:"Listener Command Line",parentProcessIdLabel:"Parent PID",parentProcessCommandLabel:"Parent Command Line",terminationScopeLabel:"Stop Scope",terminationScopeProcess:"Listener only",terminationScopeProcessGroup:"Whole process group",stopProcessAction:"Stop Process",stoppingProcess:"Stopping...",stopProcessSuccess:"The listening process or its process group has been stopped.",stopProcessFailed:"Failed to stop the listening process or process group",defaultCommandName:"New Launch Command",defaultScriptName:"New Launch Script",lastActiveAt:"Last Active",updatedAt:"Updated At",processCommandFallback:"This process did not expose its command line",portUnset:"Port Not Configured",portUnsetDescription:"Without a port, the item can only be started. The system cannot determine automatically whether the service is running.",portOccupied:"Process Started",portAvailable:"Port Available",portAvailableDescription:"There is currently no listening process on the port used by this launch item.",statusRunning:"Running",statusStopped:"Stopped",exitCode:"Exit Code",runningValue:"Running"},theme:{light:"浅色",dark:"深色",skyBlue:"赛博",eyeGreen:"护眼",switchLabel:"Theme"}},vp={"zh-CN":ch,"en-US":sh},nb={butlerInitTitle:"设置助手",butlerInitDescription:"先完成几个基本设置。",butlerInitPreviewTitle:"当前效果",butlerInitPreviewDescription:"",butlerInitBasicsTitle:"基本信息",butlerInitBasicsDescription:"",butlerInitPersonaTitle:"说话方式",butlerInitPersonaDescription:"",butlerInitPreferenceTitle:"默认偏好",butlerInitPreferenceDescription:"",butlerInitRuleLabel:"规则方式",butlerInitPreviewRuleLabel:"管理方式",butlerInitTipAutoWorkspace:"",butlerInitTipProviderSwitch:"",butlerInitTipReportPriority:"",butlerDisplayNameLabel:"助手称呼",butlerDisplayNamePlaceholder:"例如:小助手",butlerDisplayNameHint:"这个名字会显示在助手页面里。",butlerProviderLabel:"助手引擎",butlerAgentsModeLabel:"规则方式",butlerAgentsModeInline:"自动管理",butlerAgentsModeFile:"手动编辑",butlerAgentsModeInlineDescription:"规则由系统自动管理。",butlerAgentsModeFileDescription:"会生成一份可编辑的规则文件。",butlerPersonaToneLabel:"语气",butlerPersonaLanguageLabel:"使用语言",butlerPersonaSummaryStyleLabel:"回答风格",butlerFocusRiskPreferenceLabel:"处理方式",butlerFocusReportPriorityLabel:"优先提醒",butlerToneDirect:"直接",butlerToneSteady:"稳重",butlerToneFriendly:"亲切",butlerLanguageZhCn:"中文",butlerLanguageEnUs:"英文",butlerLanguageBilingual:"中英双语",butlerSummaryBrief:"简洁",butlerSummaryStructured:"清晰",butlerSummaryThorough:"详细",butlerRiskConservative:"保守稳妥",butlerRiskBalanced:"平衡",butlerRiskProactive:"主动提醒",butlerReportPriorityPresetLabel:"优先提醒",butlerSummaryDebounceLabel:"摘要节奏",butlerSettingsTitle:"助手设置",butlerSettingsSaveAction:"保存设置",butlerSettingsSaving:"保存中...",butlerSettingsSaved:"助手设置已保存",butlerSettingsSaveFailed:"保存助手设置失败",butlerInitSubmitting:"保存中...",butlerInitSubmit:"完成设置",butlerInitSuccess:"助手已设置完成",butlerInitFailed:"助手设置失败",butlerInitNameRequired:"请先填写助手名称",affairsInitSubmit:"完成事务模式初始化",affairsInitSuccess:"事务模式已设置完成",affairsInitFailed:"事务模式设置失败",affairsInitPreviewRuleLabel:"事务助手方式",affairsInitLibraryTitle:"文档库设置",affairsInitLibraryDescription:"先决定要不要直接接入文档库。",affairsInitLibraryEnabledLabel:"文档库",affairsInitLibraryEnabledHint:"启用后会在初始化完成后直接接入。",affairsInitLibraryPathHint:"这里填文档库路径,后面还能修改。",affairsInitLibraryPathRequired:"启用文档库前,请先选择文档库路径",affairsConnectionCheckingTitle:"正在连接事务服务",affairsConnectionCheckingDescription:"先确认 Host 能不能连上,再决定显示哪个页面。",affairsConnectionCheckingSidebarEmpty:"正在检查连接状态,左侧分区稍后再加载。",affairsConnectionCheckingAuxiliaryEmpty:"正在检查连接状态,右侧详情区稍后再加载。",affairsHostUnavailableTitle:"暂时连不上事务服务",affairsHostUnavailableDescription:"这不是没初始化,而是前端现在连不上 Host。",affairsHostUnavailableRetryAction:"重新连接",affairsHostUnavailableRetryHint:"重试只会重新检查连接,不会改你的初始化状态。",affairsHostUnavailableErrorTitle:"连接报错",affairsHostUnavailableSidebarEmpty:"连接恢复前,左侧分区内容暂时加载不出来。",affairsHostUnavailableAuxiliaryEmpty:"连接恢复前,右侧详情区暂时拿不到对象内容。",affairsInitRouteGuardHint:"事务模式还没完成初始化,文档库、待办和自动化都会先回到这里。",affairsInitRouteGuardSidebarEmpty:"先完成初始化,左侧分区内容才会出现。",affairsInitRouteGuardAuxiliaryEmpty:"先完成初始化,右侧详情区才会出现对象内容。"},ob={butlerInitTitle:"Set Up Butler",butlerInitDescription:"Finish a few basic settings first.",butlerInitPreviewTitle:"Preview",butlerInitPreviewDescription:"",butlerInitBasicsTitle:"Basic Info",butlerInitBasicsDescription:"",butlerInitPersonaTitle:"Voice",butlerInitPersonaDescription:"",butlerInitPreferenceTitle:"Default Preferences",butlerInitPreferenceDescription:"",butlerInitRuleLabel:"Rule Style",butlerInitPreviewRuleLabel:"Mode",butlerInitTipAutoWorkspace:"",butlerInitTipProviderSwitch:"",butlerInitTipReportPriority:"",butlerDisplayNameLabel:"Butler Name",butlerDisplayNamePlaceholder:"Example: Butler",butlerDisplayNameHint:"This name appears on the Butler page.",butlerProviderLabel:"Engine",butlerAgentsModeLabel:"Rule Style",butlerAgentsModeInline:"Auto",butlerAgentsModeFile:"Editable File",butlerAgentsModeInlineDescription:"Rules are managed automatically.",butlerAgentsModeFileDescription:"An editable rule file will be created.",butlerPersonaToneLabel:"Tone",butlerPersonaLanguageLabel:"Language",butlerPersonaSummaryStyleLabel:"Reply Style",butlerFocusRiskPreferenceLabel:"Work Style",butlerFocusReportPriorityLabel:"Priority",butlerToneDirect:"Direct",butlerToneSteady:"Steady",butlerToneFriendly:"Friendly",butlerLanguageZhCn:"Chinese",butlerLanguageEnUs:"English",butlerLanguageBilingual:"Bilingual",butlerSummaryBrief:"Brief",butlerSummaryStructured:"Clear",butlerSummaryThorough:"Detailed",butlerRiskConservative:"Conservative",butlerRiskBalanced:"Balanced",butlerRiskProactive:"Proactive",butlerReportPriorityPresetLabel:"Priority",butlerSummaryDebounceLabel:"Summary Cadence",butlerSettingsTitle:"Butler Settings",butlerSettingsSaveAction:"Save Settings",butlerSettingsSaving:"Saving...",butlerSettingsSaved:"Butler settings saved",butlerSettingsSaveFailed:"Failed to save Butler settings",butlerInitSubmitting:"Saving...",butlerInitSubmit:"Finish Setup",butlerInitSuccess:"Butler is ready",butlerInitFailed:"Failed to save Butler settings",butlerInitNameRequired:"Please enter a Butler name",affairsInitSubmit:"Finish affairs setup",affairsInitSuccess:"Affairs mode is ready",affairsInitFailed:"Failed to save affairs settings",affairsInitPreviewRuleLabel:"Affairs mode",affairsInitLibraryTitle:"Library setup",affairsInitLibraryDescription:"Decide whether the document library should be connected right away.",affairsInitLibraryEnabledLabel:"Document library",affairsInitLibraryEnabledHint:"When enabled, it will be connected as soon as setup finishes.",affairsInitLibraryPathHint:"Set the library path here. You can change it later.",affairsInitLibraryPathRequired:"Choose a library path before enabling the document library",affairsInitRouteGuardHint:"Affairs mode is not ready yet, so library, todo, and automation all return here first.",affairsInitRouteGuardSidebarEmpty:"Finish setup before the left-side sections appear.",affairsInitRouteGuardAuxiliaryEmpty:"Finish setup before the detail panel shows object content."};function vd(i,r){const o=i.shell;return{...i,shell:{...o&&typeof o=="object"?o:{},...r}}}const Cp={"zh-CN":vd(ib,nb),"en-US":vd(rb,ob)};function Pn(i,r){const o=i.split(".");let c=r;for(const u of o){if(!c||typeof c=="string")return i;const p=c[u];if(p==null)return i;c=p}return typeof c=="string"?c:i}function lb(){return ri.getState().profile.language??"zh-CN"}function tt(i,r){const c=lb()==="en-US"?["en-US","zh-CN"]:["zh-CN"];for(const u of c){const p=Pn(i,Cp[u]);if(p!==i)return Il(p,r);const y=Pn(i,vp[u]);if(y!==i)return Il(y,r)}return Il(i,r)}function Il(i,r){return r?i.replace(/\{([^}]+)\}/g,(o,c)=>{const u=r[c];return u==null?o:String(u)}):i}function pS({children:i,language:r}){return He.useEffect(()=>{document.documentElement.setAttribute("lang",r)},[r]),i}function fS(){const i=ab(r=>r.profile.language);return r=>{const o=i==="en-US"?["en-US","zh-CN"]:["zh-CN"];for(const c of o){const u=Pn(r,Cp[c]);if(u!==r)return u;const p=Pn(r,vp[c]);if(p!==r)return p}return r}}const _l="codingns.auth_expired_at";function sb(){sessionStorage.setItem(_l,String(Date.now()))}function mS(){const i=sessionStorage.getItem(_l);return i?(sessionStorage.removeItem(_l),Date.now()-Number(i)<5e3):!1}async function cb(i){var c,u;const r=new Date().toISOString(),o=Rn(`/api/client/runtime-config?platform=${encodeURIComponent(i.platform)}`,i.baseUrl);try{const p=await fetch(o,{method:"GET",headers:{Authorization:`Bearer ${i.accessToken}`}}),y=await ub(p);if(!p.ok){const B=Gi(y==null?void 0:y.error_code),j=Gi(y==null?void 0:y.detail)??`HTTP ${p.status}`;return p.status===401||p.status===403?{status:"unauthorized",checkedAt:r,errorCode:B??"UNAUTHORIZED",errorDetail:j,responseHostBaseUrl:null,responseBindingId:null,responseHostFingerprint:null}:{status:"mismatch",checkedAt:r,errorCode:B??"HTTP_ERROR",errorDetail:j,responseHostBaseUrl:null,responseBindingId:null,responseHostFingerprint:null}}const k=y,L=Gi((c=k==null?void 0:k.relayTunnel)==null?void 0:c.bindingId),O=Gi((u=k==null?void 0:k.relayTunnel)==null?void 0:u.hostFingerprint),E=Gi(k==null?void 0:k.hostBaseUrl);return L&&O&&L===i.expectedBindingId&&O===i.expectedHostFingerprint?{status:"verified",checkedAt:r,errorCode:null,errorDetail:null,responseHostBaseUrl:E,responseBindingId:L,responseHostFingerprint:O}:{status:"mismatch",checkedAt:r,errorCode:"HOST_IDENTITY_MISMATCH",errorDetail:"候选入口返回的 Host 身份与当前激活 Host 不一致",responseHostBaseUrl:E,responseBindingId:L,responseHostFingerprint:O}}catch(p){return{status:"unreachable",checkedAt:r,errorCode:"NETWORK_ERROR",errorDetail:p instanceof Error?p.message:"未知网络错误",responseHostBaseUrl:null,responseBindingId:null,responseHostFingerprint:null}}}async function ub(i){const r=await i.text();if(!r.trim())return null;try{return JSON.parse(r)}catch{return null}}function Gi(i){return typeof i=="string"&&i.trim()?i.trim():null}class db{constructor(){A(this,"state",{epoch:0,activeHostId:kn(X.getState()),connectionSignature:Cd(X.getState()),candidateProbeSignature:null,candidateProbePhase:"idle",candidateProbeStartedAt:null,candidateProbeFinishedAt:null,candidateEndpoints:[],preferredCandidateEndpointId:null,preferredDirectCandidateEndpointId:null});A(this,"listeners",new Set);A(this,"probeRunId",0);A(this,"subscribe",r=>(this.listeners.add(r),()=>{this.listeners.delete(r)}));A(this,"getState",()=>this.state);X.subscribe(()=>{this.handleDependencyChange()}),Me.subscribe(()=>{this.handleDependencyChange()}),this.handleDependencyChange()}handleDependencyChange(){var L;const r=X.getState(),o=kn(r),c=Cd(r),u=pb(r,((L=Me.getState().session)==null?void 0:L.accessToken)??null),p=(u==null?void 0:u.signature)??null;let y=!1,k=this.state;if((o!==this.state.activeHostId||c!==this.state.connectionSignature)&&(k={...k,epoch:this.state.epoch+1,activeHostId:o,connectionSignature:c},y=!0),p!==this.state.candidateProbeSignature)if(this.probeRunId+=1,!u)k={...k,candidateProbeSignature:null,candidateProbePhase:"idle",candidateProbeStartedAt:null,candidateProbeFinishedAt:null,candidateEndpoints:[],preferredCandidateEndpointId:null,preferredDirectCandidateEndpointId:null},y=!0;else{const O=new Date().toISOString();k={...k,candidateProbeSignature:p,candidateProbePhase:"probing",candidateProbeStartedAt:O,candidateProbeFinishedAt:null,candidateEndpoints:u.candidateEndpoints.map(E=>({...E,status:"pending",checkedAt:null,errorCode:null,errorDetail:null,responseHostBaseUrl:null,responseBindingId:null,responseHostFingerprint:null})),preferredCandidateEndpointId:null,preferredDirectCandidateEndpointId:null},y=!0,this.runCandidateProbe(u,this.probeRunId)}y&&(this.state=k,this.emit())}async runCandidateProbe(r,o){const c=await Promise.all(r.candidateEndpoints.map(async u=>{const p=await cb({baseUrl:u.url,accessToken:r.accessToken,platform:r.platform,expectedBindingId:r.expectedBindingId,expectedHostFingerprint:r.expectedHostFingerprint});return{...u,status:p.status,checkedAt:p.checkedAt,errorCode:p.errorCode,errorDetail:p.errorDetail,responseHostBaseUrl:p.responseHostBaseUrl,responseBindingId:p.responseBindingId,responseHostFingerprint:p.responseHostFingerprint}}));o===this.probeRunId&&(this.state={...this.state,candidateProbePhase:"ready",candidateProbeFinishedAt:new Date().toISOString(),candidateEndpoints:c,preferredCandidateEndpointId:mb(c),preferredDirectCandidateEndpointId:hb(c)},this.emit())}emit(){for(const r of this.listeners)r()}}const $i=new db;function hS(){return He.useSyncExternalStore($i.subscribe,()=>{const i=$i.getState();return`${i.activeHostId??"anonymous"}:${i.epoch}`})}function gS(i){return He.useSyncExternalStore($i.subscribe,()=>i($i.getState()))}function Cd(i){const r=Da(i);return r?JSON.stringify({id:r.id,baseUrl:r.baseUrl,relayTunnel:r.relayTunnel}):"no-host"}function pb(i,r){var O,E;const o=Da(i),c=o==null?void 0:o.relayTunnel,u=(O=c==null?void 0:c.bindingId)==null?void 0:O.trim(),p=(E=c==null?void 0:c.hostFingerprint)==null?void 0:E.trim(),y=(c==null?void 0:c.candidateEndpoints)??[];if(!o||!r||!u||!p||y.length===0)return null;const k=i.platform==="web"?"web":"desktop";if(k==="web")return null;const L=y.filter(B=>fb(B,k));return L.length===0?null:{signature:JSON.stringify({hostId:o.id,platform:k,accessToken:r,bindingId:u,hostFingerprint:p,candidateEndpoints:L.map(B=>({endpointId:B.endpointId,url:B.url,kind:B.kind,priority:B.priority}))}),platform:k,accessToken:r,expectedBindingId:u,expectedHostFingerprint:p,candidateEndpoints:L}}function fb(i,r){return r!=="web"}function mb(i){var r;return((r=i.find(o=>o.status==="verified"))==null?void 0:r.endpointId)??null}function hb(i){var r;return((r=i.find(o=>o.status==="verified"&&o.kind!=="relay"))==null?void 0:r.endpointId)??null}const Dp=We("https://channel.codingns.com:1443");function bS(){return Dp}function yS(){return!1}function gb(i){if(!(i!=null&&i.trim()))return null;try{return We(i)}catch{return null}}function SS(i){return gb(i)??Dp}function bb(i){try{const r=We(i),c=new URL(r).hostname.trim().toLowerCase(),u=c.split(".");if(u.length<4||u[1]!=="channel")return null;const p=new URL(r);return p.hostname=u.slice(1).join("."),p.pathname="",p.search="",p.hash="",{tunnelDomain:c,controlBaseUrl:We(p.toString()),relayBaseUrl:r}}catch{return null}}class yb{async fetch(r){return fetch(r.url,r.init)}createWebSocket(r){return new WebSocket(r.url,r.protocols)}}const Vl=new yb;class Sb{constructor(r){A(this,"nextStreamId",0);A(this,"pendingHttpRequests",new Map);A(this,"sockets",new Map);A(this,"unsubscribe");this.session=r,this.unsubscribe=r.subscribe(o=>{this.handlePacket(o)})}async fetch(r){const o=this.createStreamId("http"),c={type:"http.request",streamId:o,method:wb(r.init.method),path:Dd(r.path,r.url),headers:vb(r.init.headers),bodyBase64Url:await Cb(r.init.body)};return await new Promise((u,p)=>{this.pendingHttpRequests.set(o,{resolve:u,reject:p,streamController:null,responseStarted:!1}),this.session.send(c)})}createWebSocket(r){const o=this.createStreamId("ws"),c=new kb({streamId:o,path:Dd(r.path,r.url),headers:{},protocols:Tb(r.protocols)},this.session,()=>{this.sockets.delete(o)});return this.sockets.set(o,c),c}close(){var r;this.unsubscribe();for(const o of this.pendingHttpRequests.values()){const c=new Error("隧道会话已经关闭");if(o.responseStarted){(r=o.streamController)==null||r.error(c);continue}o.reject(c)}this.pendingHttpRequests.clear();for(const o of this.sockets.values())o.forceClose(1011,"隧道会话已经关闭");this.sockets.clear()}handlePacket(r){var o,c,u;switch(r.type){case"http.response":this.handleHttpResponse(r);return;case"http.response.start":this.handleHttpResponseStart(r);return;case"http.response.chunk":this.handleHttpResponseChunk(r);return;case"http.response.end":this.handleHttpResponseEnd(r);return;case"ws.opened":(o=this.sockets.get(r.streamId))==null||o.handleOpened(r);return;case"ws.message":(c=this.sockets.get(r.streamId))==null||c.handleMessage(r);return;case"ws.closed":(u=this.sockets.get(r.streamId))==null||u.handleClosed(r);return;case"error":this.handleError(r);return;default:return}}handleHttpResponse(r){const o=this.pendingHttpRequests.get(r.streamId);o&&(this.pendingHttpRequests.delete(r.streamId),o.resolve(new Response(Lb(r.bodyBase64Url),{status:r.status,headers:r.headers})))}handleHttpResponseStart(r){const o=this.pendingHttpRequests.get(r.streamId);if(!o||o.responseStarted)return;if(o.responseStarted=!0,Ab(r.status)){this.pendingHttpRequests.delete(r.streamId),o.resolve(new Response(null,{status:r.status,headers:r.headers}));return}const c=new ReadableStream({start:u=>{o.streamController=u},cancel:()=>{o.streamController=null}});o.resolve(new Response(c,{status:r.status,headers:r.headers}))}handleHttpResponseChunk(r){var u;const o=this.pendingHttpRequests.get(r.streamId);if(!(o!=null&&o.responseStarted))return;const c=Pp(r.bodyChunkBase64Url);(u=o.streamController)==null||u.enqueue(c)}handleHttpResponseEnd(r){var c;const o=this.pendingHttpRequests.get(r.streamId);o&&((c=o.streamController)==null||c.close(),o.streamController=null,this.pendingHttpRequests.delete(r.streamId))}handleError(r){var o,c;if(r.streamId&&this.pendingHttpRequests.has(r.streamId)){const u=this.pendingHttpRequests.get(r.streamId),p=new Error(`${r.errorCode}: ${r.detail}`);this.pendingHttpRequests.delete(r.streamId),u!=null&&u.responseStarted?(o=u.streamController)==null||o.error(p):u==null||u.reject(p);return}r.streamId&&((c=this.sockets.get(r.streamId))==null||c.handleError(r))}createStreamId(r){return this.nextStreamId+=1,`${r}-${this.nextStreamId}`}}class kb extends EventTarget{constructor(o,c,u){super();A(this,"streamId");A(this,"mutableReadyState",0);A(this,"closed",!1);this.options=o,this.session=c,this.onClosed=u,this.streamId=o.streamId,this.open()}get readyState(){return this.mutableReadyState}send(o){if(this.mutableReadyState!==1)throw new Error("当前隧道 WebSocket 尚未打开");const c=Fb(o),u={type:"ws.message",streamId:this.streamId,binary:typeof c!="string",dataBase64Url:Pb(c)};this.session.send(u)}close(o,c){this.closed||(this.closed=!0,this.mutableReadyState=2,this.session.send({type:"ws.closed",streamId:this.streamId,code:o??1e3,reason:c??null}))}handleOpened(o){this.closed||(this.mutableReadyState=1,this.dispatchEvent(new Event("open")))}handleMessage(o){if(this.closed)return;const c=o.binary?as(o.dataBase64Url):Rb(o.dataBase64Url);this.dispatchEvent(new MessageEvent("message",{data:c}))}handleClosed(o){this.forceClose(o.code,o.reason??"")}handleError(o){this.closed||(this.dispatchEvent(new ErrorEvent("error",{message:`${o.errorCode}: ${o.detail}`})),this.forceClose(1011,o.detail))}forceClose(o,c){this.mutableReadyState!==3&&(this.closed=!0,this.mutableReadyState=3,this.dispatchEvent(new CloseEvent("close",{code:o,reason:c})),this.onClosed())}open(){const o={type:"ws.open",streamId:this.streamId,path:this.options.path,headers:this.options.headers,protocols:this.options.protocols.length>0?this.options.protocols:void 0};this.session.send(o)}}function Tb(i){if(!i)return[];const r=Array.isArray(i)?i:[i],o=new Set,c=[];for(const u of r){const p=u.trim();!p||o.has(p)||(o.add(p),c.push(p))}return c}function wb(i){return(i==null?void 0:i.trim().toUpperCase())||"GET"}function vb(i){const r=new Headers(i),o={};return r.forEach((c,u)=>{o[u]=c}),o}async function Cb(i){if(i==null)return null;const r=await Db(i);return r.byteLength>0?gn(r):null}async function Db(i){if(typeof i=="string")return zl.encode(i);if(i instanceof URLSearchParams)return zl.encode(i.toString());if(i instanceof ArrayBuffer)return new Uint8Array(i);if(ArrayBuffer.isView(i))return new Uint8Array(i.buffer,i.byteOffset,i.byteLength);if(typeof Blob<"u"&&i instanceof Blob)return new Uint8Array(await i.arrayBuffer());throw new Error("当前隧道 transport 不支持这种请求体类型")}function Dd(i,r){const o=new URL(r),c=i.trim();return c?c.includes("?")||!o.search?c:`${c}${o.search}`:`${o.pathname}${o.search}`}function Pb(i){return typeof i=="string"?gn(zl.encode(i)):ArrayBuffer.isView(i)?gn(new Uint8Array(i.buffer,i.byteOffset,i.byteLength)):gn(new Uint8Array(i))}function as(i){return i?Pp(i):null}function Lb(i){const r=as(i);if(!r)return null;const o=new Uint8Array(r.byteLength);return o.set(r),o.buffer}function Ab(i){return i===101||i===103||i===204||i===205||i===304}function Rb(i){const r=as(i);return r?Mb.decode(r):""}function Fb(i){if(Eb(i))throw new Error("当前隧道 WebSocket 暂不支持直接发送 Blob");return i}function Eb(i){return typeof Blob<"u"&&i instanceof Blob}function gn(i){let r="";for(let o=0;o<i.length;o+=Pd){const c=i.subarray(o,o+Pd);r+=String.fromCharCode(...c)}return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Pp(i){const r=i.replace(/-/g,"+").replace(/_/g,"/"),o=r.padEnd(Math.ceil(r.length/4)*4,"="),c=atob(o),u=new Uint8Array(c.length);for(let p=0;p<c.length;p+=1)u[p]=c.charCodeAt(p);return u}const zl=new TextEncoder,Mb=new TextDecoder,Pd=32768,Aa=1,ca="x25519-hkdf-sha256-aes-256-gcm",Ib=12,bn=16,xb=32;class Ne extends Error{constructor(r,o){super(o),this.code=r,this.name="RelayTunnelProtocolError"}}async function Lp(i){const r=Fp(i,"PUBLIC KEY"),o=await ct().digest("SHA-256",Be(r));return`SHA256:${$b(new Uint8Array(o))}`}async function Ob(i){const r=Fd(i.expectedHostFingerprint,"expectedHostFingerprint"),o=Fd(i.expectedHostPublicKey,"expectedHostPublicKey");if(await Lp(o)!==r)throw new Ne("RELAY_TUNNEL_HOST_FINGERPRINT_MISMATCH","客户端持有的 Host 公钥和指纹不一致");const u=ct(),p=await u.generateKey(Mn,!0,["deriveBits"]),y={version:Aa,cipherSuite:ca,clientEphemeralPublicKey:ii(new Uint8Array(await u.exportKey("spki",p.publicKey))),clientNonce:ii(Mp(16)),expectedHostFingerprint:r};return{pendingHandshake:{expectedHostPublicKey:o,expectedHostFingerprint:r,clientEphemeralPrivateKey:p.privateKey,clientHello:y},clientHello:y}}async function Hb(i){if(_b(i.pendingHandshake.clientHello),Vb(i.serverHello),i.serverHello.hostKeyFingerprint!==i.pendingHandshake.expectedHostFingerprint)throw new Ne("RELAY_TUNNEL_HOST_FINGERPRINT_MISMATCH","服务端返回的 Host 指纹和客户端预期不一致");if(await Lp(i.serverHello.hostPublicKey)!==i.pendingHandshake.expectedHostFingerprint)throw new Ne("RELAY_TUNNEL_HOST_FINGERPRINT_MISMATCH","服务端返回的 Host 公钥与指纹不一致");if(Ln(i.serverHello.hostPublicKey)!==Ln(i.pendingHandshake.expectedHostPublicKey))throw new Ne("RELAY_TUNNEL_HOST_PUBLIC_KEY_MISMATCH","服务端返回的 Host 公钥和客户端持有的公钥不一致");const o=await jb(i.pendingHandshake.clientHello,i.serverHello),c=await Gb(i.pendingHandshake.expectedHostPublicKey),u=await Kb(i.serverHello.serverEphemeralPublicKey),p=await Rd(i.pendingHandshake.clientEphemeralPrivateKey,c),y=await Rd(i.pendingHandshake.clientEphemeralPrivateKey,u),k=Ep([p,y]),L=await qb(k,o),O=ni.encode(L),E=ni.encode(i.serverHello.proof);if(!Yb(O,E))throw new Ne("RELAY_TUNNEL_HANDSHAKE_PROOF_INVALID","服务端握手证明无效");return await Wb({sessionId:i.serverHello.sessionId,peerHostFingerprint:i.serverHello.hostKeyFingerprint,ikm:k,transcriptHash:o})}async function Nb(i,r){const o=ct(),c=i.sendSequence+1,u="client_to_host",p=Mp(Ib),y=Rp({sessionId:i.sessionId,direction:u,sequence:c}),k=Qb(r),L=new Uint8Array(await o.encrypt({name:"AES-GCM",iv:Be(p),additionalData:Be(y),tagLength:bn*8},i.sendKey,Be(k)));return i.sendSequence=c,{version:Aa,cipherSuite:ca,sessionId:i.sessionId,direction:u,sequence:c,iv:ii(p),authTag:ii(L.slice(-bn)),ciphertext:ii(L.slice(0,-bn))}}async function Bb(i,r){if(zb(r),r.sessionId!==i.sessionId)throw new Ne("RELAY_TUNNEL_FRAME_SESSION_MISMATCH","加密帧的会话标识和当前会话不匹配");if(r.direction!=="host_to_client")throw new Ne("RELAY_TUNNEL_FRAME_DIRECTION_MISMATCH","加密帧方向和当前接收方向不匹配");const o=i.receiveSequence+1,c=Ub(r);if(r.sequence===i.receiveSequence&&i.lastReceivedFrameFingerprint===c)return null;if(r.sequence!==o)throw new Ne("RELAY_TUNNEL_FRAME_SEQUENCE_MISMATCH",`加密帧序号错误,期望 ${o},实际 ${r.sequence}`);const u=ct(),p=Rp({sessionId:r.sessionId,direction:r.direction,sequence:r.sequence}),y=yn(r.ciphertext),k=yn(r.authTag),L=Ep([y,k]);try{const O=new Uint8Array(await u.decrypt({name:"AES-GCM",iv:Be(yn(r.iv)),additionalData:Be(p),tagLength:bn*8},i.receiveKey,Be(L)));return i.receiveSequence=r.sequence,i.lastReceivedFrameFingerprint=c,O}catch{throw new Ne("RELAY_TUNNEL_FRAME_AUTH_INVALID","加密帧完整性校验失败")}}async function Wb(i){const r=await Ld(i.ikm,i.transcriptHash,"codingns-relay-client-to-host"),o=await Ld(i.ikm,i.transcriptHash,"codingns-relay-host-to-client");return{sessionId:i.sessionId,role:"client",cipherSuite:ca,peerHostFingerprint:i.peerHostFingerprint,sendSequence:0,receiveSequence:0,lastReceivedFrameFingerprint:null,sendKey:await Ad(r,"encrypt"),receiveKey:await Ad(o,"decrypt")}}function Ub(i){return[i.sessionId,i.direction,String(i.sequence),i.iv,i.authTag,i.ciphertext].join(":")}function _b(i){if(i.version!==Aa||i.cipherSuite!==ca)throw new Ne("RELAY_TUNNEL_PROTOCOL_UNSUPPORTED","客户端握手协议版本或套件不受支持")}function Vb(i){if(i.version!==Aa||i.cipherSuite!==ca)throw new Ne("RELAY_TUNNEL_PROTOCOL_UNSUPPORTED","服务端握手协议版本或套件不受支持")}function zb(i){if(i.version!==Aa||i.cipherSuite!==ca)throw new Ne("RELAY_TUNNEL_PROTOCOL_UNSUPPORTED","加密帧协议版本或套件不受支持")}async function jb(i,r){const o=JSON.stringify({version:Aa,cipherSuite:ca,clientEphemeralPublicKey:i.clientEphemeralPublicKey,clientNonce:i.clientNonce,expectedHostFingerprint:i.expectedHostFingerprint,hostPublicKey:Ln(r.hostPublicKey),hostKeyFingerprint:r.hostKeyFingerprint,serverEphemeralPublicKey:r.serverEphemeralPublicKey,serverNonce:r.serverNonce,sessionId:r.sessionId});return new Uint8Array(await ct().digest("SHA-256",ni.encode(o)))}async function qb(i,r){const o=await Ap(i,r,"codingns-relay-handshake-proof"),c=await ct().importKey("raw",Be(o),Zb,!1,["sign"]),u=new Uint8Array(await ct().sign("HMAC",c,Be(r)));return ii(u)}async function Ld(i,r,o){return await Ap(i,r,o)}async function Ap(i,r,o){const c=ct(),u=await c.importKey("raw",Be(i),"HKDF",!1,["deriveBits"]),p=await c.deriveBits({name:"HKDF",hash:"SHA-256",salt:Be(r),info:Be(ni.encode(o))},u,xb*8);return new Uint8Array(p)}async function Ad(i,r){return await ct().importKey("raw",Be(i),Xb,!1,[r])}async function Gb(i){return await ct().importKey("spki",Be(Fp(i,"PUBLIC KEY")),Mn,!1,[])}async function Kb(i){return await ct().importKey("spki",Be(yn(i)),Mn,!1,[])}async function Rd(i,r){const o=await ct().deriveBits({...Mn,public:r},i,256);return new Uint8Array(o)}function Rp(i){return ni.encode(JSON.stringify({version:Aa,cipherSuite:ca,sessionId:i.sessionId,direction:i.direction,sequence:i.sequence}))}function Qb(i){return typeof i=="string"?ni.encode(i):i instanceof Uint8Array?i:new Uint8Array(i)}function Fd(i,r){const o=i.trim();if(!o)throw new Ne("RELAY_TUNNEL_PROTOCOL_UNSUPPORTED",`${r} 不能为空`);return o}function Ln(i){return i.trim().replace(/\r\n/g,`
50
+ `)}function Fp(i,r){const o=Ln(i),c=`-----BEGIN ${r}-----`,u=`-----END ${r}-----`;if(!o.includes(c)||!o.includes(u))throw new Ne("RELAY_TUNNEL_PROTOCOL_UNSUPPORTED",`无效的 ${r} PEM`);const p=o.replace(c,"").replace(u,"").replace(/\s+/g,"");return Jb(p)}function Yb(i,r){if(i.length!==r.length)return!1;let o=0;for(let c=0;c<i.length;c+=1)o|=i[c]^r[c];return o===0}function Ep(i){const r=i.reduce((u,p)=>u+p.length,0),o=new Uint8Array(r);let c=0;for(const u of i)o.set(u,c),c+=u.length;return o}function Mp(i){const r=new Uint8Array(i);return Op().getRandomValues(r),r}function $b(i){return Ip(i)}function ii(i){return Ip(i).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}function Jb(i){return xp(i)}function yn(i){const r=i.replace(/-/g,"+").replace(/_/g,"/"),o=r.padEnd(Math.ceil(r.length/4)*4,"=");return xp(o)}function Ip(i){let r="";for(let o=0;o<i.length;o+=Ed)r+=String.fromCharCode(...i.subarray(o,o+Ed));return btoa(r)}function xp(i){const r=atob(i),o=new Uint8Array(r.length);for(let c=0;c<r.length;c+=1)o[c]=r.charCodeAt(c);return o}function Be(i){return Uint8Array.from(i)}function Op(){if(typeof globalThis.crypto>"u")throw new Ne("RELAY_TUNNEL_PROTOCOL_UNSUPPORTED","当前运行环境不支持 Web Crypto");return globalThis.crypto}function ct(){return Op().subtle}const ni=new TextEncoder,Ed=32768,Mn={name:"X25519"},Xb={name:"AES-GCM",length:256},Zb={name:"HMAC",hash:"SHA-256"};function ey(i){return JSON.stringify(i)}function ty(i){return JSON.parse(i)}class Hp{constructor(r,o){A(this,"listeners",new Set);A(this,"unsubscribeFromChannel");A(this,"closeListeners",new Set);A(this,"unsubscribeFromChannelClose");A(this,"connectPromise",null);A(this,"textEncoder",new TextEncoder);A(this,"textDecoder",new TextDecoder);A(this,"incomingPayloadChain",Promise.resolve());A(this,"outgoingPacketChain",Promise.resolve());A(this,"pendingPackets",[]);A(this,"closedByClient",!1);A(this,"terminationNotified",!1);A(this,"handshakeState",{status:"idle"});this.channel=r,this.options=o,this.unsubscribeFromChannel=r.subscribe(c=>{this.enqueueIncomingPayload(c)}),this.unsubscribeFromChannelClose=r.subscribeClose?r.subscribeClose(c=>{this.handleChannelClosed(c)}):null}async connect(){if(this.handshakeState.status==="ready")return;if(this.connectPromise)return await this.connectPromise;if(this.handshakeState.status==="failed")throw this.handshakeState.error;const{pendingHandshake:r,clientHello:o}=await Ob({expectedHostPublicKey:this.options.expectedHostPublicKey,expectedHostFingerprint:this.options.expectedHostFingerprint});return this.connectPromise=new Promise((c,u)=>{this.handshakeState={status:"waiting_server_hello",pendingHandshake:r,resolve:c,reject:u},this.sendControlPayload(JSON.stringify({type:"client_hello",hello:o}))}),await this.connectPromise}send(r){if(this.handshakeState.status==="ready"){this.enqueueOutgoingPacket(r,this.handshakeState.session);return}if(this.handshakeState.status==="failed")throw this.handshakeState.error;if(this.handshakeState.status==="waiting_server_hello"&&this.connectPromise){this.pendingPackets.push(r);return}throw new Error("当前 CodingNS Connect 会话尚未建立完成")}subscribe(r){return this.listeners.add(r),()=>{this.listeners.delete(r)}}subscribeClose(r){return this.closeListeners.add(r),()=>{this.closeListeners.delete(r)}}close(r,o){var c;this.closedByClient=!0,this.unsubscribeFromChannel(),(c=this.unsubscribeFromChannelClose)==null||c.call(this),this.channel.close(r,o)}async handleIncomingPayload(r){this.recordWireBytes("downstream",r);const o=JSON.parse(r);if(o.type==="server_hello"){await this.handleServerHello(o);return}if(o.type==="encrypted_frame"){await this.handleEncryptedFrame(o);return}o.type==="error"&&this.failSession(new Error(`${o.errorCode}: ${o.detail}`))}async handleServerHello(r){if(this.handshakeState.status==="waiting_server_hello")try{const o=await Hb({pendingHandshake:this.handshakeState.pendingHandshake,serverHello:r.hello}),c=this.handshakeState.resolve;this.handshakeState={status:"ready",session:o},this.connectPromise=null,await this.flushPendingPackets(o),c()}catch(o){this.failSession(Ki(o))}}async handleEncryptedFrame(r){const o=this.requireReadySession();try{const c=await Bb(o.session,r.frame);if(!c)return;const u=ty(this.textDecoder.decode(c));for(const p of this.listeners)p(u)}catch(c){this.failSession(Ki(c))}}requireReadySession(){if(this.handshakeState.status==="failed")throw this.handshakeState.error;if(this.handshakeState.status!=="ready")throw new Error("当前 CodingNS Connect 会话尚未建立完成");return this.handshakeState}failSession(r){if(this.pendingPackets=[],this.handshakeState.status==="waiting_server_hello"){const o=this.handshakeState.reject;this.handshakeState={status:"failed",error:r},this.connectPromise=null,this.notifyTermination(r),o(r);return}this.handshakeState={status:"failed",error:r},this.connectPromise=null,this.notifyTermination(r)}handleChannelClosed(r){this.closedByClient||this.failSession(r)}sendControlPayload(r){return this.recordWireBytes("upstream",r),this.channel.send(r)}enqueueIncomingPayload(r){this.incomingPayloadChain=this.incomingPayloadChain.catch(()=>{}).then(async()=>{await this.handleIncomingPayload(r)}).catch(o=>{this.failSession(Ki(o))})}async flushPendingPackets(r){const o=this.pendingPackets;if(o.length!==0){this.pendingPackets=[];for(const c of o)await this.sendEncryptedPacket(c,r)}}enqueueOutgoingPacket(r,o){this.outgoingPacketChain=this.outgoingPacketChain.catch(()=>{}).then(async()=>{await this.sendEncryptedPacket(r,o)}).catch(c=>{this.failSession(Ki(c))})}async sendEncryptedPacket(r,o){try{const c=await Nb(o,ey(r));await this.sendControlPayload(JSON.stringify({type:"encrypted_frame",frame:c}))}catch(c){const u=Ki(c);throw this.failSession(u),u}}recordWireBytes(r,o){var c,u;(u=(c=this.options).onWireBytes)==null||u.call(c,r,this.textEncoder.encode(o).byteLength)}notifyTermination(r){if(!this.terminationNotified){this.terminationNotified=!0;for(const o of this.closeListeners)o(r)}}}function Ki(i){return i instanceof Error?i:new Error(String(i))}const Np=3,ay=250;async function iy(i){const r=i.fetchFn??fetch,o=new URL(`/api/v1/tunnels/${encodeURIComponent(cy(i.tunnelDomain))}/connect-init`,_p(i.controlBaseUrl)).toString(),c=await r(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({clientContext:uy()})});if(!c.ok)throw await sy(c,"初始化隧道连接失败");return await c.json()}async function ry(i,r={}){const o=await iy({controlBaseUrl:i.controlBaseUrl,tunnelDomain:i.tunnelDomain,fetchFn:r.fetchFn}),c={bindingId:o.bindingId,tunnelDomain:o.tunnelDomain,hostPublicKey:o.hostPublicKey,hostFingerprint:o.hostFingerprint,relayBaseUrl:o.relayBaseUrl,controlBaseUrl:o.controlBaseUrl,status:o.status},u={sessionId:o.sessionId,bindingId:o.bindingId,tunnelDomain:o.tunnelDomain,connectTicket:o.connectTicket,remainingBytes:o.remainingBytes,sessionRateLimitBytesPerSecond:o.sessionRateLimitBytesPerSecond,upstreamConnected:o.upstreamConnected,downstreamConnected:o.downstreamConnected,expiresAt:o.expiresAt},y=(r.createWebSocket??Vp)(Wp(c.relayBaseUrl,u.sessionId,zp(u)));return await Up(y),{binding:c,reservation:u,channel:new Bp(y)}}async function ny(i,r={}){const c=(r.createWebSocket??Vp)(Wp(i.binding.relayBaseUrl,i.reservation.sessionId,zp(i.reservation)));return await Up(c),{binding:i.binding,reservation:i.reservation,channel:new Bp(c)}}async function oy(i,r={}){let o=null;for(let c=1;c<=Np;c+=1){let u=null;try{u=await ry(i,r);const p=new Hp(u.channel,{expectedHostPublicKey:u.binding.hostPublicKey,expectedHostFingerprint:u.binding.hostFingerprint,onWireBytes:i.onWireBytes});return await p.connect(),{...u,clientSession:p}}catch(p){const y=hy(p);if(o=y,u==null||u.channel.close(1011,"relay_client_session_connect_failed"),!fy(y,c))throw y;await my(ay*c)}}throw o??new Error("当前 CodingNS Connect 会话建立失败")}async function ly(i,r={}){const o=await ny({binding:i.binding,reservation:i.reservation},r),c=new Hp(o.channel,{expectedHostPublicKey:o.binding.hostPublicKey,expectedHostFingerprint:o.binding.hostFingerprint,onWireBytes:i.onWireBytes});return await c.connect(),{...o,clientSession:c}}class Bp{constructor(r){A(this,"terminalError",null);A(this,"closeNotified",!1);A(this,"closeListeners",new Set);A(this,"handleClose",r=>{const o=r;this.terminalError=new Error(`relay-edge 原始链路关闭:${o.code}${o.reason?` ${o.reason}`:""}`),this.notifyClose(this.terminalError)});A(this,"handleError",()=>{this.terminalError||(this.terminalError=new Error("relay-edge 原始链路建立失败")),this.notifyClose(this.terminalError)});this.socket=r,this.socket.addEventListener("close",this.handleClose),this.socket.addEventListener("error",this.handleError)}send(r){if(this.socket.readyState!==1)throw this.terminalError??new Error("当前 relay-edge 原始链路尚未建立完成");this.socket.send(r)}subscribe(r){const o=c=>{const u=c;typeof u.data=="string"&&r(u.data)};return this.socket.addEventListener("message",o),()=>{this.socket.removeEventListener("message",o)}}subscribeClose(r){return this.closeListeners.add(r),()=>{this.closeListeners.delete(r)}}close(r,o){this.socket.removeEventListener("close",this.handleClose),this.socket.removeEventListener("error",this.handleError),this.socket.close(r,o)}notifyClose(r){if(!this.closeNotified){this.closeNotified=!0;for(const o of this.closeListeners)o(r)}}}function Wp(i,r,o){const c=py(i,"ws");return c.searchParams.set("sessionId",r),c.searchParams.set("role","downstream"),c.searchParams.set("connectTicket",o),c.protocol=c.protocol==="https:"||c.protocol==="wss:"?"wss:":"ws:",c.toString()}async function Up(i){i.readyState!==1&&await new Promise((r,o)=>{const c=()=>{y(),r()},u=k=>{y();const L=k;o(new Error(`relay-edge 原始链路关闭:${L.code}${L.reason?` ${L.reason}`:""}`))},p=()=>{y(),o(new Error("relay-edge 原始链路建立失败"))},y=()=>{i.removeEventListener("open",c),i.removeEventListener("close",u),i.removeEventListener("error",p)};i.addEventListener("open",c),i.addEventListener("close",u),i.addEventListener("error",p)})}async function sy(i,r){const c=(await i.text()).trim();if(!c)return new Error(`${r}(HTTP ${i.status})`);try{const u=JSON.parse(c);if(typeof u.detail=="string"&&typeof u.errorCode=="string")return new Error(`${u.errorCode}: ${u.detail}`)}catch{}return new Error(`${r}:${c}`)}function cy(i){const r=i.trim().toLowerCase();if(!r)throw new Error("tunnelDomain 不能为空");return r}function _p(i){return i.endsWith("/")?i:`${i}/`}function uy(){const i=X.getState().platform??null,r=typeof navigator>"u"?null:Sn(navigator.userAgent),o=typeof navigator>"u"?null:Sn(navigator.platform),c=typeof navigator>"u"?null:Sn(navigator.language),u=dy();return{runtimePlatform:i,systemPlatform:o,userAgent:r,language:c,timezone:u}}function dy(){try{return Sn(Intl.DateTimeFormat().resolvedOptions().timeZone)}catch{return null}}function py(i,r){return new URL(r.replace(/^\/+/,""),_p(i))}function Vp(i){return new WebSocket(i)}function zp(i){var o;const r=(o=i.connectTicket)==null?void 0:o.trim();if(!r)throw new Error("当前 CodingNS Connect 会话缺少 connectTicket,不能继续续接");return r}function fy(i,r){if(r>=Np)return!1;const o=i.message;return o.includes("relay-edge 原始链路")||o.includes("HOST_NOT_CONNECTED")||o.includes("HOST_UPSTREAM_DISCONNECTED")}async function my(i){await new Promise(r=>{setTimeout(r,i)})}function Sn(i){const r=i==null?void 0:i.trim();return r||null}function hy(i){return i instanceof Error?i:new Error(String(i))}const xl={startedAt:null,updatedAt:null,upstreamBytes:0,downstreamBytes:0,totalBytes:0};class gy{constructor(){A(this,"state",{byHostId:{}});A(this,"listeners",new Set);A(this,"subscribe",r=>(this.listeners.add(r),()=>{this.listeners.delete(r)}));Me.subscribe(()=>{Me.getState().session||this.reset()})}getSummary(r){return r?this.state.byHostId[r]??xl:xl}recordWireBytes(r,o,c){if(!r||!Number.isFinite(c)||c<=0)return;const u=this.state.byHostId[r]??xl,p=new Date().toISOString(),y={startedAt:u.startedAt??p,updatedAt:p,upstreamBytes:o==="upstream"?u.upstreamBytes+c:u.upstreamBytes,downstreamBytes:o==="downstream"?u.downstreamBytes+c:u.downstreamBytes,totalBytes:u.totalBytes+c};this.state={byHostId:{...this.state.byHostId,[r]:y}},this.emit()}reset(){Object.keys(this.state.byHostId).length!==0&&(this.state={byHostId:{}},this.emit())}emit(){for(const r of this.listeners)r()}}const jl=new gy;function Md(i,r,o){jl.recordWireBytes(i,r,o)}function kS(i){return He.useSyncExternalStore(jl.subscribe,()=>jl.getSummary(i))}class Id{constructor(r,o={}){A(this,"connectPromise",null);A(this,"fallbackTransport",null);A(this,"resumeState",null);this.options=r,this.dependencies=o}async fetch(r){return await(await this.getActiveTransport()).transport.fetch(r)}createWebSocket(r){return new by(this.getActiveTransport(),r)}close(){const r=this.connectPromise;this.connectPromise=null,this.fallbackTransport=null,this.resumeState=null,r&&r.then(o=>{o.close()}).catch(()=>{})}async getActiveTransport(){return this.fallbackTransport?{transport:this.fallbackTransport,close:()=>{}}:(this.connectPromise||(this.connectPromise=this.createActiveTransport()),await this.connectPromise)}async createActiveTransport(){var u,p;const r=this.dependencies.connectSession??oy,o=this.dependencies.resumeSession??ly,c=this.dependencies.createTransport??(y=>new Sb(y));try{const y=await this.connectWithResume(r,o),k=c(y.clientSession);this.resumeState={binding:y.binding,reservation:y.reservation};let L=!1;const O=((p=(u=y.clientSession).subscribeClose)==null?void 0:p.call(u,E=>{var B;L||(L=!0,(B=k.close)==null||B.call(k),this.connectPromise&&(this.connectPromise=null),xd(E)&&(this.resumeState=null))}))??(()=>{});return{transport:k,close:()=>{var E;L=!0,O(),(E=k.close)==null||E.call(k),y.clientSession.close(1e3,"host_transport_closed")}}}catch(y){const k=this.dependencies.fallbackTransport;if(!k)throw y;return this.fallbackTransport=k,this.connectPromise=null,{transport:k,close:()=>{}}}}async connectWithResume(r,o){if(this.resumeState)try{return await o({binding:this.resumeState.binding,reservation:this.resumeState.reservation,onWireBytes:(c,u)=>{Md(this.options.hostId,c,u)}})}catch(c){if(xd(c))this.resumeState=null;else throw c}return await r({controlBaseUrl:this.options.controlBaseUrl,tunnelDomain:this.options.tunnelDomain,onWireBytes:(c,u)=>{Md(this.options.hostId,c,u)}})}}function xd(i){const r=i instanceof Error?i.message:String(i);return r.includes("SESSION_NOT_FOUND")||r.includes("CONNECT_TICKET_INVALID")||r.includes("SESSION_INSTANCE_MISMATCH")||r.includes("缺少 connectTicket")}class by extends EventTarget{constructor(o,c){super();A(this,"innerSocket",null);A(this,"mutableReadyState",0);A(this,"closed",!1);o.then(u=>{if(this.closed)return;const p=u.transport.createWebSocket(c);this.innerSocket=p,this.mutableReadyState=p.readyState,p.addEventListener("open",()=>{this.mutableReadyState=1,this.dispatchEvent(new Event("open"))}),p.addEventListener("message",y=>{const k=y;this.dispatchEvent(new MessageEvent("message",{data:k.data}))}),p.addEventListener("error",y=>{const k=y;this.dispatchEvent(new ErrorEvent("error",{message:k.message}))}),p.addEventListener("close",y=>{const k=y;this.mutableReadyState=3,this.closed=!0,this.dispatchEvent(new CloseEvent("close",{code:k.code,reason:k.reason,wasClean:k.wasClean}))})}).catch(u=>{this.closed||(this.mutableReadyState=3,this.closed=!0,this.dispatchEvent(new ErrorEvent("error",{message:u instanceof Error?u.message:String(u)})),this.dispatchEvent(new CloseEvent("close",{code:1011,reason:u instanceof Error?u.message:String(u)})))})}get readyState(){var o;return((o=this.innerSocket)==null?void 0:o.readyState)??this.mutableReadyState}send(o){if(!this.innerSocket)throw new Error("当前 CodingNS Connect WebSocket 尚未建立完成");this.innerSocket.send(o)}close(o,c){if(!this.closed){if(this.closed=!0,this.mutableReadyState=2,this.innerSocket){this.innerSocket.close(o,c);return}this.mutableReadyState=3,this.dispatchEvent(new CloseEvent("close",{code:o??1e3,reason:c??""}))}}}const hn=new Map,Od=new Map,yy=({baseUrl:i})=>{const r=dh(X.getState(),i),o=r==null?void 0:r.relayTunnel;if(r&&(o!=null&&o.enabled)&&wy(i,r.baseUrl,o)){const u=JSON.stringify({baseUrl:r.baseUrl,relayTunnel:o}),p=hn.get(r.id);if(p&&p.signature===u)return p.transport;p==null||p.transport.close();const y=new Id({hostId:r.id,controlBaseUrl:o.controlBaseUrl,tunnelDomain:o.tunnelDomain},{fallbackTransport:Hd(X.getState().platform,r.baseUrl,o.tunnelDomain)});return hn.set(r.id,{signature:u,transport:y}),y}if(r){const u=hn.get(r.id);if(u&&(u.transport.close(),hn.delete(r.id)),(o==null?void 0:o.provider)==="codingns_relay"&&!o.enabled)return Vl}const c=bb(i);if(c){const u=JSON.stringify({tunnelDomain:c.tunnelDomain,controlBaseUrl:c.controlBaseUrl}),p=Od.get(u);if(p)return p;const y=new Id({hostId:`inferred:${c.tunnelDomain}`,controlBaseUrl:c.controlBaseUrl,tunnelDomain:c.tunnelDomain},{fallbackTransport:Hd(X.getState().platform,i,c.tunnelDomain)});return Od.set(u,y),y}return Vl};let Sy=yy;function ky(i){const r=Ty(i);return{baseUrl:r,transport:Sy({baseUrl:r})}}function Ty(i){var y;const r=X.getState(),o=Da(r);if(!o||o.baseUrl!==i||r.platform==="web"&&((y=o.relayTunnel)!=null&&y.enabled))return i;const c=$i.getState();if(c.activeHostId!==o.id||c.candidateProbePhase!=="ready"){const k=Ca.get(o.id);return(k==null?void 0:k.baseUrl)??i}const u=c.preferredDirectCandidateEndpointId??c.preferredCandidateEndpointId;if(!u){const k=Ca.get(o.id);return(k==null?void 0:k.baseUrl)??i}const p=c.candidateEndpoints.find(k=>k.endpointId===u&&k.status==="verified");return(p==null?void 0:p.url)??i}function wy(i,r,o){var u;const c=(u=o==null?void 0:o.candidateEndpoints)==null?void 0:u.find(p=>p.url===i);if(c)return c.kind==="relay";if(!(o!=null&&o.tunnelDomain))return!1;try{return new URL(i).hostname.toLowerCase()===o.tunnelDomain.trim().toLowerCase()}catch{try{return new URL(r).hostname.toLowerCase()===o.tunnelDomain.trim().toLowerCase()}catch{return!1}}}function Hd(i,r,o){if(i!=="web")return Vl}class vy{async request(r,o={}){const c=await this.performRequest(r,o);if(c.status===204||c.status===205)return;const u=await c.text();if(u)try{return JSON.parse(u)}catch(p){const y=p instanceof Error?`:${p.message}`:"";throw new et(0,{detail:`服务返回了无效的 JSON 响应${y}`,error_code:"INVALID_RESPONSE"})}}async requestBlob(r,o={}){return(await this.performRequest(r,o)).blob()}async requestRaw(r,o={}){return await this.performRequest(r,o)}async performRequest(r,o){var j;const c=new Headers(o.headers),u=o.body!==void 0&&o.body!==null,p=o.baseUrl??Jl(),y=ky(p),k=y.baseUrl,L=Rn(r,k),O=y.transport,E=o.omitCompatibilityHeaders||Cy(p);if(E&&Dy(c),u&&!c.has("Content-Type")&&c.set("Content-Type","application/json"),!E)for(const[Z,ce]of Object.entries(tp()))c.has(Z)||c.set(Z,ce);if(!o.skipAuth){if(Me.shouldRefreshCurrentSession()){const ce=await Me.refresh();if(ce.status==="invalid")throw new et(401,{detail:"登录态已经失效,请重新登录",error_code:"UNAUTHORIZED"});if(ce.status==="deferred")throw new et(0,{detail:"登录态暂时无法恢复,请稍后重试",error_code:"AUTH_REFRESH_UNAVAILABLE"})}const Z=(j=Me.getState().session)==null?void 0:j.accessToken;if(!Z)throw Me.clear(),new et(401,{detail:"当前没有可用的登录态",error_code:"UNAUTHORIZED"});c.set("Authorization",`Bearer ${Z}`)}let B;try{B=await O.fetch({path:r,baseUrl:k,url:L,init:{...o,headers:c}})}catch(Z){if(!E&&Py(Z)){const ae=await this.performRequest(r,{...o,omitCompatibilityHeaders:!0}).catch(()=>null);if(ae)return jp.add(p),ae}const ce=Z instanceof Error?Z.message:"未知网络错误";throw new et(0,{detail:`请求 ${L} 失败:${ce}`,error_code:"NETWORK_ERROR"})}if(!B.ok){const Z=await Ly(B);if(qp(B.status,Z.error_code)&&!o.skipAuth&&!o.retryAfterRefresh){const ce=await Me.refresh();if(ce.status==="refreshed")return this.performRequest(r,{...o,retryAfterRefresh:!0});throw ce.status==="invalid"?new et(401,{detail:"登录态已经失效,请重新登录",error_code:"UNAUTHORIZED"}):new et(0,{detail:"登录态暂时无法恢复,请稍后重试",error_code:"AUTH_REFRESH_UNAVAILABLE"})}throw!o.skipAuth&&Ry(B.status,Z.error_code)&&(sb(),Me.clear()),new et(B.status,Z)}return B}}const is=new vy,jp=new Set;function Cy(i){return jp.has(i)}function Dy(i){for(const r of Array.from(i.keys()))r.toLowerCase().startsWith("x-codingns-")&&i.delete(r)}function Py(i){if(!(i instanceof Error))return!1;const r=i.message.trim().toLowerCase();return r==="load failed"||r==="failed to fetch"}async function Ly(i){const r=await i.text();if(!r)return Nd(i.status);try{const o=JSON.parse(r);if(typeof o.detail=="string"&&typeof o.error_code=="string")return{detail:o.detail,error_code:o.error_code,field:typeof o.field=="string"?o.field:void 0,data:Ay(o.data)?o.data:void 0,timestamp:typeof o.timestamp=="string"?o.timestamp:void 0}}catch{}return Nd(i.status,r)}function Nd(i,r){return{detail:(r==null?void 0:r.trim())||`请求失败(HTTP ${i})`,error_code:i===401?"UNAUTHORIZED":"HTTP_ERROR"}}function Ay(i){return typeof i=="object"&&i!==null&&!Array.isArray(i)}function qp(i,r){return i!==401?!1:r==="UNAUTHORIZED"||r==="TOKEN_EXPIRED"||r==="TOKEN_INVALID"}function Ry(i,r){return i===403&&r==="BOOTSTRAP_REQUIRED"?!0:qp(i,r)}function Gp(i){return is.request("/api/public/bootstrap-status",{baseUrl:i,skipAuth:!0})}function Fy(i,r){return is.request("/api/public/setup",{method:"POST",body:JSON.stringify(i),baseUrl:r,skipAuth:!0})}function Ey(i,r){return is.request("/api/auth/login",{method:"POST",body:JSON.stringify(i),baseUrl:r,skipAuth:!0})}const Ol=Object.freeze(Object.defineProperty({__proto__:null,getBootstrapStatus:Gp,loginRequest:Ey,setupRequest:Fy},Symbol.toStringTag,{value:"Module"}));async function Kp(i){try{return{...await Gp(i),reachable:!0}}catch{return{initialized:!1,reachable:!1}}}const TS=Object.freeze(Object.defineProperty({__proto__:null,probeHost:Kp},Symbol.toStringTag,{value:"Module"})),My=1e4;function Qp(){return new Date().toISOString()}function Iy(i){return typeof i!="string"||!i.trim()?null:i.trim().replace(/\\/g,"/").replace(/\/+/g,"/").replace(/\/$/,"")}function xy(i,r){return r?`local-discovered:${i}:${r}`:`local-discovered:${i}`}function Oy(i){try{return new URL(i).host}catch{return i}}function Hy(i,r){return!i.dataDir&&r.dataDir||(i.pid??Number.MAX_SAFE_INTEGER)>(r.pid??Number.MAX_SAFE_INTEGER)?r:i}function Ny(i){const r=new Map;for(const o of i){if(!o.baseUrl)continue;let c;try{c=We(o.baseUrl)}catch{continue}const u=r.get(c);if(!u){r.set(c,{...o,baseUrl:c});continue}r.set(c,Hy(u,{...o,baseUrl:c}))}return Array.from(r.values())}async function By(i){const r=Ny(i),o=Qp();return(await Promise.all(r.map(async u=>{const p=u.baseUrl;if(!p||!(await Kp(p)).reachable)return null;const k=Iy(u.dataDir),L=xy(p,k);return{id:L,discoveryKey:L,name:Oy(p),baseUrl:p,kind:"local",createdAt:o,updatedAt:o,lastConnectedAt:null,lastUserId:null,lastUsername:null,source:"desktop-process-scan",pid:u.pid??null,executable:u.executable??null,dataDir:k,discoveredAt:o,lastReachableAt:o}}))).filter(u=>u!==null)}function wS(i){const r=new Set(i.hosts.map(o=>We(o.baseUrl)));return i.discoveredHosts.filter(o=>!r.has(We(o.baseUrl)))}function Wy(i){const r=kn(i);return r?i.hosts.find(o=>o.id===r)??i.discoveredHosts.find(o=>o.id===r)??null:null}class Uy{constructor(){A(this,"inFlight",null)}initialize(){this.refresh()}async refresh(r={}){if(this.inFlight)return this.inFlight;const o=this.performRefresh(r).finally(()=>{this.inFlight===o&&(this.inFlight=null)});return this.inFlight=o,o}setActiveDiscoveredHost(r){const o=X.getState(),c=r&&o.discoveredHosts.some(u=>u.id===r)?r:null;c!==o.activeDiscoveredHostId&&X.updateRuntime({activeDiscoveredHostId:c})}async performRefresh({force:r=!1}){const o=An(),c=X.getState();if(!o.isDesktop||o.ui.osFamily!=="windows"&&o.ui.osFamily!=="macos"){X.updateRuntime({discoveredHosts:[],activeDiscoveredHostId:null,localHostDiscovery:{status:"unsupported",lastScannedAt:c.localHostDiscovery.lastScannedAt,cooldownUntil:null,errorCode:"PLATFORM_NOT_SUPPORTED",errorDetail:"当前平台不支持本机 HOST 自动发现。"}});return}const u=c.localHostDiscovery.cooldownUntil?Date.parse(c.localHostDiscovery.cooldownUntil):Number.NaN;if(!r&&Number.isFinite(u)&&u>Date.now())return;X.updateRuntime({localHostDiscovery:{...c.localHostDiscovery,status:"refreshing",errorCode:null,errorDetail:null}});const p=await o.bridge.scanLocalHosts(),y=Qp(),k=new Date(Date.now()+My).toISOString();if(!p.ok){X.updateRuntime({localHostDiscovery:{status:p.errorCode==="PLATFORM_NOT_SUPPORTED"?"unsupported":"failed",lastScannedAt:y,cooldownUntil:k,errorCode:p.errorCode??"LOCAL_HOST_DISCOVERY_FAILED",errorDetail:p.detail??"本机 HOST 扫描失败。"}});return}const L=await By(p.value??[]),O=Wy(X.getState()),E=Wd(O)&&L.some(B=>B.id===O.id)?O.id:null;X.updateRuntime({discoveredHosts:L,activeDiscoveredHostId:E,localHostDiscovery:{status:"ready",lastScannedAt:y,cooldownUntil:k,errorCode:null,errorDetail:null}})}}const _y=new Uy;async function Vy(){const i=An();return await X.initialize(),_y.initialize(),tb().catch(()=>{}),{platform:i.platform}}const zy=He.lazy(async()=>({default:(await sa(()=>import("./App-DrNI9lWA.js").then(r=>r.A),__vite__mapDeps([0,1]))).App}));function jy(){const[i,r]=He.useState(!1),[o,c]=He.useState(null);return He.useEffect(()=>{let u=!1;return Vy().then(()=>{u||r(!0)}).catch(p=>{u||c(p instanceof Error&&p.message.trim()?p.message:tt("shell.navigationLoadFailed"))}),()=>{u=!0}},[]),i?la.jsx(He.Suspense,{fallback:null,children:la.jsx(zy,{})}):la.jsx("main",{className:"page-center app-shell",children:la.jsxs("section",{className:"auth-card surface-card",children:[la.jsx("h1",{children:"CodingNS"}),la.jsx("p",{className:"status-text",children:tt("common.loading")}),o?la.jsx("p",{className:"status-text","data-tone":"error",children:o}):null]})})}rh.createRoot(document.getElementById("root")).render(la.jsx(jy,{}));export{gS as $,et as A,hS as B,is as C,Rn as D,eb as E,wg as F,vg as G,eS as H,pS as I,Xy as J,ih as K,Jl as L,lh as M,bS as N,yS as O,SS as P,gb as Q,Gy as R,ph as S,wp as T,Jy as U,ky as V,uh as W,Kp as X,Qy as Y,_y as Z,sa as _,dS as a,kS as a0,tS as a1,aS as a2,oS as a3,lS as a4,sS as a5,Eg as a6,up as a7,cS as a8,sp as a9,nS as aa,rS as ab,uS as ac,TS as ad,He as b,An as c,ri as d,X as e,Zy as f,Bd as g,Da as h,Wd as i,la as j,bb as k,wS as l,Me as m,We as n,fS as o,kn as p,xh as q,th as r,Ky as s,tt as t,ab as u,mh as v,iS as w,mS as x,$y as y,Yy as z};