gloomberb 0.18.3 → 0.18.4

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 (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -0,0 +1,193 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import type { CryptoEtfFlowAsset, CryptoEtfFlowDay } from "../../../api-client/crypto-etf-flows";
3
+ import { isAccessDenied } from "../../../api-client/errors";
4
+ import {
5
+ ChartTableHeader,
6
+ DataTableView,
7
+ PaneStatusBody,
8
+ QueryBar,
9
+ useChartTableSelection,
10
+ usePaneNoticeFooter,
11
+ usePaneStatusLinkFooter,
12
+ type DataTableCell,
13
+ type StatItem,
14
+ } from "../../../components";
15
+ import { formatCompactAxis } from "../../../components/chart-table";
16
+ import { useChartViewReset } from "../../../components/chart/core/view-reset";
17
+ import { scalarPoint, staticSeries } from "../../../components/chart/static/series";
18
+ import { handleRefreshKey, usePaneRefreshKey } from "../../../components/data-table/table-pane";
19
+ import { useAsyncResource, useAutoRefresh, usePaneSettingValue, usePluginPaneState, useUpdatedAgo } from "../../../public/react";
20
+ import { colors } from "../../../theme/colors";
21
+ import type { PaneProps } from "../../../types/plugin";
22
+ import { Box } from "../../../ui";
23
+ import { isPlainKeyboardEvent } from "../../../utils/keyboard";
24
+ import { cachedCryptoEtfFlows, loadCryptoEtfFlows } from "./client";
25
+ import {
26
+ CRYPTO_ETF_FLOW_ASSETS,
27
+ CRYPTO_ETF_FLOW_RANGES,
28
+ CRYPTO_ETF_FLOWS_PANE_ID,
29
+ cryptoEtfFlowAsset,
30
+ cryptoEtfFlowAssetLabel,
31
+ cryptoEtfFlowColumns,
32
+ cryptoEtfFlowRange,
33
+ cryptoEtfFlowSummary,
34
+ cumulativeFlows,
35
+ daysInRange,
36
+ flowColor,
37
+ formatFlow,
38
+ formatFlowAmount,
39
+ fundTickerOfColumn,
40
+ pendingText,
41
+ type CryptoEtfFlowColumn,
42
+ type CryptoEtfFlowRange,
43
+ } from "./model";
44
+
45
+ const EMPTY_DAYS: CryptoEtfFlowDay[] = [];
46
+ const rowId = (day: CryptoEtfFlowDay) => day.date;
47
+ const rowDate = (day: CryptoEtfFlowDay) => new Date(`${day.date}T00:00:00Z`);
48
+ /** Ticks in one compact unit for the axis (`$40B`, `-$1.5B`), with the decimals the plotted range needs. */
49
+ function formatFlowAxis(value: number, domain: Parameters<typeof formatCompactAxis>[1]): string {
50
+ const text = formatCompactAxis(value, domain);
51
+ return text.startsWith("-") ? `-$${text.slice(1)}` : `$${text}`;
52
+ }
53
+ /** The legend's running total, in dollars: no sign for an inflow, as a level reads. */
54
+ const formatRunningTotal = (dollars: number) => formatFlowAmount(dollars / 1_000_000).replace(/^\+/, "");
55
+
56
+ export function CryptoEtfFlowsPane({ focused, width, height }: PaneProps) {
57
+ const [assetSetting, setAssetSetting] = usePaneSettingValue<string>("asset", "btc");
58
+ const asset = cryptoEtfFlowAsset(assetSetting);
59
+ const [storedRange, setStoredRange] = usePluginPaneState<string>("range", "1Y");
60
+ const range = cryptoEtfFlowRange(storedRange);
61
+ const [selectedByAsset, setSelectedByAsset] = usePluginPaneState<Partial<Record<CryptoEtfFlowAsset, string>>>("selected", {});
62
+ const resetChartView = useChartViewReset();
63
+
64
+ const loader = useCallback((force: boolean) => loadCryptoEtfFlows(asset, force), [asset]);
65
+ const resource = useAsyncResource(loader, { initialData: () => cachedCryptoEtfFlows(asset), clearOnError: isAccessDenied });
66
+ // Reuse this asset's cached view immediately when switching back to it.
67
+ const current = resource.data ?? (resource.loading ? cachedCryptoEtfFlows(asset) : null);
68
+ // A copy of the other asset's flows is never drawn under this one's name.
69
+ const data = current?.payload.asset === asset ? current.payload : null;
70
+ const days = useMemo(() => data ? daysInRange(data.days, range) : EMPTY_DAYS, [data, range]);
71
+ const columns = useMemo(() => cryptoEtfFlowColumns(data), [data]);
72
+ const summary = useMemo(() => data ? cryptoEtfFlowSummary(data) : null, [data]);
73
+ const selectedId = selectedByAsset[asset] && days.some((day) => day.date === selectedByAsset[asset]) ? selectedByAsset[asset]! : days[0]?.date ?? null;
74
+ const selectDay = useCallback((id: string | null) => {
75
+ setSelectedByAsset((current) => ({ ...current, [asset]: id ?? undefined }));
76
+ }, [asset, setSelectedByAsset]);
77
+
78
+ const label = cryptoEtfFlowAssetLabel(asset);
79
+ // The running total since the first fund launched, drawn over the range the table lists.
80
+ const series = useMemo(() => {
81
+ if (!data) return [];
82
+ const first = days.at(-1)?.date ?? "";
83
+ const points = cumulativeFlows(data).filter((point) => point.date >= first)
84
+ .map((point) => scalarPoint(new Date(`${point.date}T00:00:00Z`), point.value * 1_000_000));
85
+ return [staticSeries(points, { id: `etf-flows:${asset}`, label: `${label} ETF net flows since launch`, color: colors.positive, calendarSpaced: true })];
86
+ }, [asset, data, days, label]);
87
+ const link = useChartTableSelection({ rows: days, getId: rowId, getDate: rowDate, selectedId, onSelect: selectDay, focused });
88
+
89
+ const latest = summary?.latest ?? null;
90
+ const pending = pendingText(latest);
91
+ const figures: StatItem[] = summary ? [
92
+ { id: "latest", label: "Latest day", value: formatFlowAmount(latest?.total), color: flowColor(latest?.total, colors),
93
+ detail: [latest?.date, pending].filter(Boolean).join(" · ") || undefined },
94
+ { id: "week", label: "5 days", value: formatFlowAmount(summary.week), color: flowColor(summary.week, colors) },
95
+ { id: "month", label: "20 days", value: formatFlowAmount(summary.month), color: flowColor(summary.month, colors) },
96
+ { id: "launch", label: "Since launch", value: formatFlowAmount(summary.sinceLaunch), color: flowColor(summary.sinceLaunch, colors),
97
+ detail: summary.firstDate ? `since ${summary.firstDate}` : undefined },
98
+ ] : [];
99
+
100
+ const updatedAgo = useUpdatedAgo(resource.updatedAt);
101
+ const footerInfo = useMemo(() => data ? [
102
+ { id: "as-of", parts: [{ text: `as of ${data.asOf}`, tone: "muted" as const }] },
103
+ ...(updatedAgo ? [{ id: "updated", parts: [{ text: updatedAgo, tone: "muted" as const }] }] : []),
104
+ ] : [], [data, updatedAgo]);
105
+ useAutoRefresh(resource.updatedAt, resource.load);
106
+ const refresh = useCallback(() => void resource.reload(), [resource.reload]);
107
+ usePaneRefreshKey(refresh, { focused });
108
+ usePaneStatusLinkFooter({
109
+ registrationId: CRYPTO_ETF_FLOWS_PANE_ID, focused, loading: resource.loading, error: data ? null : resource.error,
110
+ url: data?.source.url ?? null, source: data?.source.publisher ?? null, label: "publisher", showOpenHint: true,
111
+ info: footerInfo, stale: !!data && (data.stale || !!current?.stale),
112
+ });
113
+ usePaneNoticeFooter({
114
+ registrationId: `${CRYPTO_ETF_FLOWS_PANE_ID}:notices`, focused,
115
+ notices: [
116
+ ...(data?.stale ? [`The flows were last read ${data.fetchedAt.slice(0, 10)}; newer days may be missing.`] : []),
117
+ ...(data && current?.refreshError ? [current.refreshError] : []),
118
+ ],
119
+ });
120
+
121
+ const selectAsset = useCallback((value: string) => setAssetSetting(cryptoEtfFlowAsset(value).toLowerCase()), [setAssetSetting]);
122
+ const selectRange = useCallback((value: CryptoEtfFlowRange) => setStoredRange(value), [setStoredRange]);
123
+ // The number keys pick the range, as the bar's hints say; picking the one showing sends the chart back to it.
124
+ const handleKeyDown = useCallback((event: Parameters<typeof handleRefreshKey>[0]) => {
125
+ if (handleRefreshKey(event, refresh, { stopPropagation: true })) return true;
126
+ if (!isPlainKeyboardEvent(event)) return false;
127
+ const picked = CRYPTO_ETF_FLOW_RANGES.find((option) => option.hint === event.name);
128
+ if (!picked) return false;
129
+ event.preventDefault?.();
130
+ if (picked.value === range) resetChartView();
131
+ else selectRange(picked.value);
132
+ return true;
133
+ }, [range, refresh, resetChartView, selectRange]);
134
+
135
+ const renderCell = useCallback((day: CryptoEtfFlowDay, column: CryptoEtfFlowColumn): DataTableCell => {
136
+ if (column.id === "date") return { text: day.date, value: day.date, color: colors.text };
137
+ if (column.id === "total") return { text: formatFlow(day.total), value: day.total, color: flowColor(day.total, colors) };
138
+ const ticker = fundTickerOfColumn(column.id) ?? "";
139
+ const value = day.flows[ticker] ?? null;
140
+ // A fund that reported the day before and not yet today: its figure is to come, not none.
141
+ if (value == null && day.pending.includes(ticker)) return { text: "pending", value: null, color: colors.textMuted };
142
+ return { text: formatFlow(value), value, color: flowColor(value, colors) };
143
+ }, []);
144
+
145
+ const query = (
146
+ <QueryBar
147
+ width={width}
148
+ filters={[
149
+ { id: "asset", label: "Asset", inline: true, value: asset, options: CRYPTO_ETF_FLOW_ASSETS.map(({ value, label: name }) => ({ value, label: name })), onChange: selectAsset },
150
+ { id: "range", label: "Range", inline: true, chartRange: true, value: range, options: CRYPTO_ETF_FLOW_RANGES, onChange: (value: string) => selectRange(cryptoEtfFlowRange(value)) },
151
+ ]}
152
+ meta="US$ millions"
153
+ />
154
+ );
155
+
156
+ return (
157
+ <Box flexDirection="column" width={width} height={height}>
158
+ {query}
159
+ <PaneStatusBody loading={resource.loading && !data} error={!data ? resource.error : null} subject={`${label.toLowerCase()} ETF flows`}
160
+ empty={!resource.loading && !resource.error && !!data && !data.days.length} emptyTitle={`No ${label.toLowerCase()} ETF flows listed yet.`}>
161
+ {data ? (
162
+ <DataTableView<CryptoEtfFlowDay, CryptoEtfFlowColumn>
163
+ focused={focused}
164
+ rootWidth={width}
165
+ rootHeight={Math.max(0, height - 1)}
166
+ rootBefore={(
167
+ <ChartTableHeader
168
+ width={width}
169
+ height={Math.max(0, height - 1)}
170
+ tableRows={days.length}
171
+ tableColumns={columns}
172
+ figures={figures}
173
+ chart={{ series, formatValue: formatRunningTotal, formatAxisValue: formatFlowAxis, remoteKind: "crypto-etf-flows", ...link }}
174
+ />
175
+ )}
176
+ selection={{ kind: "id", selectedId, getId: rowId, onChange: selectDay }}
177
+ onRootKeyDown={handleKeyDown}
178
+ columns={columns}
179
+ items={days}
180
+ freezeFirstColumn
181
+ sortColumnId={null}
182
+ sortDirection="desc"
183
+ getItemKey={rowId}
184
+ renderCell={renderCell}
185
+ selectedTextOverridesCellColor
186
+ resetScrollKey={`${asset}:${range}`}
187
+ emptyStateTitle="No trading days in this range."
188
+ />
189
+ ) : null}
190
+ </PaneStatusBody>
191
+ </Box>
192
+ );
193
+ }
@@ -288,6 +288,7 @@ export const debugPlugin: GloomPlugin = {
288
288
  name: "Debug Log",
289
289
  icon: "D",
290
290
  component: DebugPane,
291
+ reportFreshness: { status: "not-a-feed", basis: "debug log" },
291
292
  defaultPosition: "right",
292
293
  defaultMode: "floating",
293
294
  defaultFloatingSize: { width: 120, height: 30 },
@@ -69,7 +69,7 @@ function createDividendYieldModule({
69
69
  id: "dividend-yield-pane",
70
70
  paneId: "dividend-yield",
71
71
  label: "Dividend Yield",
72
- description: "Cash distribution history, trailing and forward yield, payout and growth; gloomberb fn DVD with several tickers ranks them by yield. "
72
+ description: "Cash distribution history, trailing and forward yield, payout and growth; gloom fn DVD with several tickers ranks them by yield. "
73
73
  + "A bond fund's SEC yield beside its distribution yield, and with --tax-rate a muni fund's tax-equivalent yield. Future payments are not forecast.",
74
74
  keywords: ["dividend", "dividends", "yield", "dvd", "income", "payout", "ex-date", "distribution", "dividend income", "income investing",
75
75
  "dividend growth", "payout ratio", "drip", "reinvest", "reinvestment", "dividend reinvestment", "rank dividend payers",
@@ -14,7 +14,7 @@ const DOCS_INSTANCE_ID = "docs";
14
14
 
15
15
  function requestedTopic(context: PaneTemplateContext, options?: PaneTemplateCreateOptions): DocsTopic {
16
16
  const registry = getSharedRegistry();
17
- // The command line (`gloomberb fn DOCS RV`) has no registry: the argument goes to the reader as a search.
17
+ // The command line (`gloom fn DOCS RV`) has no registry: the argument goes to the reader as a search.
18
18
  const index = registry ? buildRegistryHelpIndex(registry) : null;
19
19
  const paneId = options?.values?.pane;
20
20
  if (paneId && registry && index) {
@@ -331,13 +331,13 @@ export function DocsPane({ focused, width, height }: PaneProps) {
331
331
  }, [entries, query, show]);
332
332
 
333
333
  const visibleEntries = useMemo(() => rows.filter(isSectionedItemRow).map((row) => row.item), [rows]);
334
- // A request that matches nothing fails a report of the pane (`gloomberb fn DOCS zzzz`) instead of listing the whole index.
334
+ // A request that matches nothing fails a report of the pane (`gloom fn DOCS zzzz`) instead of listing the whole index.
335
335
  const requested = requestKey ? parseDocsTopicKey(requestKey) : null;
336
336
  const requestedQuery = requested?.kind === "home" ? requested.query?.trim() ?? "" : "";
337
337
  useRemoteUiNode(feed && requestedQuery && stack.length === 0 && query.trim() === requestedQuery && visibleEntries.length === 0 ? {
338
338
  role: "report-failure",
339
339
  label: "No docs entry",
340
- getMetadata: () => ({ message: `No docs entry for ${requestedQuery}.`, details: "Run gloomberb fn DOCS for the index." }),
340
+ getMetadata: () => ({ message: `No docs entry for ${requestedQuery}.`, details: "Run gloom fn DOCS for the index." }),
341
341
  } : null);
342
342
  const effectiveSelectedKey = visibleEntries.some((entry) => entry.key === selectedKey)
343
343
  ? selectedKey
@@ -66,7 +66,7 @@ export function docsTopicForPane(
66
66
  export function docsTopicForArgument(index: HelpFunctionIndex | null, argument: string): DocsTopic {
67
67
  const query = argument.trim();
68
68
  if (!query) return { kind: "home" };
69
- // A command line with no registry (`gloomberb fn DOCS RV`) cannot resolve a mnemonic here: the reader does, from its own entries.
69
+ // A command line with no registry (`gloom fn DOCS RV`) cannot resolve a mnemonic here: the reader does, from its own entries.
70
70
  const fn = index?.get(query.toUpperCase()) ?? index?.get((query.split(/\s+/)[0] ?? "").toUpperCase());
71
71
  if (fn) return docsTopicForFunction(fn);
72
72
  return { kind: "home", query };
@@ -21,6 +21,8 @@ const dateOrNull = (value: unknown) => value === null || date(value);
21
21
  const instantOrNull = (value: unknown) => value === null || typeof value === "string" && Number.isFinite(Date.parse(value));
22
22
  const finite = (value: unknown): value is number => typeof value === "number" && Number.isFinite(value);
23
23
  const finiteOrNull = (value: unknown) => value === null || finite(value);
24
+ /** A field older servers leave out: absent, null or a number. */
25
+ const optionalFinite = (value: unknown) => value === undefined || finiteOrNull(value);
24
26
  const pairs = (value: unknown) => Array.isArray(value)
25
27
  && value.every((pair) => Array.isArray(pair) && Number.isInteger(pair[0]) && finite(pair[1]));
26
28
 
@@ -29,6 +31,7 @@ function validRow(row: DoeSeriesRow): boolean {
29
31
  return typeof row.id === "string" && typeof row.label === "string" && UNITS.has(row.unit) && TABS.has(row.tab)
30
32
  && dateOrNull(row.weekEnding) && finiteOrNull(row.value) && finiteOrNull(row.weekChange) && (row.value == null) === (row.weekEnding == null)
31
33
  && (row.read === null || typeof row.read === "string")
34
+ && (row.basis === undefined || row.basis === "published" || row.basis === "computed")
32
35
  && (ago === null || date(ago.weekEnding) && finite(ago.value) && finite(ago.change) && finiteOrNull(ago.changePercent))
33
36
  && (five === null || Array.isArray(five.years) && five.years.length > 0 && [five.min, five.max, five.average, five.vsAverage].every(finite)
34
37
  && five.min <= five.max && finiteOrNull(five.averageChange) && finiteOrNull(five.vsAveragePercent) && finiteOrNull(five.position))
@@ -44,7 +47,8 @@ function validateDoeBoard(payload: DoeBoardPayload): DoeBoardPayload {
44
47
  || !Array.isArray(payload.gaps) || !payload.gaps.every((gap) => typeof gap === "string")
45
48
  || !Array.isArray(payload.reports) || !payload.reports.every((report) => (report.id === "petroleum" || report.id === "gas")
46
49
  && dateOrNull(report.weekEnding) && dateOrNull(report.nextWeekEnding)
47
- && instantOrNull(report.releasedAt) && instantOrNull(report.nextReleaseAt))
50
+ && instantOrNull(report.releasedAt) && instantOrNull(report.nextReleaseAt)
51
+ && optionalFinite(report.nextConsensus) && optionalFinite(report.nextPrior))
48
52
  || !Array.isArray(payload.series) || new Set(payload.series.map((row) => row.id)).size !== payload.series.length
49
53
  || !payload.series.every(validRow)) {
50
54
  throw new Error("The server returned an invalid EIA weekly board");
@@ -4,6 +4,7 @@ import { fetchDoeBoard } from "./client";
4
4
  import {
5
5
  DOE_TABS,
6
6
  DOE_UNIT_LABEL,
7
+ doeComparisonBasis,
7
8
  doeHeaderLine,
8
9
  doeReport,
9
10
  doeRows,
@@ -62,11 +63,16 @@ export function doeHeadless(defaultTab: DoeTab | "all"): HeadlessPaneDefinition<
62
63
  async load(args) {
63
64
  const data = await fetchDoeBoard();
64
65
  // Each tab is dated by its own EIA report (petroleum Wednesday, gas Thursday);
65
- // once the next one is a day overdue the tables have missed it.
66
- const freshness = (tabs: readonly DoeTab[]) => {
66
+ // once the next one is a day overdue the tables have missed it. The basis
67
+ // names what Vs 1Y and Vs 5Y avg are measured against.
68
+ const freshness = (tabs: readonly DoeTab[], rows: readonly DoeSeriesRow[]) => {
67
69
  const reports = [...new Set(tabs.flatMap((tab) => doeReport(data, tab) ?? []))];
68
- return { source: "EIA", status: "not-a-feed" as const, basis: "weekly release",
69
- asOf: newestReportTime(reports.map((report) => report.releasedAt)),
70
+ const comparison = doeComparisonBasis(rows);
71
+ // The newest report's week and when EIA released it: `Fri 16 Oct 2026, released Thu 22 Oct 14:30 UTC`.
72
+ const releasedAt = newestReportTime(reports.map((report) => report.releasedAt));
73
+ const week = reports.find((report) => report.releasedAt === releasedAt)?.weekEnding;
74
+ return { source: "EIA", status: "not-a-feed" as const, basis: comparison ? `weekly release; ${comparison}` : "weekly release",
75
+ ...(week && releasedAt ? { asOf: week, releasedOn: releasedAt } : { asOf: releasedAt }),
70
76
  nextExpectedAt: oldestReportTime(reports.map((report) => report.nextReleaseAt)) };
71
77
  };
72
78
  const argument = Array.isArray(args.argument) ? args.argument.join(" ") : args.argument;
@@ -84,7 +90,7 @@ export function doeHeadless(defaultTab: DoeTab | "all"): HeadlessPaneDefinition<
84
90
  rows: seasonalRows(row) },
85
91
  ],
86
92
  errors: data.gaps,
87
- freshness: freshness([row.tab]),
93
+ freshness: freshness([row.tab], [row]),
88
94
  metadata: { ...data, series: [row], complete: data.status === "available" },
89
95
  };
90
96
  }
@@ -96,7 +102,7 @@ export function doeHeadless(defaultTab: DoeTab | "all"): HeadlessPaneDefinition<
96
102
  rows: doeRows(data, tab).map(reportRow),
97
103
  })),
98
104
  errors: data.gaps,
99
- freshness: freshness(tabs),
105
+ freshness: freshness(tabs, tabs.flatMap((tab) => doeRows(data, tab))),
100
106
  metadata: { ...data, complete: data.status === "available" },
101
107
  };
102
108
  },
@@ -131,19 +131,56 @@ function doeReleaseTime(iso: string): string {
131
131
  return `${parts.weekday} ${parts.month} ${parts.day} ${parts.hour}:${parts.minute} ET`;
132
132
  }
133
133
 
134
+ /** The calendar's expectation for the next gas release, as the 1W change column reads it: "consensus +80 Bcf, prior +77 Bcf". */
135
+ function doeExpected(report: DoeReportStatus): string | null {
136
+ if (report.id !== "gas") return null;
137
+ const parts = [
138
+ report.nextConsensus != null ? `consensus ${formatDoeChange("bcf", report.nextConsensus)} Bcf` : null,
139
+ report.nextPrior != null ? `prior ${formatDoeChange("bcf", report.nextPrior)} Bcf` : null,
140
+ ].filter((part): part is string => !!part);
141
+ return parts.length ? parts.join(", ") : null;
142
+ }
143
+
134
144
  /**
135
145
  * The tab's report on one line: the data week, when it came out and when the
136
- * next one is due, with the holiday that moved it.
146
+ * next one is due, with the holiday that moved it and, for gas storage, the
147
+ * calendar's consensus and prior for it. Where the line runs longer than
148
+ * `width`, when the week came out gives way first, so the next release and
149
+ * what it is expected to show stay whole.
137
150
  */
138
- export function doeHeaderLine(report: DoeReportStatus | null, now = Date.now()): string | undefined {
151
+ export function doeHeaderLine(report: DoeReportStatus | null, now = Date.now(), width = Number.POSITIVE_INFINITY): string | undefined {
139
152
  if (!report?.weekEnding) return undefined;
140
- const parts = [`Week ending ${doeDay(report.weekEnding)}`];
141
- if (report.releasedAt) parts.push(`released ${doeReleaseTime(report.releasedAt)}`);
153
+ const week = `Week ending ${doeDay(report.weekEnding)}`;
154
+ const released = report.releasedAt ? `released ${doeReleaseTime(report.releasedAt)}` : null;
155
+ let next: string | null = null;
142
156
  if (report.nextReleaseAt) {
143
157
  const due = Date.parse(report.nextReleaseAt) <= now ? "due" : "next";
144
- parts.push(`${due} ${doeReleaseTime(report.nextReleaseAt)}${report.nextReleaseHoliday ? ` (${report.nextReleaseHoliday})` : ""}`);
158
+ const expected = doeExpected(report);
159
+ next = `${due} ${doeReleaseTime(report.nextReleaseAt)}${report.nextReleaseHoliday ? ` (${report.nextReleaseHoliday})` : ""}`
160
+ + (expected ? `, ${expected}` : "");
145
161
  }
146
- return parts.join(" · ");
162
+ const line = [week, released, next].filter((part): part is string => !!part).join(" · ");
163
+ return line.length <= width || !released || !next ? line : [week, next].join(" · ");
164
+ }
165
+
166
+ const PUBLISHED_BASIS = "year-ago and 5-year average as EIA published";
167
+ const COMPUTED_BASIS = "year-ago and 5-year average from EIA weekly history";
168
+
169
+ /**
170
+ * What the year-ago and five-year columns are measured against, for the
171
+ * footer: the EIA's own published figures (gas storage) or the stored weekly
172
+ * history, and both where the rows mix them. Null from an older server,
173
+ * which does not say.
174
+ */
175
+ export function doeComparisonBasis(rows: readonly DoeSeriesRow[]): string | null {
176
+ const shown = rows.filter((row) => row.yearAgo || row.fiveYear);
177
+ if (!shown.length || shown.some((row) => row.basis === undefined)) return null;
178
+ const published = shown.filter((row) => row.basis === "published");
179
+ if (published.length === shown.length) return PUBLISHED_BASIS;
180
+ if (!published.length) return COMPUTED_BASIS;
181
+ const tabs = (basis: string) => [...new Set(shown.filter((row) => row.basis === basis).map((row) => row.tab))]
182
+ .map((tab) => DOE_TABS.find((entry) => entry.value === tab)!.label.toLowerCase()).join(" and ");
183
+ return `${tabs("published")} ${PUBLISHED_BASIS}, ${tabs("computed")} from EIA weekly history`;
147
184
  }
148
185
 
149
186
  const DAY_MS = 86_400_000;
@@ -1,11 +1,13 @@
1
1
  import { useMemo } from "react";
2
2
  import type { DoeBoardPayload, DoeSeriesRow, DoeTab } from "../../../api-client/doe";
3
3
  import {
4
+ ChartRead,
4
5
  ChartTableHeader,
5
6
  CompositeChart,
6
7
  DataTableView,
7
8
  PaneStatusBody,
8
9
  QueryBar,
10
+ useChartReadRows,
9
11
  usePaneNoticeFooter,
10
12
  usePaneStatusFooter,
11
13
  usePaneTabs,
@@ -19,12 +21,12 @@ import { useThemeColors } from "../../../theme/theme-context";
19
21
  import type { ResolvedSeries } from "../../../time-series/types";
20
22
  import type { PaneProps } from "../../../types/plugin";
21
23
  import { Box } from "../../../ui";
22
- import { ClippedText } from "../../../components/ui/display";
23
24
  import { DOE_NOT_AVAILABLE, getCachedDoeBoard, loadDoeBoard } from "./client";
24
25
  import {
25
26
  DOE_TABS,
26
27
  DOE_UNIT_LABEL,
27
28
  doeAxisFormatter,
29
+ doeComparisonBasis,
28
30
  doeHeaderLine,
29
31
  doeReport,
30
32
  doeRows,
@@ -51,8 +53,8 @@ const COLUMNS: DataTableColumn[] = [
51
53
  { id: "range", label: "5Y Range", width: 12, align: "left" },
52
54
  ];
53
55
  const PANELS = [{ id: "main" }];
54
- /** Legend, four plot rows, the week axis and the read under it. */
55
- const CHART_MIN_ROWS = 7;
56
+ /** Legend, four plot rows and the week axis; the read under them takes its own rows. */
57
+ const CHART_ROWS_ABOVE_READ = 6;
56
58
 
57
59
  function legendValue(row: DoeSeriesRow) {
58
60
  return (value: number) => `${value.toLocaleString("en-US", { minimumFractionDigits: row.unit === "kb" || row.unit === "pct" ? 1 : 0,
@@ -66,20 +68,19 @@ function legendValue(row: DoeSeriesRow) {
66
68
  * the years; the plain read sits under the axis.
67
69
  */
68
70
  function SeasonalChart({ row, series, width, height }: { row: DoeSeriesRow; series: ResolvedSeries[]; width: number; height: number }) {
69
- const colors = useThemeColors();
70
71
  const weeks = row.seasonal?.weeks ?? 52;
71
72
  const latestWeek = row.seasonal?.current.at(-1)?.[0] ?? null;
72
73
  const viewport = useMemo(() => ({ start: doeWeekDate(1), end: doeWeekDate(weeks) }), [weeks]);
73
74
  const xAxis = useMemo(() => ({ ticks: doeWeekTicks(weeks), formatCursor: (ratio: number) => `W${Math.round(ratio * (weeks - 1)) + 1}` }), [weeks]);
74
- // The plain read under the axis; the desktop cuts it where its line ends.
75
- const read = row.read && width > 2 ? row.read : "";
75
+ // The plain read under the axis: wrapped in the terminal, cut by CSS where its line ends on the desktop.
76
+ const readRows = useChartReadRows([row.read], width);
76
77
  return (
77
78
  <Box width={width} height={height} flexDirection="column">
78
- <CompositeChart series={series} panels={PANELS} width={width} height={Math.max(3, height - (read ? 1 : 0))}
79
+ <CompositeChart series={series} panels={PANELS} width={width} height={Math.max(3, height - readRows)}
79
80
  focused={false} navigable={false} showLegend showTimeAxis viewport={viewport} clipToViewport xAxis={xAxis}
80
81
  cursorDate={latestWeek ? doeWeekDate(latestWeek) : null} formatValue={legendValue(row)} formatAxisValue={doeAxisFormatter(row.unit)}
81
82
  remoteKind="doe-seasonal" />
82
- {read ? <Box height={1} paddingX={1}><ClippedText fg={colors.textMuted} text={read} width={width - 2} /></Box> : null}
83
+ <ChartRead text={row.read} width={width} />
83
84
  </Box>
84
85
  );
85
86
  }
@@ -93,10 +94,13 @@ function DoeBoard({ payload, tab, initialSeries, width, height, focused }: {
93
94
  const [selectedId, setSelectedId] = usePluginPaneState<string | null>("selected", initialSeries);
94
95
  const selected = rows.find((row) => row.id === selectedId) ?? rows[0] ?? null;
95
96
  const series = useMemo(() => selected ? doeSeasonalSeries(selected, colors) : [], [selected, colors]);
96
- const meta = doeHeaderLine(doeReport(payload, tab));
97
+ // The query bar's padding aside, the line keeps the next release whole on a narrow pane.
98
+ const meta = doeHeaderLine(doeReport(payload, tab), Date.now(), width - 2);
99
+ // Room for the longest read at this width, so the chart does not give way to the strip as the selection moves.
100
+ const readRows = useChartReadRows(rows.map((row) => row.read), width);
97
101
  const chart: ChartTableChart | null = selected && series.length ? {
98
102
  render: (size) => <SeasonalChart row={selected} series={series} width={size.width} height={size.height} />,
99
- minRows: CHART_MIN_ROWS,
103
+ minRows: CHART_ROWS_ABOVE_READ + Math.max(1, readRows),
100
104
  strip: doeSeasonalStrip(selected, colors.positive),
101
105
  } : null;
102
106
  return (
@@ -134,8 +138,11 @@ export function DoePane({ width, height, focused }: PaneProps) {
134
138
  usePaneRefreshKey(() => void resource.reload(), { focused });
135
139
  usePaneNoticeFooter({ registrationId: "doe:notices", focused,
136
140
  notices: [...(data?.gaps ?? []), ...(resource.data?.refreshError ? [resource.data.refreshError] : [])] });
141
+ // What Vs 1Y and Vs 5Y are measured against on this tab: the EIA's published figures for gas storage.
142
+ const basis = useMemo(() => data ? doeComparisonBasis(doeRows(data, tab)) : null, [data, tab]);
143
+ const info = useMemo(() => basis ? [{ id: "basis", parts: [{ text: basis, tone: "muted" as const }] }] : undefined, [basis]);
137
144
  usePaneStatusFooter({ registrationId: "doe", loading: resource.loading, error: notAvailable ? null : resource.error,
138
- stale: !!data && resource.data?.stale });
145
+ stale: !!data && resource.data?.stale, info });
139
146
  return (
140
147
  <Box width={width} height={height} flexDirection="column">
141
148
  {strip}
@@ -4,8 +4,9 @@ import { getPublishedUsEquityCalendarDay } from "../../../market-data/published-
4
4
  import type { EarningsEvent } from "../../../types/data-provider";
5
5
  import type { EarningsDateStatus, EarningsEpsBasis, Quote } from "../../../types/financials";
6
6
  import type { TickerRecord } from "../../../types/ticker";
7
- import { dateStatusFromEstimateFlag, earningsDateStatus, earningsEpsBasis, isProvisionalActual } from "../shared/earnings-report";
8
- import { coherentEarningsValue } from "./estimate-basis";
7
+ import { earningsDateStatus, earningsEpsBasis, isProvisionalActual } from "../shared/earnings-report";
8
+ import { calendarStatus } from "../shared/earnings-calendar";
9
+ import { coherentEarningsValue } from "../shared/earnings-estimate-basis";
9
10
  import { shortDate, surprise, weekday } from "./format";
10
11
 
11
12
  /** A held name is in a portfolio; a watched one only in watchlists. */
@@ -59,7 +60,7 @@ export function addDays(date: string, days: number): string {
59
60
  }
60
61
 
61
62
  /** NYSE sessions from the published calendar; weekdays for years it does not cover. */
62
- function isSession(date: string): boolean {
63
+ export function isSession(date: string): boolean {
63
64
  const known = getPublishedUsEquityCalendarDay("NYSE", date);
64
65
  if (known) return known === "session";
65
66
  const day = new Date(`${date}T00:00:00Z`).getUTCDay();
@@ -149,7 +150,7 @@ export function boardReport(report: EarningsCalendarReport, owned: ReadonlyMap<s
149
150
  }
150
151
 
151
152
  /** A company the stored calendar does not carry (a listing abroad, a date past its horizon) from the per-ticker calendar. */
152
- export function fallbackReport(event: EarningsEvent, owned: ReadonlyMap<string, Ownership>): BoardReport {
153
+ export function fallbackReport(event: EarningsEvent, owned: ReadonlyMap<string, Ownership>, today: string): BoardReport {
153
154
  const date = event.earningsDate.toISOString().slice(0, 10);
154
155
  const timing = event.timing === "BMO" ? "bmo" : event.timing === "AMC" ? "amc" : null;
155
156
  // Estimates in another currency would read as dollars beside the rest.
@@ -165,7 +166,8 @@ export function fallbackReport(event: EarningsEvent, owned: ReadonlyMap<string,
165
166
  date,
166
167
  timing,
167
168
  expectedTiming: false,
168
- dateStatus: dateStatusFromEstimateFlag(event.isDateEstimate),
169
+ // A date gone by is reported, as every earnings surface reads it (shared/earnings-calendar).
170
+ dateStatus: calendarStatus(event, today),
169
171
  marketCap: null,
170
172
  epsEstimate,
171
173
  // The count belongs to the estimate beside it.
@@ -218,6 +220,11 @@ function compare(left: BoardReport, right: BoardReport, sort: BoardSort): number
218
220
  return sort.direction === "asc" ? a - b : b - a;
219
221
  }
220
222
 
223
+ /** Held names, then watched, then the rest, when the board puts mine first; one rank for all otherwise. */
224
+ export function ownershipRank(report: Pick<BoardReport, "owned">, mineFirst: boolean): number {
225
+ return !mineFirst ? 0 : report.owned === "held" ? 0 : report.owned === "watched" ? 1 : 2;
226
+ }
227
+
221
228
  /**
222
229
  * Sections in date order, each ranked by the sort (largest company first by
223
230
  * default). With `mineFirst`, held names lead, then watched, then the rest.
@@ -228,7 +235,7 @@ export function boardRows(
228
235
  sort: BoardSort,
229
236
  mineFirst: boolean,
230
237
  ): BoardRow[] {
231
- const rank = (report: BoardReport) => (!mineFirst ? 0 : report.owned === "held" ? 0 : report.owned === "watched" ? 1 : 2);
238
+ const rank = (report: BoardReport) => ownershipRank(report, mineFirst);
232
239
  const rows: BoardRow[] = [];
233
240
  for (const day of days) {
234
241
  const inDay = reports
@@ -1,4 +1,5 @@
1
1
  import type { DataTableCell, DataTableColumn } from "../../../components";
2
+ import { withCompanyLogo } from "../../../components/company-logo";
2
3
  import { TABLE_COLUMN_GAP, tableColumnWidth } from "../../../components/ui/table-layout";
3
4
  import { colors } from "../../../theme/colors";
4
5
  import { TextAttributes } from "../../../ui";
@@ -81,6 +82,8 @@ export interface BoardCellContext {
81
82
  statusShown: boolean;
82
83
  /** The move on a report out today (reportMove); "loading" while its quote is. */
83
84
  move: (report: BoardReport) => number | "loading" | null;
85
+ /** The desktop and the web lead each name with the company's logo; the terminal draws none. */
86
+ logos?: boolean;
84
87
  }
85
88
 
86
89
  const NO_CONTEXT: BoardCellContext = { statusShown: true, move: () => null };
@@ -101,7 +104,7 @@ export function renderBoardCell(row: BoardRow, column: BoardColumn, context: Boa
101
104
  case "symbol":
102
105
  return { text: report.symbol, color: colors.text, attributes: TextAttributes.BOLD };
103
106
  case "name":
104
- return { text: report.name, color: colors.text };
107
+ return withCompanyLogo({ text: report.name, color: colors.text }, report, context.logos === true);
105
108
  case "when": {
106
109
  const timing = report.timing ? TIMING_LABEL[report.timing] : "--";
107
110
  const text = row.showDay ? `${weekday(report.date)} ${timing}` : timing;