@ashlr/hub 3.22.0 → 3.22.1

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 (929) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +5 -5
  3. package/dist/authority-surface.json +16 -11
  4. package/dist/build-identity.json +2 -2
  5. package/dist/cli/verify-safety-sources.d.ts +4 -0
  6. package/dist/cli/verify-safety-sources.js +41 -0
  7. package/dist/cli/verify-safety-sources.js.map +1 -0
  8. package/dist/cli/verify-safety.js +16 -1
  9. package/dist/cli/verify-safety.js.map +1 -1
  10. package/dist/core/decide/needs-you.d.ts +3 -1
  11. package/dist/core/decide/needs-you.js +52 -28
  12. package/dist/core/decide/needs-you.js.map +1 -1
  13. package/dist/core/fleet/fleet-control-model.d.ts +2 -1
  14. package/dist/core/fleet/fleet-control-model.js +5 -0
  15. package/dist/core/fleet/fleet-control-model.js.map +1 -1
  16. package/dist/core/fleet/fleet-control-types.d.ts +11 -1
  17. package/dist/core/fleet/fleet-control.d.ts +4 -0
  18. package/dist/core/fleet/fleet-control.js +23 -1
  19. package/dist/core/fleet/fleet-control.js.map +1 -1
  20. package/dist/core/fleet/quota.js +1 -1
  21. package/dist/core/fleet/quota.js.map +1 -1
  22. package/dist/core/universe/builtins/preparation/manifest.json +1 -1
  23. package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +4 -2
  24. package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +3 -1
  25. package/dist/core/web/public/next/assets/ActionMenu-Z14OhnFI.js +2 -0
  26. package/dist/core/web/public/next/assets/ActionMenu-Z14OhnFI.js.map +1 -0
  27. package/dist/core/web/public/next/assets/Advanced-fUyq-fpH.js +2 -0
  28. package/dist/core/web/public/next/assets/Advanced-fUyq-fpH.js.map +1 -0
  29. package/dist/core/web/public/next/assets/AgentDetailScreen-C8h--Nah.js +2 -0
  30. package/dist/core/web/public/next/assets/AgentDetailScreen-C8h--Nah.js.map +1 -0
  31. package/dist/core/web/public/next/assets/AgentToolsSheet-BP3h-UbZ.js +2 -0
  32. package/dist/core/web/public/next/assets/AgentToolsSheet-BP3h-UbZ.js.map +1 -0
  33. package/dist/core/web/public/next/assets/AgentToolsStrip--hf18knJ.js +2 -0
  34. package/dist/core/web/public/next/assets/AgentToolsStrip--hf18knJ.js.map +1 -0
  35. package/dist/core/web/public/next/assets/AgentsScreen-BR-j0Fzd.js +2 -0
  36. package/dist/core/web/public/next/assets/AgentsScreen-BR-j0Fzd.js.map +1 -0
  37. package/dist/core/web/public/next/assets/AgentsSection-OKKOuYed.js +3 -0
  38. package/dist/core/web/public/next/assets/AgentsSection-OKKOuYed.js.map +1 -0
  39. package/dist/core/web/public/next/assets/App-ttVrZYp5.js +8 -0
  40. package/dist/core/web/public/next/assets/App-ttVrZYp5.js.map +1 -0
  41. package/dist/core/web/public/next/assets/AppsSection-sqsXqENO.js +2 -0
  42. package/dist/core/web/public/next/assets/AppsSection-sqsXqENO.js.map +1 -0
  43. package/dist/core/web/public/next/assets/AreaTrend-LVgaB49b.js +2 -0
  44. package/dist/core/web/public/next/assets/AreaTrend-LVgaB49b.js.map +1 -0
  45. package/dist/core/web/public/next/assets/AutomationsSection-BITmxjuB.js +2 -0
  46. package/dist/core/web/public/next/assets/AutomationsSection-BITmxjuB.js.map +1 -0
  47. package/dist/core/web/public/next/assets/AutonomyOffState-nO9lIcCv.js +3 -0
  48. package/dist/core/web/public/next/assets/AutonomyOffState-nO9lIcCv.js.map +1 -0
  49. package/dist/core/web/public/next/assets/AutonomySection-DWYUPDP6.js +2 -0
  50. package/dist/core/web/public/next/assets/AutonomySection-DWYUPDP6.js.map +1 -0
  51. package/dist/core/web/public/next/assets/AutonomyStatus-C4Yp1JTY.js +2 -0
  52. package/dist/core/web/public/next/assets/AutonomyStatus-C4Yp1JTY.js.map +1 -0
  53. package/dist/core/web/public/next/assets/BranchBar-CkiZSNqB.js +2 -0
  54. package/dist/core/web/public/next/assets/BranchBar-CkiZSNqB.js.map +1 -0
  55. package/dist/core/web/public/next/assets/BrowserPanel-CECVGJBS.js +7 -0
  56. package/dist/core/web/public/next/assets/BrowserPanel-CECVGJBS.js.map +1 -0
  57. package/dist/core/web/public/next/assets/BudgetControl-De1TPzvX.js +2 -0
  58. package/dist/core/web/public/next/assets/BudgetControl-De1TPzvX.js.map +1 -0
  59. package/dist/core/web/public/next/assets/Button-CstSJwha.js +2 -0
  60. package/dist/core/web/public/next/assets/Button-CstSJwha.js.map +1 -0
  61. package/dist/core/web/public/next/assets/CapacityStrip-nIJcB_lA.js +2 -0
  62. package/dist/core/web/public/next/assets/CapacityStrip-nIJcB_lA.js.map +1 -0
  63. package/dist/core/web/public/next/assets/ChangesPaneHost-Bnj_NcRa.js +16 -0
  64. package/dist/core/web/public/next/assets/ChangesPaneHost-Bnj_NcRa.js.map +1 -0
  65. package/dist/core/web/public/next/assets/ChartFrame-Dljee9y6.js +2 -0
  66. package/dist/core/web/public/next/assets/ChartFrame-Dljee9y6.js.map +1 -0
  67. package/dist/core/web/public/next/assets/ChatPanes-x_ySUIyR.js +2 -0
  68. package/dist/core/web/public/next/assets/ChatPanes-x_ySUIyR.js.map +1 -0
  69. package/dist/core/web/public/next/assets/ChatSection-CXJa8QOi.js +3 -0
  70. package/dist/core/web/public/next/assets/ChatSection-CXJa8QOi.js.map +1 -0
  71. package/dist/core/web/public/next/assets/ChecksPanel-D9r8koxq.js +5 -0
  72. package/dist/core/web/public/next/assets/ChecksPanel-D9r8koxq.js.map +1 -0
  73. package/dist/core/web/public/next/assets/CloudBudgetForm-D5ajpoMe.js +2 -0
  74. package/dist/core/web/public/next/assets/CloudBudgetForm-D5ajpoMe.js.map +1 -0
  75. package/dist/core/web/public/next/assets/CommandPalette-ONyqYZzt.js +3 -0
  76. package/dist/core/web/public/next/assets/CommandPalette-ONyqYZzt.js.map +1 -0
  77. package/dist/core/web/public/next/assets/CommandSection-DxNIibnI.js +3 -0
  78. package/dist/core/web/public/next/assets/CommandSection-DxNIibnI.js.map +1 -0
  79. package/dist/core/web/public/next/assets/CommandWorkflowForm-Bz3PuZXH.js +9 -0
  80. package/dist/core/web/public/next/assets/CommandWorkflowForm-Bz3PuZXH.js.map +1 -0
  81. package/dist/core/web/public/next/assets/CommandWorkflowPicker-COVyeer0.js +3 -0
  82. package/dist/core/web/public/next/assets/CommandWorkflowPicker-COVyeer0.js.map +1 -0
  83. package/dist/core/web/public/next/assets/CompareDialog-PVqv0Tx9.js +4 -0
  84. package/dist/core/web/public/next/assets/CompareDialog-PVqv0Tx9.js.map +1 -0
  85. package/dist/core/web/public/next/assets/ComputerControl-DkSIUrYm.js +2 -0
  86. package/dist/core/web/public/next/assets/ComputerControl-DkSIUrYm.js.map +1 -0
  87. package/dist/core/web/public/next/assets/ConfirmDialog-CdCzzk0I.js +2 -0
  88. package/dist/core/web/public/next/assets/ConfirmDialog-CdCzzk0I.js.map +1 -0
  89. package/dist/core/web/public/next/assets/DeleteChatDialog-BTzOgqho.js +2 -0
  90. package/dist/core/web/public/next/assets/DeleteChatDialog-BTzOgqho.js.map +1 -0
  91. package/dist/core/web/public/next/assets/DevinStopDialog-CGsDqfan.js +2 -0
  92. package/dist/core/web/public/next/assets/DevinStopDialog-CGsDqfan.js.map +1 -0
  93. package/dist/core/web/public/next/assets/Dialog-DDHg9cuT.js +2 -0
  94. package/dist/core/web/public/next/assets/Dialog-DDHg9cuT.js.map +1 -0
  95. package/dist/core/web/public/next/assets/DiffPane-BR3HU7pC.js +2 -0
  96. package/dist/core/web/public/next/assets/DiffPane-BR3HU7pC.js.map +1 -0
  97. package/dist/core/web/public/next/assets/DiffViewer-hJK75qko.js +2 -0
  98. package/dist/core/web/public/next/assets/DiffViewer-hJK75qko.js.map +1 -0
  99. package/dist/core/web/public/next/assets/DockHost-DhOosHbo.js +2 -0
  100. package/dist/core/web/public/next/assets/DockHost-DhOosHbo.js.map +1 -0
  101. package/dist/core/web/public/next/assets/EmptyState-CGVr0VO2.js +2 -0
  102. package/dist/core/web/public/next/assets/EmptyState-CGVr0VO2.js.map +1 -0
  103. package/dist/core/web/public/next/assets/Epistemic-tp0ZNAKZ.js +2 -0
  104. package/dist/core/web/public/next/assets/Epistemic-tp0ZNAKZ.js.map +1 -0
  105. package/dist/core/web/public/next/assets/EvidenceTimeline-YmKIoxNx.js +2 -0
  106. package/dist/core/web/public/next/assets/EvidenceTimeline-YmKIoxNx.js.map +1 -0
  107. package/dist/core/web/public/next/assets/FilesPane-CoNjfkPP.js +2 -0
  108. package/dist/core/web/public/next/assets/FilesPane-CoNjfkPP.js.map +1 -0
  109. package/dist/core/web/public/next/assets/FleetScreen-CstwycnB.js +2 -0
  110. package/dist/core/web/public/next/assets/FleetScreen-CstwycnB.js.map +1 -0
  111. package/dist/core/web/public/next/assets/FleetSection-D0xk0s5J.js +5 -0
  112. package/dist/core/web/public/next/assets/FleetSection-D0xk0s5J.js.map +1 -0
  113. package/dist/core/web/public/next/assets/Funnel-UPrk7fcy.js +2 -0
  114. package/dist/core/web/public/next/assets/Funnel-UPrk7fcy.js.map +1 -0
  115. package/dist/core/web/public/next/assets/GearTray-BSjga1J_.js +2 -0
  116. package/dist/core/web/public/next/assets/GearTray-BSjga1J_.js.map +1 -0
  117. package/dist/core/web/public/next/assets/GitDialogs-ekwzxl76.js +2 -0
  118. package/dist/core/web/public/next/assets/GitDialogs-ekwzxl76.js.map +1 -0
  119. package/dist/core/web/public/next/assets/GrowthSection-Dh-gnkgc.js +3 -0
  120. package/dist/core/web/public/next/assets/GrowthSection-Dh-gnkgc.js.map +1 -0
  121. package/dist/core/web/public/next/assets/HandoffDialog-BDiyA3u-.js +2 -0
  122. package/dist/core/web/public/next/assets/HandoffDialog-BDiyA3u-.js.map +1 -0
  123. package/dist/core/web/public/next/assets/HomeBody-Ce3HBIEb.js +3 -0
  124. package/dist/core/web/public/next/assets/HomeBody-Ce3HBIEb.js.map +1 -0
  125. package/dist/core/web/public/next/assets/HomeSeats-BFLCWCFp.js +2 -0
  126. package/dist/core/web/public/next/assets/HomeSeats-BFLCWCFp.js.map +1 -0
  127. package/dist/core/web/public/next/assets/Input-Cpn9uYj2.js +2 -0
  128. package/dist/core/web/public/next/assets/Input-Cpn9uYj2.js.map +1 -0
  129. package/dist/core/web/public/next/assets/LaunchDialog-CrPEf652.js +9 -0
  130. package/dist/core/web/public/next/assets/LaunchDialog-CrPEf652.js.map +1 -0
  131. package/dist/core/web/public/next/assets/LeaderCard-Dhq-w_Mf.js +2 -0
  132. package/dist/core/web/public/next/assets/LeaderCard-Dhq-w_Mf.js.map +1 -0
  133. package/dist/core/web/public/next/assets/LeaderConversation-CiWqhsoa.js +3 -0
  134. package/dist/core/web/public/next/assets/LeaderConversation-CiWqhsoa.js.map +1 -0
  135. package/dist/core/web/public/next/assets/LeaderScreen-Z5KPjxBV.js +2 -0
  136. package/dist/core/web/public/next/assets/LeaderScreen-Z5KPjxBV.js.map +1 -0
  137. package/dist/core/web/public/next/assets/LessonsPanel-B6XVKAPE.js +2 -0
  138. package/dist/core/web/public/next/assets/LessonsPanel-B6XVKAPE.js.map +1 -0
  139. package/dist/core/web/public/next/assets/LiveTimer-B8t2iX5h.js +2 -0
  140. package/dist/core/web/public/next/assets/LiveTimer-B8t2iX5h.js.map +1 -0
  141. package/dist/core/web/public/next/assets/LocalSeatBadge-HMxIrMiL.js +2 -0
  142. package/dist/core/web/public/next/assets/LocalSeatBadge-HMxIrMiL.js.map +1 -0
  143. package/dist/core/web/public/next/assets/MatrixHeatmap-BlFI5oao.js +2 -0
  144. package/dist/core/web/public/next/assets/MatrixHeatmap-BlFI5oao.js.map +1 -0
  145. package/dist/core/web/public/next/assets/McpSection-snZNKexW.js +2 -0
  146. package/dist/core/web/public/next/assets/McpSection-snZNKexW.js.map +1 -0
  147. package/dist/core/web/public/next/assets/MessageMarkdown-CS0mAtSs.js +3 -0
  148. package/dist/core/web/public/next/assets/MessageMarkdown-CS0mAtSs.js.map +1 -0
  149. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-D5R-zr-W.js +72 -0
  150. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-D5R-zr-W.js.map +1 -0
  151. package/dist/core/web/public/next/assets/Meter-VXI75VNe.js +2 -0
  152. package/dist/core/web/public/next/assets/Meter-VXI75VNe.js.map +1 -0
  153. package/dist/core/web/public/next/assets/MicButton-DORAXsUU.js +2 -0
  154. package/dist/core/web/public/next/assets/MicButton-DORAXsUU.js.map +1 -0
  155. package/dist/core/web/public/next/assets/MindSection-DZLHz29Q.js +3 -0
  156. package/dist/core/web/public/next/assets/MindSection-DZLHz29Q.js.map +1 -0
  157. package/dist/core/web/public/next/assets/MobileComposer-B8nWsIJO.js +2 -0
  158. package/dist/core/web/public/next/assets/MobileComposer-B8nWsIJO.js.map +1 -0
  159. package/dist/core/web/public/next/assets/MobileGuardSheet-BRwOfD9o.js +2 -0
  160. package/dist/core/web/public/next/assets/MobileGuardSheet-BRwOfD9o.js.map +1 -0
  161. package/dist/core/web/public/next/assets/MobileRuntime-kMob_MjB.js +3 -0
  162. package/dist/core/web/public/next/assets/MobileRuntime-kMob_MjB.js.map +1 -0
  163. package/dist/core/web/public/next/assets/MoreScreen-92dC6Bj7.js +2 -0
  164. package/dist/core/web/public/next/assets/MoreScreen-92dC6Bj7.js.map +1 -0
  165. package/dist/core/web/public/next/assets/MultiModelBar-BhAUUQOq.js +7 -0
  166. package/dist/core/web/public/next/assets/MultiModelBar-BhAUUQOq.js.map +1 -0
  167. package/dist/core/web/public/next/assets/MutationTokenDialog-DlY2VLVh.js +2 -0
  168. package/dist/core/web/public/next/assets/MutationTokenDialog-DlY2VLVh.js.map +1 -0
  169. package/dist/core/web/public/next/assets/NeedsYouDrawer-BH0ffbht.js +3 -0
  170. package/dist/core/web/public/next/assets/NeedsYouDrawer-BH0ffbht.js.map +1 -0
  171. package/dist/core/web/public/next/assets/NeedsYouList-CI_Dy-hi.js +2 -0
  172. package/dist/core/web/public/next/assets/NeedsYouList-CI_Dy-hi.js.map +1 -0
  173. package/dist/core/web/public/next/assets/NeedsYouScreen-CvDiEphJ.js +2 -0
  174. package/dist/core/web/public/next/assets/NeedsYouScreen-CvDiEphJ.js.map +1 -0
  175. package/dist/core/web/public/next/assets/NewAgentScreen-BpTRKp9z.js +2 -0
  176. package/dist/core/web/public/next/assets/NewAgentScreen-BpTRKp9z.js.map +1 -0
  177. package/dist/core/web/public/next/assets/NewChatDialog-O1LwwBc4.js +4 -0
  178. package/dist/core/web/public/next/assets/NewChatDialog-O1LwwBc4.js.map +1 -0
  179. package/dist/core/web/public/next/assets/OnboardingFlow-uMNBVHvK.js +3 -0
  180. package/dist/core/web/public/next/assets/OnboardingFlow-uMNBVHvK.js.map +1 -0
  181. package/dist/core/web/public/next/assets/OnboardingGate-sdzxSPZF.js +3 -0
  182. package/dist/core/web/public/next/assets/OnboardingGate-sdzxSPZF.js.map +1 -0
  183. package/dist/core/web/public/next/assets/PlaybooksSection-CnWfwZv8.js +9 -0
  184. package/dist/core/web/public/next/assets/PlaybooksSection-CnWfwZv8.js.map +1 -0
  185. package/dist/core/web/public/next/assets/PreviewPane-D1WaefIG.js +2 -0
  186. package/dist/core/web/public/next/assets/PreviewPane-D1WaefIG.js.map +1 -0
  187. package/dist/core/web/public/next/assets/ProviderLogo-g2YWCmNY.js +2 -0
  188. package/dist/core/web/public/next/assets/ProviderLogo-g2YWCmNY.js.map +1 -0
  189. package/dist/core/web/public/next/assets/RailStatus-OrvAuyzs.js +2 -0
  190. package/dist/core/web/public/next/assets/RailStatus-OrvAuyzs.js.map +1 -0
  191. package/dist/core/web/public/next/assets/ReasoningPane-BARDPl4-.js +2 -0
  192. package/dist/core/web/public/next/assets/ReasoningPane-BARDPl4-.js.map +1 -0
  193. package/dist/core/web/public/next/assets/ReasoningSheet-rPTXyt-b.js +2 -0
  194. package/dist/core/web/public/next/assets/ReasoningSheet-rPTXyt-b.js.map +1 -0
  195. package/dist/core/web/public/next/assets/RefreshIndicator-D96C9qiH.js +2 -0
  196. package/dist/core/web/public/next/assets/RefreshIndicator-D96C9qiH.js.map +1 -0
  197. package/dist/core/web/public/next/assets/RemoteMobileApp-DfDjiBTR.js +2 -0
  198. package/dist/core/web/public/next/assets/RemoteMobileApp-DfDjiBTR.js.map +1 -0
  199. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CcfULh_p.js +7 -0
  200. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CcfULh_p.js.map +1 -0
  201. package/dist/core/web/public/next/assets/ResourcesChrome-DuEa7WOo.css +1 -0
  202. package/dist/core/web/public/next/assets/ResourcesChrome-e9ifgnWf.js +3 -0
  203. package/dist/core/web/public/next/assets/ResourcesChrome-e9ifgnWf.js.map +1 -0
  204. package/dist/core/web/public/next/assets/ResourcesDrawer-DOv_mxpe.js +3 -0
  205. package/dist/core/web/public/next/assets/ResourcesDrawer-DOv_mxpe.js.map +1 -0
  206. package/dist/core/web/public/next/assets/ReviewMenu-Ba3saQlX.js +2 -0
  207. package/dist/core/web/public/next/assets/ReviewMenu-Ba3saQlX.js.map +1 -0
  208. package/dist/core/web/public/next/assets/RouteErrorBoundary-BaJ1ZePy.js +2 -0
  209. package/dist/core/web/public/next/assets/RouteErrorBoundary-BaJ1ZePy.js.map +1 -0
  210. package/dist/core/web/public/next/assets/RunInCloudAction-DRSX84Jy.js +2 -0
  211. package/dist/core/web/public/next/assets/RunInCloudAction-DRSX84Jy.js.map +1 -0
  212. package/dist/core/web/public/next/assets/RunInDevinAction-BMji-YN2.js +2 -0
  213. package/dist/core/web/public/next/assets/RunInDevinAction-BMji-YN2.js.map +1 -0
  214. package/dist/core/web/public/next/assets/SchedulingEvidence-xxjV6HF_.js +2 -0
  215. package/dist/core/web/public/next/assets/SchedulingEvidence-xxjV6HF_.js.map +1 -0
  216. package/dist/core/web/public/next/assets/ScreenHost-Dv6z76Ta.js +3 -0
  217. package/dist/core/web/public/next/assets/ScreenHost-Dv6z76Ta.js.map +1 -0
  218. package/dist/core/web/public/next/assets/SeatSelector-YRNdNpP8.js +3 -0
  219. package/dist/core/web/public/next/assets/SeatSelector-YRNdNpP8.js.map +1 -0
  220. package/dist/core/web/public/next/assets/Segmented-BA8RmKYq.js +2 -0
  221. package/dist/core/web/public/next/assets/Segmented-BA8RmKYq.js.map +1 -0
  222. package/dist/core/web/public/next/assets/Select-B8GqZOX9.js +2 -0
  223. package/dist/core/web/public/next/assets/Select-B8GqZOX9.js.map +1 -0
  224. package/dist/core/web/public/next/assets/SessionGate-CnASHl7g.js +2 -0
  225. package/dist/core/web/public/next/assets/SessionGate-CnASHl7g.js.map +1 -0
  226. package/dist/core/web/public/next/assets/SessionInsightChip-DIKfih6i.js +2 -0
  227. package/dist/core/web/public/next/assets/SessionInsightChip-DIKfih6i.js.map +1 -0
  228. package/dist/core/web/public/next/assets/SessionSearch-K6lvMlji.js +2 -0
  229. package/dist/core/web/public/next/assets/SessionSearch-K6lvMlji.js.map +1 -0
  230. package/dist/core/web/public/next/assets/SettingsSection-C-c3f_6J.js +2 -0
  231. package/dist/core/web/public/next/assets/SettingsSection-C-c3f_6J.js.map +1 -0
  232. package/dist/core/web/public/next/assets/SetupChecklist-DAbAdrX4.js +2 -0
  233. package/dist/core/web/public/next/assets/SetupChecklist-DAbAdrX4.js.map +1 -0
  234. package/dist/core/web/public/next/assets/ShadowDecisions-C41uRSw4.js +3 -0
  235. package/dist/core/web/public/next/assets/ShadowDecisions-C41uRSw4.js.map +1 -0
  236. package/dist/core/web/public/next/assets/Sheet-Bk64-Hlt.js +2 -0
  237. package/dist/core/web/public/next/assets/Sheet-Bk64-Hlt.js.map +1 -0
  238. package/dist/core/web/public/next/assets/ShortcutsOverlay-CcP96zqy.js +2 -0
  239. package/dist/core/web/public/next/assets/ShortcutsOverlay-CcP96zqy.js.map +1 -0
  240. package/dist/core/web/public/next/assets/Sidebar-sSNKd57n.js +3 -0
  241. package/dist/core/web/public/next/assets/Sidebar-sSNKd57n.js.map +1 -0
  242. package/dist/core/web/public/next/assets/SkipToContent-BynsXs9i.js +2 -0
  243. package/dist/core/web/public/next/assets/SkipToContent-BynsXs9i.js.map +1 -0
  244. package/dist/core/web/public/next/assets/Slider-DS5HrVzl.js +2 -0
  245. package/dist/core/web/public/next/assets/Slider-DS5HrVzl.js.map +1 -0
  246. package/dist/core/web/public/next/assets/SourcesPane-QffcyDfA.js +2 -0
  247. package/dist/core/web/public/next/assets/SourcesPane-QffcyDfA.js.map +1 -0
  248. package/dist/core/web/public/next/assets/SourcesPanel-DlttePk7.js +2 -0
  249. package/dist/core/web/public/next/assets/SourcesPanel-DlttePk7.js.map +1 -0
  250. package/dist/core/web/public/next/assets/StatTile-mYm1GPj7.js +2 -0
  251. package/dist/core/web/public/next/assets/StatTile-mYm1GPj7.js.map +1 -0
  252. package/dist/core/web/public/next/assets/StatusBadge-Yz7S3kZ2.js +2 -0
  253. package/dist/core/web/public/next/assets/StatusBadge-Yz7S3kZ2.js.map +1 -0
  254. package/dist/core/web/public/next/assets/StepBand-Bdkv7iGd.js +2 -0
  255. package/dist/core/web/public/next/assets/StepBand-Bdkv7iGd.js.map +1 -0
  256. package/dist/core/web/public/next/assets/Surface-DVOAKl2g.js +2 -0
  257. package/dist/core/web/public/next/assets/Surface-DVOAKl2g.js.map +1 -0
  258. package/dist/core/web/public/next/assets/Swimlane-CeMBD_FC.js +2 -0
  259. package/dist/core/web/public/next/assets/Swimlane-CeMBD_FC.js.map +1 -0
  260. package/dist/core/web/public/next/assets/Switch-Cqc_bSoh.js +2 -0
  261. package/dist/core/web/public/next/assets/Switch-Cqc_bSoh.js.map +1 -0
  262. package/dist/core/web/public/next/assets/Tag-BvOxSxYi.js +2 -0
  263. package/dist/core/web/public/next/assets/Tag-BvOxSxYi.js.map +1 -0
  264. package/dist/core/web/public/next/assets/TerminalPane-D3f02aI4.js +3 -0
  265. package/dist/core/web/public/next/assets/TerminalPane-D3f02aI4.js.map +1 -0
  266. package/dist/core/web/public/next/assets/TerminalPane-XZ5n3Pns.js +26 -0
  267. package/dist/core/web/public/next/assets/TerminalPane-XZ5n3Pns.js.map +1 -0
  268. package/dist/core/web/public/next/assets/ThinkingBlock-DZNlOGaV.js +2 -0
  269. package/dist/core/web/public/next/assets/ThinkingBlock-DZNlOGaV.js.map +1 -0
  270. package/dist/core/web/public/next/assets/UniverseConsoleApp-CzBI6Upl.js +2 -0
  271. package/dist/core/web/public/next/assets/UniverseConsoleApp-CzBI6Upl.js.map +1 -0
  272. package/dist/core/web/public/next/assets/UniverseView-Dsi3Kk8o.js +9 -0
  273. package/dist/core/web/public/next/assets/UniverseView-Dsi3Kk8o.js.map +1 -0
  274. package/dist/core/web/public/next/assets/UsageSection-rVvLat9z.js +3 -0
  275. package/dist/core/web/public/next/assets/UsageSection-rVvLat9z.js.map +1 -0
  276. package/dist/core/web/public/next/assets/UsePlaybookAction-B4XAzSeI.js +2 -0
  277. package/dist/core/web/public/next/assets/UsePlaybookAction-B4XAzSeI.js.map +1 -0
  278. package/dist/core/web/public/next/assets/VerseConsoleApp-BmckthwC.css +1 -0
  279. package/dist/core/web/public/next/assets/VerseConsoleApp-DjPpZLo1.js +3 -0
  280. package/dist/core/web/public/next/assets/VerseConsoleApp-DjPpZLo1.js.map +1 -0
  281. package/dist/core/web/public/next/assets/VerseMobileApp-ePNuVERe.js +3 -0
  282. package/dist/core/web/public/next/assets/VerseMobileApp-ePNuVERe.js.map +1 -0
  283. package/dist/core/web/public/next/assets/VerseShared-Bf-XTHCh.js +2 -0
  284. package/dist/core/web/public/next/assets/VerseShared-Bf-XTHCh.js.map +1 -0
  285. package/dist/core/web/public/next/assets/VoiceHud-BG5FV2h0.js +2 -0
  286. package/dist/core/web/public/next/assets/VoiceHud-BG5FV2h0.js.map +1 -0
  287. package/dist/core/web/public/next/assets/VoiceInput-k3vB_FxV.js +2 -0
  288. package/dist/core/web/public/next/assets/VoiceInput-k3vB_FxV.js.map +1 -0
  289. package/dist/core/web/public/next/assets/WikiSection-DeBKNqd6.js +2 -0
  290. package/dist/core/web/public/next/assets/WikiSection-DeBKNqd6.js.map +1 -0
  291. package/dist/core/web/public/next/assets/Workspace-CvwS2-RN.js +6 -0
  292. package/dist/core/web/public/next/assets/Workspace-CvwS2-RN.js.map +1 -0
  293. package/dist/core/web/public/next/assets/actions-Dg6UJTLn.js +2 -0
  294. package/dist/core/web/public/next/assets/actions-Dg6UJTLn.js.map +1 -0
  295. package/dist/core/web/public/next/assets/agent-tools-client-DmJq7zlr.js +2 -0
  296. package/dist/core/web/public/next/assets/agent-tools-client-DmJq7zlr.js.map +1 -0
  297. package/dist/core/web/public/next/assets/agents-focus-B1LKhUVg.js +2 -0
  298. package/dist/core/web/public/next/assets/agents-focus-B1LKhUVg.js.map +1 -0
  299. package/dist/core/web/public/next/assets/app-version-Cb1z8iCO.js +2 -0
  300. package/dist/core/web/public/next/assets/app-version-Cb1z8iCO.js.map +1 -0
  301. package/dist/core/web/public/next/assets/apps-model-_chbcQeN.js +2 -0
  302. package/dist/core/web/public/next/assets/apps-model-_chbcQeN.js.map +1 -0
  303. package/dist/core/web/public/next/assets/ask-seat-O60AydbV.js +2 -0
  304. package/dist/core/web/public/next/assets/ask-seat-O60AydbV.js.map +1 -0
  305. package/dist/core/web/public/next/assets/authority-model-BeDDHF22.js +2 -0
  306. package/dist/core/web/public/next/assets/authority-model-BeDDHF22.js.map +1 -0
  307. package/dist/core/web/public/next/assets/automations-focus-BXaRZ8nX.js +2 -0
  308. package/dist/core/web/public/next/assets/automations-focus-BXaRZ8nX.js.map +1 -0
  309. package/dist/core/web/public/next/assets/budget-queries-Nvx0H2XE.js +2 -0
  310. package/dist/core/web/public/next/assets/budget-queries-Nvx0H2XE.js.map +1 -0
  311. package/dist/core/web/public/next/assets/capacity-strip-model-CBMJ2U-w.js +2 -0
  312. package/dist/core/web/public/next/assets/capacity-strip-model-CBMJ2U-w.js.map +1 -0
  313. package/dist/core/web/public/next/assets/charts-DT9PYS49.js +2 -0
  314. package/dist/core/web/public/next/assets/charts-DT9PYS49.js.map +1 -0
  315. package/dist/core/web/public/next/assets/chat-pane-data-CfbpeAYX.js +2 -0
  316. package/dist/core/web/public/next/assets/chat-pane-data-CfbpeAYX.js.map +1 -0
  317. package/dist/core/web/public/next/assets/checkpoint-queries-BKD2evmX.js +2 -0
  318. package/dist/core/web/public/next/assets/checkpoint-queries-BKD2evmX.js.map +1 -0
  319. package/dist/core/web/public/next/assets/cloud-queries-CsU54eNn.js +2 -0
  320. package/dist/core/web/public/next/assets/cloud-queries-CsU54eNn.js.map +1 -0
  321. package/dist/core/web/public/next/assets/command-catalog-B0ApAGD0.js +2 -0
  322. package/dist/core/web/public/next/assets/command-catalog-B0ApAGD0.js.map +1 -0
  323. package/dist/core/web/public/next/assets/composer-queries-D1H4E0Ye.js +2 -0
  324. package/dist/core/web/public/next/assets/composer-queries-D1H4E0Ye.js.map +1 -0
  325. package/dist/core/web/public/next/assets/connectivity-xQ0Nh0j3.js +2 -0
  326. package/dist/core/web/public/next/assets/connectivity-xQ0Nh0j3.js.map +1 -0
  327. package/dist/core/web/public/next/assets/context-queries-bnI3P0Wt.js +2 -0
  328. package/dist/core/web/public/next/assets/context-queries-bnI3P0Wt.js.map +1 -0
  329. package/dist/core/web/public/next/assets/control-queries-BG53otwz.js +2 -0
  330. package/dist/core/web/public/next/assets/control-queries-BG53otwz.js.map +1 -0
  331. package/dist/core/web/public/next/assets/copy-setup-COMDnur3.js +2 -0
  332. package/dist/core/web/public/next/assets/copy-setup-COMDnur3.js.map +1 -0
  333. package/dist/core/web/public/next/assets/deep-link-CqOP-JEm.js +2 -0
  334. package/dist/core/web/public/next/assets/deep-link-CqOP-JEm.js.map +1 -0
  335. package/dist/core/web/public/next/assets/device-permissions-DpsJJcUW.js +2 -0
  336. package/dist/core/web/public/next/assets/device-permissions-DpsJJcUW.js.map +1 -0
  337. package/dist/core/web/public/next/assets/devin-queries-BSEOfLuZ.js +2 -0
  338. package/dist/core/web/public/next/assets/devin-queries-BSEOfLuZ.js.map +1 -0
  339. package/dist/core/web/public/next/assets/dock-icons-DK7QcBXJ.js +2 -0
  340. package/dist/core/web/public/next/assets/dock-icons-DK7QcBXJ.js.map +1 -0
  341. package/dist/core/web/public/next/assets/dock-panes-DvQ6t4Nl.js +2 -0
  342. package/dist/core/web/public/next/assets/dock-panes-DvQ6t4Nl.js.map +1 -0
  343. package/dist/core/web/public/next/assets/fleet-control-queries-BL-Vlf85.js +2 -0
  344. package/dist/core/web/public/next/assets/fleet-control-queries-BL-Vlf85.js.map +1 -0
  345. package/dist/core/web/public/next/assets/fleet-queries-eacERnLm.js +2 -0
  346. package/dist/core/web/public/next/assets/fleet-queries-eacERnLm.js.map +1 -0
  347. package/dist/core/web/public/next/assets/fleet-state-DfKcuo4A.js +3 -0
  348. package/dist/core/web/public/next/assets/fleet-state-DfKcuo4A.js.map +1 -0
  349. package/dist/core/web/public/next/assets/focus-trap-BZeH0rVB.js +2 -0
  350. package/dist/core/web/public/next/assets/focus-trap-BZeH0rVB.js.map +1 -0
  351. package/dist/core/web/public/next/assets/git-model-C1I4z_iQ.js +5 -0
  352. package/dist/core/web/public/next/assets/git-model-C1I4z_iQ.js.map +1 -0
  353. package/dist/core/web/public/next/assets/global-w7KDTTi0.js +3 -0
  354. package/dist/core/web/public/next/assets/global-w7KDTTi0.js.map +1 -0
  355. package/dist/core/web/public/next/assets/guarded-action-J9umcJgI.js +3 -0
  356. package/dist/core/web/public/next/assets/guarded-action-J9umcJgI.js.map +1 -0
  357. package/dist/core/web/public/next/assets/guarded-runners-Da5yA9Im.js +2 -0
  358. package/dist/core/web/public/next/assets/guarded-runners-Da5yA9Im.js.map +1 -0
  359. package/dist/core/web/public/next/assets/health-queries-D3HgrdU_.js +2 -0
  360. package/dist/core/web/public/next/assets/health-queries-D3HgrdU_.js.map +1 -0
  361. package/dist/core/web/public/next/assets/icons-C3G-y5j2.js +2 -0
  362. package/dist/core/web/public/next/assets/icons-C3G-y5j2.js.map +1 -0
  363. package/dist/core/web/public/next/assets/index-BC5Uslm5.js +11 -0
  364. package/dist/core/web/public/next/assets/index-BC5Uslm5.js.map +1 -0
  365. package/dist/core/web/public/next/assets/jev-queries-D6JNU-s6.js +2 -0
  366. package/dist/core/web/public/next/assets/jev-queries-D6JNU-s6.js.map +1 -0
  367. package/dist/core/web/public/next/assets/ladder-queries-BnYWjJoi.js +2 -0
  368. package/dist/core/web/public/next/assets/ladder-queries-BnYWjJoi.js.map +1 -0
  369. package/dist/core/web/public/next/assets/leader-focus-C6LVWgYI.js +2 -0
  370. package/dist/core/web/public/next/assets/leader-focus-C6LVWgYI.js.map +1 -0
  371. package/dist/core/web/public/next/assets/live-model-BPyZCTr1.js +2 -0
  372. package/dist/core/web/public/next/assets/live-model-BPyZCTr1.js.map +1 -0
  373. package/dist/core/web/public/next/assets/mobile-actions-avKNGddD.js +2 -0
  374. package/dist/core/web/public/next/assets/mobile-actions-avKNGddD.js.map +1 -0
  375. package/dist/core/web/public/next/assets/mobile-toast-BqSzGmw1.js +2 -0
  376. package/dist/core/web/public/next/assets/mobile-toast-BqSzGmw1.js.map +1 -0
  377. package/dist/core/web/public/next/assets/multimodel-flows-DOHsEKUG.js +7 -0
  378. package/dist/core/web/public/next/assets/multimodel-flows-DOHsEKUG.js.map +1 -0
  379. package/dist/core/web/public/next/assets/multimodel-queries-xmBBUT6n.js +2 -0
  380. package/dist/core/web/public/next/assets/multimodel-queries-xmBBUT6n.js.map +1 -0
  381. package/dist/core/web/public/next/assets/mutations-CdLi0erM.js +2 -0
  382. package/dist/core/web/public/next/assets/mutations-CdLi0erM.js.map +1 -0
  383. package/dist/core/web/public/next/assets/nav-CUXtg-Iw.js +2 -0
  384. package/dist/core/web/public/next/assets/nav-CUXtg-Iw.js.map +1 -0
  385. package/dist/core/web/public/next/assets/needs-you-actions-B2tjWO-0.js +2 -0
  386. package/dist/core/web/public/next/assets/needs-you-actions-B2tjWO-0.js.map +1 -0
  387. package/dist/core/web/public/next/assets/needs-you-model-DL9EEd2L.js +2 -0
  388. package/dist/core/web/public/next/assets/needs-you-model-DL9EEd2L.js.map +1 -0
  389. package/dist/core/web/public/next/assets/open-terminal-BfbxGoYQ.js +2 -0
  390. package/dist/core/web/public/next/assets/open-terminal-BfbxGoYQ.js.map +1 -0
  391. package/dist/core/web/public/next/assets/open-terminal-request-BT1UE0fz.js +2 -0
  392. package/dist/core/web/public/next/assets/open-terminal-request-BT1UE0fz.js.map +1 -0
  393. package/dist/core/web/public/next/assets/overnight-queries-cjjogTzn.js +2 -0
  394. package/dist/core/web/public/next/assets/overnight-queries-cjjogTzn.js.map +1 -0
  395. package/dist/core/web/public/next/assets/palette-handoff-XL2WWc9I.js +2 -0
  396. package/dist/core/web/public/next/assets/palette-handoff-XL2WWc9I.js.map +1 -0
  397. package/dist/core/web/public/next/assets/panes-5GU8cuI9.js +3 -0
  398. package/dist/core/web/public/next/assets/panes-5GU8cuI9.js.map +1 -0
  399. package/dist/core/web/public/next/assets/path-display-ZSzKoo8T.js +2 -0
  400. package/dist/core/web/public/next/assets/path-display-ZSzKoo8T.js.map +1 -0
  401. package/dist/core/web/public/next/assets/playbook-composer-D04tqOmU.js +2 -0
  402. package/dist/core/web/public/next/assets/playbook-composer-D04tqOmU.js.map +1 -0
  403. package/dist/core/web/public/next/assets/playbook-focus-DD1VIfkd.js +2 -0
  404. package/dist/core/web/public/next/assets/playbook-focus-DD1VIfkd.js.map +1 -0
  405. package/dist/core/web/public/next/assets/playbooks-queries-X7NGzpIn.js +2 -0
  406. package/dist/core/web/public/next/assets/playbooks-queries-X7NGzpIn.js.map +1 -0
  407. package/dist/core/web/public/next/assets/preloaded-6hKNGuRp.js +2 -0
  408. package/dist/core/web/public/next/assets/preloaded-6hKNGuRp.js.map +1 -0
  409. package/dist/core/web/public/next/assets/primitives-6nAFZkcg.js +1 -0
  410. package/dist/core/web/public/next/assets/pwa-BzXJXtDt.js +2 -0
  411. package/dist/core/web/public/next/assets/pwa-BzXJXtDt.js.map +1 -0
  412. package/dist/core/web/public/next/assets/queries-PgZlvFqO.js +2 -0
  413. package/dist/core/web/public/next/assets/queries-PgZlvFqO.js.map +1 -0
  414. package/dist/core/web/public/next/assets/reasoning-pref-BS0PSZ8d.js +2 -0
  415. package/dist/core/web/public/next/assets/reasoning-pref-BS0PSZ8d.js.map +1 -0
  416. package/dist/core/web/public/next/assets/remote-session-Bu-dtRcS.js +3 -0
  417. package/dist/core/web/public/next/assets/remote-session-Bu-dtRcS.js.map +1 -0
  418. package/dist/core/web/public/next/assets/resolved-store-UYN2k9My.js +2 -0
  419. package/dist/core/web/public/next/assets/resolved-store-UYN2k9My.js.map +1 -0
  420. package/dist/core/web/public/next/assets/resources-queries-XfQ8w9In.js +2 -0
  421. package/dist/core/web/public/next/assets/resources-queries-XfQ8w9In.js.map +1 -0
  422. package/dist/core/web/public/next/assets/reveal-anchor-3ZUTtB8Q.js +2 -0
  423. package/dist/core/web/public/next/assets/reveal-anchor-3ZUTtB8Q.js.map +1 -0
  424. package/dist/core/web/public/next/assets/sheet-DP8ByDWU.js +2 -0
  425. package/dist/core/web/public/next/assets/sheet-DP8ByDWU.js.map +1 -0
  426. package/dist/core/web/public/next/assets/slots-DWlj_c7i.js +3 -0
  427. package/dist/core/web/public/next/assets/slots-DWlj_c7i.js.map +1 -0
  428. package/dist/core/web/public/next/assets/sources-queries-Cjk1rpDU.js +4 -0
  429. package/dist/core/web/public/next/assets/sources-queries-Cjk1rpDU.js.map +1 -0
  430. package/dist/core/web/public/next/assets/sse-Z3U8XhDI.js +2 -0
  431. package/dist/core/web/public/next/assets/sse-Z3U8XhDI.js.map +1 -0
  432. package/dist/core/web/public/next/assets/surface-data-hufdOfpz.js +2 -0
  433. package/dist/core/web/public/next/assets/surface-data-hufdOfpz.js.map +1 -0
  434. package/dist/core/web/public/next/assets/surface-prefetch-CFtP8imB.js +2 -0
  435. package/dist/core/web/public/next/assets/surface-prefetch-CFtP8imB.js.map +1 -0
  436. package/dist/core/web/public/next/assets/terminal-client-CCSvMeEv.js +2 -0
  437. package/dist/core/web/public/next/assets/terminal-client-CCSvMeEv.js.map +1 -0
  438. package/dist/core/web/public/next/assets/terminal-icons-Dx6neM-J.js +2 -0
  439. package/dist/core/web/public/next/assets/terminal-icons-Dx6neM-J.js.map +1 -0
  440. package/dist/core/web/public/next/assets/terminal-view-BSieiQvi.js +6 -0
  441. package/dist/core/web/public/next/assets/terminal-view-BSieiQvi.js.map +1 -0
  442. package/dist/core/web/public/next/assets/thread-data-Cd2DZffn.js +2 -0
  443. package/dist/core/web/public/next/assets/thread-data-Cd2DZffn.js.map +1 -0
  444. package/dist/core/web/public/next/assets/ui-parts-wvov2ktB.js +2 -0
  445. package/dist/core/web/public/next/assets/ui-parts-wvov2ktB.js.map +1 -0
  446. package/dist/core/web/public/next/assets/usage-queries-nZjJ1aky.js +2 -0
  447. package/dist/core/web/public/next/assets/usage-queries-nZjJ1aky.js.map +1 -0
  448. package/dist/core/web/public/next/assets/use-chat-activity-_tBmEPPN.js +2 -0
  449. package/dist/core/web/public/next/assets/use-chat-activity-_tBmEPPN.js.map +1 -0
  450. package/dist/core/web/public/next/assets/use-guarded-action-DKKjhPKG.js +2 -0
  451. package/dist/core/web/public/next/assets/use-guarded-action-DKKjhPKG.js.map +1 -0
  452. package/dist/core/web/public/next/assets/use-ticker-w1c3SOqK.js +2 -0
  453. package/dist/core/web/public/next/assets/use-ticker-w1c3SOqK.js.map +1 -0
  454. package/dist/core/web/public/next/assets/use-token-gate-h5QAERLT.js +2 -0
  455. package/dist/core/web/public/next/assets/use-token-gate-h5QAERLT.js.map +1 -0
  456. package/dist/core/web/public/next/assets/useAutoSeat-Dpbn0XUv.js +2 -0
  457. package/dist/core/web/public/next/assets/useAutoSeat-Dpbn0XUv.js.map +1 -0
  458. package/dist/core/web/public/next/assets/useOnboarding-VoV1LcuJ.js +2 -0
  459. package/dist/core/web/public/next/assets/useOnboarding-VoV1LcuJ.js.map +1 -0
  460. package/dist/core/web/public/next/assets/useSeatHealth-DuSaKdIs.js +2 -0
  461. package/dist/core/web/public/next/assets/useSeatHealth-DuSaKdIs.js.map +1 -0
  462. package/dist/core/web/public/next/assets/useSeatsRefresh-DFaR1jSz.js +2 -0
  463. package/dist/core/web/public/next/assets/useSeatsRefresh-DFaR1jSz.js.map +1 -0
  464. package/dist/core/web/public/next/assets/useVerseSession-BOsgJzT5.js +2 -0
  465. package/dist/core/web/public/next/assets/useVerseSession-BOsgJzT5.js.map +1 -0
  466. package/dist/core/web/public/next/assets/useVerseTranscript-BN_fMz6x.js +2 -0
  467. package/dist/core/web/public/next/assets/useVerseTranscript-BN_fMz6x.js.map +1 -0
  468. package/dist/core/web/public/next/assets/verse-bootstrap-query-B3vFD9XK.js +2 -0
  469. package/dist/core/web/public/next/assets/verse-bootstrap-query-B3vFD9XK.js.map +1 -0
  470. package/dist/core/web/public/next/assets/verse-icons-vSkflmRB.js +2 -0
  471. package/dist/core/web/public/next/assets/verse-icons-vSkflmRB.js.map +1 -0
  472. package/dist/core/web/public/next/assets/warmup-D9MjYs5S.js +3 -0
  473. package/dist/core/web/public/next/assets/warmup-D9MjYs5S.js.map +1 -0
  474. package/dist/core/web/public/next/assets/wiki-focus-De8-E48Z.js +2 -0
  475. package/dist/core/web/public/next/assets/wiki-focus-De8-E48Z.js.map +1 -0
  476. package/dist/core/web/public/next/index.html +1 -1
  477. package/dist/release-dependency-inventory.json +1 -1
  478. package/package.json +1 -1
  479. package/dist/core/web/public/next/assets/ActionMenu-CebJFKYy.js +0 -2
  480. package/dist/core/web/public/next/assets/ActionMenu-CebJFKYy.js.map +0 -1
  481. package/dist/core/web/public/next/assets/Advanced-Dr9aVbXV.js +0 -2
  482. package/dist/core/web/public/next/assets/Advanced-Dr9aVbXV.js.map +0 -1
  483. package/dist/core/web/public/next/assets/AgentDetailScreen-DCVf81Vo.js +0 -2
  484. package/dist/core/web/public/next/assets/AgentDetailScreen-DCVf81Vo.js.map +0 -1
  485. package/dist/core/web/public/next/assets/AgentToolsSheet-C3SbvEiV.js +0 -2
  486. package/dist/core/web/public/next/assets/AgentToolsSheet-C3SbvEiV.js.map +0 -1
  487. package/dist/core/web/public/next/assets/AgentToolsStrip-CZNxj_Iv.js +0 -2
  488. package/dist/core/web/public/next/assets/AgentToolsStrip-CZNxj_Iv.js.map +0 -1
  489. package/dist/core/web/public/next/assets/AgentsScreen-zLj4gzPR.js +0 -2
  490. package/dist/core/web/public/next/assets/AgentsScreen-zLj4gzPR.js.map +0 -1
  491. package/dist/core/web/public/next/assets/AgentsSection-CIo_nRmi.js +0 -3
  492. package/dist/core/web/public/next/assets/AgentsSection-CIo_nRmi.js.map +0 -1
  493. package/dist/core/web/public/next/assets/App-CPKNuUdC.js +0 -8
  494. package/dist/core/web/public/next/assets/App-CPKNuUdC.js.map +0 -1
  495. package/dist/core/web/public/next/assets/AppsSection-D2F2CM-E.js +0 -2
  496. package/dist/core/web/public/next/assets/AppsSection-D2F2CM-E.js.map +0 -1
  497. package/dist/core/web/public/next/assets/AreaTrend-DiZu8bjc.js +0 -2
  498. package/dist/core/web/public/next/assets/AreaTrend-DiZu8bjc.js.map +0 -1
  499. package/dist/core/web/public/next/assets/AutomationsSection-B4rBNUyo.js +0 -2
  500. package/dist/core/web/public/next/assets/AutomationsSection-B4rBNUyo.js.map +0 -1
  501. package/dist/core/web/public/next/assets/AutonomyOffState-DEznxI-Q.js +0 -3
  502. package/dist/core/web/public/next/assets/AutonomyOffState-DEznxI-Q.js.map +0 -1
  503. package/dist/core/web/public/next/assets/AutonomySection-Dq5n3gs7.js +0 -2
  504. package/dist/core/web/public/next/assets/AutonomySection-Dq5n3gs7.js.map +0 -1
  505. package/dist/core/web/public/next/assets/AutonomyStatus-Uydy6-pZ.js +0 -2
  506. package/dist/core/web/public/next/assets/AutonomyStatus-Uydy6-pZ.js.map +0 -1
  507. package/dist/core/web/public/next/assets/BranchBar-BzUmUM_j.js +0 -2
  508. package/dist/core/web/public/next/assets/BranchBar-BzUmUM_j.js.map +0 -1
  509. package/dist/core/web/public/next/assets/BrowserPanel-C_VI6Awi.js +0 -7
  510. package/dist/core/web/public/next/assets/BrowserPanel-C_VI6Awi.js.map +0 -1
  511. package/dist/core/web/public/next/assets/BudgetControl-B23rNAuC.js +0 -2
  512. package/dist/core/web/public/next/assets/BudgetControl-B23rNAuC.js.map +0 -1
  513. package/dist/core/web/public/next/assets/Button-DJY_Pu5B.js +0 -2
  514. package/dist/core/web/public/next/assets/Button-DJY_Pu5B.js.map +0 -1
  515. package/dist/core/web/public/next/assets/CapacityStrip-B5Yj2PhZ.js +0 -2
  516. package/dist/core/web/public/next/assets/CapacityStrip-B5Yj2PhZ.js.map +0 -1
  517. package/dist/core/web/public/next/assets/ChangesPaneHost-LsUonc7P.js +0 -16
  518. package/dist/core/web/public/next/assets/ChangesPaneHost-LsUonc7P.js.map +0 -1
  519. package/dist/core/web/public/next/assets/ChartFrame-CakjKkPx.js +0 -2
  520. package/dist/core/web/public/next/assets/ChartFrame-CakjKkPx.js.map +0 -1
  521. package/dist/core/web/public/next/assets/ChatPanes-DgKskpXb.js +0 -2
  522. package/dist/core/web/public/next/assets/ChatPanes-DgKskpXb.js.map +0 -1
  523. package/dist/core/web/public/next/assets/ChatSection-DXpzV1NW.js +0 -3
  524. package/dist/core/web/public/next/assets/ChatSection-DXpzV1NW.js.map +0 -1
  525. package/dist/core/web/public/next/assets/ChecksPanel-BeCJVOJC.js +0 -5
  526. package/dist/core/web/public/next/assets/ChecksPanel-BeCJVOJC.js.map +0 -1
  527. package/dist/core/web/public/next/assets/CloudBudgetForm-4SWIGJLs.js +0 -2
  528. package/dist/core/web/public/next/assets/CloudBudgetForm-4SWIGJLs.js.map +0 -1
  529. package/dist/core/web/public/next/assets/CommandPalette-B4QaFGY5.js +0 -3
  530. package/dist/core/web/public/next/assets/CommandPalette-B4QaFGY5.js.map +0 -1
  531. package/dist/core/web/public/next/assets/CommandSection-8TFjYitt.js +0 -3
  532. package/dist/core/web/public/next/assets/CommandSection-8TFjYitt.js.map +0 -1
  533. package/dist/core/web/public/next/assets/CommandWorkflowForm-B2ooVjof.js +0 -9
  534. package/dist/core/web/public/next/assets/CommandWorkflowForm-B2ooVjof.js.map +0 -1
  535. package/dist/core/web/public/next/assets/CommandWorkflowPicker-C09vJiUG.js +0 -3
  536. package/dist/core/web/public/next/assets/CommandWorkflowPicker-C09vJiUG.js.map +0 -1
  537. package/dist/core/web/public/next/assets/CompareDialog-CaopnGI0.js +0 -4
  538. package/dist/core/web/public/next/assets/CompareDialog-CaopnGI0.js.map +0 -1
  539. package/dist/core/web/public/next/assets/ComputerControl-BflC6wd1.js +0 -2
  540. package/dist/core/web/public/next/assets/ComputerControl-BflC6wd1.js.map +0 -1
  541. package/dist/core/web/public/next/assets/ConfirmDialog-CTeMFavv.js +0 -2
  542. package/dist/core/web/public/next/assets/ConfirmDialog-CTeMFavv.js.map +0 -1
  543. package/dist/core/web/public/next/assets/DeleteChatDialog-B2bUTuZ9.js +0 -2
  544. package/dist/core/web/public/next/assets/DeleteChatDialog-B2bUTuZ9.js.map +0 -1
  545. package/dist/core/web/public/next/assets/DevinStopDialog-DPP34cna.js +0 -2
  546. package/dist/core/web/public/next/assets/DevinStopDialog-DPP34cna.js.map +0 -1
  547. package/dist/core/web/public/next/assets/Dialog-r4j4R4b6.js +0 -2
  548. package/dist/core/web/public/next/assets/Dialog-r4j4R4b6.js.map +0 -1
  549. package/dist/core/web/public/next/assets/DiffPane-CKnpzqaU.js +0 -2
  550. package/dist/core/web/public/next/assets/DiffPane-CKnpzqaU.js.map +0 -1
  551. package/dist/core/web/public/next/assets/DiffViewer-BzQ7245p.js +0 -2
  552. package/dist/core/web/public/next/assets/DiffViewer-BzQ7245p.js.map +0 -1
  553. package/dist/core/web/public/next/assets/DockHost-BCZtC_lm.js +0 -2
  554. package/dist/core/web/public/next/assets/DockHost-BCZtC_lm.js.map +0 -1
  555. package/dist/core/web/public/next/assets/EmptyState-Cwpga8L9.js +0 -2
  556. package/dist/core/web/public/next/assets/EmptyState-Cwpga8L9.js.map +0 -1
  557. package/dist/core/web/public/next/assets/Epistemic-BBwXv-C1.js +0 -2
  558. package/dist/core/web/public/next/assets/Epistemic-BBwXv-C1.js.map +0 -1
  559. package/dist/core/web/public/next/assets/EvidenceTimeline-hAENJQCa.js +0 -2
  560. package/dist/core/web/public/next/assets/EvidenceTimeline-hAENJQCa.js.map +0 -1
  561. package/dist/core/web/public/next/assets/FilesPane-CrPN5zlx.js +0 -2
  562. package/dist/core/web/public/next/assets/FilesPane-CrPN5zlx.js.map +0 -1
  563. package/dist/core/web/public/next/assets/FleetScreen-Cz9HQ-st.js +0 -2
  564. package/dist/core/web/public/next/assets/FleetScreen-Cz9HQ-st.js.map +0 -1
  565. package/dist/core/web/public/next/assets/FleetSection-CmZKQ1rr.js +0 -5
  566. package/dist/core/web/public/next/assets/FleetSection-CmZKQ1rr.js.map +0 -1
  567. package/dist/core/web/public/next/assets/Funnel-Cfg55EZp.js +0 -2
  568. package/dist/core/web/public/next/assets/Funnel-Cfg55EZp.js.map +0 -1
  569. package/dist/core/web/public/next/assets/GearTray-D-Mhc8TJ.js +0 -2
  570. package/dist/core/web/public/next/assets/GearTray-D-Mhc8TJ.js.map +0 -1
  571. package/dist/core/web/public/next/assets/GitDialogs-e-7RQEGv.js +0 -2
  572. package/dist/core/web/public/next/assets/GitDialogs-e-7RQEGv.js.map +0 -1
  573. package/dist/core/web/public/next/assets/GrowthSection-DsIrdTDd.js +0 -3
  574. package/dist/core/web/public/next/assets/GrowthSection-DsIrdTDd.js.map +0 -1
  575. package/dist/core/web/public/next/assets/HandoffDialog-1MB2fmT1.js +0 -2
  576. package/dist/core/web/public/next/assets/HandoffDialog-1MB2fmT1.js.map +0 -1
  577. package/dist/core/web/public/next/assets/HomeBody-n_t3A58_.js +0 -3
  578. package/dist/core/web/public/next/assets/HomeBody-n_t3A58_.js.map +0 -1
  579. package/dist/core/web/public/next/assets/HomeSeats-DA66aOWC.js +0 -2
  580. package/dist/core/web/public/next/assets/HomeSeats-DA66aOWC.js.map +0 -1
  581. package/dist/core/web/public/next/assets/Input-Bt6fp051.js +0 -2
  582. package/dist/core/web/public/next/assets/Input-Bt6fp051.js.map +0 -1
  583. package/dist/core/web/public/next/assets/LaunchDialog-BCd7XqCv.js +0 -9
  584. package/dist/core/web/public/next/assets/LaunchDialog-BCd7XqCv.js.map +0 -1
  585. package/dist/core/web/public/next/assets/LeaderCard-DFAFcyfZ.js +0 -2
  586. package/dist/core/web/public/next/assets/LeaderCard-DFAFcyfZ.js.map +0 -1
  587. package/dist/core/web/public/next/assets/LeaderConversation-LSenfZzT.js +0 -3
  588. package/dist/core/web/public/next/assets/LeaderConversation-LSenfZzT.js.map +0 -1
  589. package/dist/core/web/public/next/assets/LeaderScreen-B2UxRWUm.js +0 -2
  590. package/dist/core/web/public/next/assets/LeaderScreen-B2UxRWUm.js.map +0 -1
  591. package/dist/core/web/public/next/assets/LessonsPanel-D86ZT0we.js +0 -2
  592. package/dist/core/web/public/next/assets/LessonsPanel-D86ZT0we.js.map +0 -1
  593. package/dist/core/web/public/next/assets/LiveTimer-AtG5hPwV.js +0 -2
  594. package/dist/core/web/public/next/assets/LiveTimer-AtG5hPwV.js.map +0 -1
  595. package/dist/core/web/public/next/assets/LocalSeatBadge-XfGRZCA3.js +0 -2
  596. package/dist/core/web/public/next/assets/LocalSeatBadge-XfGRZCA3.js.map +0 -1
  597. package/dist/core/web/public/next/assets/MatrixHeatmap-PSnyMJ2h.js +0 -2
  598. package/dist/core/web/public/next/assets/MatrixHeatmap-PSnyMJ2h.js.map +0 -1
  599. package/dist/core/web/public/next/assets/McpSection-BG2FSkgH.js +0 -2
  600. package/dist/core/web/public/next/assets/McpSection-BG2FSkgH.js.map +0 -1
  601. package/dist/core/web/public/next/assets/MessageMarkdown-CQEqoMvf.js +0 -3
  602. package/dist/core/web/public/next/assets/MessageMarkdown-CQEqoMvf.js.map +0 -1
  603. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DU-VLDhb.js +0 -72
  604. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DU-VLDhb.js.map +0 -1
  605. package/dist/core/web/public/next/assets/Meter-BfaE-BjY.js +0 -2
  606. package/dist/core/web/public/next/assets/Meter-BfaE-BjY.js.map +0 -1
  607. package/dist/core/web/public/next/assets/MicButton-BbGB7y_9.js +0 -2
  608. package/dist/core/web/public/next/assets/MicButton-BbGB7y_9.js.map +0 -1
  609. package/dist/core/web/public/next/assets/MindSection-CX0VaHo1.js +0 -3
  610. package/dist/core/web/public/next/assets/MindSection-CX0VaHo1.js.map +0 -1
  611. package/dist/core/web/public/next/assets/MobileComposer-CFeLWUCz.js +0 -2
  612. package/dist/core/web/public/next/assets/MobileComposer-CFeLWUCz.js.map +0 -1
  613. package/dist/core/web/public/next/assets/MobileGuardSheet-cGW9RCTr.js +0 -2
  614. package/dist/core/web/public/next/assets/MobileGuardSheet-cGW9RCTr.js.map +0 -1
  615. package/dist/core/web/public/next/assets/MobileRuntime-BWTZ_QLr.js +0 -3
  616. package/dist/core/web/public/next/assets/MobileRuntime-BWTZ_QLr.js.map +0 -1
  617. package/dist/core/web/public/next/assets/MoreScreen-BcHZhVrR.js +0 -2
  618. package/dist/core/web/public/next/assets/MoreScreen-BcHZhVrR.js.map +0 -1
  619. package/dist/core/web/public/next/assets/MultiModelBar-COxIRv7m.js +0 -7
  620. package/dist/core/web/public/next/assets/MultiModelBar-COxIRv7m.js.map +0 -1
  621. package/dist/core/web/public/next/assets/MutationTokenDialog-Dnf_rcnc.js +0 -2
  622. package/dist/core/web/public/next/assets/MutationTokenDialog-Dnf_rcnc.js.map +0 -1
  623. package/dist/core/web/public/next/assets/NeedsYouDrawer-COrUlnd0.js +0 -3
  624. package/dist/core/web/public/next/assets/NeedsYouDrawer-COrUlnd0.js.map +0 -1
  625. package/dist/core/web/public/next/assets/NeedsYouList-AXzOe4EL.js +0 -2
  626. package/dist/core/web/public/next/assets/NeedsYouList-AXzOe4EL.js.map +0 -1
  627. package/dist/core/web/public/next/assets/NeedsYouScreen-HSXybHgd.js +0 -2
  628. package/dist/core/web/public/next/assets/NeedsYouScreen-HSXybHgd.js.map +0 -1
  629. package/dist/core/web/public/next/assets/NewAgentScreen-BI849ZsG.js +0 -2
  630. package/dist/core/web/public/next/assets/NewAgentScreen-BI849ZsG.js.map +0 -1
  631. package/dist/core/web/public/next/assets/NewChatDialog-BHoCnP6Q.js +0 -4
  632. package/dist/core/web/public/next/assets/NewChatDialog-BHoCnP6Q.js.map +0 -1
  633. package/dist/core/web/public/next/assets/OnboardingFlow-BVljU2uy.js +0 -3
  634. package/dist/core/web/public/next/assets/OnboardingFlow-BVljU2uy.js.map +0 -1
  635. package/dist/core/web/public/next/assets/OnboardingGate-DlI4L7Ki.js +0 -3
  636. package/dist/core/web/public/next/assets/OnboardingGate-DlI4L7Ki.js.map +0 -1
  637. package/dist/core/web/public/next/assets/PlaybooksSection-hhNpXnsR.js +0 -9
  638. package/dist/core/web/public/next/assets/PlaybooksSection-hhNpXnsR.js.map +0 -1
  639. package/dist/core/web/public/next/assets/PreviewPane-BbXr63u2.js +0 -2
  640. package/dist/core/web/public/next/assets/PreviewPane-BbXr63u2.js.map +0 -1
  641. package/dist/core/web/public/next/assets/ProviderLogo-BliSWEMw.js +0 -2
  642. package/dist/core/web/public/next/assets/ProviderLogo-BliSWEMw.js.map +0 -1
  643. package/dist/core/web/public/next/assets/RailStatus-SnrVxLnp.js +0 -2
  644. package/dist/core/web/public/next/assets/RailStatus-SnrVxLnp.js.map +0 -1
  645. package/dist/core/web/public/next/assets/ReasoningPane-C04_bOAi.js +0 -2
  646. package/dist/core/web/public/next/assets/ReasoningPane-C04_bOAi.js.map +0 -1
  647. package/dist/core/web/public/next/assets/ReasoningSheet-BvNFwtuX.js +0 -2
  648. package/dist/core/web/public/next/assets/ReasoningSheet-BvNFwtuX.js.map +0 -1
  649. package/dist/core/web/public/next/assets/RefreshIndicator-BNptNJiV.js +0 -2
  650. package/dist/core/web/public/next/assets/RefreshIndicator-BNptNJiV.js.map +0 -1
  651. package/dist/core/web/public/next/assets/RemoteMobileApp-osaSEvnm.js +0 -2
  652. package/dist/core/web/public/next/assets/RemoteMobileApp-osaSEvnm.js.map +0 -1
  653. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-LO31zjUR.js +0 -7
  654. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-LO31zjUR.js.map +0 -1
  655. package/dist/core/web/public/next/assets/ResourcesChrome-ByZE532G.js +0 -3
  656. package/dist/core/web/public/next/assets/ResourcesChrome-ByZE532G.js.map +0 -1
  657. package/dist/core/web/public/next/assets/ResourcesChrome-p_VCkMZH.css +0 -1
  658. package/dist/core/web/public/next/assets/ResourcesDrawer-BH9uwNE8.js +0 -3
  659. package/dist/core/web/public/next/assets/ResourcesDrawer-BH9uwNE8.js.map +0 -1
  660. package/dist/core/web/public/next/assets/ReviewMenu-B2A_YDPi.js +0 -2
  661. package/dist/core/web/public/next/assets/ReviewMenu-B2A_YDPi.js.map +0 -1
  662. package/dist/core/web/public/next/assets/RouteErrorBoundary-CVabFM97.js +0 -2
  663. package/dist/core/web/public/next/assets/RouteErrorBoundary-CVabFM97.js.map +0 -1
  664. package/dist/core/web/public/next/assets/RunInCloudAction-BpNHE7m8.js +0 -2
  665. package/dist/core/web/public/next/assets/RunInCloudAction-BpNHE7m8.js.map +0 -1
  666. package/dist/core/web/public/next/assets/RunInDevinAction-Bkf5Gb3a.js +0 -2
  667. package/dist/core/web/public/next/assets/RunInDevinAction-Bkf5Gb3a.js.map +0 -1
  668. package/dist/core/web/public/next/assets/SchedulingEvidence-B08-qhhm.js +0 -2
  669. package/dist/core/web/public/next/assets/SchedulingEvidence-B08-qhhm.js.map +0 -1
  670. package/dist/core/web/public/next/assets/ScreenHost-BGSxFyWK.js +0 -3
  671. package/dist/core/web/public/next/assets/ScreenHost-BGSxFyWK.js.map +0 -1
  672. package/dist/core/web/public/next/assets/SeatSelector-B4lRZl0K.js +0 -3
  673. package/dist/core/web/public/next/assets/SeatSelector-B4lRZl0K.js.map +0 -1
  674. package/dist/core/web/public/next/assets/Segmented-Dokzywy8.js +0 -2
  675. package/dist/core/web/public/next/assets/Segmented-Dokzywy8.js.map +0 -1
  676. package/dist/core/web/public/next/assets/Select-tf4lNvWD.js +0 -2
  677. package/dist/core/web/public/next/assets/Select-tf4lNvWD.js.map +0 -1
  678. package/dist/core/web/public/next/assets/SessionGate-Bab2qO29.js +0 -2
  679. package/dist/core/web/public/next/assets/SessionGate-Bab2qO29.js.map +0 -1
  680. package/dist/core/web/public/next/assets/SessionInsightChip-C-fj8h4A.js +0 -2
  681. package/dist/core/web/public/next/assets/SessionInsightChip-C-fj8h4A.js.map +0 -1
  682. package/dist/core/web/public/next/assets/SessionSearch-CqjjwOW2.js +0 -2
  683. package/dist/core/web/public/next/assets/SessionSearch-CqjjwOW2.js.map +0 -1
  684. package/dist/core/web/public/next/assets/SettingsSection-DfOsHzl6.js +0 -2
  685. package/dist/core/web/public/next/assets/SettingsSection-DfOsHzl6.js.map +0 -1
  686. package/dist/core/web/public/next/assets/SetupChecklist-BsxCTcYY.js +0 -2
  687. package/dist/core/web/public/next/assets/SetupChecklist-BsxCTcYY.js.map +0 -1
  688. package/dist/core/web/public/next/assets/ShadowDecisions-B1ZPv7K-.js +0 -3
  689. package/dist/core/web/public/next/assets/ShadowDecisions-B1ZPv7K-.js.map +0 -1
  690. package/dist/core/web/public/next/assets/Sheet-DLlZ00Lu.js +0 -2
  691. package/dist/core/web/public/next/assets/Sheet-DLlZ00Lu.js.map +0 -1
  692. package/dist/core/web/public/next/assets/ShortcutsOverlay-CDwQdpGV.js +0 -2
  693. package/dist/core/web/public/next/assets/ShortcutsOverlay-CDwQdpGV.js.map +0 -1
  694. package/dist/core/web/public/next/assets/Sidebar-H5WNri2S.js +0 -3
  695. package/dist/core/web/public/next/assets/Sidebar-H5WNri2S.js.map +0 -1
  696. package/dist/core/web/public/next/assets/SkipToContent-BjJE6yOo.js +0 -2
  697. package/dist/core/web/public/next/assets/SkipToContent-BjJE6yOo.js.map +0 -1
  698. package/dist/core/web/public/next/assets/Slider-C68TumXj.js +0 -2
  699. package/dist/core/web/public/next/assets/Slider-C68TumXj.js.map +0 -1
  700. package/dist/core/web/public/next/assets/SourcesPane-DHYs4YIg.js +0 -2
  701. package/dist/core/web/public/next/assets/SourcesPane-DHYs4YIg.js.map +0 -1
  702. package/dist/core/web/public/next/assets/SourcesPanel-DFyLfYBO.js +0 -2
  703. package/dist/core/web/public/next/assets/SourcesPanel-DFyLfYBO.js.map +0 -1
  704. package/dist/core/web/public/next/assets/StatTile-CTUuhOLS.js +0 -2
  705. package/dist/core/web/public/next/assets/StatTile-CTUuhOLS.js.map +0 -1
  706. package/dist/core/web/public/next/assets/StatusBadge-DrVbi5dF.js +0 -2
  707. package/dist/core/web/public/next/assets/StatusBadge-DrVbi5dF.js.map +0 -1
  708. package/dist/core/web/public/next/assets/StepBand-CXDpnu2R.js +0 -2
  709. package/dist/core/web/public/next/assets/StepBand-CXDpnu2R.js.map +0 -1
  710. package/dist/core/web/public/next/assets/Surface-DCL7uORg.js +0 -2
  711. package/dist/core/web/public/next/assets/Surface-DCL7uORg.js.map +0 -1
  712. package/dist/core/web/public/next/assets/Swimlane-BAEjfoVU.js +0 -2
  713. package/dist/core/web/public/next/assets/Swimlane-BAEjfoVU.js.map +0 -1
  714. package/dist/core/web/public/next/assets/Switch-Z7RmRjWE.js +0 -2
  715. package/dist/core/web/public/next/assets/Switch-Z7RmRjWE.js.map +0 -1
  716. package/dist/core/web/public/next/assets/Tag-Ciht3C94.js +0 -2
  717. package/dist/core/web/public/next/assets/Tag-Ciht3C94.js.map +0 -1
  718. package/dist/core/web/public/next/assets/TerminalPane-BdIyhtzJ.js +0 -26
  719. package/dist/core/web/public/next/assets/TerminalPane-BdIyhtzJ.js.map +0 -1
  720. package/dist/core/web/public/next/assets/TerminalPane-DJKT600N.js +0 -3
  721. package/dist/core/web/public/next/assets/TerminalPane-DJKT600N.js.map +0 -1
  722. package/dist/core/web/public/next/assets/ThinkingBlock-CHRZX_fJ.js +0 -2
  723. package/dist/core/web/public/next/assets/ThinkingBlock-CHRZX_fJ.js.map +0 -1
  724. package/dist/core/web/public/next/assets/UniverseConsoleApp-QSoaY_Fk.js +0 -2
  725. package/dist/core/web/public/next/assets/UniverseConsoleApp-QSoaY_Fk.js.map +0 -1
  726. package/dist/core/web/public/next/assets/UniverseView-ZXAOJ0Rq.js +0 -9
  727. package/dist/core/web/public/next/assets/UniverseView-ZXAOJ0Rq.js.map +0 -1
  728. package/dist/core/web/public/next/assets/UsageSection-BEAa-W_q.js +0 -3
  729. package/dist/core/web/public/next/assets/UsageSection-BEAa-W_q.js.map +0 -1
  730. package/dist/core/web/public/next/assets/UsePlaybookAction-S7Yky_M8.js +0 -2
  731. package/dist/core/web/public/next/assets/UsePlaybookAction-S7Yky_M8.js.map +0 -1
  732. package/dist/core/web/public/next/assets/VerseConsoleApp-Cj6yPJo3.js +0 -3
  733. package/dist/core/web/public/next/assets/VerseConsoleApp-Cj6yPJo3.js.map +0 -1
  734. package/dist/core/web/public/next/assets/VerseConsoleApp-n6qr3lCF.css +0 -1
  735. package/dist/core/web/public/next/assets/VerseMobileApp-BRayqF_2.js +0 -3
  736. package/dist/core/web/public/next/assets/VerseMobileApp-BRayqF_2.js.map +0 -1
  737. package/dist/core/web/public/next/assets/VerseShared-CH8mV5ew.js +0 -2
  738. package/dist/core/web/public/next/assets/VerseShared-CH8mV5ew.js.map +0 -1
  739. package/dist/core/web/public/next/assets/VoiceHud-CO4yGRlr.js +0 -2
  740. package/dist/core/web/public/next/assets/VoiceHud-CO4yGRlr.js.map +0 -1
  741. package/dist/core/web/public/next/assets/VoiceInput-fSLnbGJ4.js +0 -2
  742. package/dist/core/web/public/next/assets/VoiceInput-fSLnbGJ4.js.map +0 -1
  743. package/dist/core/web/public/next/assets/WikiSection-CN-HansV.js +0 -2
  744. package/dist/core/web/public/next/assets/WikiSection-CN-HansV.js.map +0 -1
  745. package/dist/core/web/public/next/assets/Workspace-dufi6DmW.js +0 -6
  746. package/dist/core/web/public/next/assets/Workspace-dufi6DmW.js.map +0 -1
  747. package/dist/core/web/public/next/assets/actions-gBplqbpY.js +0 -2
  748. package/dist/core/web/public/next/assets/actions-gBplqbpY.js.map +0 -1
  749. package/dist/core/web/public/next/assets/agent-tools-client-ClFut2J1.js +0 -2
  750. package/dist/core/web/public/next/assets/agent-tools-client-ClFut2J1.js.map +0 -1
  751. package/dist/core/web/public/next/assets/agents-focus-DjBz83BQ.js +0 -2
  752. package/dist/core/web/public/next/assets/agents-focus-DjBz83BQ.js.map +0 -1
  753. package/dist/core/web/public/next/assets/app-version-B0FcXqqB.js +0 -2
  754. package/dist/core/web/public/next/assets/app-version-B0FcXqqB.js.map +0 -1
  755. package/dist/core/web/public/next/assets/apps-model-C-SdWY0N.js +0 -2
  756. package/dist/core/web/public/next/assets/apps-model-C-SdWY0N.js.map +0 -1
  757. package/dist/core/web/public/next/assets/ask-seat-DhGxiGSd.js +0 -2
  758. package/dist/core/web/public/next/assets/ask-seat-DhGxiGSd.js.map +0 -1
  759. package/dist/core/web/public/next/assets/authority-model-CoXAS-Z6.js +0 -2
  760. package/dist/core/web/public/next/assets/authority-model-CoXAS-Z6.js.map +0 -1
  761. package/dist/core/web/public/next/assets/automations-focus-CeneF7lP.js +0 -2
  762. package/dist/core/web/public/next/assets/automations-focus-CeneF7lP.js.map +0 -1
  763. package/dist/core/web/public/next/assets/budget-queries-DCZevH2S.js +0 -2
  764. package/dist/core/web/public/next/assets/budget-queries-DCZevH2S.js.map +0 -1
  765. package/dist/core/web/public/next/assets/capacity-strip-model-Wna9o0dS.js +0 -2
  766. package/dist/core/web/public/next/assets/capacity-strip-model-Wna9o0dS.js.map +0 -1
  767. package/dist/core/web/public/next/assets/charts-CzqC55eL.js +0 -2
  768. package/dist/core/web/public/next/assets/charts-CzqC55eL.js.map +0 -1
  769. package/dist/core/web/public/next/assets/chat-pane-data-BBA55Pw-.js +0 -2
  770. package/dist/core/web/public/next/assets/chat-pane-data-BBA55Pw-.js.map +0 -1
  771. package/dist/core/web/public/next/assets/checkpoint-queries-gP6Vh70H.js +0 -2
  772. package/dist/core/web/public/next/assets/checkpoint-queries-gP6Vh70H.js.map +0 -1
  773. package/dist/core/web/public/next/assets/cloud-queries-Bsqo7wye.js +0 -2
  774. package/dist/core/web/public/next/assets/cloud-queries-Bsqo7wye.js.map +0 -1
  775. package/dist/core/web/public/next/assets/command-catalog-Dnx-iMLX.js +0 -2
  776. package/dist/core/web/public/next/assets/command-catalog-Dnx-iMLX.js.map +0 -1
  777. package/dist/core/web/public/next/assets/composer-queries-DHGJlnFJ.js +0 -2
  778. package/dist/core/web/public/next/assets/composer-queries-DHGJlnFJ.js.map +0 -1
  779. package/dist/core/web/public/next/assets/connectivity-BViMMNcD.js +0 -2
  780. package/dist/core/web/public/next/assets/connectivity-BViMMNcD.js.map +0 -1
  781. package/dist/core/web/public/next/assets/context-queries-Bsl-w0q-.js +0 -2
  782. package/dist/core/web/public/next/assets/context-queries-Bsl-w0q-.js.map +0 -1
  783. package/dist/core/web/public/next/assets/control-queries-CUNa6TAx.js +0 -2
  784. package/dist/core/web/public/next/assets/control-queries-CUNa6TAx.js.map +0 -1
  785. package/dist/core/web/public/next/assets/copy-setup-C2goNcTZ.js +0 -2
  786. package/dist/core/web/public/next/assets/copy-setup-C2goNcTZ.js.map +0 -1
  787. package/dist/core/web/public/next/assets/deep-link-Dg_zaqAl.js +0 -2
  788. package/dist/core/web/public/next/assets/deep-link-Dg_zaqAl.js.map +0 -1
  789. package/dist/core/web/public/next/assets/device-permissions-CEXY0Vor.js +0 -2
  790. package/dist/core/web/public/next/assets/device-permissions-CEXY0Vor.js.map +0 -1
  791. package/dist/core/web/public/next/assets/devin-queries-Cu_YYhw2.js +0 -2
  792. package/dist/core/web/public/next/assets/devin-queries-Cu_YYhw2.js.map +0 -1
  793. package/dist/core/web/public/next/assets/dock-icons-DGZoDN6N.js +0 -2
  794. package/dist/core/web/public/next/assets/dock-icons-DGZoDN6N.js.map +0 -1
  795. package/dist/core/web/public/next/assets/dock-panes-BgSO9q_f.js +0 -2
  796. package/dist/core/web/public/next/assets/dock-panes-BgSO9q_f.js.map +0 -1
  797. package/dist/core/web/public/next/assets/fleet-control-queries-clsJWanE.js +0 -2
  798. package/dist/core/web/public/next/assets/fleet-control-queries-clsJWanE.js.map +0 -1
  799. package/dist/core/web/public/next/assets/fleet-queries-DX1AwHEt.js +0 -2
  800. package/dist/core/web/public/next/assets/fleet-queries-DX1AwHEt.js.map +0 -1
  801. package/dist/core/web/public/next/assets/fleet-state-EgNiSDxu.js +0 -3
  802. package/dist/core/web/public/next/assets/fleet-state-EgNiSDxu.js.map +0 -1
  803. package/dist/core/web/public/next/assets/focus-trap-B1vuEhZX.js +0 -2
  804. package/dist/core/web/public/next/assets/focus-trap-B1vuEhZX.js.map +0 -1
  805. package/dist/core/web/public/next/assets/git-model-Bu59fz1m.js +0 -5
  806. package/dist/core/web/public/next/assets/git-model-Bu59fz1m.js.map +0 -1
  807. package/dist/core/web/public/next/assets/global-BJ_kVFpD.js +0 -3
  808. package/dist/core/web/public/next/assets/global-BJ_kVFpD.js.map +0 -1
  809. package/dist/core/web/public/next/assets/guarded-action-CzvG7Qgc.js +0 -3
  810. package/dist/core/web/public/next/assets/guarded-action-CzvG7Qgc.js.map +0 -1
  811. package/dist/core/web/public/next/assets/guarded-runners-BPM0KdoQ.js +0 -2
  812. package/dist/core/web/public/next/assets/guarded-runners-BPM0KdoQ.js.map +0 -1
  813. package/dist/core/web/public/next/assets/health-queries-CMxSsJKS.js +0 -2
  814. package/dist/core/web/public/next/assets/health-queries-CMxSsJKS.js.map +0 -1
  815. package/dist/core/web/public/next/assets/icons-MYfI6vZr.js +0 -2
  816. package/dist/core/web/public/next/assets/icons-MYfI6vZr.js.map +0 -1
  817. package/dist/core/web/public/next/assets/index-DOAOxiKl.js +0 -11
  818. package/dist/core/web/public/next/assets/index-DOAOxiKl.js.map +0 -1
  819. package/dist/core/web/public/next/assets/jev-queries-CS2A5uWe.js +0 -2
  820. package/dist/core/web/public/next/assets/jev-queries-CS2A5uWe.js.map +0 -1
  821. package/dist/core/web/public/next/assets/ladder-queries-CBoG3heV.js +0 -2
  822. package/dist/core/web/public/next/assets/ladder-queries-CBoG3heV.js.map +0 -1
  823. package/dist/core/web/public/next/assets/leader-focus-DDQlv0TB.js +0 -2
  824. package/dist/core/web/public/next/assets/leader-focus-DDQlv0TB.js.map +0 -1
  825. package/dist/core/web/public/next/assets/live-model-CCjYFk48.js +0 -2
  826. package/dist/core/web/public/next/assets/live-model-CCjYFk48.js.map +0 -1
  827. package/dist/core/web/public/next/assets/mobile-actions-XqB_h7a8.js +0 -2
  828. package/dist/core/web/public/next/assets/mobile-actions-XqB_h7a8.js.map +0 -1
  829. package/dist/core/web/public/next/assets/mobile-toast-eIrghd9o.js +0 -2
  830. package/dist/core/web/public/next/assets/mobile-toast-eIrghd9o.js.map +0 -1
  831. package/dist/core/web/public/next/assets/multimodel-flows-CzI-yHg5.js +0 -7
  832. package/dist/core/web/public/next/assets/multimodel-flows-CzI-yHg5.js.map +0 -1
  833. package/dist/core/web/public/next/assets/multimodel-queries-DxIT9AZY.js +0 -2
  834. package/dist/core/web/public/next/assets/multimodel-queries-DxIT9AZY.js.map +0 -1
  835. package/dist/core/web/public/next/assets/mutations-BlGALvmG.js +0 -2
  836. package/dist/core/web/public/next/assets/mutations-BlGALvmG.js.map +0 -1
  837. package/dist/core/web/public/next/assets/nav-ByibvQW1.js +0 -2
  838. package/dist/core/web/public/next/assets/nav-ByibvQW1.js.map +0 -1
  839. package/dist/core/web/public/next/assets/needs-you-actions-Dp5UxM3X.js +0 -2
  840. package/dist/core/web/public/next/assets/needs-you-actions-Dp5UxM3X.js.map +0 -1
  841. package/dist/core/web/public/next/assets/needs-you-model-DYsqHMqy.js +0 -2
  842. package/dist/core/web/public/next/assets/needs-you-model-DYsqHMqy.js.map +0 -1
  843. package/dist/core/web/public/next/assets/open-terminal-dOVyLFvn.js +0 -2
  844. package/dist/core/web/public/next/assets/open-terminal-dOVyLFvn.js.map +0 -1
  845. package/dist/core/web/public/next/assets/open-terminal-request-BIhvirIl.js +0 -2
  846. package/dist/core/web/public/next/assets/open-terminal-request-BIhvirIl.js.map +0 -1
  847. package/dist/core/web/public/next/assets/overnight-queries-KxqH6BRN.js +0 -2
  848. package/dist/core/web/public/next/assets/overnight-queries-KxqH6BRN.js.map +0 -1
  849. package/dist/core/web/public/next/assets/palette-handoff-69pw9oBv.js +0 -2
  850. package/dist/core/web/public/next/assets/palette-handoff-69pw9oBv.js.map +0 -1
  851. package/dist/core/web/public/next/assets/panes-CHt3427X.js +0 -3
  852. package/dist/core/web/public/next/assets/panes-CHt3427X.js.map +0 -1
  853. package/dist/core/web/public/next/assets/path-display-DuIZF5G3.js +0 -2
  854. package/dist/core/web/public/next/assets/path-display-DuIZF5G3.js.map +0 -1
  855. package/dist/core/web/public/next/assets/playbook-composer-DipWgX7t.js +0 -2
  856. package/dist/core/web/public/next/assets/playbook-composer-DipWgX7t.js.map +0 -1
  857. package/dist/core/web/public/next/assets/playbook-focus-EXJPMBBI.js +0 -2
  858. package/dist/core/web/public/next/assets/playbook-focus-EXJPMBBI.js.map +0 -1
  859. package/dist/core/web/public/next/assets/playbooks-queries-BlpGBpOV.js +0 -2
  860. package/dist/core/web/public/next/assets/playbooks-queries-BlpGBpOV.js.map +0 -1
  861. package/dist/core/web/public/next/assets/preloaded-TmpzuCEi.js +0 -2
  862. package/dist/core/web/public/next/assets/preloaded-TmpzuCEi.js.map +0 -1
  863. package/dist/core/web/public/next/assets/primitives-CDKCUR2v.js +0 -1
  864. package/dist/core/web/public/next/assets/pwa-CTGMm-wR.js +0 -2
  865. package/dist/core/web/public/next/assets/pwa-CTGMm-wR.js.map +0 -1
  866. package/dist/core/web/public/next/assets/queries--mGK10fL.js +0 -2
  867. package/dist/core/web/public/next/assets/queries--mGK10fL.js.map +0 -1
  868. package/dist/core/web/public/next/assets/reasoning-pref-CWGL9MD2.js +0 -2
  869. package/dist/core/web/public/next/assets/reasoning-pref-CWGL9MD2.js.map +0 -1
  870. package/dist/core/web/public/next/assets/remote-session-I4RXlsas.js +0 -3
  871. package/dist/core/web/public/next/assets/remote-session-I4RXlsas.js.map +0 -1
  872. package/dist/core/web/public/next/assets/resolved-store-DwGn9hb_.js +0 -2
  873. package/dist/core/web/public/next/assets/resolved-store-DwGn9hb_.js.map +0 -1
  874. package/dist/core/web/public/next/assets/resources-queries-T6ER_hPN.js +0 -2
  875. package/dist/core/web/public/next/assets/resources-queries-T6ER_hPN.js.map +0 -1
  876. package/dist/core/web/public/next/assets/reveal-anchor-CHtvhrYm.js +0 -2
  877. package/dist/core/web/public/next/assets/reveal-anchor-CHtvhrYm.js.map +0 -1
  878. package/dist/core/web/public/next/assets/sheet-BlzGO1wo.js +0 -2
  879. package/dist/core/web/public/next/assets/sheet-BlzGO1wo.js.map +0 -1
  880. package/dist/core/web/public/next/assets/slots-40edgV7X.js +0 -3
  881. package/dist/core/web/public/next/assets/slots-40edgV7X.js.map +0 -1
  882. package/dist/core/web/public/next/assets/sources-queries-BrM41X16.js +0 -4
  883. package/dist/core/web/public/next/assets/sources-queries-BrM41X16.js.map +0 -1
  884. package/dist/core/web/public/next/assets/sse-CAFwslNC.js +0 -2
  885. package/dist/core/web/public/next/assets/sse-CAFwslNC.js.map +0 -1
  886. package/dist/core/web/public/next/assets/surface-data-D_oFOgkh.js +0 -2
  887. package/dist/core/web/public/next/assets/surface-data-D_oFOgkh.js.map +0 -1
  888. package/dist/core/web/public/next/assets/surface-prefetch-wqfiATYQ.js +0 -2
  889. package/dist/core/web/public/next/assets/surface-prefetch-wqfiATYQ.js.map +0 -1
  890. package/dist/core/web/public/next/assets/terminal-client-iL4DagCN.js +0 -2
  891. package/dist/core/web/public/next/assets/terminal-client-iL4DagCN.js.map +0 -1
  892. package/dist/core/web/public/next/assets/terminal-icons-BakeOpKV.js +0 -2
  893. package/dist/core/web/public/next/assets/terminal-icons-BakeOpKV.js.map +0 -1
  894. package/dist/core/web/public/next/assets/terminal-view-D6AAh08q.js +0 -6
  895. package/dist/core/web/public/next/assets/terminal-view-D6AAh08q.js.map +0 -1
  896. package/dist/core/web/public/next/assets/thread-data-CSDZ514s.js +0 -2
  897. package/dist/core/web/public/next/assets/thread-data-CSDZ514s.js.map +0 -1
  898. package/dist/core/web/public/next/assets/ui-parts-DubQJIoq.js +0 -2
  899. package/dist/core/web/public/next/assets/ui-parts-DubQJIoq.js.map +0 -1
  900. package/dist/core/web/public/next/assets/usage-queries-BONqdout.js +0 -2
  901. package/dist/core/web/public/next/assets/usage-queries-BONqdout.js.map +0 -1
  902. package/dist/core/web/public/next/assets/use-chat-activity-BZjdPPNP.js +0 -2
  903. package/dist/core/web/public/next/assets/use-chat-activity-BZjdPPNP.js.map +0 -1
  904. package/dist/core/web/public/next/assets/use-guarded-action-xJ4rxyVo.js +0 -2
  905. package/dist/core/web/public/next/assets/use-guarded-action-xJ4rxyVo.js.map +0 -1
  906. package/dist/core/web/public/next/assets/use-ticker-Bsu0cMvl.js +0 -2
  907. package/dist/core/web/public/next/assets/use-ticker-Bsu0cMvl.js.map +0 -1
  908. package/dist/core/web/public/next/assets/use-token-gate-E-xzEAu6.js +0 -2
  909. package/dist/core/web/public/next/assets/use-token-gate-E-xzEAu6.js.map +0 -1
  910. package/dist/core/web/public/next/assets/useAutoSeat-CXC9e4vx.js +0 -2
  911. package/dist/core/web/public/next/assets/useAutoSeat-CXC9e4vx.js.map +0 -1
  912. package/dist/core/web/public/next/assets/useOnboarding-Csw_AXrj.js +0 -2
  913. package/dist/core/web/public/next/assets/useOnboarding-Csw_AXrj.js.map +0 -1
  914. package/dist/core/web/public/next/assets/useSeatHealth-B6AXxre9.js +0 -2
  915. package/dist/core/web/public/next/assets/useSeatHealth-B6AXxre9.js.map +0 -1
  916. package/dist/core/web/public/next/assets/useSeatsRefresh-BIAa7Exn.js +0 -2
  917. package/dist/core/web/public/next/assets/useSeatsRefresh-BIAa7Exn.js.map +0 -1
  918. package/dist/core/web/public/next/assets/useVerseSession-BOyvOEDi.js +0 -2
  919. package/dist/core/web/public/next/assets/useVerseSession-BOyvOEDi.js.map +0 -1
  920. package/dist/core/web/public/next/assets/useVerseTranscript-BOhcfdp7.js +0 -2
  921. package/dist/core/web/public/next/assets/useVerseTranscript-BOhcfdp7.js.map +0 -1
  922. package/dist/core/web/public/next/assets/verse-bootstrap-query-D-fU89IT.js +0 -2
  923. package/dist/core/web/public/next/assets/verse-bootstrap-query-D-fU89IT.js.map +0 -1
  924. package/dist/core/web/public/next/assets/verse-icons-UKbUG3gv.js +0 -2
  925. package/dist/core/web/public/next/assets/verse-icons-UKbUG3gv.js.map +0 -1
  926. package/dist/core/web/public/next/assets/warmup-CZ-IBU5L.js +0 -3
  927. package/dist/core/web/public/next/assets/warmup-CZ-IBU5L.js.map +0 -1
  928. package/dist/core/web/public/next/assets/wiki-focus-DhAvbMnX.js +0 -2
  929. package/dist/core/web/public/next/assets/wiki-focus-DhAvbMnX.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capacity-strip-model-CBMJ2U-w.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/resources/resource-usage-history.ts","../../../../../../src/web-ui/routes/verse/usage/capacity-model.ts","../../../../../../src/web-ui/routes/verse/health/health-model.ts","../../../../../../src/web-ui/routes/verse/usage/capacity-strip-model.ts"],"sourcesContent":["import type { ResourceLastKnownUsage } from '../../../../core/resources/reading-cache-types.js';\nimport type { VerseSeat } from '../../../data/api-types.js';\n\nfunction instant(value: unknown): value is string {\n return typeof value === 'string' && Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;\n}\n/** Historical windows are a separate display value, never an input to live capacity. */\nexport function resourceUsageHistory(seat: VerseSeat, now: number): ResourceLastKnownUsage | null {\n const history = seat.lastKnownUsage;\n if (!history || history.source !== 'native-account-checked-history' ||\n !['native-account-checked', 'native-account-checked-local-epoch'].includes(history.identitySource) ||\n !instant(history.observedAt) || !instant(history.expiresAt) || Date.parse(history.observedAt) > now ||\n Date.parse(history.expiresAt) <= Date.parse(history.observedAt) ||\n Date.parse(history.expiresAt) - Date.parse(history.observedAt) > 60_000 || !Array.isArray(history.windows) ||\n !history.windows.length || !history.windows.every(window => !!window && typeof window === 'object' && !Array.isArray(window) &&\n typeof window.id === 'string' && /^[a-z0-9][a-z0-9_-]{0,63}$/.test(window.id) &&\n (window.usedPercent === null || typeof window.usedPercent === 'number' &&\n Number.isFinite(window.usedPercent) && window.usedPercent >= 0 && window.usedPercent <= 100) &&\n (window.resetsAt === null || instant(window.resetsAt)) &&\n (window.limitReached === undefined || window.limitReached === true && window.usedPercent === 100))) return null;\n return history;\n}\n/** A gray historical meter compares the recorded window readings, not current availability. */\nexport function historicalLeftPercent(history: ResourceLastKnownUsage): number | null {\n const values = history.windows.flatMap(window => window.limitReached ? [100] : window.usedPercent === null ? [] : [window.usedPercent]);\n return values.length ? 100 - Math.max(...values) : null;\n}\n","/**\n * routes/verse/usage/capacity-model.ts — \"what can I run right now\", in one\n * pure projection.\n *\n * The Usage section already answers this per seat, one card at a time. This\n * module answers it for the WHOLE ROSTER in one line, because the operator's\n * first question on opening the view is not \"how is Codex A doing\" — it is\n * \"do I have anything to run, and if not, when does that change\".\n *\n * Four rules, each one a place where the obvious summary would lie:\n *\n * 1. A COUNT IS NOT A CAPACITY. \"3 of 5 seats usable\" is only true if the\n * other two were actually read. Seats with no reading are counted in their\n * own bucket and named in the sentence, never folded into \"blocked\" — an\n * unread seat might be perfectly usable.\n * 2. ONLY A MACHINE-READABLE INSTANT MAY BECOME A COUNTDOWN. Claude's reset\n * is provider prose and `resetsAt` is structurally null\n * (docs/VERSE-TELEMETRY-V2.md), so prose resets travel in their own\n * channel and are rendered verbatim. Nothing here parses a sentence into\n * a time.\n * 3. A RESET IN THE PAST IS NOT A RESET. A `resetsAt` that has already\n * elapsed means the reading predates the rollover; it is reported as\n * overdue rather than as a negative countdown or as \"now\".\n * 4. LOCAL HEADROOM IS NOT \"BUDGET MINUS RESIDENT\" UNLESS BOTH ARE KNOWN.\n * One unknown makes the headroom unknown, and the strip says so.\n *\n * Pure: no React, no I/O, no formatting of currency/percent.\n */\nimport type { AccountCardModel, AccountVerdictState, LocalCardModel, WindowView } from './accounts-model.js';\nimport type { LocalModelsView } from './local-model.js';\n\n/**\n * The four buckets the strip counts in. Deliberately coarser than\n * `AccountVerdictState`: at a glance there are only four useful answers, and\n * the card below carries the nuance.\n */\nexport type CapacityClass = 'ready' | 'tight' | 'blocked' | 'unread';\n\n/**\n * `signed-out` and `probe-unsupported` are BLOCKED-by-action, not unread: in\n * both cases we know exactly why there is no capacity and what to do about\n * it. `unknown` is the only genuinely unread state — nobody told us anything,\n * so counting it as blocked would assert an outage we did not observe.\n */\nexport const CAPACITY_CLASS: Record<AccountVerdictState, CapacityClass> = {\n available: 'ready',\n credits: 'ready',\n tight: 'tight',\n exhausted: 'blocked',\n 'signed-out': 'blocked',\n 'probe-unsupported': 'blocked',\n unknown: 'unread',\n};\n\nexport interface SeatCapacity {\n id: string;\n label: string;\n kind: 'account' | 'local';\n /** Engine hue — used only for the 2px marker, never for text. */\n color: string;\n cls: CapacityClass;\n /** The card's own verdict headline, so the strip and the card agree. */\n headline: string;\n /**\n * The binding window's percent, when it is a real measurement. Null for an\n * unread seat AND for a flagged limit, whose sentinel 100 is not a reading.\n */\n usedPct: number | null;\n /** False when `usedPct` is null because the figure would be a sentinel. */\n measured: boolean;\n}\n\n/** A reset the provider gave as a real instant, so a countdown is honest. */\nexport interface ResetInstant {\n seatLabel: string;\n windowLabel: string;\n /**\n * Epoch ms — the ONLY durable fact here. `inMs`/`overdue` below are a\n * snapshot taken when the model was built; a view that renders a countdown\n * must derive it from `atMs` against a live clock instead, or it will print\n * whatever the elapsed time happened to be when the memo last ran.\n */\n atMs: number;\n /** Signed ms until the reset AT BUILD TIME. Selection only — never rendered. */\n inMs: number;\n /** True when `inMs <= 0` AT BUILD TIME. Selection only — never rendered. */\n overdue: boolean;\n}\n\n/** A reset whose ONLY signal is provider prose. Rendered verbatim, never parsed. */\nexport interface ResetProse {\n seatLabel: string;\n windowLabel: string;\n text: string;\n}\n\nexport interface LocalCapacity {\n reachable: boolean;\n residentCount: number;\n installedCount: number;\n /** Models that can actually drive an agentic session. */\n agenticCount: number;\n /** Models whose runtime did not report a capability list. Never \"cannot\". */\n unknownToolCount: number;\n residentBytes: number | null;\n memoryBudgetBytes: number | null;\n /** Budget minus resident. Null when either side is unknown. */\n headroomBytes: number | null;\n /** The machine's own reported free memory, which is not the same figure. */\n freeMemoryBytes: number | null;\n usedPct: number | null;\n}\n\nexport interface CapacityOverview {\n seats: SeatCapacity[];\n ready: number;\n tight: number;\n blocked: number;\n unread: number;\n total: number;\n /**\n * Every dated reset, so a view can re-select the soonest one against a live\n * clock rather than against the instant this model was built.\n */\n resets: ResetInstant[];\n /** The soonest real reset across every seat, or null when none is dated. */\n nextReset: ResetInstant | null;\n /** Every window whose reset is prose only, deduplicated by sentence. */\n proseResets: ResetProse[];\n local: LocalCapacity | null;\n /** The one-line answer. Never claims anything about an unread seat. */\n headline: string;\n /**\n * True when the roster WAS read and nothing in it is usable.\n *\n * An entirely unread roster is deliberately excluded. `noCapacity` is what\n * tints the headline as a warning, and \"you have no capacity\" over seats\n * nobody managed to probe is an assertion about an unobserved state — the\n * same lie `capacityHeadline` is written case-by-case to avoid, and the same\n * one the `unread` chip word exists to prevent. A PARTLY unread roster still\n * counts: a seat known to be blocked is a measured constraint.\n */\n noCapacity: boolean;\n}\n\nfunction plural(n: number, one: string, many: string): string {\n return n === 1 ? one : many;\n}\n\n/**\n * The strip's sentence. Written by cases rather than by template because each\n * case has a different honest claim to make, and a single interpolated string\n * ended up asserting \"0 usable\" over a roster nobody had read.\n */\nexport function capacityHeadline(input: {\n ready: number;\n tight: number;\n blocked: number;\n unread: number;\n total: number;\n local: LocalCapacity | null;\n}): string {\n const { ready, tight, blocked, unread, total, local } = input;\n if (total === 0) {\n return 'No seats found.';\n }\n\n const localClause =\n local === null\n ? ''\n : local.reachable && local.residentCount > 0\n ? ` ${local.residentCount} local ${plural(local.residentCount, 'model is', 'models are')} resident and answer with no load delay.`\n : local.reachable && local.agenticCount > 0\n ? ` No local model is resident, but ${local.agenticCount} installed ${plural(local.agenticCount, 'one can', 'ones can')} drive a session after a load.`\n : local.reachable\n ? ' No local model is resident.'\n : ' The local runtime did not answer, so local capacity is unknown.';\n\n const unreadClause =\n unread === 0\n ? ''\n : ` ${unread} ${plural(unread, 'seat has', 'seats have')} no reading yet.`;\n\n if (ready > 0) {\n return `${ready} of ${total} ${plural(total, 'seat is', 'seats are')} usable right now.${unreadClause}${localClause}`;\n }\n if (tight > 0) {\n return `No seat is clear: ${tight} ${plural(tight, 'is', 'are')} running tight and ${blocked} ${plural(blocked, 'is', 'are')} blocked.${unreadClause}${localClause}`;\n }\n if (blocked > 0) {\n return `No cloud seat reports headroom — ${blocked} blocked.${unreadClause}${localClause}`;\n }\n return `No seat reported a usable window.${unreadClause}${localClause}`;\n}\n\nfunction seatFromCard(card: AccountCardModel): SeatCapacity {\n const binding = card.binding;\n return {\n id: card.id,\n label: card.label,\n kind: 'account',\n color: card.color,\n cls: CAPACITY_CLASS[card.verdict.state],\n headline: card.verdict.headline,\n usedPct: binding && binding.measured && !binding.limitReached ? binding.usedPct : null,\n measured: binding !== null && binding.measured && !binding.limitReached,\n };\n}\n\nfunction seatFromLocal(card: LocalCardModel): SeatCapacity {\n return {\n id: 'local',\n label: 'Local',\n kind: 'local',\n color: card.color,\n cls: CAPACITY_CLASS[card.verdict.state],\n headline: card.verdict.headline,\n usedPct: card.usedPct,\n measured: card.usedPct !== null,\n };\n}\n\n/**\n * Collect reset signals, keeping the two channels apart.\n *\n * A window contributes to `instants` ONLY through `resetsAt`, an ISO string\n * the provider actually gave. `resetText` alone — Claude's entire reset\n * signal — contributes to `prose` and is never parsed.\n */\nexport function collectResets(\n seats: readonly { label: string; windows: readonly WindowView[] }[],\n nowMs: number,\n): { instants: ResetInstant[]; prose: ResetProse[] } {\n const instants: ResetInstant[] = [];\n const prose: ResetProse[] = [];\n const seenProse = new Set<string>();\n\n for (const seat of seats) {\n for (const w of seat.windows) {\n if (w.resetsAt !== null) {\n const atMs = Date.parse(w.resetsAt);\n if (!Number.isNaN(atMs)) {\n const inMs = atMs - nowMs;\n instants.push({\n seatLabel: seat.label,\n windowLabel: w.label,\n atMs,\n inMs,\n overdue: inMs <= 0,\n });\n continue;\n }\n }\n if (w.resetText !== null) {\n const key = `${seat.label}|${w.label}|${w.resetText}`;\n if (seenProse.has(key)) continue;\n seenProse.add(key);\n prose.push({ seatLabel: seat.label, windowLabel: w.label, text: w.resetText });\n }\n }\n }\n return { instants, prose };\n}\n\n/**\n * The soonest reset still ahead of us. An overdue instant is never chosen as\n * \"next\" — it is in the past — but if EVERY instant is overdue the most recent\n * one is returned so the strip can say the readings predate a rollover rather\n * than silently showing nothing.\n */\nexport function nextReset(instants: readonly ResetInstant[]): ResetInstant | null {\n const ahead = instants.filter((r) => !r.overdue);\n if (ahead.length > 0) {\n return ahead.reduce((soonest, r) => (r.inMs < soonest.inMs ? r : soonest));\n }\n if (instants.length === 0) return null;\n return instants.reduce((latest, r) => (r.atMs > latest.atMs ? r : latest));\n}\n\n/**\n * The same choice as {@link nextReset}, but judged against a clock the caller\n * supplies rather than against the `overdue` flag frozen into each instant.\n * This is what a rendering countdown must use: a reset that was 40s away when\n * the model was built is in the PAST a minute later, and picking it as \"next\"\n * would keep a positive number on screen for a window that already rolled.\n */\nexport function nextResetAt(instants: readonly ResetInstant[], nowMs: number): ResetInstant | null {\n const ahead = instants.filter((r) => r.atMs > nowMs);\n if (ahead.length > 0) {\n return ahead.reduce((soonest, r) => (r.atMs < soonest.atMs ? r : soonest));\n }\n if (instants.length === 0) return null;\n return instants.reduce((latest, r) => (r.atMs > latest.atMs ? r : latest));\n}\n\nfunction buildLocalCapacity(\n card: LocalCardModel | null,\n view: LocalModelsView | null,\n): LocalCapacity | null {\n if (card === null && view === null) return null;\n const residentBytes = card?.residentBytes ?? view?.residentBytes ?? null;\n const budget = card?.memoryBudgetBytes ?? view?.memoryBudgetBytes ?? null;\n return {\n reachable: view?.reachable ?? card?.verdict.state !== 'unknown',\n residentCount: card?.residentCount ?? view?.rows.filter((r) => r.resident).length ?? 0,\n installedCount: card?.installedCount ?? view?.rows.length ?? 0,\n agenticCount: view?.agenticCount ?? 0,\n unknownToolCount: view?.unknownToolCount ?? 0,\n residentBytes,\n memoryBudgetBytes: budget,\n // One unknown side makes the difference unknown. Treating a missing\n // resident figure as 0 would report the whole machine as free.\n headroomBytes:\n residentBytes !== null && budget !== null ? Math.max(0, budget - residentBytes) : null,\n freeMemoryBytes: view?.freeMemoryBytes ?? null,\n usedPct: card?.usedPct ?? view?.memoryUsedPct ?? null,\n };\n}\n\nexport function buildCapacityOverview(input: {\n cards: readonly AccountCardModel[];\n localCard: LocalCardModel | null;\n localView: LocalModelsView | null;\n nowMs?: number;\n}): CapacityOverview {\n const nowMs = input.nowMs ?? Date.now();\n const seats: SeatCapacity[] = input.cards.map(seatFromCard);\n if (input.localCard) seats.push(seatFromLocal(input.localCard));\n\n const count = (cls: CapacityClass): number => seats.filter((s) => s.cls === cls).length;\n const ready = count('ready');\n const tight = count('tight');\n const blocked = count('blocked');\n const unread = count('unread');\n\n const { instants, prose } = collectResets(\n input.cards.map((c) => ({ label: c.label, windows: c.allWindows })),\n nowMs,\n );\n\n const local = buildLocalCapacity(input.localCard, input.localView);\n\n return {\n seats,\n ready,\n tight,\n blocked,\n unread,\n total: seats.length,\n resets: instants,\n nextReset: nextReset(instants),\n proseResets: prose,\n local,\n headline: capacityHeadline({ ready, tight, blocked, unread, total: seats.length, local }),\n // `unread < seats.length` is the whole guard: a roster where every seat\n // came back unread is unobserved, not exhausted.\n noCapacity: seats.length > 0 && ready === 0 && tight === 0 && unread < seats.length,\n };\n}\n\n/**\n * \"in 2h 14m\" material for a dated reset. Kept beside the model rather than in\n * `chartFormat` because it is a duration, not a chart number, and because the\n * overdue case must not read as a negative time.\n */\nexport function formatUntil(inMs: number): string {\n if (!Number.isFinite(inMs)) return '—';\n if (inMs <= 0) return 'overdue';\n const total = Math.floor(inMs / 1000);\n const d = Math.floor(total / 86_400);\n const h = Math.floor((total % 86_400) / 3600);\n const m = Math.floor((total % 3600) / 60);\n if (d > 0) return `${d}d ${h}h`;\n if (h > 0) return `${h}h ${m}m`;\n if (m > 0) return `${m}m`;\n return `${total}s`;\n}\n","/**\n * routes/verse/health/health-model.ts — how a seat health report reads on\n * screen (V3.10, unit A2). Pure: no React, no I/O.\n *\n * Every surface that shows seat health (the banner, the Composer block, the\n * seat picker) takes its words from here so one seat is never described two\n * ways. State is never carried by colour alone: every tone comes with a word.\n */\nimport type { SeatConnection, SeatHealthReport } from '../../../../core/verse/health-types.js';\nimport { describeResetAt } from '../../../../core/verse/seat-readiness.js';\nimport type { VerseSeat } from '../../../data/api-types.js';\nimport { tidyProse } from '../autonomy/format.js';\nimport { seatReopensAt, seatSubscription } from '../seat-subscription.js';\nimport { formatUntil } from '../usage/capacity-model.js';\n\nexport type HealthTone = 'danger' | 'warning' | 'neutral' | 'success';\n\nexport const CONNECTION_WORD: Record<SeatConnection, string> = {\n connected: 'connected',\n expiring: 'sign-in expiring',\n 'signed-out': 'signed out',\n exhausted: 'out of usage',\n 'binary-skew': 'older CLI pinned',\n unknown: 'not checked',\n};\n\nexport const CONNECTION_TONE: Record<SeatConnection, HealthTone> = {\n connected: 'success',\n expiring: 'warning',\n 'signed-out': 'danger',\n exhausted: 'danger',\n 'binary-skew': 'warning',\n unknown: 'neutral',\n};\n\n/** Most urgent first: what blocks work, then what will, then what could be better. */\nconst SEVERITY: Record<SeatConnection, number> = {\n 'signed-out': 0,\n exhausted: 1,\n expiring: 2,\n 'binary-skew': 3,\n unknown: 4,\n connected: 5,\n};\n\nexport interface SeatHealthIssue {\n report: SeatHealthReport;\n /** The seat's human label (falls back to the id when the seat is not in the roster). */\n label: string;\n word: string;\n tone: HealthTone;\n /** The first, most specific reason, or null. */\n detail: string | null;\n /** \"resets Fri 2:25 PM\" when the provider gave an instant. */\n reset: string | null;\n /** \"usable again in 7h 12m\" for a spent seat whose reset is still ahead; null otherwise. */\n usableAgain: string | null;\n}\n\n/**\n * \"usable again in 7h 12m\" for an instant still ahead of `now`; null when the\n * instant is missing, unparseable or already past (a past reset is a stale\n * reading, not a negative countdown).\n */\nexport function usableAgainPhrase(resetAt: string | null | undefined, now: number = Date.now()): string | null {\n if (typeof resetAt !== 'string') return null;\n const at = Date.parse(resetAt);\n if (!Number.isFinite(at) || at <= now) return null;\n return `usable again in ${formatUntil(at - now)}`;\n}\n\n/**\n * Is this report worth interrupting the operator for? Every non-connected\n * state is, EXCEPT an `unknown` with nothing to say (a sweep that has not run\n * yet is not a fault, and saying \"not checked\" about every seat at boot would\n * teach the operator to ignore the banner).\n */\nexport function needsAttention(report: SeatHealthReport): boolean {\n if (report.connection === 'connected') return false;\n if (report.connection === 'unknown') {\n return report.reasons.length > 0 && !report.reasons[0]!.includes('has not reached this seat');\n }\n return true;\n}\n\nexport function seatHealthIssues(\n reports: readonly SeatHealthReport[],\n seats: readonly VerseSeat[] = [],\n now: number = Date.now(),\n): SeatHealthIssue[] {\n const byId = new Map(seats.map((seat) => [seat.id, seat]));\n return reports\n .filter(needsAttention)\n .map((report) => {\n // A spent seat is usable again when its LAST spent window resets, not\n // when the sweep's binding window does (seatReopensAt) — the same instant\n // Accounts and Fleet name. Without the seat's windows, the sweep's own.\n const seat = byId.get(report.seatId);\n const resetAt = report.connection === 'exhausted' && seat !== undefined\n ? seatReopensAt(seatSubscription(seat, now), report.resetAt)\n : report.resetAt;\n const when = describeResetAt(resetAt, now);\n return {\n report,\n label: seat?.label ?? report.seatId,\n word: CONNECTION_WORD[report.connection],\n tone: CONNECTION_TONE[report.connection],\n // Server sentences may carry a raw ISO instant or a \".;\" join; tidyProse fixes exactly those.\n detail: report.reasons[0] ? tidyProse(report.reasons[0], now) : null,\n reset: when === null ? null : `resets ${when}`,\n usableAgain: report.connection === 'exhausted' ? usableAgainPhrase(resetAt, now) : null,\n };\n })\n .sort((a, b) => SEVERITY[a.report.connection] - SEVERITY[b.report.connection]);\n}\n\n/**\n * An argv rendered for copy-paste into a POSIX shell. Plain words stay bare;\n * anything else is single-quoted. A leading `~/` stays OUTSIDE the quotes so\n * the shell still expands it.\n */\nexport function shellCommandText(argv: readonly string[]): string {\n return argv.map((arg) => {\n if (/^[A-Za-z0-9_@%+=:,./-]+$/.test(arg)) return arg;\n if (arg.startsWith('~/') && /^[A-Za-z0-9_@%+=:,./~-]+$/.test(arg)) return arg;\n if (arg.startsWith('~/')) return `~/'${arg.slice(2).replaceAll(\"'\", \"'\\\\''\")}'`;\n return `'${arg.replaceAll(\"'\", \"'\\\\''\")}'`;\n }).join(' ');\n}\n\n/** One line summarising the whole roster for a collapsed banner. */\nexport function issuesHeadline(issues: readonly SeatHealthIssue[]): string {\n if (issues.length === 0) return 'All seats are connected.';\n const blocked = issues.filter((issue) => issue.tone === 'danger').length;\n if (blocked > 0) {\n return blocked === 1 ? `${issues.find((i) => i.tone === 'danger')!.label} can't run turns right now.`\n : `${blocked} seats can't run turns right now.`;\n }\n return issues.length === 1 ? `${issues[0]!.label} needs attention.` : `${issues.length} seats need attention.`;\n}\n","/**\n * routes/verse/usage/capacity-strip-model.ts — ONE projection of \"how much of\n * each seat is left, what is it tied to, and how much is kept for me\", for\n * every surface that shows seat capacity (SPEC-310C §4: Apps & Accounts,\n * Usage, Resources, NewChatDialog, onboarding; the rail foot's capacity ring\n * and the composer's seat chip read `scarcestSeat` / `capacityRowFor`).\n *\n * Three sources, each already cached app-wide, each read HERE and nowhere\n * else so a seat is never described two ways:\n * - the seat itself (`VerseSeat`, from bootstrap / the /seats poll) — plan,\n * windows, resets, credits, through `seat-subscription.ts`, which owns the\n * honesty rules (binding window leads, no reading ≠ zero, the sentinel 100\n * is a flag, prose resets stay prose);\n * - A2's health report — connected / expiring / signed out / older CLI, and\n * the command that fixes it;\n * - A9's budget view — the reserve kept for Mason and whether autonomy may\n * use the seat right now, through `budget-model.ts`'s own rows.\n * Any of the last two may be missing; the row then says less, never more.\n *\n * Pure: no React, no I/O.\n */\nimport type { BudgetView } from '../../../../core/routing/policy.js';\nimport type { SeatBudgetPolicy, SeatHeadroom } from '../../../../core/routing/types.js';\nimport type { SeatConnection, SeatFixKind, SeatHealthReport } from '../../../../core/verse/health-types.js';\nimport { describeResetAt } from '../../../../core/verse/seat-readiness.js';\nimport { ENGINE_MONOGRAM } from '../../../../core/verse/workbench-types.js';\nimport type { VerseEngine, VerseSeat } from '../../../data/api-types.js';\nimport type { ResourceLastKnownUsage } from '../../../../core/resources/reading-cache-types.js';\nimport { resourceUsageHistory } from '../resources/resource-usage-history.js';\nimport { buildBudgetRows, STATUS_WORDS, type BudgetSeatStatus } from '../budget/budget-model.js';\nimport { relativePhrase } from '../context/context-model.js';\nimport { percentText, tidyProse } from '../autonomy/format.js';\nimport { CONNECTION_TONE, CONNECTION_WORD, usableAgainPhrase, type HealthTone } from '../health/health-model.js';\nimport { seatReopensAt, seatSubscription, type SeatCapacityClass, type SeatWindowView } from '../seat-subscription.js';\nimport { SEAT_CAPACITY_WORD } from '../verse-model.js';\n\nexport type { SeatCapacityClass };\n\ntype BudgetRow = ReturnType<typeof buildBudgetRows>[number];\n\n/** Rows show at most this many windows: the binding one and the next two. */\nexport const CAPACITY_MAX_WINDOWS = 3;\n\nexport interface CapacityWindowRow {\n id: string;\n /** \"5-hour window\", \"weekly window\", \"weekly fable window\". */\n label: string;\n /** 0–100, or null = no reading (never a substituted zero). */\n usedPercent: number | null;\n /** The provider flagged the limit; no percentage exists. */\n limitReached: boolean;\n /** Provider prose verbatim, or a formatted local instant; null when neither. */\n resetText: string | null;\n /** The machine-readable reset instant (ISO), when the provider gave one. */\n resetsAt: string | null;\n /** True for the window that constrains work right now. */\n binding: boolean;\n}\n\nexport interface CapacityConnection {\n connection: SeatConnection;\n word: string;\n tone: HealthTone;\n /** Plain, already-scrubbed reasons; empty when connected. */\n reasons: string[];\n fixKind: SeatFixKind;\n /** argv; null when nothing fixes it from a terminal. */\n fixCommand: string[] | null;\n}\n\nexport interface CapacityReserve {\n /** Share of the binding window kept for Mason; null when autonomy is off for this seat. */\n percent: number | null;\n /** \"Reserved for you 40%\", \"Autonomy off — all yours\", \"No reserve\". */\n label: string;\n autonomy: BudgetSeatStatus;\n /** \"Eligible\", \"Held back\", \"Off\", \"No reading\". */\n autonomyWord: string;\n /** The router's own first reason, verbatim. */\n why: string;\n}\n\nexport interface CapacityRow {\n /** A seat id, or `local` for the collapsed local row. */\n seatId: string;\n label: string;\n engine: VerseEngine;\n monogram: string;\n kind: 'subscription' | 'local';\n plan: string | null;\n cls: SeatCapacityClass;\n /** usable / tight / blocked / no reading. */\n word: string;\n /** One phrase: \"62% of 5-hour window used\", \"signed out — reconnect this account\". */\n summary: string;\n connection: CapacityConnection | null;\n windows: CapacityWindowRow[];\n credits: string | null;\n creditSpendControlReached?: boolean | null;\n creditBalance?: string | null;\n creditState?: 'available' | 'held' | 'none' | 'unknown';\n reserve: CapacityReserve | null;\n notes: string[];\n /** For the collapsed local row: how many local seats it stands for. */\n localCount: number;\n /** When this seat was last checked (health sweep, else the usage reading), ISO; null when never. */\n checkedAt: string | null;\n /** The instant a spent seat becomes usable again (ISO), when one is known. */\n resetAt: string | null;\n /** The account is signed out — by the health sweep or by its own capacity record. */\n signedOut: boolean;\n /** A verified, still-fresh window retained only for display after a failed check. */\n lastReading?: boolean;\n /** Original account-checked historical display; excluded from windows, status and headroom. */\n historicalUsage?: ResourceLastKnownUsage | null;\n}\n\nexport interface CapacityInputs {\n health?: readonly SeatHealthReport[] | null;\n budget?: BudgetView | null;\n /**\n * Local seats: `collapse` (default) folds every Ollama tag into one row —\n * they share one machine and one readiness, and twelve identical rows are\n * noise; `each` lists them; `hide` drops them.\n */\n local?: 'collapse' | 'each' | 'hide';\n /** Only these seats, in this order (the new-chat dialog passes the chosen one). */\n seatIds?: readonly string[];\n /**\n * The clock every reset and reason in the rows is worded against (\"today\n * 11:46 PM\" vs \"Sat 11:46 PM\"); defaults to now. Passed explicitly so the\n * words are a function of the inputs — a row built against the real clock\n * inside a test is a time bomb.\n */\n now?: number;\n}\n\nconst TONE_OF_CLASS: Record<SeatCapacityClass, HealthTone> = {\n ready: 'success',\n tight: 'warning',\n blocked: 'danger',\n unread: 'neutral',\n};\n\n/** How a capacity class reads as a tone (a word always rides with it). */\nexport function capacityTone(cls: SeatCapacityClass): HealthTone {\n return TONE_OF_CLASS[cls];\n}\n\n/**\n * `resetText` comes from seat-subscription as-is: it already words a machine\n * instant the way every other reset in the app does (`describeResetAt`:\n * \"resets Fri 11:46 PM\") and leaves provider prose verbatim — one wording,\n * owned in one place.\n */\nfunction windowRow(w: SeatWindowView, binding: boolean): CapacityWindowRow {\n return {\n id: w.id,\n label: w.label,\n usedPercent: w.usedPercent,\n limitReached: w.limitReached,\n resetText: w.resetText,\n resetsAt: w.resetsAt,\n binding,\n };\n}\n\nfunction parseable(iso: string | null | undefined): iso is string {\n return typeof iso === 'string' && Number.isFinite(Date.parse(iso));\n}\n\nfunction isSpentWindow(w: Pick<SeatWindowView, 'limitReached' | 'usedPercent'>): boolean {\n return w.limitReached || (w.usedPercent !== null && w.usedPercent >= 100);\n}\n\nfunction connectionOf(report: SeatHealthReport | undefined, now: number): CapacityConnection | null {\n if (!report) return null;\n return {\n connection: report.connection,\n word: CONNECTION_WORD[report.connection],\n tone: CONNECTION_TONE[report.connection],\n reasons: readableReasons(report.reasons, now),\n fixKind: report.fix.kind,\n fixCommand: report.fix.command && report.fix.command.length > 0 ? [...report.fix.command] : null,\n };\n}\n\n/** Reasons as printed: server sentences with any ISO instant shown in local time. */\nfunction readableReasons(reasons: readonly string[], now: number): string[] {\n return reasons.map((r) => tidyProse(r, now).trim()).filter((r) => r.length > 0);\n}\n\nfunction reserveOf(budgetRow: BudgetRow | undefined): CapacityReserve | null {\n if (!budgetRow || budgetRow.free) return null;\n const { policy } = budgetRow;\n const pct = Math.max(0, Math.min(100, Math.round(policy.reservePercent)));\n const label = !policy.enabled\n ? 'Autonomy off — all yours'\n : pct === 0\n ? 'No reserve — autonomy may use all of it'\n : `Reserved for you ${pct}%`;\n return {\n percent: policy.enabled ? pct : null,\n label,\n autonomy: budgetRow.status,\n autonomyWord: STATUS_WORDS[budgetRow.status],\n why: budgetRow.why,\n };\n}\n\nfunction seatRow(\n seat: VerseSeat,\n health: ReadonlyMap<string, SeatHealthReport>,\n budget: ReadonlyMap<string, BudgetRow>,\n now: number,\n): CapacityRow {\n const view = seatSubscription(seat, now);\n const windows: CapacityWindowRow[] = [];\n if (view.binding) windows.push(windowRow(view.binding, true));\n for (const w of view.others) {\n if (windows.length >= CAPACITY_MAX_WINDOWS) break;\n windows.push(windowRow(w, false));\n }\n const report = health.get(seat.id);\n const connection = connectionOf(report, now);\n // A seat A2 found signed out or out of usage cannot run a turn, whatever\n // its last window reading says (the engine's readiness gate refuses it —\n // seat-readiness.ts SEAT_BLOCKING_CONNECTIONS). Counting it \"usable\"\n // would promise a chat the engine will refuse.\n const blockedByHealth = connection !== null && (connection.connection === 'signed-out' || connection.connection === 'exhausted');\n return {\n seatId: seat.id,\n label: seat.label,\n engine: seat.engine,\n monogram: ENGINE_MONOGRAM[seat.engine],\n kind: view.kind,\n plan: view.plan,\n cls: blockedByHealth ? 'blocked' : view.cls,\n word: blockedByHealth ? SEAT_CAPACITY_WORD.blocked : view.word,\n summary: blockedByHealth ? (connection.reasons[0] ?? connection.word) : view.summary,\n connection,\n windows,\n historicalUsage: windows.length === 0 ? resourceUsageHistory(seat, now) : null,\n credits: view.credits,\n creditBalance: view.creditBalance ?? null,\n creditState: view.creditState ?? 'unknown',\n creditSpendControlReached: view.creditSpendControlReached ?? null,\n reserve: reserveOf(budget.get(seat.id)),\n notes: [...view.notes],\n localCount: 1,\n checkedAt: parseable(report?.checkedAt) ? report!.checkedAt : parseable(view.observedAt) ? view.observedAt : null,\n // The LATEST reset among ALL the spent windows (not only the ones this row\n // has room to draw) — seat-subscription `seatReopensAt`, which Fleet's\n // \"eligible again\" and the health banner agree with.\n resetAt: seatReopensAt(view, report?.resetAt),\n signedOut: connection?.connection === 'signed-out' || seat.capacity?.usability === 'signed-out',\n lastReading: seat.health.state === 'degraded' && seat.capacity?.usability === 'unknown' && windows.length > 0,\n };\n}\n\nfunction collapsedLocal(seats: readonly VerseSeat[], health: ReadonlyMap<string, SeatHealthReport>, now: number): CapacityRow {\n const rows = seats.map((s) => seatSubscription(s, now));\n const ready = rows.filter((r) => r.cls === 'ready').length;\n const blocked = rows.filter((r) => r.cls === 'blocked').length;\n const cls: SeatCapacityClass = ready > 0 ? 'ready' : blocked === rows.length ? 'blocked' : 'unread';\n // One runtime behind every tag: the first report that says anything speaks for it.\n const report = seats.map((s) => health.get(s.id)).find((r) => r !== undefined);\n const count = seats.length;\n return {\n seatId: 'local',\n label: 'Local models',\n engine: 'local',\n monogram: ENGINE_MONOGRAM.local,\n kind: 'local',\n plan: null,\n cls,\n word: rows.find((r) => r.cls === cls)?.word ?? 'no reading',\n summary: cls === 'ready'\n ? `${count} ${count === 1 ? 'model' : 'models'} on this machine · free`\n : cls === 'blocked'\n ? (rows[0]?.summary ?? 'local runtime unavailable')\n : 'readiness not reported',\n connection: connectionOf(report, now),\n windows: [],\n credits: null,\n reserve: null,\n notes: [],\n localCount: count,\n checkedAt: parseable(report?.checkedAt)\n ? report!.checkedAt\n : rows.map((r) => r.observedAt).filter(parseable).sort((a, b) => Date.parse(b) - Date.parse(a))[0] ?? null,\n resetAt: null,\n signedOut: false,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tolerant readers\n// ---------------------------------------------------------------------------\n//\n// WHY THESE EXIST. The strip is mounted on five surfaces (Apps, Usage,\n// onboarding, NewChatDialog, the rail ring via scarcestSeat) and renders\n// synchronously from three cached server reads. The types say what a healthy\n// server sends, but the cache holds whatever arrived: a `{}` from a budget\n// route that has not landed on an older sidecar, a half-written health file,\n// a future field shape. One `undefined.map` inside `useMemo` takes the whole\n// surface down with it (INT6 found exactly that with `/api/verse/budget` →\n// `{}`). So each optional source is checked HERE, at the one boundary every\n// view shares, and the rule is the module's own: a source that cannot be\n// read makes the row say LESS, never crash and never invent. A bad entry is\n// dropped on its own; the rest of the source still speaks.\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nconst nullablePercent = (v: unknown): number | null => (typeof v === 'number' && Number.isFinite(v) ? v : null);\n\nfunction readHeadroom(value: unknown): SeatHeadroom | null {\n if (!isRecord(value) || typeof value['seatId'] !== 'string') return null;\n const binding = value['bindingWindow'];\n return {\n seatId: value['seatId'],\n sessionUsedPercent: nullablePercent(value['sessionUsedPercent']),\n weeklyUsedPercent: nullablePercent(value['weeklyUsedPercent']),\n bindingWindow: binding === 'session' || binding === 'weekly' ? binding : null,\n autonomyHeadroomPercent: nullablePercent(value['autonomyHeadroomPercent']),\n resetAt: typeof value['resetAt'] === 'string' ? value['resetAt'] : null,\n // Only an explicit `true` makes a seat eligible — a garbled flag is \"not known to be eligible\".\n eligibleForAutonomy: value['eligibleForAutonomy'] === true,\n reasons: Array.isArray(value['reasons']) ? value['reasons'].filter((r): r is string => typeof r === 'string') : [],\n };\n}\n\nfunction readPolicy(seatId: string, value: unknown): SeatBudgetPolicy | null {\n if (!isRecord(value) || typeof value['enabled'] !== 'boolean') return null;\n const reserve = value['reservePercent'];\n if (typeof reserve !== 'number' || !Number.isFinite(reserve)) return null;\n const out: SeatBudgetPolicy = { seatId, enabled: value['enabled'], reservePercent: reserve };\n const session = value['maxSessionWindowPercent'];\n if (typeof session === 'number' && Number.isFinite(session)) out.maxSessionWindowPercent = session;\n return out;\n}\n\n/**\n * The budget view → rows keyed by seat, or an empty map when the view cannot\n * be read. A seat whose policy entry is present but malformed is DROPPED\n * rather than handed to budget-model's \"no policy → off\" default: that default\n * is right for a seat the server genuinely has no policy for, but for a\n * garbled entry it would print \"Autonomy off — all yours\", a claim nobody\n * made.\n */\nexport function readBudgetRows(view: unknown): Map<string, BudgetRow> {\n if (!isRecord(view) || !Array.isArray(view['seatInfo'])) return new Map();\n const effectiveIn = isRecord(view['effective']) ? view['effective'] : {};\n const effective: Record<string, SeatBudgetPolicy> = {};\n const seatInfo: BudgetView['seatInfo'] = [];\n for (const info of view['seatInfo']) {\n if (!isRecord(info) || typeof info['seatId'] !== 'string') continue;\n const seatId = info['seatId'];\n const engine = info['engine'];\n if (engine !== 'claude' && engine !== 'codex' && engine !== 'grok' && engine !== 'local') continue;\n if (Object.prototype.hasOwnProperty.call(effectiveIn, seatId)) {\n const policy = readPolicy(seatId, effectiveIn[seatId]);\n if (policy === null) continue;\n effective[seatId] = policy;\n }\n seatInfo.push({\n seatId,\n label: typeof info['label'] === 'string' ? info['label'] : seatId,\n engine,\n free: info['free'] === true,\n });\n }\n const headroom = Array.isArray(view['headroom'])\n ? view['headroom'].map(readHeadroom).filter((h): h is SeatHeadroom => h !== null)\n : [];\n const safe = { ...(view as unknown as BudgetView), seatInfo, effective, headroom };\n try {\n return new Map(buildBudgetRows(safe).map((r) => [r.seatId, r]));\n } catch {\n // Belt and braces: budget-model is pure and the input is now well-typed,\n // but a reserve line is never worth a blank strip.\n return new Map();\n }\n}\n\n/** Health reports keyed by seat, keeping only reports that can be described honestly. */\nexport function readHealthReports(reports: unknown): Map<string, SeatHealthReport> {\n const out = new Map<string, SeatHealthReport>();\n if (!Array.isArray(reports)) return out;\n for (const r of reports) {\n if (!isRecord(r) || typeof r['seatId'] !== 'string') continue;\n const connection = r['connection'];\n // An unknown connection word has no tone or wording — describing it\n // would mean guessing; the row falls back to its window reading.\n if (typeof connection !== 'string' || !Object.prototype.hasOwnProperty.call(CONNECTION_WORD, connection)) continue;\n const fix = isRecord(r['fix']) ? r['fix'] : {};\n const kind = fix['kind'];\n const command = Array.isArray(fix['command']) && fix['command'].every((a) => typeof a === 'string')\n ? (fix['command'] as string[])\n : undefined;\n out.set(r['seatId'], {\n ...(r as unknown as SeatHealthReport),\n reasons: Array.isArray(r['reasons']) ? r['reasons'].filter((x): x is string => typeof x === 'string') : [],\n fix: {\n kind: kind === 'reauth' || kind === 'repin' || kind === 'wait' ? kind : 'none',\n ...(command ? { command } : {}),\n },\n });\n }\n return out;\n}\n\n/** Seats → rows, in the roster's own order (the server lists the operator's preferred seats first). */\nexport function buildCapacityRows(seats: readonly VerseSeat[], inputs: CapacityInputs = {}): CapacityRow[] {\n const health = readHealthReports(inputs.health);\n const budget = readBudgetRows(inputs.budget);\n // The roster comes from bootstrap; a malformed one reads as \"no seats yet\",\n // the strip's honest empty state, rather than a crash.\n const roster = Array.isArray(seats)\n ? seats.filter((s): s is VerseSeat => isRecord(s) && typeof (s as { id?: unknown }).id === 'string')\n : [];\n const localMode = inputs.local ?? 'collapse';\n const now = inputs.now ?? Date.now();\n let chosen: readonly VerseSeat[] = roster;\n if (inputs.seatIds) {\n const byId = new Map(roster.map((s) => [s.id, s]));\n chosen = inputs.seatIds.map((id) => byId.get(id)).filter((s): s is VerseSeat => s !== undefined);\n }\n const out: CapacityRow[] = [];\n const locals: VerseSeat[] = [];\n let localIndex = -1;\n for (const seat of chosen) {\n if (seat.engine === 'local') {\n if (localMode === 'hide') continue;\n if (localMode === 'collapse') {\n if (localIndex === -1) localIndex = out.length;\n locals.push(seat);\n continue;\n }\n }\n out.push(seatRow(seat, health, budget, now));\n }\n if (locals.length > 0) {\n // A single local seat keeps its own name; several fold into one row.\n const row = locals.length === 1 ? seatRow(locals[0]!, health, budget, now) : collapsedLocal(locals, health, now);\n out.splice(localIndex, 0, row);\n }\n return out;\n}\n\n/**\n * The strip's one sentence: how many paid seats are usable, and what local\n * adds. Counts only what was READ — an unread seat is named as unread, never\n * folded into \"blocked\".\n */\nexport function capacityHeadline(rows: readonly CapacityRow[]): string {\n const paid = rows.filter((r) => r.kind === 'subscription');\n const local = rows.filter((r) => r.kind === 'local');\n const usable = paid.filter((r) => r.cls === 'ready' || r.cls === 'tight').length;\n const lastReadings = paid.filter((r) => r.lastReading).length;\n const unread = paid.filter((r) => r.cls === 'unread' && !r.lastReading).length;\n const parts: string[] = [];\n if (paid.length === 0) parts.push('No accounts connected');\n else parts.push(`${usable} of ${paid.length} ${paid.length === 1 ? 'account' : 'accounts'} usable`);\n if (lastReadings > 0) parts.push(`${lastReadings} last ${lastReadings === 1 ? 'reading' : 'readings'}`);\n if (unread > 0) parts.push(`${unread} not read yet`);\n if (local.some((r) => r.cls === 'ready')) parts.push('local models ready');\n else if (local.length > 0) parts.push('local models not ready');\n return parts.join(' · ');\n}\n\n/**\n * The seat closest to running out — the rail foot's capacity ring (C1).\n * Blocked beats tight beats a measured percent; unread seats never win,\n * because an empty ring would claim headroom nobody measured.\n */\nexport function scarcestSeat(rows: readonly CapacityRow[]): CapacityRow | null {\n let best: { row: CapacityRow; score: number } | null = null;\n for (const row of rows) {\n if (row.kind !== 'subscription') continue;\n const binding = row.windows.find((w) => w.binding) ?? null;\n let score: number;\n if (row.cls === 'blocked' || binding?.limitReached) score = 300;\n else if (binding?.usedPercent != null) score = (row.cls === 'tight' ? 100 : 0) + binding.usedPercent;\n else continue;\n if (best === null || score > best.score) best = { row, score };\n }\n return best?.row ?? null;\n}\n\n/** One seat's row (the composer's seat chip, C3), or null when the seat is not in the roster. */\nexport function capacityRowFor(seats: readonly VerseSeat[], seatId: string, inputs: Omit<CapacityInputs, 'seatIds' | 'local'> = {}): CapacityRow | null {\n return buildCapacityRows(seats, { ...inputs, seatIds: [seatId], local: 'each' })[0] ?? null;\n}\n\n/**\n * The one percent rule lives with the app's other number formats\n * (autonomy/format); re-exported so every capacity view keeps importing it\n * from the capacity model.\n */\nexport { percentText };\n\n/** The accessible sentence for one window bar. */\nexport function windowSentence(row: Pick<CapacityRow, 'label'>, w: CapacityWindowRow, reservePercent: number | null): string {\n const head = `${row.label} ${w.label}`;\n const reset = w.resetText === null ? '' : `, ${w.resetText}`;\n if (w.limitReached) return `${head}: limit reached${reset}`;\n if (w.usedPercent === null) return `${head}: no reading${reset}`;\n const kept = reservePercent !== null && reservePercent > 0 ? `; ${reservePercent}% kept for you` : '';\n return `${head}: ${percentText(w.usedPercent)} used${kept}${reset}`;\n}\n\n// ---------------------------------------------------------------------------\n// Account status (Apps & Accounts)\n// ---------------------------------------------------------------------------\n\n/**\n * - `usable` — connected (or read as usable) with room left;\n * - `low` — usable, but tight: past the warning line, or spent and running on credits;\n * - `spent` — the binding window is used up; comes back at `resetAt`;\n * - `signed-out` — needs the provider's own sign-in (Reconnect);\n * - `unavailable` — blocked for another reason (runtime down, CLI missing);\n * - `not-checked` — the health sweep has answered but said nothing usable about this seat;\n * - `checking` — nothing has answered yet, or a check is running right now.\n */\nexport type AccountStatusKind = 'usable' | 'low' | 'spent' | 'signed-out' | 'unavailable' | 'not-checked' | 'checking';\n\nexport interface AccountStatus {\n kind: AccountStatusKind;\n /** Sentence case, leads the row: \"Connected\", \"Spent\", \"Signed out\", \"Checking…\". */\n label: string;\n /** Rides after a middle dot: \"usable now\", \"resets Fri 11:46 PM\", \"reconnect to use it\". */\n detail: string | null;\n tone: HealthTone;\n /** \"usable again in 7h 12m\" — only for a spent seat whose reset is still ahead. */\n usableAgain: string | null;\n /** \"checked 2m ago\"; null when the seat was never checked. */\n checked: string | null;\n /** The last check as a local date and time, for a tooltip. */\n checkedTitle: string | null;\n /** True when `label` already says what the connection word would (signed out, out of usage). */\n coversConnection: boolean;\n}\n\nexport interface AccountStatusOptions {\n /** False until the health sweep has answered once: an unanswered seat is \"Checking…\", not \"Not checked\". */\n healthRead: boolean;\n /** A check of this seat is running right now. */\n checking?: boolean;\n now?: number;\n}\n\nconst STATUS_TONE: Record<AccountStatusKind, HealthTone> = {\n usable: 'success',\n low: 'warning',\n spent: 'danger',\n 'signed-out': 'danger',\n unavailable: 'danger',\n 'not-checked': 'neutral',\n checking: 'neutral',\n};\n\n/** Usable first, then what will come back by itself, then what needs you. Used by `orderAccountRows`. */\nconst STATUS_RANK: Record<AccountStatusKind, number> = {\n usable: 0,\n low: 1,\n checking: 2,\n 'not-checked': 3,\n spent: 4,\n unavailable: 5,\n 'signed-out': 6,\n};\n\nfunction checkedParts(row: Pick<CapacityRow, 'checkedAt'>, now: number): { checked: string | null; checkedTitle: string | null } {\n const phrase = relativePhrase(row.checkedAt, now);\n if (phrase === null || row.checkedAt === null) return { checked: null, checkedTitle: null };\n const at = new Date(row.checkedAt);\n return {\n checked: `checked ${phrase}`,\n checkedTitle: `Last checked ${at.toLocaleString([], { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })}`,\n };\n}\n\n/**\n * The one status an account row leads with, in the operator's words:\n *\n * Connected · usable now Spent · resets Fri 11:46 PM\n * Connected · running low Signed out · reconnect to use it\n * Connected · usable on credits Checking…\n *\n * Built from the row alone (no second reading of the seat), against a clock\n * the caller passes, because \"usable again in 7h\" must keep counting down\n * while the rows themselves are memoized on the data.\n */\nexport function accountStatus(row: CapacityRow, opts: AccountStatusOptions): AccountStatus {\n const now = opts.now ?? Date.now();\n const { checked, checkedTitle } = checkedParts(row, now);\n const make = (kind: AccountStatusKind, label: string, detail: string | null, extra: Partial<AccountStatus> = {}): AccountStatus => ({\n kind,\n label,\n detail,\n tone: STATUS_TONE[kind],\n usableAgain: null,\n checked,\n checkedTitle,\n coversConnection: false,\n ...extra,\n });\n\n if (opts.checking) return make('checking', 'Checking…', null);\n\n if (row.kind === 'local') {\n if (row.cls === 'ready') {\n return make('usable', 'Ready', row.localCount > 1 ? `${row.localCount} models on this machine · free` : 'runs on this machine · free');\n }\n if (row.cls === 'blocked') return make('unavailable', 'Not running', row.summary);\n return opts.healthRead ? make('not-checked', 'Not checked', 'readiness not reported yet') : make('checking', 'Checking…', null);\n }\n\n const c = row.connection?.connection ?? null;\n if (row.signedOut) return make('signed-out', 'Signed out', 'reconnect to use it', { coversConnection: true });\n if (row.lastReading) return make('unavailable', 'Last reading', 'latest check failed · access unconfirmed', { coversConnection: true });\n\n const binding = row.windows.find((w) => w.binding) ?? null;\n const spent = c === 'exhausted' || (row.cls === 'blocked' && binding !== null && isSpentWindow(binding)) ||\n row.engine === 'codex' && row.credits === null && binding?.limitReached === true;\n // Credit availability is a separate interactive-use signal, never Fleet eligibility.\n if (row.engine === 'codex' && row.credits !== null) {\n if (row.creditSpendControlReached === true) return make('unavailable', 'Credits held', 'native spend control reached · balance is separate', { coversConnection: true });\n return make('low', 'Credits available', binding !== null && isSpentWindow(binding) ? 'subscription window spent · autonomous credit spending is not admitted' : 'native credit balance · separate from subscription usage', { coversConnection: c === 'exhausted' });\n }\n if (spent) {\n const when = describeResetAt(row.resetAt, now);\n const ahead = row.resetAt !== null && Date.parse(row.resetAt) > now;\n // No instant: the provider's own reset prose, verbatim, is the next best\n // thing — the prose of the spent window with no instant (the one that\n // holds the seat), never another window's earlier instant, which would\n // promise the seat back before it is.\n const heldBy = row.windows.find((w) => isSpentWindow(w) && !parseable(w.resetsAt) && w.resetText !== null) ?? null;\n const prose = heldBy?.resetText ?? (binding !== null && !parseable(binding.resetsAt) ? binding.resetText : null);\n const detail = when !== null\n ? (ahead ? `resets ${when}` : `was due to reset ${when}`)\n : (prose ?? 'reset time not reported');\n return make('spent', 'Spent', detail, {\n usableAgain: usableAgainPhrase(row.resetAt, now),\n coversConnection: c === 'exhausted',\n });\n }\n\n if (row.cls === 'blocked') return make('unavailable', 'Unavailable', row.summary);\n\n // A seat nobody has read is not \"fine\" and not \"broken\": it is waiting on a check.\n if (row.cls === 'unread') {\n if (!opts.healthRead) return make('checking', 'Checking…', null);\n if (c === null || c === 'unknown') return make('not-checked', 'Not checked', 'no reading yet');\n return make('usable', 'Connected', 'no usage reading yet');\n }\n\n const lead = c === null || c === 'unknown' ? 'Usable' : 'Connected';\n if (row.cls === 'tight') {\n const onCredits = binding !== null && isSpentWindow(binding) && row.credits !== null;\n if (lead === 'Usable') return make('low', 'Usable', onCredits ? 'on credits' : 'running low');\n return make('low', lead, onCredits ? 'usable on credits' : 'running low');\n }\n return lead === 'Usable' ? make('usable', 'Usable now', null) : make('usable', 'Connected', 'usable now');\n}\n\n/**\n * Usable accounts first, then the ones that come back on their own, then the\n * ones that need you — stable within each group (the roster's own order), and\n * paid seats ahead of local ones of the same standing. Ordered on the settled\n * status (never on a running check), so a row does not jump while \"Checking…\".\n */\n/** Where a status sorts among cards: usable first, what needs you last (the `orderAccountRows` rank). */\nexport function accountStatusRank(kind: AccountStatusKind): number {\n return STATUS_RANK[kind];\n}\n\nexport function orderAccountRows(rows: readonly CapacityRow[], opts: Omit<AccountStatusOptions, 'checking'>): CapacityRow[] {\n const ranked = rows.map((row, index) => ({\n row,\n index,\n rank: STATUS_RANK[accountStatus(row, { ...opts, checking: false }).kind],\n local: row.kind === 'local' ? 1 : 0,\n }));\n ranked.sort((a, b) => a.rank - b.rank || a.local - b.local || a.index - b.index);\n return ranked.map((r) => r.row);\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-BC5Uslm5.js";import{A as r,E as i,F as a,H as o,I as s,L as ee,N as te,P as c,S as l,U as u,W as d,_ as f,a as ne,b as re,c as p,d as m,f as h,i as ie,j as ae,k as g,n as oe,o as se,r as ce,s as le,t as ue,u as _,v as de,x as v,y as fe,z as pe}from"./ChartFrame-Dljee9y6.js";import{a as y,c as b,p as me,t as x,v as S,y as he}from"./colors-DvK0wMHH.js";import{c as ge,d as _e,f as ve,r as ye,s as be,t as xe}from"./format-D7nBg2bn.js";import"./Swimlane-CeMBD_FC.js";import"./StatTile-mYm1GPj7.js";import"./AreaTrend-LVgaB49b.js";import"./Funnel-UPrk7fcy.js";import"./StepBand-Bdkv7iGd.js";import"./MatrixHeatmap-BlFI5oao.js";var C={figure:`_figure_1si9v_1`,caption:`_caption_1si9v_12`,title:`_title_1si9v_20`,description:`_description_1si9v_26`,plot:`_plot_1si9v_31`,tableDisclosure:`_tableDisclosure_1si9v_36`,tableBody:`_tableBody_1si9v_61`,caveat:`_caveat_1si9v_65`,empty:`_empty_1si9v_75`},w=t();function T({title:e,description:t,caveat:n,children:r,table:i,empty:a,emptyMessage:o=`No data for this window.`}){return(0,w.jsxs)(`figure`,{className:C.figure,children:[(0,w.jsxs)(`figcaption`,{className:C.caption,children:[(0,w.jsx)(`span`,{className:C.title,children:e}),t?(0,w.jsx)(`span`,{className:C.description,children:t}):null]}),n?(0,w.jsx)(`p`,{className:C.caveat,role:`note`,children:n}):null,a?(0,w.jsx)(`p`,{className:C.empty,children:o}):(0,w.jsx)(`div`,{className:C.plot,children:r}),i?(0,w.jsxs)(`details`,{className:C.tableDisclosure,children:[(0,w.jsx)(`summary`,{children:`View as table`}),(0,w.jsx)(`div`,{className:C.tableBody,children:i})]}):null]})}var E={legend:`_legend_4pgvn_1`,item:`_item_4pgvn_10`,swatch:`_swatch_4pgvn_18`,swatchLine:`_swatchLine_4pgvn_25`};function Se({items:e}){return e.length<2?null:(0,w.jsx)(`ul`,{className:E.legend,children:e.map(e=>(0,w.jsxs)(`li`,{className:E.item,children:[(0,w.jsx)(`span`,{className:e.kind===`line`?E.swatchLine:E.swatch,style:{background:e.color},"aria-hidden":`true`}),e.label]},e.label))})}var D=e(n(),1),O={svg:`_svg_2zwdg_5`,gridline:`_gridline_2zwdg_12`,axis:`_axis_2zwdg_18`,axisLabel:`_axisLabel_2zwdg_24`,line:`_line_2zwdg_31`,area:`_area_2zwdg_40`,marker:`_marker_2zwdg_44`,endLabel:`_endLabel_2zwdg_49`,crosshairLine:`_crosshairLine_2zwdg_55`,overlay:`_overlay_2zwdg_62`,wrap:`_wrap_2zwdg_67`},Ce=640,we=44,Te=12,k=12,A=24,j=4,M=6.4,Ee=4,De=150,N=14;function P(e){let t=[],n=[];for(let r of e){if(r.y===null){n.length&&t.push(n),n=[];continue}n.push({x:r.x,y:r.y})}return n.length&&t.push(n),t}function F({series:e,height:t=200,area:n=!1,formatX:i,formatY:ee,formatTooltip:c,formatTooltipX:l,ariaLabel:f,width:ae}){let oe=(0,D.useRef)(null),ue=(0,D.useRef)(null),v=ie(ue,ae,Ce),b=ce(),he=ne(),ge=(0,D.useId)(),xe=(0,D.useId)(),C=fe(b),[T,E]=(0,D.useState)(null),F=c??ee??ye,I=a(e.flatMap(e=>e.points.map(e=>e.x))),L=e.map(e=>({...e,points:e.points.filter(e=>I(e.x))})),R=L.flatMap(e=>e.points.map(e=>e.x)),z=L.flatMap(e=>e.points.map(e=>e.y)).filter(e=>e!==null&&Number.isFinite(e));if(R.length===0)return(0,w.jsx)(`div`,{ref:ue,className:O.wrap,children:(0,w.jsx)(`p`,{children:`No data.`})});let B=Math.min(...R),Oe=Math.max(...R),ke=de(R),Ae=i??(ke?be:e=>String(e)),V=l??i??(ke?ve(R):Ae),[je,H]=ke&&Oe>B?h(B,Oe,se):[B,Oe],U=H-je||1,W=p(Math.min(0,...z),Math.max(0,...z),{count:j,integer:z.length>0&&le(z),format:ee}),Me=W.ticks,Ne=Me[0],Pe=Me[Me.length-1]-Ne||1,G=t-k-A,K=e=>k+G-(e-Ne)/Pe*G,q=Math.max(we,Math.ceil(Math.max(0,...W.labels.map(e=>e.length))*C)+8),J=L.length>=1&&L.length<=4,Y=J?Math.max(...L.map(e=>e.label.length))*M*b:0,Fe=L.flatMap(e=>{for(let t=e.points.length-1;t>=0;t--){let n=e.points[t].y;if(n!==null&&Number.isFinite(n))return[{key:e.id,y:K(n)}]}return[]}),Ie=J&&Y<=De?m(Fe,N*b,k,k+G):null,Le=Ie!==null&&Fe.length>0,X=Te+(Le?Ee+Y:0),Re=L.length>=2,ze=Math.max(40,v-q-X),Z=e=>q+(e-je)/U*ze,Q=Array.from(new Set(R)).sort((e,t)=>e-t),$=Q.length>1?te(Q.length,Math.max(2,Math.floor(ze/84))):[],Be=ke?_e(B,Oe,i,$.map(e=>Q[e])):[Ae],Ve=re($.map((e,t)=>{let n=Q[e],r=Z(n),i=t===0,a=t===$.length-1,o=i&&r<=q+.5?`start`:a&&r>=v-X-.5?`end`:`middle`;return{key:i?`start`:a?`end`:`t${e}`,x:r,anchor:o,priority:a?3:i?2:1,required:i||a,variants:Be.map(e=>e(n))}}),{min:q,max:v-X,charPx:C});function He(e){let t=oe.current;if(!t)return null;let n=t.getBoundingClientRect(),r=(e-n.left)/(n.width||v)*v,i=je+(r-q)/ze*U,a=Q[0],o=1/0;for(let e of Q){let t=Math.abs(e-i);t<o&&(o=t,a=e)}return a}function Ue(e){let t=He(e.clientX);t!==null&&E(t)}function We(e){if(Q.length===0)return;let t=T===null?Q.length-1:Math.max(0,Q.indexOf(T)),n=e.key===`ArrowLeft`?t-1:e.key===`ArrowRight`?t+1:e.key===`Home`?0:e.key===`End`?Q.length-1:null;n!==null&&(e.preventDefault(),E(Q[Math.max(0,Math.min(Q.length-1,n))]))}let Ge=n&&L.length<=3,Ke=T===null?null:L.map(e=>({series:e,point:e.points.find(e=>e.x===T)??null}));return(0,w.jsxs)(`div`,{ref:ue,className:`${O.wrap} ${d.focusable}`,"data-motion":he,tabIndex:0,role:`group`,"aria-label":`${f}. Use the left and right arrow keys to read values.`,"aria-describedby":xe,onFocus:()=>E(e=>e??Q[Q.length-1]??null),onBlur:()=>E(null),onKeyDown:We,children:[(0,w.jsxs)(`svg`,{ref:oe,className:O.svg,width:v,height:t,viewBox:`0 0 ${v} ${t}`,role:`img`,"aria-label":f,onPointerMove:Ue,onPointerLeave:()=>E(null),children:[Ge?(0,w.jsx)(`defs`,{children:L.map((e,n)=>(0,w.jsx)(s,{id:me(ge,e.id),color:S(n),top:k,bottom:t-A,from:L.length>1?.16:.22},e.id))}):null,Me.map((e,t)=>(0,w.jsxs)(`g`,{children:[(0,w.jsx)(`line`,{x1:q,x2:v-X,y1:_(K(e)),y2:_(K(e)),className:O.gridline,stroke:y}),(0,w.jsx)(`text`,{x:q-6,y:K(e),dy:`0.32em`,textAnchor:`end`,className:O.axisLabel,children:W.labels[t]})]},t)),(0,w.jsx)(`line`,{x1:q,x2:v-X,y1:_(t-A),y2:_(t-A),className:O.axis,stroke:x}),Ve.map(e=>(0,w.jsx)(`text`,{"data-axis-label":e.key,x:e.x,y:t-6,textAnchor:e.anchor,className:O.axisLabel,children:e.text},e.key)),L.map((e,t)=>{let n=S(t),i=P(e.points);return(0,w.jsxs)(`g`,{children:[Ge?i.map((t,n)=>{let r=t.map(e=>({x:Z(e.x),y:K(e.y)})),i=r.map(e=>({x:e.x,y:K(Math.max(Ne,0))}));return(0,w.jsx)(`path`,{"data-role":`area`,d:g(r,i),fill:`url(#${me(ge,e.id)})`,className:`${O.area} ${d.fadeIn}`},n)}):null,i.map((e,t)=>e.length===1?(0,w.jsx)(`circle`,{cx:Z(e[0].x),cy:K(e[0].y),r:3,fill:n},t):(0,w.jsx)(`path`,{"data-role":`line`,d:r(e.map(e=>({x:Z(e.x),y:K(e.y)}))),pathLength:1,stroke:n,className:`${O.line} ${d.draw}`},t)),T===null&&i.length&&i[i.length-1].length>1?(()=>{let e=i[i.length-1],t=e[e.length-1];return(0,w.jsx)(`circle`,{"data-role":`end-dot`,className:`${d.endDot} ${d.fadeIn}`,cx:Z(t.x),cy:K(t.y),r:3.5,fill:n})})():null,Le&&i.length?(()=>{let t=i[i.length-1],r=t[t.length-1];return(0,w.jsx)(`text`,{"data-end-label":e.id,x:Z(r.x)+Ee,y:Ie?.get(e.id)??K(r.y),dy:`0.32em`,className:O.endLabel,fill:n,children:e.label})})():null]},e.id)}),T===null?null:(0,w.jsx)(`line`,{"data-role":`crosshair`,x1:_(Z(T)),x2:_(Z(T)),y1:k,y2:t-A,className:O.crosshairLine}),T===null?null:L.map((e,t)=>{let n=e.points.find(e=>e.x===T);return!n||n.y===null?null:(0,w.jsx)(`circle`,{cx:Z(n.x),cy:K(n.y),r:4,fill:S(t),className:O.marker},e.id)}),(0,w.jsx)(`rect`,{x:q,y:k,width:ze,height:G,className:O.overlay})]}),(0,w.jsx)(`span`,{id:xe,className:d.srOnly,"aria-live":`polite`,children:Ke?`${V(T)}: ${Ke.map(({series:e,point:t})=>`${e.label} ${t&&t.y!==null?F(t.y):`no data`}`).join(`, `)}`:``}),Ke&&T!==null?(0,w.jsx)(pe,{left:u(Z(T),v)?Z(T):o(Z(T),v),side:u(Z(T),v),top:k,title:V(T),rows:Ke.map(({series:e,point:t},n)=>({key:e.id,label:e.label,value:t&&t.y!==null?F(t.y):null,color:S(n),kind:`line`}))}):null,Re?(0,w.jsx)(Se,{items:L.map((e,t)=>({label:e.label,color:S(t),kind:`line`}))}):null]})}var I={svg:`_svg_o4jfa_1`,bar:`_bar_o4jfa_6`,baseline:`_baseline_o4jfa_15`,gridline:`_gridline_o4jfa_20`,axisLabel:`_axisLabel_o4jfa_25`,valueLabel:`_valueLabel_o4jfa_31`,categoryLabel:`_categoryLabel_o4jfa_38`,hitArea:`_hitArea_o4jfa_44`,tooltip:`_tooltip_o4jfa_49`,tooltipValue:`_tooltipValue_o4jfa_63`,tooltipLabel:`_tooltipLabel_o4jfa_68`,wrap:`_wrap_o4jfa_73`},L=24,R=10;function z({data:e,height:t=160,orientation:n=`vertical`,color:r=b,formatValue:i=e=>String(e),ariaLabel:a,width:o}){let s=(0,D.useId)(),ee=(0,D.useRef)(null),te=ie(ee,o,588),[c,l]=(0,D.useState)(null),u=e.map(e=>e.value).filter(e=>e!==null),d=Math.max(0,...u,1e-4),f=Math.min(0,...u),ne=d-f||1;if(n===`horizontal`){let n=Math.min(L,Math.max(14,Math.floor((t-R)/e.length)-R)),o=e.length*(n+R)+R,s=te,u=Math.max(40,s-120-48);return(0,w.jsxs)(`div`,{ref:ee,className:I.wrap,children:[(0,w.jsxs)(`svg`,{className:I.svg,width:s,height:o,viewBox:`0 0 ${s} ${o}`,role:`img`,"aria-label":a,children:[(0,w.jsx)(`line`,{x1:120,y1:0,x2:120,y2:o,className:I.baseline,stroke:x}),e.map((e,t)=>{let a=R+t*(n+R),o=e.value===null?0:(e.value-f)/ne*u;return(0,w.jsxs)(`g`,{children:[(0,w.jsx)(`text`,{x:112,y:a+n/2,dy:`0.32em`,textAnchor:`end`,className:I.categoryLabel,children:e.label.length>22?`${e.label.slice(0,21)}…`:e.label}),e.value===null?(0,w.jsx)(`line`,{x1:124,y1:a+n/2,x2:134,y2:a+n/2,stroke:y,strokeWidth:2,strokeDasharray:`2 2`}):(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(`rect`,{x:120,y:a,width:Math.max(2,o),height:n,rx:4,fill:r,className:I.bar}),(0,w.jsx)(`text`,{x:120+Math.max(2,o)+6,y:a+n/2,dy:`0.32em`,className:I.valueLabel,children:i(e.value)})]}),(0,w.jsx)(`rect`,{className:I.hitArea,x:0,y:a-R/2,width:s,height:n+R,tabIndex:0,role:`img`,"aria-label":`${e.label}: ${e.value===null?`no data`:i(e.value)}`,onPointerEnter:()=>l(t),onPointerLeave:()=>l(e=>e===t?null:e),onFocus:()=>l(t),onBlur:()=>l(e=>e===t?null:e)})]},e.label+t)})]}),c===null?null:(0,w.jsxs)(`div`,{className:I.tooltip,style:{left:128,top:R+c*(n+R)-4},children:[(0,w.jsx)(`span`,{className:I.tooltipValue,children:e[c].value===null?`no data`:i(e[c].value)}),(0,w.jsx)(`span`,{className:I.tooltipLabel,children:e[c].label})]})]})}let re=e.length?Math.max(L,0):L,p=Math.min(L,re),m=t,h=m+20+30,ae=e.length*(p+R)+R,g=20+m-(0-f)/ne*m;return(0,w.jsxs)(`div`,{className:I.wrap,children:[(0,w.jsxs)(`svg`,{className:I.svg,width:ae,height:h,viewBox:`0 0 ${ae} ${h}`,role:`img`,"aria-label":a,children:[(0,w.jsx)(`line`,{x1:0,y1:g,x2:ae,y2:g,className:I.baseline,stroke:x}),e.map((e,t)=>{let n=R+t*(p+R),a=e.value===null?0:Math.abs(e.value-f)/ne*m,o=e.value!==null&&e.value>=0?g-a:g;return(0,w.jsxs)(`g`,{children:[e.value===null?(0,w.jsx)(`line`,{x1:n+p/2-5,y1:g,x2:n+p/2+5,y2:g,stroke:y,strokeWidth:2,strokeDasharray:`2 2`}):(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(`rect`,{x:n,y:o,width:p,height:Math.max(2,a),rx:4,fill:r,className:I.bar}),(0,w.jsx)(`text`,{x:n+p/2,y:o-4,textAnchor:`middle`,className:I.valueLabel,children:i(e.value)})]}),(0,w.jsx)(`text`,{x:n+p/2,y:h-8,textAnchor:`middle`,className:I.axisLabel,children:e.label.length>10?`${e.label.slice(0,9)}…`:e.label}),(0,w.jsx)(`rect`,{className:I.hitArea,x:n-R/2,y:0,width:p+R,height:h,tabIndex:0,role:`img`,"aria-label":`${e.label}: ${e.value===null?`no data`:i(e.value)}`,onPointerEnter:()=>l(t),onPointerLeave:()=>l(e=>e===t?null:e),onFocus:()=>l(t),onBlur:()=>l(e=>e===t?null:e)})]},e.label+t)})]}),c===null?null:(0,w.jsxs)(`div`,{className:I.tooltip,style:{left:R+c*(p+R),top:0},id:`${s}-tooltip`,children:[(0,w.jsx)(`span`,{className:I.tooltipValue,children:e[c].value===null?`no data`:i(e[c].value)}),(0,w.jsx)(`span`,{className:I.tooltipLabel,children:e[c].label})]})]})}var B=16,Oe=26,ke=14;function Ae(e){let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleString(`en-US`,{weekday:`short`,hour:`numeric`,minute:`2-digit`})}function V(e){let t=Math.max(0,Math.round(e/6e4));if(t<60)return`${t}m`;let n=Math.floor(t/60);return n<48?t%60?`${n}h ${t%60}m`:`${n}h`:`${Math.round(n/24)}d`}function je(e,t,n,r,i){let a=t!==null&&Number.isFinite(t)?t:null;if(e.from&&e.from.remaining<=0)return{text:a===null?`Used up — reset time unknown.`:`Used up — resets ${r(a)}.`,severity:`danger`};if(e.from&&i!==void 0&&e.reserveAt!==null&&e.reserveAt<=e.from.t){let e=a===null?`until it resets (reset time unknown)`:`until ${r(a)}`;return{text:`Inside ${i.toLowerCase()} — autonomy has stopped using this window ${e}.`,severity:`warn`}}return a===null?{text:`Reset time unknown — not projecting this window.`,severity:`unknown`}:e.slopePerMs===null?{text:`Not enough readings to project this window yet.`,severity:`unknown`}:e.exhaustAt===null?e.reserveAt===null?{text:`At this pace: about ${n(e.remainingAtReset??0)} left at reset.`,severity:`ok`}:{text:`At this pace: ${i??`reserve`} reached ${r(e.reserveAt)}, ${V(a-e.reserveAt)} before reset.`,severity:`warn`}:{text:`At this pace: runs out ${r(e.exhaustAt)}, ${V(a-e.exhaustAt)} before reset.`,severity:`danger`}}function H({title:e,description:t,caveat:n,status:a,points:te,capacity:m,start:le,resetAt:de,now:y,reserve:x,height:S=200,width:ve,formatValue:ye,formatTime:be,ariaLabel:C}){let T=ye??xe,E=be??Ae,Se=(0,D.useRef)(null),O=ie(Se,ve),Ce=ce(),we=ne(),Te=(0,D.useId)(),k=(0,D.useId)(),[A,j]=(0,D.useState)(null),M=te.filter(e=>f(e.t)).sort((e,t)=>e.t-t.t),Ee=M.some(e=>e.remaining!==null),De=a??(M.length===0?{kind:`empty`,message:`No readings in this window yet.`}:Ee?{kind:`ready`}:{kind:`unknown`}),N=f(de),P=N?de:null,F=i(M,P,{reserve:x?.value??null}),I=je(F,P,T,E,x?.label),L=M.flatMap(e=>e.remaining!==null&&Number.isFinite(e.remaining)?[e.remaining]:[]),R=p(0,Math.max(m,...L,1),{count:4,integer:Number.isInteger(m)&&L.every(e=>Number.isInteger(e)),format:ye}),z=R.ticks,V=z[z.length-1],H=c(R.labels,28,56,Ce),U=Math.max(40,O-H-ke),W=S-B-Oe,Me=M.length?M[M.length-1].t:y,Ne=P??Math.max(y,Me),Pe=f(le)?le:M[0]?.t??Ne,[G,K]=h(Pe,Ne,se,`end`),q=l(G,K,H,H+U),J=l(0,V,B+W,B),Y=e=>Math.min(K,Math.max(G,e)),Fe=_e(G,K,be??Ae,[G,K]),Ie=re([{key:`start`,x:H,anchor:`start`,priority:2,variants:Fe.map(e=>e(G))},N?{key:`reset`,x:H+U,anchor:`end`,priority:3,variants:Fe.map(e=>`Resets ${e(K)}`)}:{key:`end`,x:H+U,anchor:`end`,priority:3,variants:Fe.map(e=>e(K))}],{min:H,max:H+U,charPx:fe(Ce)}),Le=ae(M.map(e=>({x:Y(e.t),y:e.remaining}))).map(e=>e.map(e=>({x:q(e.x),y:J(Math.max(0,e.y))}))),X=e=>N&&K>G?Math.max(0,Math.min(m,m*(1-(e-G)/(K-G)))):null;function Re(e){let t=Se.current;if(!t||M.length===0)return null;let n=e-t.getBoundingClientRect().left,r=0,i=1/0;return M.forEach((e,t)=>{let a=Math.abs(q(Y(e.t))-n);a<i&&(i=a,r=t)}),r}function ze(e){if(M.length===0)return;let t=A??M.length-1,n=e.key===`ArrowLeft`?t-1:e.key===`ArrowRight`?t+1:e.key===`Home`?0:e.key===`End`?M.length-1:null;n!==null&&(e.preventDefault(),j(Math.max(0,Math.min(M.length-1,n))))}let Z=A===null?void 0:M[A],Q=Z?X(Z.t):null,$=y>G&&y<K?q(y):null,Be=$!==null&&$-H>24&&H+U-$>24,Ve=``;if(P!==null&&F.from&&F.slopePerMs!==null){let e=F.exhaustAt??P,t=F.exhaustAt===null?F.remainingAtReset??F.from.remaining:0;e>F.from.t&&(Ve=v([{x:q(Y(F.from.t)),y:J(F.from.remaining)},{x:q(Y(e)),y:J(Math.max(0,t))}]))}let He=I.severity===`danger`?he(`danger`):I.severity===`warn`?he(`warning`):`var(--text-tertiary)`,Ue=C??`${e}: ${F.from?`${T(F.from.remaining)} of ${T(m)} left at ${E(F.from.t)}`:`no readings`}; ${P===null?`reset time unknown`:`resets ${E(P)}`}. ${I.text}`,We=[{key:`t`,label:`When`,render:e=>E(e.t)},{key:`r`,label:`Remaining`,numeric:!0,render:e=>e.remaining===null?`—`:T(e.remaining)}],Ge=[{label:`Remaining`,color:b,kind:`line`},...N?[{label:`Even pace`,color:`var(--text-tertiary)`,kind:`line`}]:[],...Ve?[{label:`Projection`,color:He,kind:`line`}]:[]];return(0,w.jsx)(ue,{title:e,description:t,caveat:n,status:De,skeleton:`line`,skeletonHeight:S,table:(0,w.jsx)(oe,{caption:e,columns:We,rows:M,rowKey:e=>String(e.t)}),footer:(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(`p`,{className:d.note,"data-severity":I.severity,role:`status`,children:I.text}),(0,w.jsx)(ee,{items:Ge})]}),children:(0,w.jsxs)(`div`,{ref:Se,className:`${d.plotWrap} ${d.focusable}`,"data-motion":we,tabIndex:0,role:`group`,"aria-label":`${e}. Use the left and right arrow keys to read each reading.`,"aria-describedby":k,onFocus:()=>j(e=>e??(M.length?M.length-1:null)),onBlur:()=>j(null),onKeyDown:ze,children:[(0,w.jsxs)(`svg`,{className:d.svg,width:O,height:S,viewBox:`0 0 ${O} ${S}`,role:`img`,"aria-label":Ue,onPointerMove:e=>j(Re(e.clientX)),onPointerLeave:()=>j(null),children:[(0,w.jsx)(`defs`,{children:(0,w.jsx)(s,{id:me(Te,`remaining`),color:b,top:B,bottom:B+W})}),x&&x.value>0?(0,w.jsx)(`rect`,{"data-role":`reserve-band`,className:`${d.reserveBand} ${d.fadeIn}`,x:H,y:J(Math.min(V,x.value)),width:U,height:Math.max(0,J(0)-J(Math.min(V,x.value)))}):null,z.map((e,t)=>(0,w.jsxs)(`g`,{children:[(0,w.jsx)(`line`,{className:d.grid,x1:H,x2:H+U,y1:_(J(e)),y2:_(J(e))}),(0,w.jsx)(`text`,{className:d.tick,x:H-6,y:J(e),dy:`0.32em`,textAnchor:`end`,children:R.labels[t]})]},e)),(0,w.jsx)(`line`,{className:d.axis,x1:H,x2:H+U,y1:_(J(0)),y2:_(J(0))}),Ie.map(e=>(0,w.jsx)(`text`,{"data-axis-label":e.key,className:d.tick,x:e.x,y:S-8,textAnchor:e.anchor,children:e.text},e.key)),N?(0,w.jsx)(`path`,{"data-role":`pace`,className:d.reference,d:v([{x:q(G),y:J(m)},{x:q(K),y:J(0)}])}):null,x?(0,w.jsxs)(`g`,{"data-role":`reserve`,children:[(0,w.jsx)(`line`,{className:d.reference,x1:H,x2:H+U,y1:_(J(x.value)),y2:_(J(x.value))}),(0,w.jsxs)(`text`,{"data-role":`reserve-label`,className:`${d.tick} ${d.halo}`,x:H+4,y:J(x.value)-5,textAnchor:`start`,children:[x.label,` · `,T(x.value)]})]}):null,$===null?null:(0,w.jsxs)(`g`,{"data-role":`now`,children:[(0,w.jsx)(`line`,{className:d.now,x1:_($),x2:_($),y1:B,y2:B+W}),Be?(0,w.jsx)(`text`,{"data-role":`now-label`,className:`${d.tick} ${d.halo}`,x:$,y:12,textAnchor:`middle`,children:`Now`}):null]}),Le.map((e,t)=>(0,w.jsxs)(`g`,{"data-role":`remaining`,children:[(0,w.jsx)(`path`,{"data-role":`area`,className:`${d.area} ${d.fadeIn}`,fill:`url(#${me(Te,`remaining`)})`,d:g(e,e.map(e=>({x:e.x,y:J(0)})))}),e.length>1?(0,w.jsx)(`path`,{"data-role":`line`,className:`${d.line} ${d.draw}`,pathLength:1,stroke:b,d:r(e)}):null]},t)),Ve?(0,w.jsx)(`path`,{"data-role":`projection`,className:d.projection,stroke:He,d:Ve}):null,F.from?(0,w.jsx)(`circle`,{className:d.marker,cx:q(Y(F.from.t)),cy:J(F.from.remaining),r:4,fill:b}):null,Z?(0,w.jsxs)(`g`,{"data-role":`hover`,children:[(0,w.jsx)(`line`,{className:d.crosshair,"data-role":`crosshair`,x1:_(q(Y(Z.t))),x2:_(q(Y(Z.t))),y1:B,y2:B+W}),Z.remaining===null?null:(0,w.jsx)(`circle`,{className:d.marker,cx:q(Y(Z.t)),cy:J(Math.max(0,Z.remaining)),r:4,fill:b})]}):null]}),(0,w.jsx)(`span`,{id:k,className:d.srOnly,"aria-live":`polite`,children:Z?`${ge(Z.t)}: ${Z.remaining===null?`no reading`:`${T(Z.remaining)} remaining`}`+(Q===null?``:`; even pace ${T(Q)}`):``}),Z?(0,w.jsx)(pe,{left:u(q(Y(Z.t)),O)?q(Y(Z.t)):o(q(Y(Z.t)),O),side:u(q(Y(Z.t)),O),top:B,title:ge(Z.t),rows:[{key:`r`,label:`Remaining`,value:Z.remaining===null?null:T(Z.remaining),color:b,kind:`line`},...Q===null?[]:[{key:`p`,label:`Even pace`,value:T(Q),color:`var(--text-tertiary)`,kind:`line`}]]}):null]})})}export{T as a,Se as i,z as n,F as r,H as t};
2
+ //# sourceMappingURL=charts-DT9PYS49.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"charts-DT9PYS49.js","names":[],"sources":["../../../../../../src/web-ui/components/charts/ChartContainer.module.css","../../../../../../src/web-ui/components/charts/ChartContainer.tsx","../../../../../../src/web-ui/components/charts/Legend.module.css","../../../../../../src/web-ui/components/charts/Legend.tsx","../../../../../../src/web-ui/components/charts/LineChart.module.css","../../../../../../src/web-ui/components/charts/LineChart.tsx","../../../../../../src/web-ui/components/charts/BarChart.module.css","../../../../../../src/web-ui/components/charts/BarChart.tsx","../../../../../../src/web-ui/components/charts/BurnDown.tsx"],"sourcesContent":[".figure {\n margin: 0;\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-lg);\n background: var(--bg-surface);\n padding: var(--space-4);\n /* Fixed heights must include the axis-label band — this container instead\n grows with its content so a chart's x-axis labels never get clipped or\n forced into a nested scroll (dataviz anti-patterns). */\n}\n\n.caption {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-3);\n margin-bottom: var(--space-3);\n}\n\n.title {\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.description {\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n.plot {\n width: 100%;\n overflow-x: auto;\n}\n\n.tableDisclosure {\n margin-top: var(--space-3);\n border-top: 1px solid var(--border-subtle);\n padding-top: var(--space-2);\n}\n\n.tableDisclosure > summary {\n cursor: pointer;\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n list-style: none;\n}\n\n.tableDisclosure > summary::-webkit-details-marker {\n display: none;\n}\n\n.tableDisclosure > summary::before {\n content: '▸ ';\n}\n\n.tableDisclosure[open] > summary::before {\n content: '▾ ';\n}\n\n.tableBody {\n margin-top: var(--space-2);\n}\n\n.caveat {\n margin: 0 0 var(--space-3);\n padding: var(--space-2) var(--space-3);\n border-radius: var(--radius-md);\n background: var(--status-unknown-bg);\n color: var(--status-unknown-fg);\n font-size: var(--text-xs-size);\n line-height: var(--text-sm-line);\n}\n\n.empty {\n color: var(--text-tertiary);\n font-size: var(--text-sm-size);\n padding: var(--space-6) 0;\n text-align: center;\n}\n","/**\n * components/charts/ChartContainer.tsx — the figure every chart mounts\n * inside: title/description, the plot itself, an optional caveat banner\n * (epistemic-honesty-adjacent: for a chart built on data with a known,\n * disclosed limitation — see ProductionView's judge-verdict caveat), an\n * optional table-view twin (the WCAG-clean accessibility equivalent every\n * chart should ship per the dataviz skill), and an empty state that never\n * lies about missing data.\n */\nimport type { ReactNode } from 'react';\nimport './chart-tokens.css';\nimport styles from './ChartContainer.module.css';\n\nexport interface ChartContainerProps {\n title: string;\n description?: string;\n /** A short, honest note about a known limitation of the data behind this\n * chart (e.g. \"counts may include X, not yet separable\"). Never omit a\n * caveat to make a chart look cleaner than the data actually is. */\n caveat?: string;\n /** The chart itself (SVG + legend). */\n children: ReactNode;\n /** The accessibility twin — same data as a real HTML table. Omit only\n * when the chart already IS a table. */\n table?: ReactNode;\n /** When true, renders the empty state instead of `children`. */\n empty?: boolean;\n emptyMessage?: string;\n}\n\nexport function ChartContainer({\n title,\n description,\n caveat,\n children,\n table,\n empty,\n emptyMessage = 'No data for this window.',\n}: ChartContainerProps) {\n return (\n <figure className={styles.figure}>\n <figcaption className={styles.caption}>\n <span className={styles.title}>{title}</span>\n {description ? <span className={styles.description}>{description}</span> : null}\n </figcaption>\n {caveat ? (\n <p className={styles.caveat} role=\"note\">\n {caveat}\n </p>\n ) : null}\n {empty ? (\n <p className={styles.empty}>{emptyMessage}</p>\n ) : (\n <div className={styles.plot}>{children}</div>\n )}\n {table ? (\n <details className={styles.tableDisclosure}>\n <summary>View as table</summary>\n <div className={styles.tableBody}>{table}</div>\n </details>\n ) : null}\n </figure>\n );\n}\n",".legend {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-1) var(--space-4);\n margin: var(--space-2) 0 0;\n padding: 0;\n list-style: none;\n}\n\n.item {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n\n.swatch {\n width: 10px;\n height: 10px;\n border-radius: var(--radius-full);\n flex: none;\n}\n\n.swatchLine {\n width: 14px;\n height: 2px;\n border-radius: var(--radius-full);\n flex: none;\n}\n","/**\n * components/charts/Legend.tsx — the dependable identity channel. A legend\n * is always present for two or more series (never rely on color-matching\n * alone); a single series needs no legend box because the chart's own title\n * already names it (see marks-and-anatomy.md \"Labels & legend\").\n */\nimport styles from './Legend.module.css';\n\nexport interface LegendItem {\n label: string;\n color: string;\n /** 'line' for line charts (a short stroke key), 'swatch' for bar/area. */\n kind?: 'line' | 'swatch';\n}\n\nexport function Legend({ items }: { items: LegendItem[] }) {\n if (items.length < 2) return null;\n return (\n <ul className={styles.legend}>\n {items.map((it) => (\n <li key={it.label} className={styles.item}>\n <span\n className={it.kind === 'line' ? styles.swatchLine : styles.swatch}\n style={{ background: it.color }}\n aria-hidden=\"true\"\n />\n {it.label}\n </li>\n ))}\n </ul>\n );\n}\n","/* Drawn at its measured width and a fixed height (width/height attributes\n set by LineChart). Never `width: 100%; height: auto` — that stretches the\n viewBox, text included, with the window. `max-width` keeps a not-yet-\n measured first paint from pushing its container wider. */\n.svg {\n display: block;\n max-width: 100%;\n font-variant-numeric: tabular-nums;\n}\n\n/* Hairlines, snapped to the pixel grid by LineChart (chart-math crisp). */\n.gridline {\n stroke: var(--chart-grid);\n stroke-width: 1;\n shape-rendering: crispEdges;\n}\n\n.axis {\n stroke: var(--chart-axis);\n stroke-width: 1;\n shape-rendering: crispEdges;\n}\n\n.axisLabel {\n font-size: var(--text-xs-size);\n fill: var(--text-tertiary);\n font-family: var(--font-ui);\n font-variant-numeric: tabular-nums;\n}\n\n.line {\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n/* The wash is a gradient (ChartParts AreaGradient) — its opacity lives in\n the gradient stops, never here. */\n.area {\n stroke: none;\n}\n\n.marker {\n stroke: var(--chart-surface);\n stroke-width: 2;\n}\n\n.endLabel {\n font-size: var(--text-xs-size);\n font-family: var(--font-ui);\n font-weight: var(--font-weight-medium);\n}\n\n.crosshairLine {\n stroke: var(--chart-axis);\n stroke-width: 1;\n shape-rendering: crispEdges;\n pointer-events: none;\n}\n\n.overlay {\n fill: transparent;\n cursor: crosshair;\n}\n\n.wrap {\n position: relative;\n width: 100%;\n min-width: 0;\n}\n","/**\n * components/charts/LineChart.tsx — trend over time. A gap (`null` y) is\n * split into a separate path segment so it renders as a visible break in\n * the line, never as a straight line through a missing value and never as\n * a silent zero. Single series gets an optional soft area fill; two-plus\n * series always render a legend (never color-matching alone).\n *\n * Sizing (after 3.11.3): the chart draws at its MEASURED pixel width and a fixed\n * pixel `height` — one user unit is one CSS pixel — like the V3.10 kit\n * (useChartWidth). It used to draw into a fixed 640-unit viewBox stretched\n * with `width: 100%; height: auto`, so on a 1900 px window the whole figure,\n * text included, scaled ~2.8×: 12 px tick labels rendered at ~34 px, the\n * 200 px chart stood ~560 px tall, and the end label (\"Tokens in\") dwarfed\n * the card. Now the coordinate system scales and the text never does.\n *\n * Polish (verse-visual-quality), matching the V3.10 kit's AreaTrend:\n * - monotone curves through every reading (chart-math monotoneSegments:\n * they never overshoot, so smoothing cannot invent a peak or a dip);\n * - `area` fills a gradient of the series ink (up to three series, on one\n * shared scale), not a flat 10% wash;\n * - interior x ticks at the same density as the kit (~one per 84 px);\n * - gridlines snapped to the pixel grid (crisp 1 px), tabular numerals;\n * - the latest reading carries a ringed dot;\n * - hover crosshair + the kit's ChartTooltip with EXACT values and the\n * local day / instant; the plot is a keyboard stop too (arrow keys,\n * Home/End) and announces each reading through a live region;\n * - it draws itself in once on mount, unless reduced motion (motion.ts).\n */\nimport { useId, useRef, useState, type KeyboardEvent, type PointerEvent } from 'react';\nimport type { Series } from './types.js';\nimport { gradientId, seriesColor, CHART_GRID, CHART_AXIS } from './colors.js';\nimport { AreaGradient, ChartTooltip, clampTooltipLeft, tooltipSide } from './ChartParts.js';\nimport { Legend } from './Legend.js';\nimport {\n MIN_TIME_SPAN_MS,\n allIntegers,\n axisTicks,\n crisp,\n dodgeLabels,\n ensureSpan,\n isTimeAxis,\n labelCharPx,\n layoutAxisLabels,\n smoothAreaPath,\n smoothPath,\n thinIndexes,\n xKeeper,\n} from './chart-math.js';\nimport { formatExact, formatTimeLabel, timeLabelLadder, tooltipTimeFormatter } from './format.js';\nimport { useChartMotion } from './motion.js';\nimport { useChartWidth } from './useChartWidth.js';\nimport { useTextScale } from './useTextScale.js';\nimport './chart-tokens.css';\nimport styles from './LineChart.module.css';\nimport plot from './plot.module.css';\n\n/** Width drawn at before the container is measured (jsdom, first paint). */\nconst FALLBACK_W = 640;\n/** Minimum left gutter; it widens when the y tick labels need more (see padL). */\nconst PAD_L = 44;\nconst PAD_R = 12;\nconst PAD_T = 12;\nconst PAD_B = 24;\nconst TICKS_Y = 4;\n/* Direct end-of-line labels need a gutter of their own. User units are CSS\n pixels here (the viewBox matches the measured width), and `--text-xs-size`\n is 12 px, where the UI sans averages a shade over 6 px per character at\n medium weight. 6.4 rounds that up so the reserve errs\n wide rather than clipping. Without the reserve the label was drawn at\n `width - PAD_R + 4` with only PAD_R (12 px) of room and the svg's own\n `overflow: hidden` cropped it to its first glyph — \"Estimated spend\"\n rendered as a lone \"E\".\n Every text measure here (END_LABEL_CH, END_LABEL_GAP_Y, the axis label\n advance) is for 12 px text and is multiplied by the operator's Display\n size (useTextScale): --text-xs-size is 12px × --ui-text-scale, so at\n XLarge the same label is 15 units tall and 25% wider. END_LABEL_MAX is a\n budget of plot width, not a text measure, and stays as it is. */\nconst END_LABEL_CH = 6.4;\nconst END_LABEL_GAP = 4;\n/* Past this the gutter would cost more plot than the label is worth, so the\n label is dropped rather than shrinking the chart around it. Nothing is lost:\n Legend.tsx deliberately renders nothing below two series because the panel\n heading already names a lone series, and two-plus series always have the\n legend regardless. */\nconst END_LABEL_MAX = 150;\n/** Line height of a direct end label at 12 px (user units): two closer than this overlap. */\nconst END_LABEL_GAP_Y = 14;\n\ninterface Run {\n x: number;\n y: number;\n}\n\nfunction splitRuns(points: Series['points']): Run[][] {\n const runs: Run[][] = [];\n let current: Run[] = [];\n for (const p of points) {\n if (p.y === null) {\n if (current.length) runs.push(current);\n current = [];\n continue;\n }\n current.push({ x: p.x, y: p.y });\n }\n if (current.length) runs.push(current);\n return runs;\n}\n\nexport function LineChart({\n series: seriesProp,\n height = 200,\n area = false,\n formatX: formatXProp,\n formatY: formatYProp,\n formatTooltip: formatTooltipProp,\n formatTooltipX: formatTooltipXProp,\n ariaLabel,\n width: fixedWidth,\n}: {\n series: Series[];\n /** Plot height in px, including the x-axis band. Fixed at every width. */\n height?: number;\n /** Fixed width in px (tests, print). Omit to fill the container. */\n width?: number;\n /** A gradient wash under each line (up to three series). */\n area?: boolean;\n formatX?: (x: number) => string;\n formatY?: (y: number) => string;\n /** Tooltip value format. Default: `formatY` when given, else formatExact (\"12,934\", not \"13K\"). */\n formatTooltip?: (y: number) => string;\n /** Tooltip title format. Default: `formatX` when given, else the local day / instant on a time axis. */\n formatTooltipX?: (x: number) => string;\n ariaLabel: string;\n}) {\n const svgRef = useRef<SVGSVGElement>(null);\n const wrapRef = useRef<HTMLDivElement>(null);\n const width = useChartWidth(wrapRef, fixedWidth, FALLBACK_W);\n const textScale = useTextScale();\n const motion = useChartMotion();\n const gradKey = useId();\n const liveId = useId();\n /* Axis labels' estimated advance per character, at the size they render. */\n const axisLabelCh = labelCharPx(textScale);\n const [hoverX, setHoverX] = useState<number | null>(null);\n\n const formatTip = formatTooltipProp ?? formatYProp ?? formatExact;\n /* On a time axis a 0 / NaN / pre-2000 x is a null timestamp that leaked\n through, not a moment: it would start the axis at \"Dec 31\" 1969. Such\n points are left out of the domain AND the drawing. */\n const keepX = xKeeper(seriesProp.flatMap((s) => s.points.map((p) => p.x)));\n const series = seriesProp.map((s) => ({ ...s, points: s.points.filter((p) => keepX(p.x)) }));\n const allX = series.flatMap((s) => s.points.map((p) => p.x));\n const knownY = series.flatMap((s) => s.points.map((p) => p.y)).filter((y): y is number => y !== null && Number.isFinite(y));\n if (allX.length === 0) {\n return (\n <div ref={wrapRef} className={styles.wrap}>\n <p>No data.</p>\n </div>\n );\n }\n const rawXMin = Math.min(...allX);\n const rawXMax = Math.max(...allX);\n const timeAxis = isTimeAxis(allX);\n // An epoch-ms x printed with String() read \"1758960000000\" in the tooltip.\n const formatX = formatXProp ?? (timeAxis ? formatTimeLabel : (x: number) => String(x));\n const formatTipX = formatTooltipXProp ?? formatXProp ?? (timeAxis ? tooltipTimeFormatter(allX) : formatX);\n // A burst of points seconds apart is widened to MIN_TIME_SPAN_MS around\n // itself instead of stretched edge to edge under identical labels.\n const [xMin, xMax] = timeAxis && rawXMax > rawXMin ? ensureSpan(rawXMin, rawXMax, MIN_TIME_SPAN_MS) : [rawXMin, rawXMax];\n const xRange = xMax - xMin || 1;\n\n // Nice ticks whose labels are exact: integer data get integer ticks, and a\n // caller's formatter never prints a rounded label on a precise tick.\n const yAxis = axisTicks(Math.min(0, ...knownY), Math.max(0, ...knownY), {\n count: TICKS_Y,\n integer: knownY.length > 0 && allIntegers(knownY),\n format: formatYProp,\n });\n const yTicks = yAxis.ticks;\n const yMin = yTicks[0]!;\n const yMax = yTicks[yTicks.length - 1]!;\n const yRange = yMax - yMin || 1;\n const plotH = height - PAD_T - PAD_B;\n const yScale = (y: number) => PAD_T + plotH - ((y - yMin) / yRange) * plotH;\n /* The y labels hang right-aligned 6 units left of the plot, and the svg\n clips at its edge: the gutter grows to fit the widest one (+2 of air) —\n 44 still fits five 12 px characters, a larger Display size fewer. */\n const padL = Math.max(PAD_L, Math.ceil(Math.max(0, ...yAxis.labels.map((l) => l.length)) * axisLabelCh) + 8);\n\n /* Decided before the x scale, because the reserved gutter is what plotW is\n measured against — and the gridlines and x-axis stop at the same edge.\n End labels are dodged vertically so two lines ending on one value never\n print their names over each other; if they cannot all fit, the legend\n (always present for 2+ series) names them instead. */\n const wantEndLabels = series.length >= 1 && series.length <= 4;\n const endLabelW = wantEndLabels\n ? Math.max(...series.map((s) => s.label.length)) * END_LABEL_CH * textScale\n : 0;\n const endPoints = series.flatMap((s) => {\n for (let i = s.points.length - 1; i >= 0; i--) {\n const y = s.points[i]!.y;\n if (y !== null && Number.isFinite(y)) return [{ key: s.id, y: yScale(y) }];\n }\n return [];\n });\n const dodged = wantEndLabels && endLabelW <= END_LABEL_MAX ? dodgeLabels(endPoints, END_LABEL_GAP_Y * textScale, PAD_T, PAD_T + plotH) : null;\n const showEndLabels = dodged !== null && endPoints.length > 0;\n const padR = PAD_R + (showEndLabels ? END_LABEL_GAP + endLabelW : 0);\n const showLegend = series.length >= 2;\n\n const plotW = Math.max(40, width - padL - padR);\n const xScale = (x: number) => padL + ((x - xMin) / xRange) * plotW;\n\n // Nearest-x lookup across a reference axis (the union of all distinct x\n // values, since series may not share every point).\n const xAxis = Array.from(new Set(allX)).sort((a, b) => a - b);\n\n /* X labels, collision-free, at the kit's density (about one per 84 px —\n the same as AreaTrend, so sibling cards read alike): the end outranks\n the start and both outrank the interior ticks, which are simply dropped\n when they collide. On a time axis every label walks one detail ladder\n (the caller's format → a shorter date/time; clock time only inside one\n day) until the ends fit. */\n const tickIdx = xAxis.length > 1 ? thinIndexes(xAxis.length, Math.max(2, Math.floor(plotW / 84))) : [];\n const ladder = timeAxis ? timeLabelLadder(rawXMin, rawXMax, formatXProp, tickIdx.map((i) => xAxis[i]!)) : [formatX];\n const xLabels = layoutAxisLabels(\n tickIdx.map((idx, n) => {\n const x = xAxis[idx]!;\n const px = xScale(x);\n const isFirst = n === 0;\n const isLast = n === tickIdx.length - 1;\n const anchor = isFirst && px <= padL + 0.5 ? 'start' as const : isLast && px >= width - padR - 0.5 ? 'end' as const : 'middle' as const;\n return {\n key: isFirst ? 'start' : isLast ? 'end' : `t${idx}`,\n x: px,\n anchor,\n priority: isLast ? 3 : isFirst ? 2 : 1,\n required: isFirst || isLast,\n variants: ladder.map((f) => f(x)),\n };\n }),\n { min: padL, max: width - padR, charPx: axisLabelCh },\n );\n\n function nearestX(clientX: number): number | null {\n const svg = svgRef.current;\n if (!svg) return null;\n const rect = svg.getBoundingClientRect();\n // rect.width equals `width` once measured; the ratio only matters while the\n // fallback width is still being drawn (or a CSS max-width squeezes it).\n const svgX = ((clientX - rect.left) / (rect.width || width)) * width;\n const dataX = xMin + ((svgX - padL) / plotW) * xRange;\n let nearest = xAxis[0];\n let best = Infinity;\n for (const x of xAxis) {\n const d = Math.abs(x - dataX);\n if (d < best) {\n best = d;\n nearest = x;\n }\n }\n return nearest;\n }\n\n function handleMove(e: PointerEvent<SVGSVGElement>) {\n const x = nearestX(e.clientX);\n if (x === null) return;\n setHoverX(x);\n }\n\n function onKey(e: KeyboardEvent<HTMLDivElement>): void {\n if (xAxis.length === 0) return;\n const cur = hoverX === null ? xAxis.length - 1 : Math.max(0, xAxis.indexOf(hoverX));\n const next = e.key === 'ArrowLeft' ? cur - 1 : e.key === 'ArrowRight' ? cur + 1 : e.key === 'Home' ? 0 : e.key === 'End' ? xAxis.length - 1 : null;\n if (next === null) return;\n e.preventDefault();\n setHoverX(xAxis[Math.max(0, Math.min(xAxis.length - 1, next))]!);\n }\n\n const areaOn = area && series.length <= 3;\n\n const hoverPoints =\n hoverX !== null\n ? series.map((s) => ({\n series: s,\n point: s.points.find((p) => p.x === hoverX) ?? null,\n }))\n : null;\n\n return (\n <div\n ref={wrapRef}\n className={`${styles.wrap} ${plot.focusable}`}\n data-motion={motion}\n tabIndex={0}\n role=\"group\"\n aria-label={`${ariaLabel}. Use the left and right arrow keys to read values.`}\n aria-describedby={liveId}\n onFocus={() => setHoverX((h) => h ?? xAxis[xAxis.length - 1] ?? null)}\n onBlur={() => setHoverX(null)}\n onKeyDown={onKey}\n >\n <svg\n ref={svgRef}\n className={styles.svg}\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n role=\"img\"\n aria-label={ariaLabel}\n onPointerMove={handleMove}\n onPointerLeave={() => setHoverX(null)}\n >\n {areaOn ? (\n <defs>\n {series.map((s, si) => (\n <AreaGradient key={s.id} id={gradientId(gradKey, s.id)} color={seriesColor(si)} top={PAD_T} bottom={height - PAD_B} from={series.length > 1 ? 0.16 : 0.22} />\n ))}\n </defs>\n ) : null}\n {yTicks.map((t, i) => (\n <g key={i}>\n <line\n x1={padL}\n x2={width - padR}\n y1={crisp(yScale(t))}\n y2={crisp(yScale(t))}\n className={styles.gridline}\n stroke={CHART_GRID}\n />\n <text x={padL - 6} y={yScale(t)} dy=\"0.32em\" textAnchor=\"end\" className={styles.axisLabel}>\n {yAxis.labels[i]}\n </text>\n </g>\n ))}\n <line\n x1={padL}\n x2={width - padR}\n y1={crisp(height - PAD_B)}\n y2={crisp(height - PAD_B)}\n className={styles.axis}\n stroke={CHART_AXIS}\n />\n {xLabels.map((l) => (\n <text key={l.key} data-axis-label={l.key} x={l.x} y={height - 6} textAnchor={l.anchor} className={styles.axisLabel}>\n {l.text}\n </text>\n ))}\n\n {series.map((s, si) => {\n const color = seriesColor(si);\n const runs = splitRuns(s.points);\n return (\n <g key={s.id}>\n {areaOn\n ? runs.map((run, ri) => {\n const top = run.map((p) => ({ x: xScale(p.x), y: yScale(p.y) }));\n const base = top.map((p) => ({ x: p.x, y: yScale(Math.max(yMin, 0)) }));\n return (\n <path\n key={ri}\n data-role=\"area\"\n d={smoothAreaPath(top, base)}\n fill={`url(#${gradientId(gradKey, s.id)})`}\n className={`${styles.area} ${plot.fadeIn}`}\n />\n );\n })\n : null}\n {runs.map((run, ri) =>\n run.length === 1 ? (\n <circle key={ri} cx={xScale(run[0].x)} cy={yScale(run[0].y)} r={3} fill={color} />\n ) : (\n <path\n key={ri}\n data-role=\"line\"\n d={smoothPath(run.map((p) => ({ x: xScale(p.x), y: yScale(p.y) })))}\n pathLength={1}\n stroke={color}\n className={`${styles.line} ${plot.draw}`}\n />\n ),\n )}\n {hoverX === null && runs.length && runs[runs.length - 1].length > 1 ? (() => {\n // The latest reading, ringed — the \"you are here\" of a trend.\n const lastRun = runs[runs.length - 1];\n const last = lastRun[lastRun.length - 1];\n return <circle data-role=\"end-dot\" className={`${plot.endDot} ${plot.fadeIn}`} cx={xScale(last.x)} cy={yScale(last.y)} r={3.5} fill={color} />;\n })() : null}\n {showEndLabels && runs.length ? (\n (() => {\n const lastRun = runs[runs.length - 1];\n const last = lastRun[lastRun.length - 1];\n return (\n <text\n data-end-label={s.id}\n x={xScale(last.x) + END_LABEL_GAP}\n y={dodged?.get(s.id) ?? yScale(last.y)}\n dy=\"0.32em\"\n className={styles.endLabel}\n fill={color}\n >\n {s.label}\n </text>\n );\n })()\n ) : null}\n </g>\n );\n })}\n\n {hoverX !== null ? (\n <line\n data-role=\"crosshair\"\n x1={crisp(xScale(hoverX))}\n x2={crisp(xScale(hoverX))}\n y1={PAD_T}\n y2={height - PAD_B}\n className={styles.crosshairLine}\n />\n ) : null}\n {hoverX !== null\n ? series.map((s, si) => {\n const p = s.points.find((pt) => pt.x === hoverX);\n if (!p || p.y === null) return null;\n return (\n <circle\n key={s.id}\n cx={xScale(p.x)}\n cy={yScale(p.y)}\n r={4}\n fill={seriesColor(si)}\n className={styles.marker}\n />\n );\n })\n : null}\n\n <rect\n x={padL}\n y={PAD_T}\n width={plotW}\n height={plotH}\n className={styles.overlay}\n />\n </svg>\n <span id={liveId} className={plot.srOnly} aria-live=\"polite\">\n {hoverPoints\n ? `${formatTipX(hoverX as number)}: ${hoverPoints.map(({ series: s, point }) => `${s.label} ${point && point.y !== null ? formatTip(point.y) : 'no data'}`).join(', ')}`\n : ''}\n </span>\n {hoverPoints && hoverX !== null ? (\n <ChartTooltip\n left={tooltipSide(xScale(hoverX), width) ? xScale(hoverX) : clampTooltipLeft(xScale(hoverX), width)}\n side={tooltipSide(xScale(hoverX), width)}\n top={PAD_T}\n title={formatTipX(hoverX)}\n rows={hoverPoints.map(({ series: s, point }, i) => ({\n key: s.id,\n label: s.label,\n value: point && point.y !== null ? formatTip(point.y) : null,\n color: seriesColor(i),\n kind: 'line' as const,\n }))}\n />\n ) : null}\n {showLegend ? (\n <Legend items={series.map((s, i) => ({ label: s.label, color: seriesColor(i), kind: 'line' }))} />\n ) : null}\n </div>\n );\n}\n",".svg {\n display: block;\n overflow: visible;\n}\n\n.bar {\n transition: opacity var(--duration-fast) var(--ease-standard);\n}\n\n.bar:hover,\n.bar:focus-visible {\n opacity: 0.82;\n}\n\n.baseline {\n stroke: var(--chart-axis);\n stroke-width: 1;\n}\n\n.gridline {\n stroke: var(--chart-grid);\n stroke-width: 1;\n}\n\n.axisLabel {\n font-size: 10px;\n fill: var(--text-tertiary);\n font-family: var(--font-ui);\n}\n\n.valueLabel {\n font-size: 10px;\n fill: var(--text-secondary);\n font-family: var(--font-ui);\n font-variant-numeric: tabular-nums;\n}\n\n.categoryLabel {\n font-size: 10px;\n fill: var(--text-secondary);\n font-family: var(--font-ui);\n}\n\n.hitArea {\n fill: transparent;\n cursor: pointer;\n}\n\n.tooltip {\n position: absolute;\n pointer-events: none;\n background: var(--chart-tooltip-bg);\n border: 1px solid var(--chart-tooltip-border);\n border-radius: var(--radius-sm);\n box-shadow: var(--shadow-md);\n padding: var(--space-1) var(--space-2);\n font-size: var(--text-xs-size);\n color: var(--text-primary);\n white-space: nowrap;\n z-index: var(--z-dropdown);\n}\n\n.tooltipValue {\n font-weight: var(--font-weight-semibold);\n font-variant-numeric: tabular-nums;\n}\n\n.tooltipLabel {\n color: var(--text-tertiary);\n margin-left: var(--space-1);\n}\n\n.wrap {\n position: relative;\n}\n","/**\n * components/charts/BarChart.tsx — categorical magnitude comparison.\n * Single hue by default (nominal categories never get a value-ramp — see\n * dataviz anti-patterns \"a value-ramp on nominal categories\"). Vertical for\n * a handful of short-named categories, horizontal for many or long-named\n * ones (dataviz choosing-a-form.md). Null values render as an explicit\n * \"no data\" dash, never a silent zero-height bar indistinguishable from a\n * real zero.\n */\nimport { useId, useRef, useState } from 'react';\nimport type { CategoricalDatum } from './types.js';\nimport { CHART_SEQUENTIAL, CHART_AXIS, CHART_GRID } from './colors.js';\nimport { useChartWidth } from './useChartWidth.js';\nimport './chart-tokens.css';\nimport styles from './BarChart.module.css';\n\nconst BAR_MAX = 24;\nconst GAP = 10;\n\nexport function BarChart({\n data,\n height = 160,\n orientation = 'vertical',\n color = CHART_SEQUENTIAL,\n formatValue = (v: number) => String(v),\n ariaLabel,\n width: fixedWidth,\n}: {\n data: CategoricalDatum[];\n height?: number;\n orientation?: 'vertical' | 'horizontal';\n /** Horizontal only: fixed width in px (tests, print). Omit to fill the container. */\n width?: number;\n color?: string;\n formatValue?: (v: number) => string;\n ariaLabel: string;\n}) {\n const uid = useId();\n const wrapRef = useRef<HTMLDivElement>(null);\n // Horizontal bars take the container's measured width (fallback: the old\n // fixed 588 px). A fixed-width svg under the global `svg { max-width: 100% }`\n // was scaled DOWN in a narrower card, shrinking its 10 px labels with it.\n const measuredW = useChartWidth(wrapRef, fixedWidth, 588);\n const [hover, setHover] = useState<number | null>(null);\n\n const known = data.map((d) => d.value).filter((v): v is number => v !== null);\n const maxVal = Math.max(0, ...known, 0.0001);\n const minVal = Math.min(0, ...known);\n const range = maxVal - minVal || 1;\n\n if (orientation === 'horizontal') {\n const LABEL_W = 120;\n const PAD_R = 48;\n const rowH = Math.min(BAR_MAX, Math.max(14, Math.floor((height - GAP) / data.length) - GAP));\n const svgH = data.length * (rowH + GAP) + GAP;\n const svgW = measuredW;\n const plotW = Math.max(40, svgW - LABEL_W - PAD_R);\n\n return (\n <div ref={wrapRef} className={styles.wrap}>\n <svg\n className={styles.svg}\n width={svgW}\n height={svgH}\n viewBox={`0 0 ${svgW} ${svgH}`}\n role=\"img\"\n aria-label={ariaLabel}\n >\n <line x1={LABEL_W} y1={0} x2={LABEL_W} y2={svgH} className={styles.baseline} stroke={CHART_AXIS} />\n {data.map((d, i) => {\n const y = GAP + i * (rowH + GAP);\n const barW = d.value !== null ? ((d.value - minVal) / range) * plotW : 0;\n return (\n <g key={d.label + i}>\n <text\n x={LABEL_W - 8}\n y={y + rowH / 2}\n dy=\"0.32em\"\n textAnchor=\"end\"\n className={styles.categoryLabel}\n >\n {d.label.length > 22 ? `${d.label.slice(0, 21)}…` : d.label}\n </text>\n {d.value === null ? (\n <line\n x1={LABEL_W + 4}\n y1={y + rowH / 2}\n x2={LABEL_W + 14}\n y2={y + rowH / 2}\n stroke={CHART_GRID}\n strokeWidth={2}\n strokeDasharray=\"2 2\"\n />\n ) : (\n <>\n <rect\n x={LABEL_W}\n y={y}\n width={Math.max(2, barW)}\n height={rowH}\n rx={4}\n fill={color}\n className={styles.bar}\n />\n <text\n x={LABEL_W + Math.max(2, barW) + 6}\n y={y + rowH / 2}\n dy=\"0.32em\"\n className={styles.valueLabel}\n >\n {formatValue(d.value)}\n </text>\n </>\n )}\n <rect\n className={styles.hitArea}\n x={0}\n y={y - GAP / 2}\n width={svgW}\n height={rowH + GAP}\n tabIndex={0}\n role=\"img\"\n aria-label={`${d.label}: ${d.value === null ? 'no data' : formatValue(d.value)}`}\n onPointerEnter={() => setHover(i)}\n onPointerLeave={() => setHover((h) => (h === i ? null : h))}\n onFocus={() => setHover(i)}\n onBlur={() => setHover((h) => (h === i ? null : h))}\n />\n </g>\n );\n })}\n </svg>\n {hover !== null ? (\n <div\n className={styles.tooltip}\n style={{ left: LABEL_W + 8, top: GAP + hover * (rowH + GAP) - 4 }}\n >\n <span className={styles.tooltipValue}>\n {data[hover].value === null ? 'no data' : formatValue(data[hover].value as number)}\n </span>\n <span className={styles.tooltipLabel}>{data[hover].label}</span>\n </div>\n ) : null}\n </div>\n );\n }\n\n // Vertical orientation.\n const barSlot = data.length ? Math.max(BAR_MAX, 0) : BAR_MAX;\n const barW = Math.min(BAR_MAX, barSlot);\n const PAD_T = 20;\n const PAD_B = 30;\n const plotH = height;\n const svgH = plotH + PAD_T + PAD_B;\n const svgW = data.length * (barW + GAP) + GAP;\n const zeroY = PAD_T + plotH - ((0 - minVal) / range) * plotH;\n\n return (\n <div className={styles.wrap}>\n <svg\n className={styles.svg}\n width={svgW}\n height={svgH}\n viewBox={`0 0 ${svgW} ${svgH}`}\n role=\"img\"\n aria-label={ariaLabel}\n >\n <line x1={0} y1={zeroY} x2={svgW} y2={zeroY} className={styles.baseline} stroke={CHART_AXIS} />\n {data.map((d, i) => {\n const x = GAP + i * (barW + GAP);\n const barH = d.value !== null ? (Math.abs(d.value - minVal) / range) * plotH : 0;\n const top = d.value !== null && d.value >= 0 ? zeroY - barH : zeroY;\n return (\n <g key={d.label + i}>\n {d.value === null ? (\n <line\n x1={x + barW / 2 - 5}\n y1={zeroY}\n x2={x + barW / 2 + 5}\n y2={zeroY}\n stroke={CHART_GRID}\n strokeWidth={2}\n strokeDasharray=\"2 2\"\n />\n ) : (\n <>\n <rect\n x={x}\n y={top}\n width={barW}\n height={Math.max(2, barH)}\n rx={4}\n fill={color}\n className={styles.bar}\n />\n <text x={x + barW / 2} y={top - 4} textAnchor=\"middle\" className={styles.valueLabel}>\n {formatValue(d.value)}\n </text>\n </>\n )}\n <text\n x={x + barW / 2}\n y={svgH - 8}\n textAnchor=\"middle\"\n className={styles.axisLabel}\n >\n {d.label.length > 10 ? `${d.label.slice(0, 9)}…` : d.label}\n </text>\n <rect\n className={styles.hitArea}\n x={x - GAP / 2}\n y={0}\n width={barW + GAP}\n height={svgH}\n tabIndex={0}\n role=\"img\"\n aria-label={`${d.label}: ${d.value === null ? 'no data' : formatValue(d.value)}`}\n onPointerEnter={() => setHover(i)}\n onPointerLeave={() => setHover((h) => (h === i ? null : h))}\n onFocus={() => setHover(i)}\n onBlur={() => setHover((h) => (h === i ? null : h))}\n />\n </g>\n );\n })}\n </svg>\n {hover !== null ? (\n <div\n className={styles.tooltip}\n style={{ left: GAP + hover * (barW + GAP), top: 0 }}\n id={`${uid}-tooltip`}\n >\n <span className={styles.tooltipValue}>\n {data[hover].value === null ? 'no data' : formatValue(data[hover].value as number)}\n </span>\n <span className={styles.tooltipLabel}>{data[hover].label}</span>\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * components/charts/BurnDown.tsx — a quota window burning down to its reset:\n * remaining capacity over time (solid line + wash), the even-pace reference\n * from full at window start to empty at reset (thin dashed), a projection\n * from the recent slope (dashed), an optional reserve line (the headroom kept\n * for interactive use) and the reset marker.\n *\n * The verdict is written in words under the plot — \"At this pace: reserve\n * reached 14:20, 3h 40m before reset\" — so the chart's point never depends on\n * reading slopes. With fewer than two readings it says it cannot project,\n * rather than drawing a guess — and with no plausible reset (0 / NaN /\n * pre-2000) it draws neither pace nor projection and says the reset is\n * unknown, rather than projecting to an invented one.\n *\n * Polish (verse-visual-quality): the reserve is a BAND from empty up to the\n * reserve line (the region autonomy stays out of), the remaining line is a\n * monotone curve over a gradient wash, \"now\" is a labelled dashed rule, and\n * the plot is hoverable and a keyboard stop — the crosshair snaps to each\n * reading and the tooltip gives its local time, the exact remaining and,\n * with a known reset, where even pace would have it.\n */\nimport { useId, useRef, useState, type KeyboardEvent, type PointerEvent } from 'react';\nimport { CHART_SEQUENTIAL, gradientId, toneColor } from './colors.js';\nimport { ChartFrame, type ChartStatus } from './ChartFrame.js';\nimport { AreaGradient, ChartLegend, ChartTooltip, clampTooltipLeft, tooltipSide } from './ChartParts.js';\nimport { TableView, type TableColumn } from './TableView.js';\nimport {\n MIN_TIME_SPAN_MS,\n axisTicks,\n crisp,\n ensureSpan,\n isPlausibleTime,\n labelCharPx,\n layoutAxisLabels,\n linePath,\n linearScale,\n projectBurnDown,\n smoothAreaPath,\n smoothPath,\n splitRuns,\n tickGutter,\n type BurnPoint,\n} from './chart-math.js';\nimport { formatCompact, formatTooltipInstant, timeLabelLadder } from './format.js';\nimport { useChartMotion } from './motion.js';\nimport { useChartWidth } from './useChartWidth.js';\nimport { useTextScale } from './useTextScale.js';\nimport plot from './plot.module.css';\n\nexport interface BurnDownProps {\n title: string;\n description?: string;\n caveat?: string;\n status?: ChartStatus;\n points: BurnPoint[];\n /** Full capacity of the window (e.g. 100 for percent). */\n capacity: number;\n /** Window start and reset, epoch ms. */\n start: number;\n resetAt: number;\n now: number;\n /** Capacity to keep in reserve (same units as `remaining`). */\n reserve?: { value: number; label: string };\n height?: number;\n width?: number;\n formatValue?: (v: number) => string;\n formatTime?: (ms: number) => string;\n ariaLabel?: string;\n}\n\nconst PAD_T = 16;\nconst PAD_B = 26;\nconst PAD_R = 14;\n\nfunction defaultFormatTime(ms: number): string {\n const d = new Date(ms);\n return Number.isNaN(d.getTime()) ? '' : d.toLocaleString('en-US', { weekday: 'short', hour: 'numeric', minute: '2-digit' });\n}\n\nexport function formatLead(ms: number): string {\n const m = Math.max(0, Math.round(ms / 60_000));\n if (m < 60) return `${m}m`;\n const h = Math.floor(m / 60);\n if (h < 48) return m % 60 ? `${h}h ${m % 60}m` : `${h}h`;\n return `${Math.round(h / 24)}d`;\n}\n\n/**\n * The verdict in words. `resetAt` null (or non-finite) is an UNKNOWN reset:\n * what the window has already crossed is still said, but nothing is\n * projected — \"about 40% left at reset\" needs a reset (V3.10.1 review: an\n * epoch-0 reset printed a green verdict for a seat burning 10%/h, and a NaN\n * one printed \"about NaN% left at reset\").\n */\nexport function burnVerdict(\n projection: ReturnType<typeof projectBurnDown>,\n resetAt: number | null,\n formatValue: (v: number) => string,\n formatTime: (ms: number) => string,\n reserveLabel?: string,\n): { text: string; severity: 'ok' | 'warn' | 'danger' | 'unknown' } {\n const reset = resetAt !== null && Number.isFinite(resetAt) ? resetAt : null;\n // Already past a line: say where it IS, not a \"projection\" to a moment\n // that has passed (a used-up seat is not \"running out at 3:02\").\n if (projection.from && projection.from.remaining <= 0) {\n return { text: reset === null ? 'Used up — reset time unknown.' : `Used up — resets ${formatTime(reset)}.`, severity: 'danger' };\n }\n if (projection.from && reserveLabel !== undefined && projection.reserveAt !== null && projection.reserveAt <= projection.from.t) {\n const until = reset === null ? 'until it resets (reset time unknown)' : `until ${formatTime(reset)}`;\n return { text: `Inside ${reserveLabel.toLowerCase()} — autonomy has stopped using this window ${until}.`, severity: 'warn' };\n }\n if (reset === null) return { text: 'Reset time unknown — not projecting this window.', severity: 'unknown' };\n if (projection.slopePerMs === null) return { text: 'Not enough readings to project this window yet.', severity: 'unknown' };\n if (projection.exhaustAt !== null) {\n return {\n text: `At this pace: runs out ${formatTime(projection.exhaustAt)}, ${formatLead(reset - projection.exhaustAt)} before reset.`,\n severity: 'danger',\n };\n }\n if (projection.reserveAt !== null) {\n return {\n text: `At this pace: ${reserveLabel ?? 'reserve'} reached ${formatTime(projection.reserveAt)}, ${formatLead(reset - projection.reserveAt)} before reset.`,\n severity: 'warn',\n };\n }\n return {\n text: `At this pace: about ${formatValue(projection.remainingAtReset ?? 0)} left at reset.`,\n severity: 'ok',\n };\n}\n\nexport function BurnDown({\n title,\n description,\n caveat,\n status,\n points,\n capacity,\n start,\n resetAt,\n now,\n reserve,\n height = 200,\n width: fixedWidth,\n formatValue: formatValueProp,\n formatTime: formatTimeProp,\n ariaLabel,\n}: BurnDownProps) {\n const formatValue = formatValueProp ?? formatCompact;\n const formatTime = formatTimeProp ?? defaultFormatTime;\n const wrapRef = useRef<HTMLDivElement>(null);\n const width = useChartWidth(wrapRef, fixedWidth);\n const textScale = useTextScale();\n const motion = useChartMotion();\n const gradKey = useId();\n const liveId = useId();\n const [active, setActive] = useState<number | null>(null);\n // A reading stamped 0 / NaN / pre-2000 is a null timestamp that leaked\n // through: it is not on this window's time axis, and it would drag both\n // the axis and the projection's slope back to 1970.\n const sorted = points.filter((p) => isPlausibleTime(p.t)).sort((a, b) => a.t - b.t);\n const anyKnown = sorted.some((p) => p.remaining !== null);\n const resolvedStatus: ChartStatus = status ?? (sorted.length === 0 ? { kind: 'empty', message: 'No readings in this window yet.' } : anyKnown ? { kind: 'ready' } : { kind: 'unknown' });\n\n // A reset of 0 / NaN / pre-2000 is a null that leaked through (an epoch-0\n // machine reset parses as a finite 0). It is UNKNOWN, not a moment: the\n // axis ends at the latest reading or now with no \"Resets\" on it, no even\n // pace or projection is drawn toward it, and the verdict says the reset is\n // unknown instead of inventing one (V3.10.1 review).\n const resetKnown = isPlausibleTime(resetAt);\n const reset = resetKnown ? resetAt : null;\n const projection = projectBurnDown(sorted, reset, { reserve: reserve?.value ?? null });\n const verdict = burnVerdict(projection, reset, formatValue, formatTime, reserve?.label);\n\n // Always 0 → capacity (100 for percent seats), so sibling cards share one\n // scale; widened only if a reading overshoots, never clipped.\n const known = sorted.flatMap((p) => (p.remaining !== null && Number.isFinite(p.remaining) ? [p.remaining] : []));\n const yAxis = axisTicks(0, Math.max(capacity, ...known, 1), {\n count: 4,\n integer: Number.isInteger(capacity) && known.every((v) => Number.isInteger(v)),\n format: formatValueProp,\n });\n const ticks = yAxis.ticks;\n const top = ticks[ticks.length - 1]!;\n const padL = tickGutter(yAxis.labels, 28, 56, textScale);\n const plotW = Math.max(40, width - padL - PAD_R);\n const plotH = height - PAD_T - PAD_B;\n // The window runs start → reset. An implausible bound (0 / NaN) falls back\n // to the readings; a degenerate one widens to MIN_TIME_SPAN_MS, keeping the\n // right edge where it is.\n const lastT = sorted.length ? sorted[sorted.length - 1]!.t : now;\n const rawEnd = reset ?? Math.max(now, lastT);\n const rawStart = isPlausibleTime(start) ? start : sorted[0]?.t ?? rawEnd;\n const [x0, xEnd] = ensureSpan(rawStart, rawEnd, MIN_TIME_SPAN_MS, 'end');\n const xs = linearScale(x0, xEnd, padL, padL + plotW);\n const ys = linearScale(0, top, PAD_T + plotH, PAD_T);\n const clampX = (t: number) => Math.min(xEnd, Math.max(x0, t));\n\n // x labels: the reset marker outranks the window start. Both walk the same\n // detail ladder (the caller's format → \"Fri 11:46 PM\" → \"Sep 18\"; clock\n // time only inside one day) until they fit side by side; if even the\n // shortest pair collides, the start is dropped rather than overprinted.\n // Widths are budgeted at the operator's Display size. With no known reset\n // the right edge is only the latest reading / now, and says just its time.\n const ladder = timeLabelLadder(x0, xEnd, formatTimeProp ?? defaultFormatTime, [x0, xEnd]);\n const xLabels = layoutAxisLabels(\n [\n { key: 'start', x: padL, anchor: 'start', priority: 2, variants: ladder.map((f) => f(x0)) },\n resetKnown\n ? { key: 'reset', x: padL + plotW, anchor: 'end', priority: 3, variants: ladder.map((f) => `Resets ${f(xEnd)}`) }\n : { key: 'end', x: padL + plotW, anchor: 'end', priority: 3, variants: ladder.map((f) => f(xEnd)) },\n ],\n { min: padL, max: padL + plotW, charPx: labelCharPx(textScale) },\n );\n\n const runs = splitRuns(sorted.map((p) => ({ x: clampX(p.t), y: p.remaining })))\n .map((run) => run.map((p) => ({ x: xs(p.x), y: ys(Math.max(0, p.y)) })));\n\n // Where even pace would have the window at `t`: full at the start, empty\n // at the reset — the same straight reference the dashed line draws.\n const paceAt = (t: number): number | null =>\n resetKnown && xEnd > x0 ? Math.max(0, Math.min(capacity, capacity * (1 - (t - x0) / (xEnd - x0)))) : null;\n\n function indexAt(clientX: number): number | null {\n const el = wrapRef.current;\n if (!el || sorted.length === 0) return null;\n const px = clientX - el.getBoundingClientRect().left;\n let best = 0;\n let bestD = Infinity;\n sorted.forEach((p, i) => {\n const d = Math.abs(xs(clampX(p.t)) - px);\n if (d < bestD) {\n bestD = d;\n best = i;\n }\n });\n return best;\n }\n\n function onKey(e: KeyboardEvent<HTMLDivElement>): void {\n if (sorted.length === 0) return;\n const cur = active ?? sorted.length - 1;\n const next = e.key === 'ArrowLeft' ? cur - 1 : e.key === 'ArrowRight' ? cur + 1 : e.key === 'Home' ? 0 : e.key === 'End' ? sorted.length - 1 : null;\n if (next === null) return;\n e.preventDefault();\n setActive(Math.max(0, Math.min(sorted.length - 1, next)));\n }\n\n const activePoint = active !== null ? sorted[active] : undefined;\n const activePace = activePoint ? paceAt(activePoint.t) : null;\n const nowX = now > x0 && now < xEnd ? xs(now) : null;\n // \"Now\" is labelled only where it cannot collide with the plot's edges.\n const nowLabel = nowX !== null && nowX - padL > 24 && padL + plotW - nowX > 24;\n\n let projectionPath = '';\n if (reset !== null && projection.from && projection.slopePerMs !== null) {\n const endT = projection.exhaustAt ?? reset;\n const endR = projection.exhaustAt !== null ? 0 : projection.remainingAtReset ?? projection.from.remaining;\n if (endT > projection.from.t) {\n projectionPath = linePath([\n { x: xs(clampX(projection.from.t)), y: ys(projection.from.remaining) },\n { x: xs(clampX(endT)), y: ys(Math.max(0, endR)) },\n ]);\n }\n }\n const projectionColor = verdict.severity === 'danger' ? toneColor('danger') : verdict.severity === 'warn' ? toneColor('warning') : 'var(--text-tertiary)';\n\n const summary = ariaLabel ?? `${title}: ${projection.from ? `${formatValue(projection.from.remaining)} of ${formatValue(capacity)} left at ${formatTime(projection.from.t)}` : 'no readings'}; ${reset === null ? 'reset time unknown' : `resets ${formatTime(reset)}`}. ${verdict.text}`;\n\n const columns: TableColumn<BurnPoint>[] = [\n { key: 't', label: 'When', render: (p) => formatTime(p.t) },\n { key: 'r', label: 'Remaining', numeric: true, render: (p) => (p.remaining === null ? '—' : formatValue(p.remaining)) },\n ];\n\n const legendItems = [\n { label: 'Remaining', color: CHART_SEQUENTIAL, kind: 'line' as const },\n // Even pace runs from full at the window's start to empty AT RESET: with\n // no reset there is no pace to draw.\n ...(resetKnown ? [{ label: 'Even pace', color: 'var(--text-tertiary)', kind: 'line' as const }] : []),\n ...(projectionPath ? [{ label: 'Projection', color: projectionColor, kind: 'line' as const }] : []),\n ];\n\n return (\n <ChartFrame\n title={title}\n description={description}\n caveat={caveat}\n status={resolvedStatus}\n skeleton=\"line\"\n skeletonHeight={height}\n table={<TableView caption={title} columns={columns} rows={sorted} rowKey={(p) => String(p.t)} />}\n footer={\n <>\n <p className={plot.note} data-severity={verdict.severity} role=\"status\">{verdict.text}</p>\n <ChartLegend items={legendItems} />\n </>\n }\n >\n <div\n ref={wrapRef}\n className={`${plot.plotWrap} ${plot.focusable}`}\n data-motion={motion}\n tabIndex={0}\n role=\"group\"\n aria-label={`${title}. Use the left and right arrow keys to read each reading.`}\n aria-describedby={liveId}\n onFocus={() => setActive((a) => a ?? (sorted.length ? sorted.length - 1 : null))}\n onBlur={() => setActive(null)}\n onKeyDown={onKey}\n >\n <svg\n className={plot.svg}\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n role=\"img\"\n aria-label={summary}\n onPointerMove={(e: PointerEvent<SVGSVGElement>) => setActive(indexAt(e.clientX))}\n onPointerLeave={() => setActive(null)}\n >\n <defs>\n <AreaGradient id={gradientId(gradKey, 'remaining')} color={CHART_SEQUENTIAL} top={PAD_T} bottom={PAD_T + plotH} />\n </defs>\n {reserve && reserve.value > 0 ? (\n <rect\n data-role=\"reserve-band\"\n className={`${plot.reserveBand} ${plot.fadeIn}`}\n x={padL}\n y={ys(Math.min(top, reserve.value))}\n width={plotW}\n height={Math.max(0, ys(0) - ys(Math.min(top, reserve.value)))}\n />\n ) : null}\n {ticks.map((t, i) => (\n <g key={t}>\n <line className={plot.grid} x1={padL} x2={padL + plotW} y1={crisp(ys(t))} y2={crisp(ys(t))} />\n <text className={plot.tick} x={padL - 6} y={ys(t)} dy=\"0.32em\" textAnchor=\"end\">{yAxis.labels[i]}</text>\n </g>\n ))}\n <line className={plot.axis} x1={padL} x2={padL + plotW} y1={crisp(ys(0))} y2={crisp(ys(0))} />\n {xLabels.map((l) => (\n <text key={l.key} data-axis-label={l.key} className={plot.tick} x={l.x} y={height - 8} textAnchor={l.anchor}>{l.text}</text>\n ))}\n\n {resetKnown ? (\n <path data-role=\"pace\" className={plot.reference} d={linePath([{ x: xs(x0), y: ys(capacity) }, { x: xs(xEnd), y: ys(0) }])} />\n ) : null}\n {reserve ? (\n <g data-role=\"reserve\">\n <line className={plot.reference} x1={padL} x2={padL + plotW} y1={crisp(ys(reserve.value))} y2={crisp(ys(reserve.value))} />\n {/* Above-left of the line, over a surface halo (SPEC-310C §6): the\n window's start is the one place the remaining line is always\n high, and the projection only ever runs to the right, so the\n label never sits on the data. */}\n <text data-role=\"reserve-label\" className={`${plot.tick} ${plot.halo}`} x={padL + 4} y={ys(reserve.value) - 5} textAnchor=\"start\">\n {reserve.label} · {formatValue(reserve.value)}\n </text>\n </g>\n ) : null}\n {nowX !== null ? (\n <g data-role=\"now\">\n <line className={plot.now} x1={crisp(nowX)} x2={crisp(nowX)} y1={PAD_T} y2={PAD_T + plotH} />\n {nowLabel ? (\n <text data-role=\"now-label\" className={`${plot.tick} ${plot.halo}`} x={nowX} y={PAD_T - 4} textAnchor=\"middle\">Now</text>\n ) : null}\n </g>\n ) : null}\n {runs.map((run, i) => (\n <g key={i} data-role=\"remaining\">\n <path\n data-role=\"area\"\n className={`${plot.area} ${plot.fadeIn}`}\n fill={`url(#${gradientId(gradKey, 'remaining')})`}\n d={smoothAreaPath(run, run.map((p) => ({ x: p.x, y: ys(0) })))}\n />\n {run.length > 1 ? (\n <path data-role=\"line\" className={`${plot.line} ${plot.draw}`} pathLength={1} stroke={CHART_SEQUENTIAL} d={smoothPath(run)} />\n ) : null}\n </g>\n ))}\n {projectionPath ? (\n <path data-role=\"projection\" className={plot.projection} stroke={projectionColor} d={projectionPath} />\n ) : null}\n {projection.from ? (\n <circle className={plot.marker} cx={xs(clampX(projection.from.t))} cy={ys(projection.from.remaining)} r={4} fill={CHART_SEQUENTIAL} />\n ) : null}\n {activePoint ? (\n <g data-role=\"hover\">\n <line className={plot.crosshair} data-role=\"crosshair\" x1={crisp(xs(clampX(activePoint.t)))} x2={crisp(xs(clampX(activePoint.t)))} y1={PAD_T} y2={PAD_T + plotH} />\n {activePoint.remaining !== null ? (\n <circle className={plot.marker} cx={xs(clampX(activePoint.t))} cy={ys(Math.max(0, activePoint.remaining))} r={4} fill={CHART_SEQUENTIAL} />\n ) : null}\n </g>\n ) : null}\n </svg>\n <span id={liveId} className={plot.srOnly} aria-live=\"polite\">\n {activePoint\n ? `${formatTooltipInstant(activePoint.t)}: ${activePoint.remaining === null ? 'no reading' : `${formatValue(activePoint.remaining)} remaining`}` +\n (activePace !== null ? `; even pace ${formatValue(activePace)}` : '')\n : ''}\n </span>\n {activePoint ? (\n <ChartTooltip\n left={tooltipSide(xs(clampX(activePoint.t)), width) ? xs(clampX(activePoint.t)) : clampTooltipLeft(xs(clampX(activePoint.t)), width)}\n side={tooltipSide(xs(clampX(activePoint.t)), width)}\n top={PAD_T}\n title={formatTooltipInstant(activePoint.t)}\n rows={[\n { key: 'r', label: 'Remaining', value: activePoint.remaining === null ? null : formatValue(activePoint.remaining), color: CHART_SEQUENTIAL, kind: 'line' },\n ...(activePace !== null ? [{ key: 'p', label: 'Even pace', value: formatValue(activePace), color: 'var(--text-tertiary)', kind: 'line' as const }] : []),\n ]}\n />\n ) : null}\n </div>\n </ChartFrame>\n );\n}\n"],"mappings":"y9BC8BA,SAAgB,EAAe,CAC7B,QACA,cACA,SACA,WACA,QACA,QACA,eAAe,4BACO,CACtB,OACE,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,UAAW,EAAO,OAA1B,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,aAAD,CAAY,UAAW,EAAO,QAA9B,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAQ,SAAA,CAAY,CAAA,EAC3C,GAAc,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,YAAc,SAAA,CAAkB,CAAA,EAAI,IACjE,IACX,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,OAAQ,KAAK,OAC/B,SAAA,CACA,CAAA,EACD,KACH,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAQ,SAAA,CAAgB,CAAA,GAE7C,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KAAO,UAAc,CAAA,EAE7C,GACC,EAAA,EAAA,KAAA,CAAC,UAAD,CAAS,UAAW,EAAO,gBAA3B,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,UAAD,CAAA,SAAS,eAAsB,CAAA,GAC/B,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,UAAY,SAAA,CAAW,CAAA,CACvC,CACP,CAAA,EAAA,IACE,GAEZ,oHEhDA,SAAgB,GAAO,CAAE,SAAkC,CAEzD,OADI,EAAM,OAAS,EAAU,MAE3B,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAO,OACnB,SAAA,EAAM,IAAK,IACV,EAAA,EAAA,KAAA,CAAC,KAAD,CAAmB,UAAW,EAAO,KAArC,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,UAAW,EAAG,OAAS,OAAS,EAAO,WAAa,EAAO,OAC3D,MAAO,CAAE,WAAY,EAAG,KAAM,EAC9B,cAAY,MACb,CAAA,EACA,EAAG,KACF,CAPK,EAAA,EAAG,KAOR,CACL,CACC,CAAA,CAER,yTE0BM,GAAa,IAEb,GAAQ,GACR,GAAQ,GACR,EAAQ,GACR,EAAQ,GACR,EAAU,EAcV,EAAe,IACf,GAAgB,EAMhB,GAAgB,IAEhB,EAAkB,GAOxB,SAAS,EAAU,EAAmC,CACpD,IAAM,EAAgB,CAAC,EACnB,EAAiB,CAAC,EACtB,IAAK,IAAM,KAAK,EAAQ,CACtB,GAAI,EAAE,IAAM,KAAM,CACZ,EAAQ,QAAQ,EAAK,KAAK,CAAO,EACrC,EAAU,CAAC,EACX,QACF,CACA,EAAQ,KAAK,CAAE,EAAG,EAAE,EAAG,EAAG,EAAE,CAAE,CAAC,CACjC,CAEA,OADI,EAAQ,QAAQ,EAAK,KAAK,CAAO,EAC9B,CACT,CAEA,SAAgB,EAAU,CACxB,OAAQ,EACR,SAAS,IACT,OAAO,GACP,QAAS,EACT,QAAS,GACT,cAAe,EACf,eAAgB,EAChB,YACA,MAAO,IAgBN,CACD,IAAM,IAAA,EAAS,EAAA,OAAA,CAAsB,IAAI,EACnC,IAAA,EAAU,EAAA,OAAA,CAAuB,IAAI,EACrC,EAAQ,GAAc,GAAS,GAAY,EAAU,EACrD,EAAY,GAAa,EACzB,GAAS,GAAe,EACxB,IAAA,EAAU,EAAA,MAAA,CAAM,EAChB,IAAA,EAAS,EAAA,MAAA,CAAM,EAEf,EAAc,GAAY,CAAS,EACnC,CAAC,EAAQ,IAAA,EAAa,EAAA,SAAA,CAAwB,IAAI,EAElD,EAAY,GAAqB,IAAe,GAIhD,EAAQ,EAAQ,EAAW,QAAS,GAAM,EAAE,OAAO,IAAK,GAAM,EAAE,CAAC,CAAC,CAAC,EACnE,EAAS,EAAW,IAAK,IAAO,CAAE,GAAG,EAAG,OAAQ,EAAE,OAAO,OAAQ,GAAM,EAAM,EAAE,CAAC,CAAC,CAAE,EAAE,EACrF,EAAO,EAAO,QAAS,GAAM,EAAE,OAAO,IAAK,GAAM,EAAE,CAAC,CAAC,EACrD,EAAS,EAAO,QAAS,GAAM,EAAE,OAAO,IAAK,GAAM,EAAE,CAAC,CAAC,CAAC,CAAC,OAAQ,GAAmB,IAAM,MAAQ,OAAO,SAAS,CAAC,CAAC,EAC1H,GAAI,EAAK,SAAW,EAClB,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,IAAK,GAAS,UAAW,EAAO,KACnC,UAAA,EAAA,EAAA,IAAA,CAAC,IAAD,CAAA,SAAG,UAAW,CAAA,CACX,CAAA,EAGT,IAAM,EAAU,KAAK,IAAI,GAAG,CAAI,EAC1B,GAAU,KAAK,IAAI,GAAG,CAAI,EAC1B,GAAW,GAAW,CAAI,EAE1B,GAAU,IAAgB,GAAW,GAAmB,GAAc,OAAO,CAAC,GAC9E,EAAa,GAAsB,IAAgB,GAAW,GAAqB,CAAI,EAAI,IAG3F,CAAC,GAAM,GAAQ,IAAY,GAAU,EAAU,EAAW,EAAS,GAAS,EAAgB,EAAI,CAAC,EAAS,EAAO,EACjH,EAAS,EAAO,IAAQ,EAIxB,EAAQ,EAAU,KAAK,IAAI,EAAG,GAAG,CAAM,EAAG,KAAK,IAAI,EAAG,GAAG,CAAM,EAAG,CACtE,MAAO,EACP,QAAS,EAAO,OAAS,GAAK,GAAY,CAAM,EAChD,OAAQ,EACV,CAAC,EACK,GAAS,EAAM,MACf,GAAO,GAAO,GAEd,GADO,GAAO,GAAO,OAAS,GACd,IAAQ,EACxB,EAAQ,EAAS,EAAQ,EACzB,EAAU,GAAc,EAAQ,GAAU,EAAI,IAAQ,GAAU,EAIhE,EAAO,KAAK,IAAI,GAAO,KAAK,KAAK,KAAK,IAAI,EAAG,GAAG,EAAM,OAAO,IAAK,GAAM,EAAE,MAAM,CAAC,EAAI,CAAW,EAAI,CAAC,EAOrG,EAAgB,EAAO,QAAU,GAAK,EAAO,QAAU,EACvD,EAAY,EACd,KAAK,IAAI,GAAG,EAAO,IAAK,GAAM,EAAE,MAAM,MAAM,CAAC,EAAI,EAAe,EAChE,EACE,GAAY,EAAO,QAAS,GAAM,CACtC,IAAK,IAAI,EAAI,EAAE,OAAO,OAAS,EAAG,GAAK,EAAG,IAAK,CAC7C,IAAM,EAAI,EAAE,OAAO,EAAE,CAAE,EACvB,GAAI,IAAM,MAAQ,OAAO,SAAS,CAAC,EAAG,MAAO,CAAC,CAAE,IAAK,EAAE,GAAI,EAAG,EAAO,CAAC,CAAE,CAAC,CAC3E,CACA,MAAO,CAAC,CACV,CAAC,EACK,GAAS,GAAiB,GAAa,GAAgB,EAAY,GAAW,EAAkB,EAAW,EAAO,EAAQ,CAAK,EAAI,KACnI,GAAgB,KAAW,MAAQ,GAAU,OAAS,EACtD,EAAO,IAAS,GAAgB,GAAgB,EAAY,GAC5D,GAAa,EAAO,QAAU,EAE9B,GAAQ,KAAK,IAAI,GAAI,EAAQ,EAAO,CAAI,EACxC,EAAU,GAAc,GAAS,EAAI,IAAQ,EAAU,GAIvD,EAAQ,MAAM,KAAK,IAAI,IAAI,CAAI,CAAC,CAAC,CAAC,MAAM,EAAG,IAAM,EAAI,CAAC,EAQtD,EAAU,EAAM,OAAS,EAAI,GAAY,EAAM,OAAQ,KAAK,IAAI,EAAG,KAAK,MAAM,GAAQ,EAAE,CAAC,CAAC,EAAI,CAAC,EAC/F,GAAS,GAAW,GAAgB,EAAS,GAAS,EAAa,EAAQ,IAAK,GAAM,EAAM,EAAG,CAAC,EAAI,CAAC,EAAO,EAC5G,GAAU,GACd,EAAQ,KAAK,EAAK,IAAM,CACtB,IAAM,EAAI,EAAM,GACV,EAAK,EAAO,CAAC,EACb,EAAU,IAAM,EAChB,EAAS,IAAM,EAAQ,OAAS,EAChC,EAAS,GAAW,GAAM,EAAO,GAAM,QAAmB,GAAU,GAAM,EAAQ,EAAO,GAAM,MAAiB,SACtH,MAAO,CACL,IAAK,EAAU,QAAU,EAAS,MAAQ,IAAI,IAC9C,EAAG,EACH,SACA,SAAU,EAAS,EAAI,EAAU,EAAI,EACrC,SAAU,GAAW,EACrB,SAAU,GAAO,IAAK,GAAM,EAAE,CAAC,CAAC,CAClC,CACF,CAAC,EACD,CAAE,IAAK,EAAM,IAAK,EAAQ,EAAM,OAAQ,CAAY,CACtD,EAEA,SAAS,GAAS,EAAgC,CAChD,IAAM,EAAM,GAAO,QACnB,GAAI,CAAC,EAAK,OAAO,KACjB,IAAM,EAAO,EAAI,sBAAsB,EAGjC,GAAS,EAAU,EAAK,OAAS,EAAK,OAAS,GAAU,EACzD,EAAQ,IAAS,EAAO,GAAQ,GAAS,EAC3C,EAAU,EAAM,GAChB,EAAO,IACX,IAAK,IAAM,KAAK,EAAO,CACrB,IAAM,EAAI,KAAK,IAAI,EAAI,CAAK,EACxB,EAAI,IACN,EAAO,EACP,EAAU,EAEd,CACA,OAAO,CACT,CAEA,SAAS,GAAW,EAAgC,CAClD,IAAM,EAAI,GAAS,EAAE,OAAO,EACxB,IAAM,MACV,EAAU,CAAC,CACb,CAEA,SAAS,GAAM,EAAwC,CACrD,GAAI,EAAM,SAAW,EAAG,OACxB,IAAM,EAAM,IAAW,KAAO,EAAM,OAAS,EAAI,KAAK,IAAI,EAAG,EAAM,QAAQ,CAAM,CAAC,EAC5E,EAAO,EAAE,MAAQ,YAAc,EAAM,EAAI,EAAE,MAAQ,aAAe,EAAM,EAAI,EAAE,MAAQ,OAAS,EAAI,EAAE,MAAQ,MAAQ,EAAM,OAAS,EAAI,KAC1I,IAAS,OACb,EAAE,eAAe,EACjB,EAAU,EAAM,KAAK,IAAI,EAAG,KAAK,IAAI,EAAM,OAAS,EAAG,CAAI,CAAC,EAAG,EACjE,CAEA,IAAM,GAAS,GAAQ,EAAO,QAAU,EAElC,GACJ,IAAW,KAKP,KAJA,EAAO,IAAK,IAAO,CACjB,OAAQ,EACR,MAAO,EAAE,OAAO,KAAM,GAAM,EAAE,IAAM,CAAM,GAAK,IACjD,EAAE,EAGR,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,IAAK,GACL,UAAW,GAAG,EAAO,KAAK,GAAG,EAAK,YAClC,cAAa,GACb,SAAU,EACV,KAAK,QACL,aAAY,GAAG,EAAU,qDACzB,mBAAkB,GAClB,YAAe,EAAW,GAAM,GAAK,EAAM,EAAM,OAAS,IAAM,IAAI,EACpE,WAAc,EAAU,IAAI,EAC5B,UAAW,GAVb,SAAA,EAYE,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,IAAK,GACL,UAAW,EAAO,IACX,QACC,SACR,QAAS,OAAO,EAAM,GAAG,IACzB,KAAK,MACL,aAAY,EACZ,cAAe,GACf,mBAAsB,EAAU,IAAI,EATtC,SAAA,CAWG,IACC,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SACG,EAAO,KAAK,EAAG,KACd,EAAA,EAAA,IAAA,CAAC,EAAD,CAAyB,GAAI,GAAW,GAAS,EAAE,EAAE,EAAG,MAAO,EAAY,CAAE,EAAG,IAAK,EAAO,OAAQ,EAAS,EAAO,KAAM,EAAO,OAAS,EAAI,IAAO,GAAO,EAAzI,EAAE,EAAuI,CAC7J,CACG,CAAA,EACJ,KACH,GAAO,KAAK,EAAG,KACd,EAAA,EAAA,KAAA,CAAC,IAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,GAAI,EACJ,GAAI,EAAQ,EACZ,GAAI,EAAM,EAAO,CAAC,CAAC,EACnB,GAAI,EAAM,EAAO,CAAC,CAAC,EACnB,UAAW,EAAO,SAClB,OAAQ,CACT,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAG,EAAO,EAAG,EAAG,EAAO,CAAC,EAAG,GAAG,SAAS,WAAW,MAAM,UAAW,EAAO,UAC7E,SAAA,EAAM,OAAO,EACV,CAAA,CACL,CAAA,EAZK,CAYL,CACJ,GACD,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,GAAI,EACJ,GAAI,EAAQ,EACZ,GAAI,EAAM,EAAS,CAAK,EACxB,GAAI,EAAM,EAAS,CAAK,EACxB,UAAW,EAAO,KAClB,OAAQ,CACT,CAAA,EACA,GAAQ,IAAK,IACZ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAkB,kBAAiB,EAAE,IAAK,EAAG,EAAE,EAAG,EAAG,EAAS,EAAG,WAAY,EAAE,OAAQ,UAAW,EAAO,UACtG,SAAA,EAAE,IACC,EAFK,EAAE,GAEP,CACP,EAEA,EAAO,KAAK,EAAG,IAAO,CACrB,IAAM,EAAQ,EAAY,CAAE,EACtB,EAAO,EAAU,EAAE,MAAM,EAC/B,OACE,EAAA,EAAA,KAAA,CAAC,IAAD,CAAA,SAAA,CACG,GACG,EAAK,KAAK,EAAK,IAAO,CACpB,IAAM,EAAM,EAAI,IAAK,IAAO,CAAE,EAAG,EAAO,EAAE,CAAC,EAAG,EAAG,EAAO,EAAE,CAAC,CAAE,EAAE,EACzD,EAAO,EAAI,IAAK,IAAO,CAAE,EAAG,EAAE,EAAG,EAAG,EAAO,KAAK,IAAI,GAAM,CAAC,CAAC,CAAE,EAAE,EACtE,OACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAEE,YAAU,OACV,EAAG,EAAe,EAAK,CAAI,EAC3B,KAAM,QAAQ,GAAW,GAAS,EAAE,EAAE,EAAE,GACxC,UAAW,GAAG,EAAO,KAAK,GAAG,EAAK,QACnC,EALM,CAKN,CAEL,CAAC,EACD,KACH,EAAK,KAAK,EAAK,IACd,EAAI,SAAW,GACb,EAAA,EAAA,IAAA,CAAC,SAAD,CAAiB,GAAI,EAAO,EAAI,EAAE,CAAC,CAAC,EAAG,GAAI,EAAO,EAAI,EAAE,CAAC,CAAC,EAAG,EAAG,EAAG,KAAM,CAAQ,EAApE,CAAoE,GAEjF,EAAA,EAAA,IAAA,CAAC,OAAD,CAEE,YAAU,OACV,EAAG,EAAW,EAAI,IAAK,IAAO,CAAE,EAAG,EAAO,EAAE,CAAC,EAAG,EAAG,EAAO,EAAE,CAAC,CAAE,EAAE,CAAC,EAClE,WAAY,EACZ,OAAQ,EACR,UAAW,GAAG,EAAO,KAAK,GAAG,EAAK,MACnC,EANM,CAMN,CAEL,EACC,IAAW,MAAQ,EAAK,QAAU,EAAK,EAAK,OAAS,EAAE,CAAC,OAAS,OAAW,CAE3E,IAAM,EAAU,EAAK,EAAK,OAAS,GAC7B,EAAO,EAAQ,EAAQ,OAAS,GACtC,OAAO,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,YAAU,UAAU,UAAW,GAAG,EAAK,OAAO,GAAG,EAAK,SAAU,GAAI,EAAO,EAAK,CAAC,EAAG,GAAI,EAAO,EAAK,CAAC,EAAG,EAAG,IAAK,KAAM,CAAQ,CAAA,CAC/I,EAAA,CAAG,EAAI,KACN,IAAiB,EAAK,YACd,CACL,IAAM,EAAU,EAAK,EAAK,OAAS,GAC7B,EAAO,EAAQ,EAAQ,OAAS,GACtC,OACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,iBAAgB,EAAE,GAClB,EAAG,EAAO,EAAK,CAAC,EAAI,GACpB,EAAG,IAAQ,IAAI,EAAE,EAAE,GAAK,EAAO,EAAK,CAAC,EACrC,GAAG,SACH,UAAW,EAAO,SAClB,KAAM,EAEL,SAAA,EAAE,KACC,CAAA,CAEV,EAAA,CAAG,EACD,IACH,CAAA,EAtDK,EAAE,EAsDP,CAEP,CAAC,EAEA,IAAW,KASR,MARF,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,YAAU,YACV,GAAI,EAAM,EAAO,CAAM,CAAC,EACxB,GAAI,EAAM,EAAO,CAAM,CAAC,EACxB,GAAI,EACJ,GAAI,EAAS,EACb,UAAW,EAAO,aACnB,CAAA,EAEF,IAAW,KAeR,KAdA,EAAO,KAAK,EAAG,IAAO,CACpB,IAAM,EAAI,EAAE,OAAO,KAAM,GAAO,EAAG,IAAM,CAAM,EAE/C,MADI,CAAC,GAAK,EAAE,IAAM,KAAa,MAE7B,EAAA,EAAA,IAAA,CAAC,SAAD,CAEE,GAAI,EAAO,EAAE,CAAC,EACd,GAAI,EAAO,EAAE,CAAC,EACd,EAAG,EACH,KAAM,EAAY,CAAE,EACpB,UAAW,EAAO,MACnB,EANM,EAAE,EAMR,CAEL,CAAC,GAGL,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,EAAG,EACH,EAAG,EACH,MAAO,GACP,OAAQ,EACR,UAAW,EAAO,OACnB,CAAA,CACE,KACL,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,GAAI,GAAQ,UAAW,EAAK,OAAQ,YAAU,SACjD,SAAA,GACG,GAAG,EAAW,CAAgB,EAAE,IAAI,GAAY,KAAK,CAAE,OAAQ,EAAG,WAAY,GAAG,EAAE,MAAM,GAAG,GAAS,EAAM,IAAM,KAAO,EAAU,EAAM,CAAC,EAAI,WAAW,CAAC,CAAC,KAAK,IAAI,IACnK,EACA,CAAA,EACL,IAAe,IAAW,MACzB,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EAAY,EAAO,CAAM,EAAG,CAAK,EAAI,EAAO,CAAM,EAAI,EAAiB,EAAO,CAAM,EAAG,CAAK,EAClG,KAAM,EAAY,EAAO,CAAM,EAAG,CAAK,EACvC,IAAK,EACL,MAAO,EAAW,CAAM,EACxB,KAAM,GAAY,KAAK,CAAE,OAAQ,EAAG,SAAS,KAAO,CAClD,IAAK,EAAE,GACP,MAAO,EAAE,MACT,MAAO,GAAS,EAAM,IAAM,KAAO,EAAU,EAAM,CAAC,EAAI,KACxD,MAAO,EAAY,CAAC,EACpB,KAAM,MACR,EAAE,CACH,CAAA,EACC,KACH,IACC,EAAA,EAAA,IAAA,CAAC,GAAD,CAAQ,MAAO,EAAO,KAAK,EAAG,KAAO,CAAE,MAAO,EAAE,MAAO,MAAO,EAAY,CAAC,EAAG,KAAM,MAAO,EAAE,CAAI,CAAA,EAC/F,IACD,GAET,+WEvcM,EAAU,GACV,EAAM,GAEZ,SAAgB,EAAS,CACvB,OACA,SAAS,IACT,cAAc,WACd,QAAQ,EACR,cAAe,GAAc,OAAO,CAAC,EACrC,YACA,MAAO,GAUN,CACD,IAAM,GAAA,EAAM,EAAA,MAAA,CAAM,EACZ,IAAA,EAAU,EAAA,OAAA,CAAuB,IAAI,EAIrC,GAAY,GAAc,GAAS,EAAY,GAAG,EAClD,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAwB,IAAI,EAEhD,EAAQ,EAAK,IAAK,GAAM,EAAE,KAAK,CAAC,CAAC,OAAQ,GAAmB,IAAM,IAAI,EACtE,EAAS,KAAK,IAAI,EAAG,GAAG,EAAO,IAAM,EACrC,EAAS,KAAK,IAAI,EAAG,GAAG,CAAK,EAC7B,GAAQ,EAAS,GAAU,EAEjC,GAAI,IAAgB,aAAc,CAChC,IAEM,EAAO,KAAK,IAAI,EAAS,KAAK,IAAI,GAAI,KAAK,OAAO,EAAS,GAAO,EAAK,MAAM,EAAI,CAAG,CAAC,EACrF,EAAO,EAAK,QAAU,EAAO,GAAO,EACpC,EAAO,GACP,EAAQ,KAAK,IAAI,GAAI,EAAO,IAAU,EAAK,EAEjD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,IAAK,GAAS,UAAW,EAAO,KAArC,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAW,EAAO,IAClB,MAAO,EACP,OAAQ,EACR,QAAS,OAAO,EAAK,GAAG,IACxB,KAAK,MACL,aAAY,EANd,SAAA,EAQE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,GAAI,IAAS,GAAI,EAAG,GAAI,IAAS,GAAI,EAAM,UAAW,EAAO,SAAU,OAAQ,CAAa,CAAA,EACjG,EAAK,KAAK,EAAG,IAAM,CAClB,IAAM,EAAI,EAAM,GAAK,EAAO,GACtB,EAAO,EAAE,QAAU,KAA8C,GAArC,EAAE,MAAQ,GAAU,GAAS,EAC/D,OACE,EAAA,EAAA,KAAA,CAAC,IAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,EAAG,IACH,EAAG,EAAI,EAAO,EACd,GAAG,SACH,WAAW,MACX,UAAW,EAAO,cAEjB,SAAA,EAAE,MAAM,OAAS,GAAK,GAAG,EAAE,MAAM,MAAM,EAAG,EAAE,EAAE,GAAK,EAAE,KAClD,CAAA,EACL,EAAE,QAAU,MACX,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,GAAI,IACJ,GAAI,EAAI,EAAO,EACf,GAAI,IACJ,GAAI,EAAI,EAAO,EACf,OAAQ,EACR,YAAa,EACb,gBAAgB,KACjB,CAAA,GAED,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,EAAG,IACA,IACH,MAAO,KAAK,IAAI,EAAG,CAAI,EACvB,OAAQ,EACR,GAAI,EACJ,KAAM,EACN,UAAW,EAAO,GACnB,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,EAAG,IAAU,KAAK,IAAI,EAAG,CAAI,EAAI,EACjC,EAAG,EAAI,EAAO,EACd,GAAG,SACH,UAAW,EAAO,WAEjB,SAAA,EAAY,EAAE,KAAK,CAChB,CAAA,CACN,CAAA,CAAA,GAEJ,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,UAAW,EAAO,QAClB,EAAG,EACH,EAAG,EAAI,EAAM,EACb,MAAO,EACP,OAAQ,EAAO,EACf,SAAU,EACV,KAAK,MACL,aAAY,GAAG,EAAE,MAAM,IAAI,EAAE,QAAU,KAAO,UAAY,EAAY,EAAE,KAAK,IAC7E,mBAAsB,EAAS,CAAC,EAChC,mBAAsB,EAAU,GAAO,IAAM,EAAI,KAAO,CAAE,EAC1D,YAAe,EAAS,CAAC,EACzB,WAAc,EAAU,GAAO,IAAM,EAAI,KAAO,CAAE,CACnD,CAAA,CACA,CAAA,EAvDK,EAAE,MAAQ,CAuDf,CAEP,CAAC,CACE,CACJ,CAAA,EAAA,IAAU,KAUP,MATF,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAW,EAAO,QAClB,MAAO,CAAE,KAAM,IAAa,IAAK,EAAM,GAAS,EAAO,GAAO,CAAE,EAFlE,SAAA,EAIE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,aACrB,SAAA,EAAK,EAAM,CAAC,QAAU,KAAO,UAAY,EAAY,EAAK,EAAM,CAAC,KAAe,CAC7E,CAAA,GACN,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,aAAe,SAAA,EAAK,EAAM,CAAC,KAAY,CAAA,CAC5D,CACH,CAAA,CACD,GAET,CAGA,IAAM,GAAU,EAAK,OAAS,KAAK,IAAI,EAAS,CAAC,EAAI,EAC/C,EAAO,KAAK,IAAI,EAAS,EAAO,EAGhC,EAAQ,EACR,EAAO,EAAQ,GAAQ,GACvB,GAAO,EAAK,QAAU,EAAO,GAAO,EACpC,EAAQ,GAAQ,GAAU,EAAI,GAAU,GAAS,EAEvD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KAAvB,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAW,EAAO,IAClB,MAAO,GACP,OAAQ,EACR,QAAS,OAAO,GAAK,GAAG,IACxB,KAAK,MACL,aAAY,EANd,SAAA,EAQE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,GAAI,EAAG,GAAI,EAAO,GAAI,GAAM,GAAI,EAAO,UAAW,EAAO,SAAU,OAAQ,CAAa,CAAA,EAC7F,EAAK,KAAK,EAAG,IAAM,CAClB,IAAM,EAAI,EAAM,GAAK,EAAO,GACtB,EAAO,EAAE,QAAU,KAAsD,EAA9C,KAAK,IAAI,EAAE,MAAQ,CAAM,EAAI,GAAS,EACjE,EAAM,EAAE,QAAU,MAAQ,EAAE,OAAS,EAAI,EAAQ,EAAO,EAC9D,OACE,EAAA,EAAA,KAAA,CAAC,IAAD,CAAA,SAAA,CACG,EAAE,QAAU,MACX,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,GAAI,EAAI,EAAO,EAAI,EACnB,GAAI,EACJ,GAAI,EAAI,EAAO,EAAI,EACnB,GAAI,EACJ,OAAQ,EACR,YAAa,EACb,gBAAgB,KACjB,CAAA,GAED,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACK,IACH,EAAG,EACH,MAAO,EACP,OAAQ,KAAK,IAAI,EAAG,CAAI,EACxB,GAAI,EACJ,KAAM,EACN,UAAW,EAAO,GACnB,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAG,EAAI,EAAO,EAAG,EAAG,EAAM,EAAG,WAAW,SAAS,UAAW,EAAO,WACtE,SAAA,EAAY,EAAE,KAAK,CAChB,CAAA,CACN,CAAA,CAAA,GAEJ,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,EAAG,EAAI,EAAO,EACd,EAAG,EAAO,EACV,WAAW,SACX,UAAW,EAAO,UAEjB,SAAA,EAAE,MAAM,OAAS,GAAK,GAAG,EAAE,MAAM,MAAM,EAAG,CAAC,EAAE,GAAK,EAAE,KACjD,CAAA,GACN,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,UAAW,EAAO,QAClB,EAAG,EAAI,EAAM,EACb,EAAG,EACH,MAAO,EAAO,EACd,OAAQ,EACR,SAAU,EACV,KAAK,MACL,aAAY,GAAG,EAAE,MAAM,IAAI,EAAE,QAAU,KAAO,UAAY,EAAY,EAAE,KAAK,IAC7E,mBAAsB,EAAS,CAAC,EAChC,mBAAsB,EAAU,GAAO,IAAM,EAAI,KAAO,CAAE,EAC1D,YAAe,EAAS,CAAC,EACzB,WAAc,EAAU,GAAO,IAAM,EAAI,KAAO,CAAE,CACnD,CAAA,CACA,CAAA,EAjDK,EAAE,MAAQ,CAiDf,CAEP,CAAC,CACE,CACJ,CAAA,EAAA,IAAU,KAWP,MAVF,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAW,EAAO,QAClB,MAAO,CAAE,KAAM,EAAM,GAAS,EAAO,GAAM,IAAK,CAAE,EAClD,GAAI,GAAG,EAAI,UAHb,SAAA,EAKE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,aACrB,SAAA,EAAK,EAAM,CAAC,QAAU,KAAO,UAAY,EAAY,EAAK,EAAM,CAAC,KAAe,CAC7E,CAAA,GACN,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,aAAe,SAAA,EAAK,EAAM,CAAC,KAAY,CAAA,CAC5D,CACH,CAAA,CACD,GAET,CC1KA,IAAM,EAAQ,GACR,GAAQ,GACR,GAAQ,GAEd,SAAS,GAAkB,EAAoB,CAC7C,IAAM,EAAI,IAAI,KAAK,CAAE,EACrB,OAAO,OAAO,MAAM,EAAE,QAAQ,CAAC,EAAI,GAAK,EAAE,eAAe,QAAS,CAAE,QAAS,QAAS,KAAM,UAAW,OAAQ,SAAU,CAAC,CAC5H,CAEA,SAAgB,EAAW,EAAoB,CAC7C,IAAM,EAAI,KAAK,IAAI,EAAG,KAAK,MAAM,EAAK,GAAM,CAAC,EAC7C,GAAI,EAAI,GAAI,MAAO,GAAG,EAAE,GACxB,IAAM,EAAI,KAAK,MAAM,EAAI,EAAE,EAE3B,OADI,EAAI,GAAW,EAAI,GAAK,GAAG,EAAE,IAAI,EAAI,GAAG,GAAK,GAAG,EAAE,GAC/C,GAAG,KAAK,MAAM,EAAI,EAAE,EAAE,EAC/B,CASA,SAAgB,GACd,EACA,EACA,EACA,EACA,EACkE,CAClE,IAAM,EAAQ,IAAY,MAAQ,OAAO,SAAS,CAAO,EAAI,EAAU,KAGvE,GAAI,EAAW,MAAQ,EAAW,KAAK,WAAa,EAClD,MAAO,CAAE,KAAM,IAAU,KAAO,gCAAkC,oBAAoB,EAAW,CAAK,EAAE,GAAI,SAAU,QAAS,EAEjI,GAAI,EAAW,MAAQ,IAAiB,IAAA,IAAa,EAAW,YAAc,MAAQ,EAAW,WAAa,EAAW,KAAK,EAAG,CAC/H,IAAM,EAAQ,IAAU,KAAO,uCAAyC,SAAS,EAAW,CAAK,IACjG,MAAO,CAAE,KAAM,UAAU,EAAa,YAAY,EAAE,4CAA4C,EAAM,GAAI,SAAU,MAAO,CAC7H,CAeA,OAdI,IAAU,KAAa,CAAE,KAAM,mDAAoD,SAAU,SAAU,EACvG,EAAW,aAAe,KAAa,CAAE,KAAM,kDAAmD,SAAU,SAAU,EACtH,EAAW,YAAc,KAMzB,EAAW,YAAc,KAMtB,CACL,KAAM,uBAAuB,EAAY,EAAW,kBAAoB,CAAC,EAAE,iBAC3E,SAAU,IACZ,EARS,CACL,KAAM,iBAAiB,GAAgB,UAAU,WAAW,EAAW,EAAW,SAAS,EAAE,IAAI,EAAW,EAAQ,EAAW,SAAS,EAAE,gBAC1I,SAAU,MACZ,EATO,CACL,KAAM,0BAA0B,EAAW,EAAW,SAAS,EAAE,IAAI,EAAW,EAAQ,EAAW,SAAS,EAAE,gBAC9G,SAAU,QACZ,CAYJ,CAEA,SAAgB,EAAS,CACvB,QACA,cACA,SACA,SACA,UACA,WACA,SACA,WACA,MACA,UACA,SAAS,IACT,MAAO,GACP,YAAa,GACb,WAAY,GACZ,aACgB,CAChB,IAAM,EAAc,IAAmB,GACjC,EAAa,IAAkB,GAC/B,IAAA,EAAU,EAAA,OAAA,CAAuB,IAAI,EACrC,EAAQ,GAAc,GAAS,EAAU,EACzC,GAAY,GAAa,EACzB,GAAS,GAAe,EACxB,IAAA,EAAU,EAAA,MAAA,CAAM,EAChB,GAAA,EAAS,EAAA,MAAA,CAAM,EACf,CAAC,EAAQ,IAAA,EAAa,EAAA,SAAA,CAAwB,IAAI,EAIlD,EAAS,GAAO,OAAQ,GAAM,EAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAG,IAAM,EAAE,EAAI,EAAE,CAAC,EAC5E,GAAW,EAAO,KAAM,GAAM,EAAE,YAAc,IAAI,EAClD,GAA8B,IAAW,EAAO,SAAW,EAAI,CAAE,KAAM,QAAS,QAAS,iCAAkC,EAAI,GAAW,CAAE,KAAM,OAAQ,EAAI,CAAE,KAAM,SAAU,GAOhL,EAAa,EAAgB,EAAO,EACpC,EAAQ,EAAa,GAAU,KAC/B,EAAa,EAAgB,EAAQ,EAAO,CAAE,QAAS,GAAS,OAAS,IAAK,CAAC,EAC/E,EAAU,GAAY,EAAY,EAAO,EAAa,EAAY,GAAS,KAAK,EAIhF,EAAQ,EAAO,QAAS,GAAO,EAAE,YAAc,MAAQ,OAAO,SAAS,EAAE,SAAS,EAAI,CAAC,EAAE,SAAS,EAAI,CAAC,CAAE,EACzG,EAAQ,EAAU,EAAG,KAAK,IAAI,EAAU,GAAG,EAAO,CAAC,EAAG,CAC1D,MAAO,EACP,QAAS,OAAO,UAAU,CAAQ,GAAK,EAAM,MAAO,GAAM,OAAO,UAAU,CAAC,CAAC,EAC7E,OAAQ,EACV,CAAC,EACK,EAAQ,EAAM,MACd,EAAM,EAAM,EAAM,OAAS,GAC3B,EAAO,EAAW,EAAM,OAAQ,GAAI,GAAI,EAAS,EACjD,EAAQ,KAAK,IAAI,GAAI,EAAQ,EAAO,EAAK,EACzC,EAAQ,EAAS,EAAQ,GAIzB,GAAQ,EAAO,OAAS,EAAO,EAAO,OAAS,EAAE,CAAE,EAAI,EACvD,GAAS,GAAS,KAAK,IAAI,EAAK,EAAK,EACrC,GAAW,EAAgB,EAAK,EAAI,GAAQ,EAAO,EAAE,EAAE,GAAK,GAC5D,CAAC,EAAI,GAAQ,EAAW,GAAU,GAAQ,GAAkB,KAAK,EACjE,EAAK,EAAY,EAAI,EAAM,EAAM,EAAO,CAAK,EAC7C,EAAK,EAAY,EAAG,EAAK,EAAQ,EAAO,CAAK,EAC7C,EAAU,GAAc,KAAK,IAAI,EAAM,KAAK,IAAI,EAAI,CAAC,CAAC,EAQtD,GAAS,GAAgB,EAAI,EAAM,IAAkB,GAAmB,CAAC,EAAI,CAAI,CAAC,EAClF,GAAU,GACd,CACE,CAAE,IAAK,QAAS,EAAG,EAAM,OAAQ,QAAS,SAAU,EAAG,SAAU,GAAO,IAAK,GAAM,EAAE,CAAE,CAAC,CAAE,EAC1F,EACI,CAAE,IAAK,QAAS,EAAG,EAAO,EAAO,OAAQ,MAAO,SAAU,EAAG,SAAU,GAAO,IAAK,GAAM,UAAU,EAAE,CAAI,GAAG,CAAE,EAC9G,CAAE,IAAK,MAAO,EAAG,EAAO,EAAO,OAAQ,MAAO,SAAU,EAAG,SAAU,GAAO,IAAK,GAAM,EAAE,CAAI,CAAC,CAAE,CACtG,EACA,CAAE,IAAK,EAAM,IAAK,EAAO,EAAO,OAAQ,GAAY,EAAS,CAAE,CACjE,EAEM,GAAO,GAAU,EAAO,IAAK,IAAO,CAAE,EAAG,EAAO,EAAE,CAAC,EAAG,EAAG,EAAE,SAAU,EAAE,CAAC,CAAC,CAC5E,IAAK,GAAQ,EAAI,IAAK,IAAO,CAAE,EAAG,EAAG,EAAE,CAAC,EAAG,EAAG,EAAG,KAAK,IAAI,EAAG,EAAE,CAAC,CAAC,CAAE,EAAE,CAAC,EAInE,EAAU,GACd,GAAc,EAAO,EAAK,KAAK,IAAI,EAAG,KAAK,IAAI,EAAU,GAAY,GAAK,EAAI,IAAO,EAAO,GAAI,CAAC,EAAI,KAEvG,SAAS,GAAQ,EAAgC,CAC/C,IAAM,EAAK,GAAQ,QACnB,GAAI,CAAC,GAAM,EAAO,SAAW,EAAG,OAAO,KACvC,IAAM,EAAK,EAAU,EAAG,sBAAsB,CAAC,CAAC,KAC5C,EAAO,EACP,EAAQ,IAQZ,OAPA,EAAO,SAAS,EAAG,IAAM,CACvB,IAAM,EAAI,KAAK,IAAI,EAAG,EAAO,EAAE,CAAC,CAAC,EAAI,CAAE,EACnC,EAAI,IACN,EAAQ,EACR,EAAO,EAEX,CAAC,EACM,CACT,CAEA,SAAS,GAAM,EAAwC,CACrD,GAAI,EAAO,SAAW,EAAG,OACzB,IAAM,EAAM,GAAU,EAAO,OAAS,EAChC,EAAO,EAAE,MAAQ,YAAc,EAAM,EAAI,EAAE,MAAQ,aAAe,EAAM,EAAI,EAAE,MAAQ,OAAS,EAAI,EAAE,MAAQ,MAAQ,EAAO,OAAS,EAAI,KAC3I,IAAS,OACb,EAAE,eAAe,EACjB,EAAU,KAAK,IAAI,EAAG,KAAK,IAAI,EAAO,OAAS,EAAG,CAAI,CAAC,CAAC,EAC1D,CAEA,IAAM,EAAc,IAAW,KAAwB,IAAA,GAAjB,EAAO,GACvC,EAAa,EAAc,EAAO,EAAY,CAAC,EAAI,KACnD,EAAO,EAAM,GAAM,EAAM,EAAO,EAAG,CAAG,EAAI,KAE1C,GAAW,IAAS,MAAQ,EAAO,EAAO,IAAM,EAAO,EAAQ,EAAO,GAExE,GAAiB,GACrB,GAAI,IAAU,MAAQ,EAAW,MAAQ,EAAW,aAAe,KAAM,CACvE,IAAM,EAAO,EAAW,WAAa,EAC/B,EAAO,EAAW,YAAc,KAAW,EAAW,kBAAoB,EAAW,KAAK,UAAnD,EACzC,EAAO,EAAW,KAAK,IACzB,GAAiB,EAAS,CACxB,CAAE,EAAG,EAAG,EAAO,EAAW,KAAK,CAAC,CAAC,EAAG,EAAG,EAAG,EAAW,KAAK,SAAS,CAAE,EACrE,CAAE,EAAG,EAAG,EAAO,CAAI,CAAC,EAAG,EAAG,EAAG,KAAK,IAAI,EAAG,CAAI,CAAC,CAAE,CAClD,CAAC,EAEL,CACA,IAAM,GAAkB,EAAQ,WAAa,SAAW,GAAU,QAAQ,EAAI,EAAQ,WAAa,OAAS,GAAU,SAAS,EAAI,uBAE7H,GAAU,GAAa,GAAG,EAAM,IAAI,EAAW,KAAO,GAAG,EAAY,EAAW,KAAK,SAAS,EAAE,MAAM,EAAY,CAAQ,EAAE,WAAW,EAAW,EAAW,KAAK,CAAC,IAAM,cAAc,IAAI,IAAU,KAAO,qBAAuB,UAAU,EAAW,CAAK,IAAI,IAAI,EAAQ,OAE7Q,GAAoC,CACxC,CAAE,IAAK,IAAK,MAAO,OAAQ,OAAS,GAAM,EAAW,EAAE,CAAC,CAAE,EAC1D,CAAE,IAAK,IAAK,MAAO,YAAa,QAAS,GAAM,OAAS,GAAO,EAAE,YAAc,KAAO,IAAM,EAAY,EAAE,SAAS,CAAG,CACxH,EAEM,GAAc,CAClB,CAAE,MAAO,YAAa,MAAO,EAAkB,KAAM,MAAgB,EAGrE,GAAI,EAAa,CAAC,CAAE,MAAO,YAAa,MAAO,uBAAwB,KAAM,MAAgB,CAAC,EAAI,CAAC,EACnG,GAAI,GAAiB,CAAC,CAAE,MAAO,aAAc,MAAO,GAAiB,KAAM,MAAgB,CAAC,EAAI,CAAC,CACnG,EAEA,OACE,EAAA,EAAA,IAAA,CAAC,GAAD,CACS,QACM,cACL,SACR,OAAQ,GACR,SAAS,OACT,eAAgB,EAChB,OAAO,EAAA,EAAA,IAAA,CAAC,GAAD,CAAW,QAAS,EAAgB,WAAS,KAAM,EAAQ,OAAS,GAAM,OAAO,EAAE,CAAC,CAAI,CAAA,EAC/F,QACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAK,KAAM,gBAAe,EAAQ,SAAU,KAAK,SAAU,SAAA,EAAQ,IAAQ,CAAA,GACzF,EAAA,EAAA,IAAA,CAAC,GAAD,CAAa,MAAO,EAAc,CAAA,CAClC,CAAA,CAAA,EAGJ,UAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,IAAK,GACL,UAAW,GAAG,EAAK,SAAS,GAAG,EAAK,YACpC,cAAa,GACb,SAAU,EACV,KAAK,QACL,aAAY,GAAG,EAAM,2DACrB,mBAAkB,EAClB,YAAe,EAAW,GAAM,IAAM,EAAO,OAAS,EAAO,OAAS,EAAI,KAAK,EAC/E,WAAc,EAAU,IAAI,EAC5B,UAAW,GAVb,SAAA,EAYE,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAW,EAAK,IACT,QACC,SACR,QAAS,OAAO,EAAM,GAAG,IACzB,KAAK,MACL,aAAY,GACZ,cAAgB,GAAmC,EAAU,GAAQ,EAAE,OAAO,CAAC,EAC/E,mBAAsB,EAAU,IAAI,EARtC,SAAA,EAUE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,GAAI,GAAW,GAAS,WAAW,EAAG,MAAO,EAAkB,IAAK,EAAO,OAAQ,EAAQ,CAAQ,CAAA,CAC7G,CAAA,EACL,GAAW,EAAQ,MAAQ,GAC1B,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,YAAU,eACV,UAAW,GAAG,EAAK,YAAY,GAAG,EAAK,SACvC,EAAG,EACH,EAAG,EAAG,KAAK,IAAI,EAAK,EAAQ,KAAK,CAAC,EAClC,MAAO,EACP,OAAQ,KAAK,IAAI,EAAG,EAAG,CAAC,EAAI,EAAG,KAAK,IAAI,EAAK,EAAQ,KAAK,CAAC,CAAC,CAC7D,CAAA,EACC,KACH,EAAM,KAAK,EAAG,KACb,EAAA,EAAA,KAAA,CAAC,IAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAK,KAAM,GAAI,EAAM,GAAI,EAAO,EAAO,GAAI,EAAM,EAAG,CAAC,CAAC,EAAG,GAAI,EAAM,EAAG,CAAC,CAAC,CAAI,CAAA,GAC7F,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAK,KAAM,EAAG,EAAO,EAAG,EAAG,EAAG,CAAC,EAAG,GAAG,SAAS,WAAW,MAAO,SAAA,EAAM,OAAO,EAAS,CAAA,CACtG,CAAA,EAHK,CAGL,CACJ,GACD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAK,KAAM,GAAI,EAAM,GAAI,EAAO,EAAO,GAAI,EAAM,EAAG,CAAC,CAAC,EAAG,GAAI,EAAM,EAAG,CAAC,CAAC,CAAI,CAAA,EAC5F,GAAQ,IAAK,IACZ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAkB,kBAAiB,EAAE,IAAK,UAAW,EAAK,KAAM,EAAG,EAAE,EAAG,EAAG,EAAS,EAAG,WAAY,EAAE,OAAS,SAAA,EAAE,IAAW,EAAhH,EAAE,GAA8G,CAC5H,EAEA,GACC,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,OAAO,UAAW,EAAK,UAAW,EAAG,EAAS,CAAC,CAAE,EAAG,EAAG,CAAE,EAAG,EAAG,EAAG,CAAQ,CAAE,EAAG,CAAE,EAAG,EAAG,CAAI,EAAG,EAAG,EAAG,CAAC,CAAE,CAAC,CAAC,CAAI,CAAA,EAC3H,KACH,GACC,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,YAAU,UAAb,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAK,UAAW,GAAI,EAAM,GAAI,EAAO,EAAO,GAAI,EAAM,EAAG,EAAQ,KAAK,CAAC,EAAG,GAAI,EAAM,EAAG,EAAQ,KAAK,CAAC,CAAI,CAAA,GAK1H,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,YAAU,gBAAgB,UAAW,GAAG,EAAK,KAAK,GAAG,EAAK,OAAQ,EAAG,EAAO,EAAG,EAAG,EAAG,EAAQ,KAAK,EAAI,EAAG,WAAW,QAA1H,SAAA,CACG,EAAQ,MAAM,MAAI,EAAY,EAAQ,KAAK,CACxC,CACL,CAAA,CAAA,CACD,CAAA,EAAA,KACH,IAAS,KAON,MANF,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,YAAU,MAAb,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAK,IAAK,GAAI,EAAM,CAAI,EAAG,GAAI,EAAM,CAAI,EAAG,GAAI,EAAO,GAAI,EAAQ,CAAQ,CAAA,EAC3F,IACC,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,YAAY,UAAW,GAAG,EAAK,KAAK,GAAG,EAAK,OAAQ,EAAG,EAAM,EAAG,GAAW,WAAW,SAAS,SAAA,KAAS,CAAA,EACtH,IACH,CACD,CAAA,EACH,GAAK,KAAK,EAAK,KACd,EAAA,EAAA,KAAA,CAAC,IAAD,CAAW,YAAU,YAArB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,YAAU,OACV,UAAW,GAAG,EAAK,KAAK,GAAG,EAAK,SAChC,KAAM,QAAQ,GAAW,GAAS,WAAW,EAAE,GAC/C,EAAG,EAAe,EAAK,EAAI,IAAK,IAAO,CAAE,EAAG,EAAE,EAAG,EAAG,EAAG,CAAC,CAAE,EAAE,CAAC,CAC9D,CAAA,EACA,EAAI,OAAS,GACZ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,OAAO,UAAW,GAAG,EAAK,KAAK,GAAG,EAAK,OAAQ,WAAY,EAAG,OAAQ,EAAkB,EAAG,EAAW,CAAG,CAAI,CAAA,EAC3H,IACH,CAVK,EAAA,CAUL,CACJ,EACA,IACC,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,aAAa,UAAW,EAAK,WAAY,OAAQ,GAAiB,EAAG,EAAiB,CAAA,EACpG,KACH,EAAW,MACV,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAW,EAAK,OAAQ,GAAI,EAAG,EAAO,EAAW,KAAK,CAAC,CAAC,EAAG,GAAI,EAAG,EAAW,KAAK,SAAS,EAAG,EAAG,EAAG,KAAM,CAAmB,CAAA,EACnI,KACH,GACC,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,YAAU,QAAb,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAK,UAAW,YAAU,YAAY,GAAI,EAAM,EAAG,EAAO,EAAY,CAAC,CAAC,CAAC,EAAG,GAAI,EAAM,EAAG,EAAO,EAAY,CAAC,CAAC,CAAC,EAAG,GAAI,EAAO,GAAI,EAAQ,CAAQ,CAAA,EACjK,EAAY,YAAc,KAEvB,MADF,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAW,EAAK,OAAQ,GAAI,EAAG,EAAO,EAAY,CAAC,CAAC,EAAG,GAAI,EAAG,KAAK,IAAI,EAAG,EAAY,SAAS,CAAC,EAAG,EAAG,EAAG,KAAM,CAAmB,CAAA,CAE3I,CACD,CAAA,EAAA,IACD,KACL,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,GAAI,EAAQ,UAAW,EAAK,OAAQ,YAAU,SACjD,SAAA,EACG,GAAG,GAAqB,EAAY,CAAC,EAAE,IAAI,EAAY,YAAc,KAAO,aAAe,GAAG,EAAY,EAAY,SAAS,EAAE,eAChI,IAAe,KAAkD,GAA3C,eAAe,EAAY,CAAU,KAC5D,EACA,CAAA,EACL,GACC,EAAA,EAAA,IAAA,CAAC,GAAD,CACE,KAAM,EAAY,EAAG,EAAO,EAAY,CAAC,CAAC,EAAG,CAAK,EAAI,EAAG,EAAO,EAAY,CAAC,CAAC,EAAI,EAAiB,EAAG,EAAO,EAAY,CAAC,CAAC,EAAG,CAAK,EACnI,KAAM,EAAY,EAAG,EAAO,EAAY,CAAC,CAAC,EAAG,CAAK,EAClD,IAAK,EACL,MAAO,GAAqB,EAAY,CAAC,EACzC,KAAM,CACJ,CAAE,IAAK,IAAK,MAAO,YAAa,MAAO,EAAY,YAAc,KAAO,KAAO,EAAY,EAAY,SAAS,EAAG,MAAO,EAAkB,KAAM,MAAO,EACzJ,GAAI,IAAe,KAAkI,CAAC,EAA5H,CAAC,CAAE,IAAK,IAAK,MAAO,YAAa,MAAO,EAAY,CAAU,EAAG,MAAO,uBAAwB,KAAM,MAAgB,CAAC,CACnJ,CACD,CAAA,EACC,IACD,GACK,CAAA,CAEhB"}
@@ -0,0 +1,2 @@
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{s as t}from"./index-BC5Uslm5.js";var n=e(t(),1),r=(0,n.createContext)({seats:[],rootsData:null,rootsError:null,otherRunning:[],dispatchEnabled:!0,onHandoff:()=>void 0,onOpenAccounts:()=>void 0});function i(){return(0,n.useContext)(r)}export{i as n,r as t};
2
+ //# sourceMappingURL=chat-pane-data-CfbpeAYX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-pane-data-CfbpeAYX.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/panes/chat-pane-data.ts"],"sourcesContent":["/**\n * routes/verse/panes/chat-pane-data.ts — the chat surface's extra data for\n * the FIRST-PARTY panes that need more than PaneProps (Tasks: other running\n * chats; Context: seats, roots detail, the handoff). DockHost provides it.\n *\n * Deliberately NOT part of the registry contract: PaneProps is what every\n * pane may rely on. A unit that needs something here should ask for it to be\n * added to PaneProps instead.\n */\nimport { createContext, useContext } from 'react';\nimport type { VerseSeat, VerseSessionRootsResponse } from '../../../data/api-types.js';\nimport type { ChatTask } from '../chat/tasks-model.js';\n\nexport interface ChatPaneData {\n seats: readonly VerseSeat[];\n rootsData: VerseSessionRootsResponse | null;\n rootsError: string | null;\n otherRunning: readonly ChatTask[];\n dispatchEnabled: boolean;\n onHandoff: (sessionId: string) => void;\n onOpenAccounts: () => void;\n}\n\nconst EMPTY: ChatPaneData = {\n seats: [],\n rootsData: null,\n rootsError: null,\n otherRunning: [],\n dispatchEnabled: true,\n onHandoff: () => undefined,\n onOpenAccounts: () => undefined,\n};\n\nexport const ChatPaneDataContext = createContext<ChatPaneData>(EMPTY);\n\nexport function useChatPaneData(): ChatPaneData {\n return useContext(ChatPaneDataContext);\n}\n"],"mappings":"0GAiCa,GAAA,EAAsB,EAAA,cAAA,CAA4B,CAT7D,MAAO,CAAC,EACR,UAAW,KACX,WAAY,KACZ,aAAc,CAAC,EACf,gBAAiB,GACjB,cAAiB,IAAA,GACjB,mBAAsB,IAAA,EAGuC,CAAK,EAEpE,SAAgB,GAAgC,CAC9C,OAAA,EAAO,EAAA,WAAA,CAAW,CAAmB,CACvC"}
@@ -0,0 +1,2 @@
1
+ import{C as e,M as t,N as n,O as r,a as i,i as a,t as o,w as s}from"./global-w7KDTTi0.js";import{r as c}from"./VerseShared-Bf-XTHCh.js";var l=/[A-Za-z0-9_$]+|\s+|[^A-Za-z0-9_$\s]/g,u=400,d=.3;function f(e){return e.match(l)??[]}function p(e,t){let n=[];for(let r of e){let e=n[n.length-1];e&&(e[1]===r[0]||/^\s*$/.test(t.slice(e[1],r[0])))?e[1]=r[1]:n.push([r[0],r[1]])}return n}function m(e,t){if(e===t)return null;let n=f(e),r=f(t);if(n.length===0||r.length===0||n.length>u||r.length>u)return null;let i=n.length,a=r.length,o=a+1,s=new Uint16Array((i+1)*o);for(let e=i-1;e>=0;e--)for(let t=a-1;t>=0;t--)s[e*o+t]=n[e]===r[t]?s[(e+1)*o+t+1]+1:Math.max(s[(e+1)*o+t],s[e*o+t+1]);let c=[],l=[],m=0,h=0,g=0,_=0,v=0;for(;m<i||h<a;)m<i&&h<a&&n[m]===r[h]?(v+=n[m].length,g+=n[m].length,_+=r[h].length,m++,h++):h<a&&(m===i||s[m*o+h+1]>=s[(m+1)*o+h])?(l.push([_,_+r[h].length]),_+=r[h].length,h++):(c.push([g,g+n[m].length]),g+=n[m].length,m++);let y=Math.max(e.length,t.length);return y>0&&v/y<d?null:{old:p(c,e),new:p(l,t)}}function h(e){let t=new Map;for(let n of e){let e=n.path.lastIndexOf(`/`),r=e<0?``:n.path.slice(0,e),i=e<0?n.path:n.path.slice(e+1),a=t.get(r);a||(a={dir:r,files:[]},t.set(r,a)),a.files.push({...n,name:i})}let n=[...t.values()];n.sort((e,t)=>e.dir===t.dir?0:e.dir===``?-1:t.dir===``?1:e.dir<t.dir?-1:1);for(let e of n)e.files.sort((e,t)=>e.name<t.name?-1:+(e.name>t.name));return n}function g(e){let t=0,n=0;for(let r of e)t+=r.additions,n+=r.deletions;return{files:e.length,additions:t,deletions:n}}var _={M:`modified`,A:`added`,D:`deleted`,R:`renamed`};function v(e){let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleTimeString(void 0,{hour:`numeric`,minute:`2-digit`})}function y(e){let t=[`Turn ${e.index}`];e.filesChanged!==null&&t.push(`${e.filesChanged} ${e.filesChanged===1?`file`:`files`}`),e.state===`running`?t.push(`running`):e.state===`undone`&&t.push(`undone`);let n=v(e.startedAt);return n&&t.push(n),t.join(` · `)}function b(e){return e.roots.some(e=>e.pre?.commit)}function x(e){for(let t of e.roots)if(t.pre&&!t.pre.commit&&t.pre.error)return t.pre.error;return null}function S(e){let t={};for(let n of e.roots){let e={};for(let t of n.conflicts)t.merge.clean&&(e[t.path]=`merge`);t[n.rootId]=e}return t}function C(e,t){let n=[];for(let r of e.roots)for(let e of r.conflicts)t[r.rootId]?.[e.path]||n.push(e.path);return n}function w(e){let t={restore:0,remove:0,conflicts:0,kept:0,uncaptured:0,unavailable:0};for(let n of e.roots){for(let e of n.apply)e.action===`delete`?t.remove+=1:t.restore+=1;t.conflicts+=n.conflicts.length,t.kept+=n.kept.length,t.uncaptured+=n.uncaptured.length,n.unavailable&&(t.unavailable+=1)}return t}function T(e,t,n=`${t}s`){return`${e.toLocaleString(`en-US`)} ${e===1?t:n}`}var E=`/api/verse/checkpoints`;async function D(e,t){if(n())return a(e,t);let i=await fetch(e,{method:`GET`,credentials:`same-origin`,headers:n()?{}:{"x-ashlr-read-client":s()},signal:t});if(i.status===401)throw r(),new o(`Read session expired.`,401,e);if(!i.ok){let t=null,n=null;try{let e=await i.json();t=typeof e.error==`string`&&e.error?e.error:null,n=typeof e.code==`string`&&e.code?e.code:null}catch{}throw new o(`GET ${e} failed (HTTP ${i.status}).`,i.status,e,t,n)}return await i.json()}async function O(n,r){let a=e();if(!a)throw new c;let o=await i(n,r,a);return t(),o}var k={list:(e,t)=>D(`${E}?${new URLSearchParams({chatId:e}).toString()}`,t),diff:(e,t)=>{let n=new URLSearchParams({chatId:e.chatId,turnId:e.turnId,rootId:e.rootId,mode:e.mode});return e.file&&n.set(`file`,e.file),D(`${E}/diff?${n.toString()}`,t)},review:e=>O(`${E}/review`,e),previewUndo:(e,t)=>O(`${E}/undo/preview`,{chatId:e,turnId:t}),previewRedo:e=>O(`${E}/redo/preview`,{chatId:e}),apply:(e,t,n)=>O(`${E}/apply`,{chatId:e,previewId:t,resolutions:n})};function A(e){if(e&&typeof e==`object`){let t=e;if(t.name===`DispatchDisabledError`)return`This server is read-only (started without dispatch), so changes cannot be restored here.`;if(t.name===`VerseMutationLockedError`)return`Unlock actions with the mutation token first.`;if(t.status===401)return"The mutation token was rejected. Unlock again with the token `ashlr verse` printed.";if(t.detail)return t.detail;if(t.status===404)return"This server has no checkpoint routes yet. Update Ashlr and restart `ashlr verse`."}return`The checkpoint action failed.`}function j(e){return e&&typeof e==`object`&&typeof e.code==`string`?e.code:null}export{h as a,T as c,b as d,y as f,_ as i,g as l,m,A as n,S as o,C as p,j as r,w as s,k as t,x as u};
2
+ //# sourceMappingURL=checkpoint-queries-BKD2evmX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint-queries-BKD2evmX.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/changes/changes-model.ts","../../../../../../src/web-ui/routes/verse/changes/checkpoint-queries.ts"],"sourcesContent":["/**\n * routes/verse/changes/changes-model.ts — pure helpers for the Changes pane:\n * word-level diff, the file tree, labels, and Undo plan bookkeeping.\n * No React, no DOM.\n */\nimport type {\n VerseCheckpointDiffFile,\n VerseCheckpointPreviewResponse,\n VerseCheckpointResolution,\n VerseCheckpointTurn,\n} from '../../../../core/verse/checkpoint-types.js';\n\n// ---------------------------------------------------------------------------\n// Word-level diff\n// ---------------------------------------------------------------------------\n\nexport type Span = [number, number];\n\nexport interface WordSpans {\n old: Span[];\n new: Span[];\n}\n\n/** Words, runs of whitespace, and single punctuation characters. */\nconst TOKEN = /[A-Za-z0-9_$]+|\\s+|[^A-Za-z0-9_$\\s]/g;\nconst WORD_DIFF_MAX_TOKENS = 400;\n/** Below this share of unchanged text, emphasis is noise: the whole line changed. */\nconst WORD_DIFF_MIN_SHARED = 0.3;\n\nfunction tokens(text: string): string[] {\n return text.match(TOKEN) ?? [];\n}\n\n/** Merge touching spans (and spans separated only by whitespace) into one. */\nfunction coalesce(spans: Span[], text: string): Span[] {\n const out: Span[] = [];\n for (const s of spans) {\n const last = out[out.length - 1];\n if (last && (last[1] === s[0] || /^\\s*$/.test(text.slice(last[1], s[0])))) last[1] = s[1];\n else out.push([s[0], s[1]]);\n }\n return out;\n}\n\n/**\n * Which parts of a changed line changed, word by word (LCS over tokens).\n * Null when the lines are equal, too long, or so different that highlighting\n * every word says nothing.\n */\nexport function wordDiff(oldLine: string, newLine: string): WordSpans | null {\n if (oldLine === newLine) return null;\n const a = tokens(oldLine);\n const b = tokens(newLine);\n if (a.length === 0 || b.length === 0 || a.length > WORD_DIFF_MAX_TOKENS || b.length > WORD_DIFF_MAX_TOKENS) return null;\n const n = a.length;\n const m = b.length;\n const width = m + 1;\n const table = new Uint16Array((n + 1) * width);\n for (let i = n - 1; i >= 0; i--) {\n for (let j = m - 1; j >= 0; j--) {\n table[i * width + j] = a[i] === b[j] ? table[(i + 1) * width + j + 1]! + 1 : Math.max(table[(i + 1) * width + j]!, table[i * width + j + 1]!);\n }\n }\n const oldSpans: Span[] = [];\n const newSpans: Span[] = [];\n let i = 0;\n let j = 0;\n let pa = 0;\n let pb = 0;\n let shared = 0;\n while (i < n || j < m) {\n if (i < n && j < m && a[i] === b[j]) {\n shared += a[i]!.length;\n pa += a[i]!.length;\n pb += b[j]!.length;\n i++;\n j++;\n } else if (j < m && (i === n || table[i * width + j + 1]! >= table[(i + 1) * width + j]!)) {\n newSpans.push([pb, pb + b[j]!.length]);\n pb += b[j]!.length;\n j++;\n } else {\n oldSpans.push([pa, pa + a[i]!.length]);\n pa += a[i]!.length;\n i++;\n }\n }\n const longest = Math.max(oldLine.length, newLine.length);\n if (longest > 0 && shared / longest < WORD_DIFF_MIN_SHARED) return null;\n return { old: coalesce(oldSpans, oldLine), new: coalesce(newSpans, newLine) };\n}\n\n// ---------------------------------------------------------------------------\n// File tree\n// ---------------------------------------------------------------------------\n\nexport interface FileGroup {\n /** Directory ('' for the repository root). */\n dir: string;\n files: Array<VerseCheckpointDiffFile & { name: string }>;\n}\n\n/** Files grouped by directory, directories and files in path order. */\nexport function groupByDirectory(files: readonly VerseCheckpointDiffFile[]): FileGroup[] {\n const groups = new Map<string, FileGroup>();\n for (const f of files) {\n const cut = f.path.lastIndexOf('/');\n const dir = cut < 0 ? '' : f.path.slice(0, cut);\n const name = cut < 0 ? f.path : f.path.slice(cut + 1);\n let g = groups.get(dir);\n if (!g) {\n g = { dir, files: [] };\n groups.set(dir, g);\n }\n g.files.push({ ...f, name });\n }\n const out = [...groups.values()];\n out.sort((x, y) => (x.dir === y.dir ? 0 : x.dir === '' ? -1 : y.dir === '' ? 1 : x.dir < y.dir ? -1 : 1));\n for (const g of out) g.files.sort((x, y) => (x.name < y.name ? -1 : x.name > y.name ? 1 : 0));\n return out;\n}\n\nexport function totals(files: readonly VerseCheckpointDiffFile[]): { files: number; additions: number; deletions: number } {\n let additions = 0;\n let deletions = 0;\n for (const f of files) {\n additions += f.additions;\n deletions += f.deletions;\n }\n return { files: files.length, additions, deletions };\n}\n\nexport const STATUS_WORD: Record<VerseCheckpointDiffFile['status'], string> = { M: 'modified', A: 'added', D: 'deleted', R: 'renamed' };\n\n// ---------------------------------------------------------------------------\n// Turns\n// ---------------------------------------------------------------------------\n\nexport function formatTime(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n}\n\nexport function turnLabel(turn: VerseCheckpointTurn): string {\n const bits = [`Turn ${turn.index}`];\n if (turn.filesChanged !== null) bits.push(`${turn.filesChanged} ${turn.filesChanged === 1 ? 'file' : 'files'}`);\n if (turn.state === 'running') bits.push('running');\n else if (turn.state === 'undone') bits.push('undone');\n const at = formatTime(turn.startedAt);\n if (at) bits.push(at);\n return bits.join(' · ');\n}\n\n/** Whether a turn has a usable `pre` checkpoint in at least one repository. */\nexport function turnHasCheckpoint(turn: VerseCheckpointTurn): boolean {\n return turn.roots.some((r) => r.pre?.commit);\n}\n\n/** The first checkpoint error of a turn, for the \"no checkpoint\" notice. */\nexport function turnCheckpointError(turn: VerseCheckpointTurn): string | null {\n for (const r of turn.roots) if (r.pre && !r.pre.commit && r.pre.error) return r.pre.error;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Undo / Redo plan\n// ---------------------------------------------------------------------------\n\nexport type Resolutions = Record<string, Record<string, VerseCheckpointResolution>>;\n\n/**\n * The starting decisions for a preview: a conflict that merges cleanly starts\n * on \"merge\" (it keeps the later edit AND reverts the agent's); every other\n * conflict starts undecided — the operator must choose.\n */\nexport function initialResolutions(preview: VerseCheckpointPreviewResponse): Resolutions {\n const out: Resolutions = {};\n for (const root of preview.roots) {\n const inner: Record<string, VerseCheckpointResolution> = {};\n for (const c of root.conflicts) if (c.merge.clean) inner[c.path] = 'merge';\n out[root.rootId] = inner;\n }\n return out;\n}\n\nexport function undecided(preview: VerseCheckpointPreviewResponse, resolutions: Resolutions): string[] {\n const out: string[] = [];\n for (const root of preview.roots) {\n for (const c of root.conflicts) if (!resolutions[root.rootId]?.[c.path]) out.push(c.path);\n }\n return out;\n}\n\nexport interface PlanCounts {\n restore: number;\n remove: number;\n conflicts: number;\n kept: number;\n uncaptured: number;\n unavailable: number;\n}\n\nexport function planCounts(preview: VerseCheckpointPreviewResponse): PlanCounts {\n const c: PlanCounts = { restore: 0, remove: 0, conflicts: 0, kept: 0, uncaptured: 0, unavailable: 0 };\n for (const r of preview.roots) {\n for (const f of r.apply) {\n if (f.action === 'delete') c.remove += 1;\n else c.restore += 1;\n }\n c.conflicts += r.conflicts.length;\n c.kept += r.kept.length;\n c.uncaptured += r.uncaptured.length;\n if (r.unavailable) c.unavailable += 1;\n }\n return c;\n}\n\nexport function plural(n: number, one: string, many = `${one}s`): string {\n return `${n.toLocaleString('en-US')} ${n === 1 ? one : many}`;\n}\n","/**\n * routes/verse/changes/checkpoint-queries.ts — the page's side of\n * `/api/verse/checkpoints*` (server: core/verse/checkpoints-api.ts).\n *\n * Reads keep the error CODE (like git-queries.ts): the pane tells \"no\n * checkpoint for this turn\" (409 VERSE_CHECKPOINT_UNAVAILABLE) apart from a\n * failure. Writes go through the held mutation token; no token →\n * VerseMutationLockedError, which the pane's token gate turns into the unlock\n * dialog.\n *\n * Everything is gathered in one `CheckpointClient` object so tests (and a\n * future pane host) can hand the panel a fake.\n */\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, getReadClientProof, reportSessionExpired, touchMutationHold } from '../../../data/auth-store.js';\nimport { isRemoteMobileMode } from '../../../data/remote-mode.js';\nimport type {\n VerseCheckpointApplyResponse,\n VerseCheckpointDecision,\n VerseCheckpointDiffMode,\n VerseCheckpointDiffResponse,\n VerseCheckpointListResponse,\n VerseCheckpointPreviewResponse,\n VerseCheckpointResolution,\n VerseCheckpointReviewResponse,\n} from '../../../../core/verse/checkpoint-types.js';\nimport { VerseMutationLockedError } from '../verse-queries.js';\n\nexport const CHECKPOINTS_API = '/api/verse/checkpoints';\n\nasync function get<T>(path: string, signal?: AbortSignal): Promise<T> {\n if (isRemoteMobileMode()) return apiGet<T>(path, signal);\n const res = await fetch(path, {\n method: 'GET',\n credentials: 'same-origin',\n headers: isRemoteMobileMode() ? {} : { 'x-ashlr-read-client': getReadClientProof() },\n signal,\n });\n if (res.status === 401) {\n reportSessionExpired();\n throw new ApiError('Read session expired.', 401, path);\n }\n if (!res.ok) {\n let detail: string | null = null;\n let code: string | null = null;\n try {\n const body = (await res.json()) as { error?: unknown; code?: unknown };\n detail = typeof body.error === 'string' && body.error ? body.error : null;\n code = typeof body.code === 'string' && body.code ? body.code : null;\n } catch {\n /* not JSON */\n }\n throw new ApiError(`GET ${path} failed (HTTP ${res.status}).`, res.status, path, detail, code);\n }\n return (await res.json()) as T;\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseMutationLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nexport interface ReviewInput {\n chatId: string;\n turnId: string;\n rootId: string;\n file: string;\n hunk?: string;\n decision: VerseCheckpointDecision;\n}\n\nexport interface CheckpointClient {\n list(chatId: string, signal?: AbortSignal): Promise<VerseCheckpointListResponse>;\n diff(\n q: { chatId: string; turnId: string; rootId: string; mode: VerseCheckpointDiffMode; file?: string | null },\n signal?: AbortSignal,\n ): Promise<VerseCheckpointDiffResponse>;\n review(input: ReviewInput): Promise<VerseCheckpointReviewResponse>;\n previewUndo(chatId: string, turnId: string): Promise<VerseCheckpointPreviewResponse>;\n previewRedo(chatId: string): Promise<VerseCheckpointPreviewResponse>;\n apply(chatId: string, previewId: string, resolutions: Record<string, Record<string, VerseCheckpointResolution>>): Promise<VerseCheckpointApplyResponse>;\n}\n\nexport const checkpointClient: CheckpointClient = {\n list: (chatId, signal) => get(`${CHECKPOINTS_API}?${new URLSearchParams({ chatId }).toString()}`, signal),\n diff: (q, signal) => {\n const params = new URLSearchParams({ chatId: q.chatId, turnId: q.turnId, rootId: q.rootId, mode: q.mode });\n if (q.file) params.set('file', q.file);\n return get(`${CHECKPOINTS_API}/diff?${params.toString()}`, signal);\n },\n review: (input) => post(`${CHECKPOINTS_API}/review`, input),\n previewUndo: (chatId, turnId) => post(`${CHECKPOINTS_API}/undo/preview`, { chatId, turnId }),\n previewRedo: (chatId) => post(`${CHECKPOINTS_API}/redo/preview`, { chatId }),\n apply: (chatId, previewId, resolutions) => post(`${CHECKPOINTS_API}/apply`, { chatId, previewId, resolutions }),\n};\n\n/** One operator sentence for a failed checkpoint call. */\nexport function describeCheckpointError(err: unknown): string {\n if (err && typeof err === 'object') {\n const e = err as { name?: string; status?: number; detail?: string | null };\n if (e.name === 'DispatchDisabledError') return 'This server is read-only (started without dispatch), so changes cannot be restored here.';\n if (e.name === 'VerseMutationLockedError') return 'Unlock actions with the mutation token first.';\n if (e.status === 401) return 'The mutation token was rejected. Unlock again with the token `ashlr verse` printed.';\n if (e.detail) return e.detail;\n if (e.status === 404) return 'This server has no checkpoint routes yet. Update Ashlr and restart `ashlr verse`.';\n }\n return 'The checkpoint action failed.';\n}\n\nexport function errorCode(err: unknown): string | null {\n return err && typeof err === 'object' && typeof (err as { code?: unknown }).code === 'string' ? (err as { code: string }).code : null;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{C as e,M as t,V as n,a as r,i,t as a}from"./global-w7KDTTi0.js";import{O as o}from"./VerseShared-Bf-XTHCh.js";import{c as s,d as c,l,o as u,r as d,s as f,u as p}from"./types-IYKrYLku.js";var m=`verse-cloud`,h=3e4,g=class extends Error{constructor(){super(`Unlock actions with the mutation token first.`),this.name=`CloudLockedError`}},_=class extends Error{failure;constructor(e,t){super(e),this.failure=t,this.name=`CloudLaunchRefusedError`}};function v(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function y(e){if(!v(e))return null;let{seat:t,budget:n,tasks:r,backlog:i}=e;if(!v(t)||typeof t.ready!=`boolean`||!v(n)||!v(n.budget)||!v(n.canLaunch)||!v(n.canSelfImprove))return null;for(let e of[`creditsTotalUsd`,`estimatedSpentUsd`,`estimatedRemainingUsd`,`sessionsToday`,`selfImproveToday`,`running`])if(typeof n[e]!=`number`||!Number.isFinite(n[e]))return null;return!Array.isArray(r)||!r.every(e=>v(e)&&typeof e.id==`string`&&typeof e.state==`string`)||!v(i)||!Array.isArray(i.items)?null:e}var b=`The cloud lane is not in this build yet.`;function x(e){return e instanceof a?e.status===404?b:e.status===503?`The cloud lane failed to load on the server.`:`The cloud lane answered HTTP ${e.status}.`:`The cloud lane could not be reached.`}var S={key:m,fetch:async e=>{try{let t=y(await i(l,e));return t===null?{value:null,available:!0,reason:`Unrecognized response — update Ashlr.`}:{value:t,available:!0,reason:null}}catch(e){if(e instanceof a&&e.status===401||e instanceof DOMException&&e.name===`AbortError`)throw e;return{value:null,available:!1,reason:x(e)}}}};async function C(n,i){let a=e();if(!a)throw new g;let o=await r(n,i,a);return t(),o}function w(){n(m),o()}async function T(e){try{let t=await C(s,e);if(!v(t)||t.ok!==!0||!v(t.task))throw new _(v(t)&&typeof t.error==`string`&&t.error?t.error:`The cloud session was not started, and the server sent no reason.`,v(t)&&typeof t.failure==`string`?t.failure:null);return t}finally{w()}}async function E(e){let t=await C(u,e);return n(m),t}async function D(e={count:1}){try{let t=await C(f,e);return{launched:v(t)&&Array.isArray(t.launched)?t.launched:[],skipped:v(t)&&Array.isArray(t.skipped)?t.skipped:[]}}finally{w()}}async function O(){try{return await C(p,{})}finally{w()}}async function k(e){if(!d.test(e))throw Error(`That task id is not one Verse issued, so nothing was sent.`);try{return await C(`${c}/${e}/dismiss`,{})}finally{w()}}export{T as a,E as c,k as i,h as n,O as o,S as r,D as s,b as t};
2
+ //# sourceMappingURL=cloud-queries-CsU54eNn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-queries-CsU54eNn.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/cloud/cloud-queries.ts"],"sourcesContent":["/**\n * routes/verse/cloud/cloud-queries.ts — the one read and the writes behind\n * the cloud lane's UI (3.11 unit C3; server: core/cloud/cloud-api.ts, C2).\n *\n * GET /api/verse/cloud CloudOverviewResponse\n * POST /api/verse/cloud/launch CloudLaunchRequest → CloudLaunchResponse\n * POST /api/verse/cloud/budget CloudBudgetUpdate\n * POST /api/verse/cloud/refresh (re-read tasks from GitHub)\n * POST /api/verse/cloud/improve CloudImproveRequest → CloudImproveResponse\n * POST /api/verse/cloud/tasks/<id>/dismiss (mark closed; never touches GitHub)\n *\n * WHY the read is OPTIONAL (the surface-data.ts rule): the routes land in a\n * parallel unit, and a server without them answers 404. That is \"this build\n * has no cloud lane yet\" — one card's designed state — never a broken\n * Command. 401 and aborts still propagate: an expired read session is the\n * whole app's state.\n *\n * LAZY ONLY. Everything that imports this file (Command's card, the Usage\n * panel, the Fleet chip, the composer's \"Run in cloud\") is itself behind an\n * import(); nothing cloud-related may cost chat first-paint bytes.\n *\n * Writes pull the held mutation token (CloudLockedError without one — the\n * callers route every write through a token gate that opens the unlock\n * dialog first), then invalidate the overview so every cloud view moves\n * together, and nudge the shell's activity poll (Needs-you carries cloud\n * items).\n */\nimport {\n CLOUD_TASK_ID_PATTERN,\n VERSE_CLOUD_BUDGET_PATH,\n VERSE_CLOUD_IMPROVE_PATH,\n VERSE_CLOUD_LAUNCH_PATH,\n VERSE_CLOUD_PATH,\n VERSE_CLOUD_REFRESH_PATH,\n VERSE_CLOUD_TASKS_PATH,\n type CloudBudgetUpdate,\n type CloudImproveRequest,\n type CloudImproveResponse,\n type CloudLaunchFailureCode,\n type CloudLaunchRequest,\n type CloudLaunchResponse,\n type CloudOverviewResponse,\n} from '../../../../core/cloud/types.js';\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { refreshActivity } from '../shell/useActivity.js';\nimport type { OptionalRead } from '../command/surface-data.js';\n\nexport const CLOUD_KEY = 'verse-cloud';\n\n/** The card, the chip and the panel all poll at this pace while visible (SPEC 3.11 C3). */\nexport const CLOUD_POLL_MS = 30_000;\n\nexport class CloudLockedError extends Error {\n constructor() {\n super('Unlock actions with the mutation token first.');\n this.name = 'CloudLockedError';\n }\n}\n\n/**\n * The server answered a launch with `ok: false` — a budget gate, a missing\n * seat, a CLI that printed no session. `message` is the server's own\n * sentence; `failure` the machine code for tests and chips.\n */\nexport class CloudLaunchRefusedError extends Error {\n constructor(message: string, public readonly failure: CloudLaunchFailureCode | null) {\n super(message);\n this.name = 'CloudLaunchRefusedError';\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Just enough structure that no render can crash on `undefined.map` or read\n * a budget field that is not there. Field-level honesty (null = unknown) is\n * the model's job.\n */\nexport function narrowCloudOverview(raw: unknown): CloudOverviewResponse | null {\n if (!isRecord(raw)) return null;\n const { seat, budget, tasks, backlog } = raw;\n if (!isRecord(seat) || typeof seat['ready'] !== 'boolean') return null;\n if (!isRecord(budget) || !isRecord(budget['budget']) || !isRecord(budget['canLaunch']) || !isRecord(budget['canSelfImprove'])) return null;\n for (const key of ['creditsTotalUsd', 'estimatedSpentUsd', 'estimatedRemainingUsd', 'sessionsToday', 'selfImproveToday', 'running']) {\n if (typeof budget[key] !== 'number' || !Number.isFinite(budget[key])) return null;\n }\n if (!Array.isArray(tasks) || !tasks.every((t) => isRecord(t) && typeof t['id'] === 'string' && typeof t['state'] === 'string')) return null;\n if (!isRecord(backlog) || !Array.isArray(backlog['items'])) return null;\n return raw as unknown as CloudOverviewResponse;\n}\n\n/**\n * The 404 sentence. Exported so Command's CloudCard can recognise a server\n * without the lane and render nothing at all, rather than spending a\n * full-width row to say so; launch buttons elsewhere still use it as their\n * disabled tooltip.\n */\nexport const CLOUD_NOT_IN_BUILD = 'The cloud lane is not in this build yet.';\n\n/** Operator words for a cloud read that did not answer — never a path, never a trace. */\nfunction absence(err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) return CLOUD_NOT_IN_BUILD;\n if (err.status === 503) return 'The cloud lane failed to load on the server.';\n return `The cloud lane answered HTTP ${err.status}.`;\n }\n return 'The cloud lane could not be reached.';\n}\n\nexport const cloudQuery: QueryDef<OptionalRead<CloudOverviewResponse>> = {\n key: CLOUD_KEY,\n fetch: async (signal) => {\n try {\n const value = narrowCloudOverview(await apiGet<unknown>(VERSE_CLOUD_PATH, signal));\n if (value === null) {\n // Nothing is shown rather than guessed from an unknown shape.\n return { value: null, available: true, reason: 'Unrecognized response — update Ashlr.' };\n }\n return { value, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { value: null, available: false, reason: absence(err) };\n }\n },\n};\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new CloudLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nfunction settled(): void {\n invalidate(CLOUD_KEY);\n void refreshActivity();\n}\n\n/**\n * Launch one cloud session. Resolves only on `ok: true` with a task; a\n * refusal the server words in a 200 body is thrown as CloudLaunchRefusedError\n * so every caller shows it the same way as a 4xx refusal (whose sentence is\n * `ApiError.detail`). Invalidates either way — a failed launch is still a\n * recorded task.\n */\nexport async function launchCloudTask(request: CloudLaunchRequest): Promise<CloudLaunchResponse & { task: NonNullable<CloudLaunchResponse['task']> }> {\n try {\n const response = await post<CloudLaunchResponse>(VERSE_CLOUD_LAUNCH_PATH, request);\n if (!isRecord(response) || response.ok !== true || !isRecord(response.task)) {\n const error = isRecord(response) && typeof response.error === 'string' && response.error ? response.error : 'The cloud session was not started, and the server sent no reason.';\n const failure = isRecord(response) && typeof response.failure === 'string' ? response.failure : null;\n throw new CloudLaunchRefusedError(error, failure);\n }\n return response as CloudLaunchResponse & { task: NonNullable<CloudLaunchResponse['task']> };\n } finally {\n settled();\n }\n}\n\n/** One budget change (any subset; the server validates and clamps). */\nexport async function updateCloudBudget(update: CloudBudgetUpdate): Promise<unknown> {\n const result = await post<unknown>(VERSE_CLOUD_BUDGET_PATH, update);\n invalidate(CLOUD_KEY);\n return result;\n}\n\n/** Launch up to `count` backlog items now (the \"Improve Verse\" button). */\nexport async function runCloudImprove(request: CloudImproveRequest = { count: 1 }): Promise<CloudImproveResponse> {\n try {\n const result = await post<unknown>(VERSE_CLOUD_IMPROVE_PATH, request);\n const launched = isRecord(result) && Array.isArray(result['launched']) ? (result['launched'] as CloudImproveResponse['launched']) : [];\n const skipped = isRecord(result) && Array.isArray(result['skipped']) ? (result['skipped'] as CloudImproveResponse['skipped']) : [];\n return { launched, skipped };\n } finally {\n settled();\n }\n}\n\n/** Ask the server to re-read every open task from GitHub now. */\nexport async function refreshCloudTasks(): Promise<unknown> {\n try {\n return await post<unknown>(VERSE_CLOUD_REFRESH_PATH, {});\n } finally {\n settled();\n }\n}\n\n/**\n * Stop tracking one task (it becomes `closed`, \"Dismissed in Verse.\"). The id\n * is re-checked against the contract's pattern: it came from the server, but\n * it is spliced into a path the mutation token is sent to.\n */\nexport async function dismissCloudTask(taskId: string): Promise<unknown> {\n if (!CLOUD_TASK_ID_PATTERN.test(taskId)) throw new Error('That task id is not one Verse issued, so nothing was sent.');\n try {\n return await post<unknown>(`${VERSE_CLOUD_TASKS_PATH}/${taskId}/dismiss`, {});\n } finally {\n settled();\n }\n}\n"],"mappings":"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"}