gloomberb 0.16.1 → 0.16.2

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 (574) hide show
  1. package/README.md +2 -1
  2. package/package.json +2 -1
  3. package/src/api-client/beneficial-owners.ts +92 -0
  4. package/src/api-client/data.ts +26 -8
  5. package/src/api-client/errors.ts +12 -0
  6. package/src/api-client/geo.ts +363 -0
  7. package/src/api-client/index.ts +2 -0
  8. package/src/api-client/market-discovery.ts +10 -0
  9. package/src/api-client/paths.ts +30 -1
  10. package/src/api-client/perps.ts +37 -0
  11. package/src/api-client/request.ts +5 -2
  12. package/src/api-client/types.ts +2 -0
  13. package/src/brokers/account-cache.ts +24 -0
  14. package/src/cli/commands/command-utils.ts +8 -0
  15. package/src/cli/commands/crypto-hints.ts +75 -0
  16. package/src/cli/commands/market.ts +414 -106
  17. package/src/cli/commands/overview.ts +77 -32
  18. package/src/cli/commands/ticker.ts +101 -43
  19. package/src/cli/desktop-pane-shot.ts +34 -4
  20. package/src/cli/freshness.ts +61 -0
  21. package/src/cli/help.ts +1 -0
  22. package/src/cli/helpers.ts +4 -8
  23. package/src/cli/index.ts +12 -2
  24. package/src/cli/listing-arg.ts +321 -0
  25. package/src/cli/pane-functions/access-gate.ts +42 -0
  26. package/src/cli/pane-functions/catalog.ts +28 -1
  27. package/src/cli/pane-functions/data.ts +3 -1
  28. package/src/cli/pane-functions/dom.ts +20 -2
  29. package/src/cli/pane-functions/freshness.ts +400 -0
  30. package/src/cli/pane-functions/function-help.ts +27 -20
  31. package/src/cli/pane-functions/headless.ts +39 -11
  32. package/src/cli/pane-functions/index.ts +15 -4
  33. package/src/cli/pane-functions/options.ts +3 -0
  34. package/src/cli/pane-functions/report.ts +4 -0
  35. package/src/cli/pane-functions/resolver.ts +35 -7
  36. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  37. package/src/cli/pane-functions/screenshot.ts +7 -3
  38. package/src/cli/result.ts +41 -27
  39. package/src/cli/ticker-resolution.ts +7 -5
  40. package/src/components/chart/composite/composite-chart.tsx +88 -2536
  41. package/src/components/chart/composite/drawing-store.ts +59 -0
  42. package/src/components/chart/composite/legend.tsx +319 -0
  43. package/src/components/chart/composite/panel-bitmap.ts +139 -0
  44. package/src/components/chart/composite/panel-gestures.ts +59 -0
  45. package/src/components/chart/composite/panel-labels.ts +107 -0
  46. package/src/components/chart/composite/panel-surface.tsx +876 -0
  47. package/src/components/chart/composite/tool-catalog.ts +98 -0
  48. package/src/components/chart/composite/toolbar.tsx +186 -0
  49. package/src/components/chart/composite/tools.ts +8 -0
  50. package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
  51. package/src/components/chart/composite/use-composite-viewport.ts +143 -0
  52. package/src/components/command-bar/list/model.ts +5 -0
  53. package/src/components/command-bar/list/view.tsx +16 -3
  54. package/src/components/command-bar/pane-templates/workflow.ts +1 -0
  55. package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
  56. package/src/components/command-bar/workflow/ops.ts +1 -1
  57. package/src/components/command-bar/workflow/tickers.ts +6 -0
  58. package/src/components/data-table/view.tsx +29 -10
  59. package/src/components/feedback-dialog.tsx +2 -1
  60. package/src/components/form-modal/field-row.tsx +2 -2
  61. package/src/components/layout/detached-pane-shell.tsx +6 -3
  62. package/src/components/layout/pane/content.tsx +23 -10
  63. package/src/components/layout/pane/error-boundary.tsx +103 -0
  64. package/src/components/layout/pane/footer/registration.tsx +68 -23
  65. package/src/components/layout/pane/header.tsx +11 -11
  66. package/src/components/layout/shell/menu.ts +2 -1
  67. package/src/components/layout/shell/pane/actions.ts +2 -1
  68. package/src/components/layout/shell/pane/layers.tsx +14 -3
  69. package/src/components/metric-treemap/heat-surface.tsx +43 -16
  70. package/src/components/metric-treemap/heat-tiles.ts +18 -0
  71. package/src/components/metric-treemap/layout.ts +2 -0
  72. package/src/components/onboarding/onboarding-keyboard.ts +311 -0
  73. package/src/components/onboarding/onboarding-wizard.tsx +101 -788
  74. package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
  75. package/src/components/onboarding/use-onboarding-progress.ts +298 -0
  76. package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
  77. package/src/components/ticker/list-table-view.tsx +13 -1
  78. package/src/components/ui/fields.tsx +8 -0
  79. package/src/components/ui/range-track.tsx +10 -3
  80. package/src/components/ui/status.tsx +8 -2
  81. package/src/components/ui/tabs.tsx +7 -4
  82. package/src/components/ui/text-prompt-dialog.tsx +4 -2
  83. package/src/data/config/store/normalize.ts +17 -1
  84. package/src/i18n/es.ts +19 -1
  85. package/src/i18n/ja.ts +19 -1
  86. package/src/i18n/ko.ts +19 -1
  87. package/src/i18n/zh-cn.ts +19 -1
  88. package/src/i18n/zh-tw.ts +19 -1
  89. package/src/market-data/coordinator/chart.ts +1 -1
  90. package/src/market-data/coordinator/quotes.ts +23 -4
  91. package/src/market-data/fx-closes.ts +72 -0
  92. package/src/market-data/market/freshness.ts +78 -6
  93. package/src/market-data/market/session-close-note.ts +57 -0
  94. package/src/market-data/market/status.ts +151 -0
  95. package/src/market-data/published-apac-sessions.ts +66 -0
  96. package/src/market-data/quotes/contributions.ts +2 -0
  97. package/src/market-data/quotes/resolution.ts +2 -0
  98. package/src/market-data/quotes/screener-live-quotes.ts +49 -4
  99. package/src/plugins/builtin/account-management/pane.tsx +4 -0
  100. package/src/plugins/builtin/alerts/cli.ts +10 -5
  101. package/src/plugins/builtin/alerts/index.tsx +1 -0
  102. package/src/plugins/builtin/analytics/metrics.ts +8 -3
  103. package/src/plugins/builtin/analytics/risk-client.ts +191 -66
  104. package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
  105. package/src/plugins/builtin/analytics/risk-headless.ts +19 -13
  106. package/src/plugins/builtin/analytics/risk-model.ts +45 -17
  107. package/src/plugins/builtin/analytics/risk-pane.tsx +1 -0
  108. package/src/plugins/builtin/analytics/risk-test-data.ts +25 -1
  109. package/src/plugins/builtin/attention/headless.ts +6 -4
  110. package/src/plugins/builtin/attention/index.tsx +1 -1
  111. package/src/plugins/builtin/attention/pane.tsx +1 -1
  112. package/src/plugins/builtin/awards/headless.ts +1 -0
  113. package/src/plugins/builtin/awards/pane.tsx +1 -1
  114. package/src/plugins/builtin/backtest/headless.ts +1 -0
  115. package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
  116. package/src/plugins/builtin/buildout/index.tsx +1 -0
  117. package/src/plugins/builtin/catalysts/headless.ts +3 -1
  118. package/src/plugins/builtin/cds/headless.ts +2 -0
  119. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
  120. package/src/plugins/builtin/chart-composer/headless.ts +38 -3
  121. package/src/plugins/builtin/chart-composer/index.tsx +3 -1
  122. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
  123. package/src/plugins/builtin/chat/channels.ts +19 -3
  124. package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
  125. package/src/plugins/builtin/chat/content/footer.tsx +15 -6
  126. package/src/plugins/builtin/chat/content/index.tsx +120 -21
  127. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
  128. package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
  129. package/src/plugins/builtin/chat/direct-messages.ts +200 -0
  130. package/src/plugins/builtin/chat/index.tsx +1 -0
  131. package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
  132. package/src/plugins/builtin/chat/message/header.tsx +16 -6
  133. package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
  134. package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
  135. package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
  136. package/src/plugins/builtin/chat/message/types.ts +14 -2
  137. package/src/plugins/builtin/chat/profile-popover.ts +18 -13
  138. package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
  139. package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
  140. package/src/plugins/builtin/cloud/plugin.tsx +1 -0
  141. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  142. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  143. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  144. package/src/plugins/builtin/comment-letters/index.tsx +1 -0
  145. package/src/plugins/builtin/company-attention/headless.ts +5 -1
  146. package/src/plugins/builtin/company-attention/pane.tsx +1 -1
  147. package/src/plugins/builtin/company-kpis/headless.ts +1 -0
  148. package/src/plugins/builtin/congress-trades/headless.ts +1 -0
  149. package/src/plugins/builtin/correlation/compute.ts +59 -16
  150. package/src/plugins/builtin/correlation/geo.ts +34 -0
  151. package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
  152. package/src/plugins/builtin/correlation/headless.ts +42 -8
  153. package/src/plugins/builtin/correlation/history.ts +2 -0
  154. package/src/plugins/builtin/correlation/index.tsx +68 -14
  155. package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
  156. package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
  157. package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
  158. package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
  159. package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
  160. package/src/plugins/builtin/correlation/settings.ts +1 -1
  161. package/src/plugins/builtin/cot/headless.ts +6 -3
  162. package/src/plugins/builtin/cot/index.tsx +3 -3
  163. package/src/plugins/builtin/cot/model.ts +36 -3
  164. package/src/plugins/builtin/cpi/headless.ts +4 -0
  165. package/src/plugins/builtin/credit-boards/headless.ts +2 -0
  166. package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
  167. package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
  168. package/src/plugins/builtin/credit-documents/headless.ts +2 -0
  169. package/src/plugins/builtin/crypto-board/headless.ts +3 -0
  170. package/src/plugins/builtin/custom-view/loader.ts +1 -1
  171. package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
  172. package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
  173. package/src/plugins/builtin/doe/headless.ts +7 -0
  174. package/src/plugins/builtin/doe/range-bar.tsx +7 -37
  175. package/src/plugins/builtin/earnings/headless.ts +5 -0
  176. package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
  177. package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
  178. package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
  179. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
  180. package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
  181. package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
  182. package/src/plugins/builtin/econ/index.tsx +1 -0
  183. package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
  184. package/src/plugins/builtin/equity-screener/headless.ts +2 -0
  185. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  186. package/src/plugins/builtin/executives/index.tsx +1 -0
  187. package/src/plugins/builtin/exposure/headless.ts +3 -1
  188. package/src/plugins/builtin/fear-greed/headless.ts +2 -0
  189. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  190. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  191. package/src/plugins/builtin/futures-curve/headless.ts +39 -10
  192. package/src/plugins/builtin/futures-curve/index.tsx +3 -3
  193. package/src/plugins/builtin/futures-curve/model.ts +188 -4
  194. package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
  195. package/src/plugins/builtin/gpu/headless.ts +7 -3
  196. package/src/plugins/builtin/gpu/ladder.tsx +26 -30
  197. package/src/plugins/builtin/gpu/model.ts +27 -1
  198. package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
  199. package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
  200. package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
  201. package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
  202. package/src/plugins/builtin/holders/headless.ts +139 -5
  203. package/src/plugins/builtin/holders/index.tsx +10 -3
  204. package/src/plugins/builtin/holders/pane.tsx +20 -3
  205. package/src/plugins/builtin/holders/report-header.ts +95 -0
  206. package/src/plugins/builtin/holders/table-model.ts +20 -5
  207. package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
  208. package/src/plugins/builtin/holders/types.ts +2 -1
  209. package/src/plugins/builtin/insider/headless.ts +2 -0
  210. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
  211. package/src/plugins/builtin/iv-history/headless.ts +4 -1
  212. package/src/plugins/builtin/jobs/headless.ts +1 -0
  213. package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
  214. package/src/plugins/builtin/macro-day/headless.ts +2 -0
  215. package/src/plugins/builtin/market-halts/index.tsx +1 -0
  216. package/src/plugins/builtin/market-heatmap/data.ts +2 -0
  217. package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
  218. package/src/plugins/builtin/market-heatmap/index.tsx +39 -46
  219. package/src/plugins/builtin/market-heatmap/model.ts +146 -0
  220. package/src/plugins/builtin/market-heatmap/portfolio.ts +23 -4
  221. package/src/plugins/builtin/market-movers/headless.ts +2 -0
  222. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  223. package/src/plugins/builtin/members/client.ts +20 -3
  224. package/src/plugins/builtin/members/headless.ts +5 -3
  225. package/src/plugins/builtin/members/model.ts +10 -2
  226. package/src/plugins/builtin/members/pane.tsx +13 -6
  227. package/src/plugins/builtin/mna/distress/headless.ts +1 -0
  228. package/src/plugins/builtin/mna/headless.ts +1 -0
  229. package/src/plugins/builtin/money-markets/headless.ts +1 -0
  230. package/src/plugins/builtin/news/headless.ts +2 -0
  231. package/src/plugins/builtin/news/wire/index.tsx +8 -1
  232. package/src/plugins/builtin/notes/cli.ts +14 -6
  233. package/src/plugins/builtin/notes/index.tsx +1 -0
  234. package/src/plugins/builtin/openfda/index.tsx +1 -0
  235. package/src/plugins/builtin/options-calculator/headless.ts +2 -0
  236. package/src/plugins/builtin/options-positioning/headless.ts +3 -0
  237. package/src/plugins/builtin/options-scenario/headless.ts +5 -0
  238. package/src/plugins/builtin/pe-band/client.ts +48 -3
  239. package/src/plugins/builtin/pe-band/headless.ts +25 -7
  240. package/src/plugins/builtin/pe-band/model.ts +92 -16
  241. package/src/plugins/builtin/pe-band/pane.tsx +33 -16
  242. package/src/plugins/builtin/perps/client.ts +50 -3
  243. package/src/plugins/builtin/perps/headless.ts +144 -16
  244. package/src/plugins/builtin/perps/index.tsx +6 -6
  245. package/src/plugins/builtin/perps/model.ts +189 -12
  246. package/src/plugins/builtin/perps/pane.tsx +248 -47
  247. package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
  248. package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -0
  249. package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
  250. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
  251. package/src/plugins/builtin/portfolio-list/cli/render.ts +230 -39
  252. package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
  253. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
  254. package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
  255. package/src/plugins/builtin/portfolio-list/headless.ts +98 -16
  256. package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
  257. package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
  258. package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
  259. package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
  260. package/src/plugins/builtin/portfolio-list/pane/index.tsx +47 -13
  261. package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
  262. package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -1
  263. package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
  264. package/src/plugins/builtin/power/headless.ts +3 -1
  265. package/src/plugins/builtin/rate-path/headless.ts +2 -0
  266. package/src/plugins/builtin/realized-vol/headless.ts +2 -0
  267. package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
  268. package/src/plugins/builtin/research/analyst-headless.ts +3 -0
  269. package/src/plugins/builtin/research/events-headless.ts +2 -0
  270. package/src/plugins/builtin/research/headless.ts +2 -0
  271. package/src/plugins/builtin/research/index.tsx +1 -0
  272. package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
  273. package/src/plugins/builtin/research/relative-valuation-model.ts +11 -3
  274. package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
  275. package/src/plugins/builtin/research-search/index.tsx +1 -0
  276. package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
  277. package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
  278. package/src/plugins/builtin/risk-factors/headless.ts +2 -0
  279. package/src/plugins/builtin/scanner/flow-history.ts +2 -13
  280. package/src/plugins/builtin/scanner/headless.ts +14 -0
  281. package/src/plugins/builtin/seasonality/headless.ts +2 -0
  282. package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
  283. package/src/plugins/builtin/sec/filing-content.ts +42 -17
  284. package/src/plugins/builtin/sec/forms.ts +12 -0
  285. package/src/plugins/builtin/sec/headless.ts +2 -0
  286. package/src/plugins/builtin/sectors/client.ts +1 -0
  287. package/src/plugins/builtin/sectors/headless.ts +9 -1
  288. package/src/plugins/builtin/sectors/sector-model.ts +2 -0
  289. package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
  290. package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
  291. package/src/plugins/builtin/shared/report-freshness.ts +57 -0
  292. package/src/plugins/builtin/shared/research-cells.tsx +4 -9
  293. package/src/plugins/builtin/short-interest/headless.ts +2 -0
  294. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  295. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  296. package/src/plugins/builtin/social-mentions/headless.ts +1 -0
  297. package/src/plugins/builtin/supply-chain/headless.ts +7 -1
  298. package/src/plugins/builtin/supply-chain/index.tsx +10 -1
  299. package/src/plugins/builtin/supply-chain/model.ts +27 -2
  300. package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
  301. package/src/plugins/builtin/themes/headless.ts +3 -0
  302. package/src/plugins/builtin/thirteenf/headless.ts +110 -25
  303. package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
  304. package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
  305. package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
  306. package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
  307. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
  308. package/src/plugins/builtin/time-sales/headless.ts +5 -1
  309. package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
  310. package/src/plugins/builtin/volatility/headless.ts +6 -1
  311. package/src/plugins/builtin/world-indices/headless.ts +2 -0
  312. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +157 -0
  313. package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
  314. package/src/plugins/builtin/world-venue-map/client.ts +45 -0
  315. package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
  316. package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
  317. package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
  318. package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
  319. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
  320. package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
  321. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +447 -0
  322. package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
  323. package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
  324. package/src/plugins/builtin/world-venue-map/index.ts +67 -4
  325. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
  326. package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
  327. package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
  328. package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
  329. package/src/plugins/builtin/world-venue-map/model.ts +7 -4
  330. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -0
  331. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
  332. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
  333. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
  334. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
  335. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
  336. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
  337. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
  338. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
  339. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
  340. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
  341. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
  342. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
  343. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
  344. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
  345. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
  346. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
  347. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
  348. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
  349. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
  350. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
  351. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
  352. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
  353. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
  354. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
  355. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
  356. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
  357. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
  358. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
  359. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
  360. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
  361. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
  362. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
  363. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
  364. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
  365. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
  366. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
  367. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
  368. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
  369. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
  370. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
  371. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
  372. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
  373. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
  374. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
  375. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
  376. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
  377. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
  378. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
  379. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
  380. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
  381. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
  382. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
  383. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
  384. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
  385. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
  386. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
  387. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
  388. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
  389. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
  390. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
  391. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
  392. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
  393. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
  394. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
  395. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
  396. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
  397. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
  398. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
  399. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
  400. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
  401. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
  402. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
  403. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
  404. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
  405. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
  406. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
  407. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
  408. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
  409. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
  410. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
  411. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
  412. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
  413. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
  414. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
  415. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
  416. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
  417. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
  418. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
  419. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
  420. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
  421. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
  422. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
  423. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
  424. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
  425. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
  426. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
  429. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
  430. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
  431. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
  432. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
  433. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
  434. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
  435. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
  436. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
  437. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
  438. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
  439. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
  440. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
  441. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
  442. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
  443. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
  444. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
  445. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
  446. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
  447. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
  448. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
  449. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
  450. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
  451. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
  452. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
  453. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
  454. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
  455. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
  456. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
  457. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
  458. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
  459. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
  460. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
  461. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
  462. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
  463. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
  464. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
  465. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
  466. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
  467. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
  468. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
  469. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
  470. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
  471. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
  472. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
  473. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
  474. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
  475. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
  476. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
  477. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
  478. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
  479. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
  480. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
  481. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
  482. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
  483. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
  484. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
  485. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
  486. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
  487. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
  488. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
  489. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
  490. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
  491. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
  492. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
  493. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
  494. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
  495. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
  496. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
  497. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
  498. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
  499. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
  500. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
  501. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
  502. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
  503. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
  504. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
  505. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
  506. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
  507. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
  508. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
  509. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
  510. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
  511. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
  512. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
  513. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
  514. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
  515. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
  516. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
  517. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
  518. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
  519. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
  520. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
  521. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
  522. package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
  523. package/src/plugins/builtin/world-venue-map/pane.tsx +28 -43
  524. package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
  525. package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
  526. package/src/plugins/builtin/yield-curve/headless.ts +16 -0
  527. package/src/plugins/loader.ts +13 -1
  528. package/src/plugins/registry/pane-settings.ts +1 -0
  529. package/src/renderers/dom/build-assets.ts +81 -3
  530. package/src/renderers/dom/data-table/row.tsx +2 -0
  531. package/src/renderers/dom/desktop/controls.tsx +7 -3
  532. package/src/renderers/dom/desktop/list-view.tsx +35 -10
  533. package/src/renderers/dom/desktop/popover.tsx +73 -14
  534. package/src/renderers/dom/host/input.tsx +14 -3
  535. package/src/renderers/dom/styles.css +6 -7
  536. package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
  537. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -0
  538. package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
  539. package/src/renderers/opentui/host.tsx +5 -0
  540. package/src/sources/gloomberb-cloud/index.ts +25 -4
  541. package/src/sources/gloomberb-cloud/normalizers.ts +27 -3
  542. package/src/sources/provider-router/cached-routes.ts +4 -1
  543. package/src/sources/provider-router/financials.ts +8 -7
  544. package/src/sources/provider-router/history.ts +15 -10
  545. package/src/sources/sec-registrant.ts +75 -0
  546. package/src/state/app/context/index.tsx +24 -8
  547. package/src/state/hooks/quote-streaming.ts +41 -26
  548. package/src/sync/core-contributors.ts +4 -0
  549. package/src/telemetry/crash-reports.ts +4 -1
  550. package/src/test-support/cli-context.ts +10 -2
  551. package/src/theme/heat-colors.ts +266 -84
  552. package/src/time-series/resolve.ts +1 -1
  553. package/src/time-series/use-chart-resolution.ts +1 -1
  554. package/src/types/context-menu.ts +6 -0
  555. package/src/types/data-provider.ts +2 -0
  556. package/src/types/financials.ts +3 -0
  557. package/src/types/headless.ts +79 -2
  558. package/src/types/plugin.ts +20 -1
  559. package/src/types/ticker.ts +15 -0
  560. package/src/ui/host.tsx +14 -0
  561. package/src/updater/index.ts +9 -11
  562. package/src/utils/async-deadline.ts +21 -0
  563. package/src/utils/cli-output.ts +5 -1
  564. package/src/utils/crypto-pair.ts +41 -0
  565. package/src/utils/currency-units.ts +14 -0
  566. package/src/utils/depositary-receipt.ts +26 -0
  567. package/src/utils/exchanges.ts +72 -0
  568. package/src/utils/fire-and-forget.ts +24 -0
  569. package/src/utils/format.ts +13 -0
  570. package/src/utils/price-earnings.ts +70 -3
  571. package/src/utils/price-history.ts +58 -13
  572. package/src/utils/rpc-timeout-error.ts +27 -0
  573. package/src/utils/sec.ts +13 -1
  574. package/src/utils/utc-time.ts +79 -0
@@ -66,17 +66,17 @@ export function PaneFooterProvider({
66
66
  const value = useMemo(() => ({ register, unregister }), [register, unregister]);
67
67
  const footer = useMemo(() => combinePaneFooterRegistrations(registrations), [registrations]);
68
68
 
69
- const [arrowClaims, setArrowClaims] = useState<ReadonlySet<string>>(() => new Set());
70
- const setArrowClaim = useCallback((id: string, claimed: boolean) => {
71
- setArrowClaims((current) => {
72
- if (current.has(id) === claimed) return current;
73
- const next = new Set(current);
74
- if (claimed) next.add(id);
75
- else next.delete(id);
76
- return next;
77
- });
78
- }, []);
79
- const arrowValue = useMemo(() => ({ claimed: arrowClaims.size > 0, setArrowClaim }), [arrowClaims, setArrowClaim]);
69
+ const [arrowClaims, setArrowClaim] = useMemberSet();
70
+ const [strips, setStrip] = useMemberSet();
71
+ const [holds, setArrowHold] = useMemberSet();
72
+ const arrowValue = useMemo<PaneArrowState>(() => ({
73
+ claimed: arrowClaims.size > 0,
74
+ strip: strips.size > 0,
75
+ held: holds.size > 0,
76
+ setArrowClaim,
77
+ setStrip,
78
+ setArrowHold,
79
+ }), [arrowClaims, holds, setArrowClaim, setArrowHold, setStrip, strips]);
80
80
 
81
81
  return (
82
82
  <PaneFooterContext.Provider value={value}>
@@ -87,22 +87,57 @@ export function PaneFooterProvider({
87
87
  );
88
88
  }
89
89
 
90
- const PaneArrowContext = createContext<{ claimed: boolean; setArrowClaim(id: string, claimed: boolean): void } | null>(null);
90
+ function useMemberSet(): [ReadonlySet<string>, (id: string, member: boolean) => void] {
91
+ const [members, setMembers] = useState<ReadonlySet<string>>(() => new Set());
92
+ const setMember = useCallback((id: string, member: boolean) => {
93
+ setMembers((current) => {
94
+ if (current.has(id) === member) return current;
95
+ const next = new Set(current);
96
+ if (member) next.add(id);
97
+ else next.delete(id);
98
+ return next;
99
+ });
100
+ }, []);
101
+ return [members, setMember];
102
+ }
103
+
104
+ interface PaneArrowState {
105
+ /** A focused tab strip owns Left, Right, h and l. */
106
+ claimed: boolean;
107
+ /** The pane has a tab strip that walks its tabs by keyboard. */
108
+ strip: boolean;
109
+ /** Content the user moved into (a chart) holds the strip's keys until Esc. */
110
+ held: boolean;
111
+ setArrowClaim(id: string, claimed: boolean): void;
112
+ setStrip(id: string, present: boolean): void;
113
+ setArrowHold(id: string, held: boolean): void;
114
+ }
115
+
116
+ const PaneArrowContext = createContext<PaneArrowState | null>(null);
117
+
118
+ function usePaneArrowMember(set: ((id: string, member: boolean) => void) | undefined, member: boolean) {
119
+ const id = useId();
120
+ useEffect(() => {
121
+ if (!set) return;
122
+ set(id, member);
123
+ return () => set(id, false);
124
+ }, [id, member, set]);
125
+ }
91
126
 
92
127
  /**
93
- * A focused tab strip owns Left and Right in its pane. It claims them here, so
94
- * a read-only chart in the same pane leaves them to the strip and the arrows
95
- * keep walking the tabs.
128
+ * A tab strip's keys. A focused strip owns Left, Right, h and l in its pane and
129
+ * claims them, so a chart in the same pane leaves them to it and the arrows
130
+ * keep walking the tabs. While content the user moved into holds them (a chart
131
+ * after Down, Enter or a click), the strip lets go until that content hands
132
+ * them back with Esc. Returns whether the strip has its keys now.
96
133
  */
97
- export function usePaneArrowClaim(claimed: boolean) {
134
+ export function usePaneTabStripKeys(navigates: boolean, focused: boolean): { active: boolean; held: boolean } {
98
135
  const context = useContext(PaneArrowContext);
99
- const id = useId();
100
- const setArrowClaim = context?.setArrowClaim;
101
- useEffect(() => {
102
- if (!setArrowClaim) return;
103
- setArrowClaim(id, claimed);
104
- return () => setArrowClaim(id, false);
105
- }, [claimed, id, setArrowClaim]);
136
+ const held = context?.held ?? false;
137
+ const active = navigates && focused && !held;
138
+ usePaneArrowMember(context?.setStrip, navigates);
139
+ usePaneArrowMember(context?.setArrowClaim, active);
140
+ return { active, held: navigates && held };
106
141
  }
107
142
 
108
143
  /** Whether a tab strip in this pane owns Left and Right. */
@@ -110,6 +145,16 @@ export function usePaneArrowsClaimed(): boolean {
110
145
  return useContext(PaneArrowContext)?.claimed ?? false;
111
146
  }
112
147
 
148
+ /** Whether this pane has a tab strip that content can hand the keys back to. */
149
+ export function usePaneHasTabStrip(): boolean {
150
+ return useContext(PaneArrowContext)?.strip ?? false;
151
+ }
152
+
153
+ /** While `held`, the pane's tab strips leave Left, Right, h and l to the caller. */
154
+ export function usePaneArrowHold(held: boolean) {
155
+ usePaneArrowMember(useContext(PaneArrowContext)?.setArrowHold, held);
156
+ }
157
+
113
158
  export function PaneFooterScope({
114
159
  active,
115
160
  children,
@@ -152,8 +152,9 @@ export function PaneHeader({
152
152
  capturePointerDrag(nativeRenderer, terminalHeaderRef.current);
153
153
  onHeaderMouseDown?.(event);
154
154
  }, [nativeRenderer, onHeaderMouseDown]);
155
- // The grip, the title and the empty bar move the pane. A fullscreen pane
156
- // cannot move, so there they move the desktop window instead.
155
+ // The whole bar moves the pane: the grip, the title, the empty space and its
156
+ // padding. Tabs and buttons stop the press before it gets here. A fullscreen
157
+ // pane cannot move, so there the bar moves the desktop window instead.
157
158
  const windowDrag = Boolean(titleBar) || (fullscreen && titleBarOverlay === true && nativeWindowChrome === true);
158
159
  const beginPaneDrag = (event: { stopPropagation?: () => void }) => {
159
160
  event.stopPropagation?.();
@@ -167,12 +168,9 @@ export function PaneHeader({
167
168
  }
168
169
  void rendererHost.startWindowDrag?.();
169
170
  };
170
- const paneDragHandlers = {
171
- onMouseDown: beginPaneDrag,
172
- onMouseDrag: onHeaderMouseDrag,
173
- onMouseDragEnd: onHeaderMouseDragEnd,
174
- };
175
- const chromeHandlers = windowDrag ? { onMouseDown: beginWindowDrag } : paneDragHandlers;
171
+ const barHandlers = windowDrag
172
+ ? { onMouseDown: beginWindowDrag }
173
+ : { onMouseDown: beginPaneDrag, onMouseDrag: onHeaderMouseDrag, onMouseDragEnd: onHeaderMouseDragEnd };
176
174
 
177
175
  if (nativePaneChrome) {
178
176
  const ruleColor = visuallyFocused ? colors.borderFocused : colors.border;
@@ -187,6 +185,8 @@ export function PaneHeader({
187
185
  data-floating={floating ? "true" : "false"}
188
186
  data-focused={focused ? "true" : "false"}
189
187
  data-window-mode-selected={windowModeSelected ? "true" : "false"}
188
+ data-drag-surface={windowDrag ? "window" : "pane"}
189
+ {...barHandlers}
190
190
  onMouseMove={onHeaderMouseMove}
191
191
  onContextMenu={onHeaderContextMenu}
192
192
  style={{
@@ -207,13 +207,13 @@ export function PaneHeader({
207
207
  }}
208
208
  >
209
209
  {!titleBar && (
210
- <Box data-gloom-role="pane-grip" flexShrink={0} flexDirection="row" alignItems="center" style={{ alignSelf: "stretch", marginRight: 6 }} {...paneDragHandlers}>
210
+ <Box data-gloom-role="pane-grip" flexShrink={0} flexDirection="row" alignItems="center" style={{ alignSelf: "stretch", marginRight: 6 }}>
211
211
  <Icon name="grip" size={12} color={visuallyFocused ? colors.borderFocused : colors.textMuted} />
212
212
  </Box>
213
213
  )}
214
214
  {/* Full header height, so trimming the title to its capitals never lets
215
215
  this clip cut descenders. */}
216
- <Box data-gloom-role="pane-header-chrome" minWidth={0} flexShrink={tabs ? 0 : 1} overflow="hidden" flexDirection="row" alignItems="center" style={{ alignSelf: "stretch", ...(tabs ? { maxWidth: "40%" } : {}) }} {...chromeHandlers}>
216
+ <Box data-gloom-role="pane-header-chrome" minWidth={0} flexShrink={tabs ? 0 : 1} overflow="hidden" flexDirection="row" alignItems="center" style={{ alignSelf: "stretch", ...(tabs ? { maxWidth: "40%" } : {}) }}>
217
217
  <Text
218
218
  fg={textColor}
219
219
  selectable={false}
@@ -285,7 +285,7 @@ export function PaneHeader({
285
285
  />
286
286
  </Box>
287
287
  ))}
288
- <Box data-gloom-role="pane-header-chrome" flexGrow={1} minWidth={0} {...chromeHandlers} />
288
+ <Box flexGrow={1} minWidth={0} />
289
289
  {locked && (
290
290
  <Box data-gloom-role="pane-lock">
291
291
  <IconButton icon="lock" label="Locked: the close shortcut leaves this pane open" color={colors.textMuted} />
@@ -17,6 +17,7 @@ import {
17
17
  import { PANE_MANAGEMENT_ACCELERATORS, type PaneManagementAccelerators } from "./shortcuts";
18
18
  import { t } from "../../../i18n";
19
19
  import { displayWidth } from "../../../utils/format";
20
+ import { fireAndForget } from "../../../utils/fire-and-forget";
20
21
 
21
22
  const MENU_MIN_WIDTH = 18;
22
23
  const MENU_MAX_WIDTH = 44;
@@ -174,7 +175,7 @@ export function menuForPane(
174
175
  label: "Pop Out",
175
176
  accelerator: accelerators.popOut,
176
177
  onSelect: () => {
177
- void desktopWindowBridge.popOutPane?.(pane.instance.instanceId);
178
+ fireAndForget(desktopWindowBridge.popOutPane?.(pane.instance.instanceId), "desktop.popOutPane");
178
179
  },
179
180
  });
180
181
  }
@@ -14,6 +14,7 @@ import type { LayoutConfig } from "../../../../types/config";
14
14
  import { isPaneLockedInLayout } from "../../../../pane-settings";
15
15
  import type { RendererHost } from "../../../../ui";
16
16
  import { capturePaneScreenshotPngBase64 } from "../../../../utils/dom-screenshot";
17
+ import { fireAndForget } from "../../../../utils/fire-and-forget";
17
18
  import {
18
19
  exportPaneTableCsv,
19
20
  hasPaneTableExporter,
@@ -160,7 +161,7 @@ export function useShellPaneActions({
160
161
  const popOutFocusedPane = useCallback(() => {
161
162
  if (!focusedPaneId || desktopWindowBridge?.kind !== "main" || !desktopWindowBridge.popOutPane) return false;
162
163
  if (!isPaneInLayout(visibleLayout, focusedPaneId)) return false;
163
- void desktopWindowBridge.popOutPane(focusedPaneId);
164
+ fireAndForget(desktopWindowBridge.popOutPane(focusedPaneId), "desktop.popOutPane");
164
165
  return true;
165
166
  }, [desktopWindowBridge, focusedPaneId, visibleLayout]);
166
167
 
@@ -1,4 +1,4 @@
1
- import { useMemo } from "react";
1
+ import { useCallback, useMemo, useRef } from "react";
2
2
  import { Box } from "../../../../ui";
3
3
  import { resolveOccludedPaneIds } from "../pane-occlusion";
4
4
  import type {
@@ -117,6 +117,11 @@ export function ShellPaneLayers({
117
117
  // the compositor already skips covered windows, and a drag keeps everything
118
118
  // drawn so the preview never reveals a blank spot.
119
119
  const occludedPaneIds = nativePaneChrome || dragFloatingRect ? EMPTY_OCCLUSION : coveredPaneIds;
120
+ // The failure card's Close. Stable, so a focus or layout change does not
121
+ // re-render every memoized pane body.
122
+ const closePaneRef = useRef(handleFloatingClose);
123
+ closePaneRef.current = handleFloatingClose;
124
+ const closePane = useCallback((paneId: string) => closePaneRef.current(paneId), []);
120
125
 
121
126
  return (
122
127
  <>
@@ -131,6 +136,7 @@ export function ShellPaneLayers({
131
136
  const focused = focusedPaneId === leaf.instanceId && (!overlayOpen || menuPaneId === leaf.instanceId);
132
137
  const windowModeSelected = windowModePaneId === leaf.instanceId;
133
138
  const showActions = focused || hoveredPaneId === leaf.instanceId || menuPaneId === leaf.instanceId;
139
+ const title = getPaneTitle(pane);
134
140
  return (
135
141
  <Box
136
142
  key={`dock:${leaf.instanceId}`}
@@ -156,7 +162,7 @@ export function ShellPaneLayers({
156
162
  return (
157
163
  <PaneWrapper
158
164
  paneId={leaf.instanceId}
159
- title={getPaneTitle(pane)}
165
+ title={title}
160
166
  focused={focused}
161
167
  width={rect.width}
162
168
  height={rect.height}
@@ -181,10 +187,12 @@ export function ShellPaneLayers({
181
187
  component={pane.def.component}
182
188
  paneId={pane.instance.instanceId}
183
189
  paneType={pane.instance.paneId}
190
+ title={title}
184
191
  focused={focused}
185
192
  width={bodyFrame.width ?? 1}
186
193
  height={bodyFrame.height ?? 1}
187
194
  inView={!coveredPaneIds.has(leaf.instanceId)}
195
+ closePane={closePane}
188
196
  />
189
197
  </PaneWrapper>
190
198
  );
@@ -205,6 +213,7 @@ export function ShellPaneLayers({
205
213
  const focused = focusedPaneId === pane.instance.instanceId && (!overlayOpen || menuPaneId === pane.instance.instanceId);
206
214
  const windowModeSelected = windowModePaneId === pane.instance.instanceId;
207
215
  const showActions = focused || hoveredPaneId === pane.instance.instanceId || menuPaneId === pane.instance.instanceId;
216
+ const title = getPaneTitle(pane);
208
217
  return (
209
218
  <PaneFooterProvider key={`float:${pane.instance.instanceId}`}>
210
219
  {(footer) => {
@@ -221,7 +230,7 @@ export function ShellPaneLayers({
221
230
  return (
222
231
  <FloatingPaneWrapper
223
232
  paneId={pane.instance.instanceId}
224
- title={getPaneTitle(pane)}
233
+ title={title}
225
234
  x={preview.x}
226
235
  y={preview.y}
227
236
  width={preview.width}
@@ -253,11 +262,13 @@ export function ShellPaneLayers({
253
262
  component={pane.def.component}
254
263
  paneId={pane.instance.instanceId}
255
264
  paneType={pane.instance.paneId}
265
+ title={title}
256
266
  focused={focused}
257
267
  width={bodyFrame.width ?? 1}
258
268
  height={bodyFrame.height ?? 1}
259
269
  inView={!coveredPaneIds.has(pane.instance.instanceId)}
260
270
  onClose={handleFloatingClose}
271
+ closePane={closePane}
261
272
  />
262
273
  </FloatingPaneWrapper>
263
274
  );
@@ -1,7 +1,13 @@
1
1
  import { memo, useEffect, useMemo, useRef, useState, type CSSProperties } from "react";
2
2
  import { Box, Text, TextAttributes, useUiCapabilities } from "../../ui";
3
- import { blendHex, colors } from "../../theme/colors";
4
- import { heatmapColorDistance, resolveHeatmapSelectedTileColors, resolveHeatmapTileColors } from "../../theme/heat-colors";
3
+ import { blendHex } from "../../theme/colors";
4
+ import {
5
+ heatmapColorDistance,
6
+ resolveHeatmapSelectedTileColors,
7
+ resolveHeatmapSelectionRing,
8
+ resolveHeatmapTileColors,
9
+ } from "../../theme/heat-colors";
10
+ import { useThemeColors } from "../../theme/theme-context";
5
11
  import { t } from "../../i18n";
6
12
  import { clipToDisplayWidth, padTo } from "../../utils/format";
7
13
  import type { FloatMetricTreemapTile, MetricTreemapItem } from "./layout";
@@ -17,6 +23,7 @@ import {
17
23
  heatTileLabelCells,
18
24
  heatTileLabelPx,
19
25
  heatTileMotion,
26
+ heatTileValueWithSuffix,
20
27
  } from "./heat-tiles";
21
28
 
22
29
  type PreventableMouseEvent = { preventDefault(): void };
@@ -203,7 +210,7 @@ function useItemsById<T>(scene: MetricTreemapScene<T>, items: readonly MetricTre
203
210
  const VISIBLE_FADE_DISTANCE = 0.03;
204
211
 
205
212
  const DomHeatTile = memo(function DomHeatTile({
206
- id, rect, canvasWidth, canvasHeight, gap, label, value, background, foreground,
213
+ id, rect, canvasWidth, canvasHeight, gap, label, value, valueSuffix, background, foreground,
207
214
  selected, reducedMotion, glide, pulseCount, events,
208
215
  }: {
209
216
  id: string;
@@ -213,6 +220,7 @@ const DomHeatTile = memo(function DomHeatTile({
213
220
  gap: number;
214
221
  label: string;
215
222
  value: string | null;
223
+ valueSuffix: string | null;
216
224
  background: string;
217
225
  foreground: string;
218
226
  selected: boolean;
@@ -222,6 +230,7 @@ const DomHeatTile = memo(function DomHeatTile({
222
230
  events: SurfaceEvents;
223
231
  }) {
224
232
  const text = heatTileLabelPx(rect.width - gap * 2, rect.height - gap * 2, label, value);
233
+ const shownValue = heatTileValueWithSuffix(value, valueSuffix, { width: rect.width - gap * 2, valuePx: text.valuePx });
225
234
  // Where this tile sat before the last relayout, kept to slide it from there.
226
235
  const placedRef = useRef(rect);
227
236
  const glideRef = useRef<{ dx: number; dy: number; count: number }>({ dx: 0, dy: 0, count: 0 });
@@ -234,13 +243,19 @@ const DomHeatTile = memo(function DomHeatTile({
234
243
  placedRef.current = rect;
235
244
  }
236
245
  const motion = heatTileMotion({ reducedMotion, glide, glideCount: glideRef.current.count, pulseCount });
246
+ const colors = useThemeColors();
247
+ const ring = resolveHeatmapSelectionRing(colors);
237
248
  // The colour this tile showed before, kept to fade out over the new one.
238
249
  const shownRef = useRef(background);
239
250
  const fadeRef = useRef<{ from: string; key: number } | null>(null);
251
+ const paletteRef = useRef(colors);
252
+ // A theme switch recolours every tile at once; only a move fades.
253
+ const themeChanged = paletteRef.current !== colors;
254
+ paletteRef.current = colors;
240
255
  if (shownRef.current !== background) {
241
256
  // A step too small to see snaps: a fade costs a compositor layer for its whole run.
242
257
  const visible = heatmapColorDistance(shownRef.current, background) >= VISIBLE_FADE_DISTANCE;
243
- if (!motion.fadeAnimation) fadeRef.current = null;
258
+ if (!motion.fadeAnimation || themeChanged) fadeRef.current = null;
244
259
  else if (visible) fadeRef.current = { from: shownRef.current, key: (fadeRef.current?.key ?? 0) + 1 };
245
260
  shownRef.current = background;
246
261
  }
@@ -267,9 +282,9 @@ const DomHeatTile = memo(function DomHeatTile({
267
282
  justifyContent: "center",
268
283
  gap: 0,
269
284
  cursor: "pointer",
270
- // The page's brightest text, then a hairline of the page: clear on a pink or
271
- // aqua tile whether its own text is dark or light.
272
- boxShadow: selected ? `inset 0 0 0 2px ${colors.textBright}, inset 0 0 0 3px ${colors.bg}` : undefined,
285
+ // The theme's text tone against the page, then a hairline of the page: one
286
+ // of the two stands out on any tile, bright or dim.
287
+ boxShadow: selected ? `inset 0 0 0 2px ${ring.outer}, inset 0 0 0 3px ${ring.inner}` : undefined,
273
288
  zIndex: selected ? 1 : undefined,
274
289
  ...(motion.glideAnimation
275
290
  ? {
@@ -336,7 +351,7 @@ const DomHeatTile = memo(function DomHeatTile({
336
351
  <Text style={{ ...lineStyle, fontSize: text.tickerPx, fontWeight: 700, lineHeight: 1.12 }}>{label}</Text>
337
352
  )}
338
353
  {text.tier === "full" && value && (
339
- <Text style={{ ...lineStyle, fontSize: text.valuePx, fontWeight: 500, lineHeight: 1.12 }}>{value}</Text>
354
+ <Text style={{ ...lineStyle, fontSize: text.valuePx, fontWeight: 500, lineHeight: 1.12 }}>{shownValue}</Text>
340
355
  )}
341
356
  </Box>
342
357
  );
@@ -347,6 +362,7 @@ function headerLabel(header: MetricTreemapHeader): string {
347
362
  }
348
363
 
349
364
  function DomHeader({ header, canvasWidth, canvasHeight }: { header: MetricTreemapHeader; canvasWidth: number; canvasHeight: number }) {
365
+ const colors = useThemeColors();
350
366
  const sector = header.level === 0 && !header.other;
351
367
  return (
352
368
  <Box
@@ -402,6 +418,7 @@ function DomTooltip<T>({ state, itemsById, otherLines }: {
402
418
  itemsById: ReadonlyMap<string, MetricTreemapItem<T>>;
403
419
  otherLines: readonly string[] | null;
404
420
  }) {
421
+ const colors = useThemeColors();
405
422
  if (!state) return null;
406
423
  const lines = state.id === OTHER_ID
407
424
  ? otherLines
@@ -457,6 +474,7 @@ function DomHeatTreemap<T>({
457
474
  scene, items, width, height, selectedId, onSelect, onActivate, otherTooltip, otherSummary: summarizeOther,
458
475
  }: HeatTreemapSurfaceProps<T>) {
459
476
  const reducedMotion = usePrefersReducedMotion();
477
+ const colors = useThemeColors();
460
478
  const itemsById = useItemsById(scene, items);
461
479
  const chartRef = useRef<{ getBoundingClientRect?: () => { x: number; y: number; width: number; height: number } } | null>(null);
462
480
  const [tooltip, setTooltip] = useState<TooltipState | null>(null);
@@ -543,7 +561,7 @@ function DomHeatTreemap<T>({
543
561
  )}
544
562
  {scene.tiles.map((tile) => {
545
563
  const item = itemsById.get(tile.item.id) ?? tile.item;
546
- const tileColors = resolveHeatmapTileColors(item.colorValue);
564
+ const tileColors = resolveHeatmapTileColors(item.colorValue, colors);
547
565
  return (
548
566
  <DomHeatTile
549
567
  key={tile.item.id}
@@ -554,6 +572,7 @@ function DomHeatTreemap<T>({
554
572
  gap={gap}
555
573
  label={item.label}
556
574
  value={item.primaryText ?? null}
575
+ valueSuffix={item.primaryTextSuffix ?? null}
557
576
  background={tileColors.background}
558
577
  foreground={tileColors.foreground}
559
578
  selected={tile.item.id === selectedId}
@@ -586,7 +605,7 @@ function tileRect(tile: FloatMetricTreemapTile<unknown>): TreemapRect {
586
605
  // Terminal: whole cells, a one-cell gutter right of and under each tile.
587
606
 
588
607
  const TerminalHeatTile = memo(function TerminalHeatTile({
589
- id, x, y, width, height, label, value, colorValue, selected, events,
608
+ id, x, y, width, height, label, value, valueSuffix, colorValue, selected, events,
590
609
  }: {
591
610
  id: string;
592
611
  x: number;
@@ -595,17 +614,21 @@ const TerminalHeatTile = memo(function TerminalHeatTile({
595
614
  height: number;
596
615
  label: string;
597
616
  value: string | null;
617
+ valueSuffix: string | null;
598
618
  colorValue: number | null;
599
619
  selected: boolean;
600
620
  events: SurfaceEvents;
601
621
  }) {
622
+ // Read here, not passed down: a theme switch reaches every tile even though its props are the same.
623
+ const colors = useThemeColors();
602
624
  const { background, foreground } = selected
603
- ? resolveHeatmapSelectedTileColors(colorValue)
604
- : resolveHeatmapTileColors(colorValue);
625
+ ? resolveHeatmapSelectedTileColors(colorValue, colors)
626
+ : resolveHeatmapTileColors(colorValue, colors);
605
627
  const renderWidth = Math.max(1, width - (width >= 3 ? 1 : 0));
606
628
  const renderHeight = Math.max(1, height - (height >= 2 ? 1 : 0));
607
629
  const tier = heatTileLabelCells(renderWidth, renderHeight, label, value);
608
- const lines = tier === "full" && value ? [label, value] : tier === "none" ? [] : [label];
630
+ const shownValue = heatTileValueWithSuffix(value, valueSuffix, { width: renderWidth });
631
+ const lines = tier === "full" && shownValue ? [label, shownValue] : tier === "none" ? [] : [label];
609
632
  const top = Math.max(0, Math.floor((renderHeight - lines.length) / 2));
610
633
  return (
611
634
  <Box
@@ -641,6 +664,7 @@ const TerminalHeatTile = memo(function TerminalHeatTile({
641
664
  function TerminalHeatTreemap<T>({
642
665
  scene, items, width, height, selectedId, onSelect, onActivate, otherSummary: summarizeOther,
643
666
  }: HeatTreemapSurfaceProps<T>) {
667
+ const colors = useThemeColors();
644
668
  const itemsById = useItemsById(scene, items);
645
669
  const events = useSurfaceEvents(itemsById, onSelect, onActivate);
646
670
  const other = scene.other;
@@ -688,6 +712,7 @@ function TerminalHeatTreemap<T>({
688
712
  height={tile.height}
689
713
  label={item.label}
690
714
  value={item.primaryText ?? null}
715
+ valueSuffix={item.primaryTextSuffix ?? null}
691
716
  colorValue={item.colorValue ?? null}
692
717
  selected={tile.item.id === selectedId}
693
718
  events={events}
@@ -701,12 +726,14 @@ function TerminalHeatTreemap<T>({
701
726
 
702
727
  /**
703
728
  * The heat map look of the treemap: optional sector and industry blocks,
704
- * calm tiles (ticker, then the move, as space allows), a continuous
705
- * pink-indigo-teal scale, and on the desktop a hover tooltip, colour fades,
706
- * a short pulse on a tile whose move jumps and a glide when sizes change.
729
+ * calm tiles (ticker, then the move, as space allows), a continuous scale
730
+ * from the theme's down colour to its up colour, and on the desktop a hover
731
+ * tooltip, colour fades, a short pulse on a tile whose move jumps and a glide
732
+ * when sizes change.
707
733
  */
708
734
  export function HeatTreemapSurface<T>(props: HeatTreemapSurfaceProps<T>) {
709
735
  const { nativePaneChrome } = useUiCapabilities();
736
+ const colors = useThemeColors();
710
737
  if (props.scene.tiles.length === 0) {
711
738
  return (
712
739
  <Box width={props.width} height={props.height} paddingX={1} paddingY={1}>
@@ -57,6 +57,24 @@ export function heatTileLabelPx(width: number, height: number, ticker: string, v
57
57
  return NO_LABEL;
58
58
  }
59
59
 
60
+ /**
61
+ * The move with its qualifier (an after-hours move's AH) where that still fits
62
+ * at the size the move alone was given, else the move alone. The qualifier
63
+ * never shrinks the text or drops the move.
64
+ */
65
+ export function heatTileValueWithSuffix(
66
+ value: string | null,
67
+ suffix: string | null | undefined,
68
+ room: { width: number; valuePx?: number },
69
+ ): string | null {
70
+ if (!value || !suffix) return value;
71
+ const withSuffix = `${value} ${suffix}`;
72
+ const width = room.valuePx == null
73
+ ? withSuffix.length
74
+ : withSuffix.length * MONO_CHAR_EM * room.valuePx + TILE_PAD_X_PX * 2;
75
+ return width <= room.width ? withSuffix : value;
76
+ }
77
+
60
78
  /** The same tiers on a cell grid: whole words or nothing, never a clipped ticker. */
61
79
  export function heatTileLabelCells(width: number, height: number, ticker: string, value: string | null): HeatTileLabelTier {
62
80
  if (width < ticker.length || height < 1 || ticker.length === 0) return "none";
@@ -4,6 +4,8 @@ export interface MetricTreemapItem<T = unknown> {
4
4
  weight: number | null | undefined;
5
5
  colorValue?: number | null;
6
6
  primaryText?: string | null;
7
+ /** A short qualifier after primaryText, such as AH for an after-hours move; the heat map shows it where the tile has room. */
8
+ primaryTextSuffix?: string | null;
7
9
  secondaryText?: string | null;
8
10
  tertiaryText?: string | null;
9
11
  /** Optional hierarchy for the heat map layout (a sector); the flat layouts ignore it. */