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
@@ -1,19 +1,25 @@
1
1
  import type {
2
+ HeadlessBundleResult,
2
3
  HeadlessPaneColumn,
3
4
  HeadlessPaneContext,
4
5
  HeadlessPaneDefinition,
5
6
  HeadlessPaneLoadArgs,
7
+ HeadlessPaneRow,
6
8
  } from "../../../types/plugin";
9
+ import { parsePublicTickerKey } from "../../../utils/exchanges";
10
+ import { US_FUND_FACTS_ONLY } from "../../../utils/sec";
7
11
  import type { SecFilingItem } from "../../../types/data-provider";
8
12
  import type { FundFactsPayload } from "../../../api-client/fund-facts";
9
13
  import { errorMessage } from "../../../utils/errors";
10
14
  import { loadSecFilings } from "./client";
11
- import { ETF_FILING_FORMS, filingFormMatches, filterFilingsByForms, SEC_FILING_FETCH_LIMIT } from "./forms";
15
+ import { ETF_FILING_FORMS, filingFormMatches, filterFilingsByForms, fundSeriesFilings, SEC_FILING_FETCH_LIMIT } from "./forms";
12
16
  import { hiddenFilingsNote, loadLatestFilings } from "../../../utils/sec-filings";
13
17
  import { buildSecFilingRows, secFilingIssuers, SEC_ACCEPTANCE_NOTE } from "./model";
14
18
  import { SEC_FILINGS } from "../shared/report-freshness";
15
19
  import { fetchFundFacts, fundFactEntries, fundFactPublishers, fundFactsEmpty, fundFactsErrorText, fundFactsStaleNote, listNames } from "./fund-facts";
16
20
  import { REPORT_ROWS } from "../shared/headless-options";
21
+ import { fundAbroadProfile, venueAbroad, type FundAbroadProfile } from "./fund-abroad";
22
+ import { listingAnnouncementsPage } from "../../../utils/exchange-announcements";
17
23
 
18
24
  const SEC_COLUMNS: HeadlessPaneColumn[] = [
19
25
  {
@@ -29,6 +35,27 @@ const SEC_COLUMNS: HeadlessPaneColumn[] = [
29
35
  { key: "accessionNumber", header: "Accession" },
30
36
  ];
31
37
 
38
+ /** Some row has 8-K item codes; a column every row leaves `-` takes no room in the text table (exports keep it). */
39
+ const hasItems = (rows: readonly HeadlessPaneRow[]) => rows.some((row) => typeof row.items === "string" && row.items !== "");
40
+
41
+ function secTextColumns(rows: readonly HeadlessPaneRow[]): HeadlessPaneColumn[] {
42
+ return hasItems(rows) ? SEC_COLUMNS : SEC_COLUMNS.filter((column) => column.key !== "items");
43
+ }
44
+
45
+ /**
46
+ * A fund's filings as the text report prints them. Filed, Form and what the
47
+ * filing is stay in a narrow table: below 100 columns the acceptance time is
48
+ * left out. Every row is the fund's registrant's (its trust), so no Issuer
49
+ * column repeats it, as the pane's list names a filer only when there are
50
+ * several; exports keep it.
51
+ */
52
+ function fundFilingTextColumns(rows: readonly HeadlessPaneRow[]): HeadlessPaneColumn[] {
53
+ const issuers = new Set(rows.map((row) => row.cik));
54
+ return secTextColumns(rows)
55
+ .filter((column) => column.key !== "companyName" || issuers.size > 1)
56
+ .map((column) => column.key === "acceptanceReported" ? { ...column, minTableWidth: 100 } : column);
57
+ }
58
+
32
59
  export interface SecHeadlessDependencies {
33
60
  loadFilings(
34
61
  symbol: string,
@@ -107,10 +134,15 @@ export function createSecHeadless(dependencies: SecHeadlessDependencies = defaul
107
134
  ? { filings: (await load(limit)).slice(0, limit), hidden: null }
108
135
  : await loadLatestFilings(load, limit);
109
136
  const note = hidden && hiddenFilingsNote(hidden);
137
+ const rows = buildSecFilingRows(filings);
138
+ // A listing abroad whose company files nothing with the SEC says where its exchange publishes its announcements.
139
+ const page = !form && filings.length === 0 ? listingAnnouncementsPage(symbol) : null;
110
140
  return {
111
- rows: buildSecFilingRows(filings),
141
+ rows,
142
+ textColumns: secTextColumns(rows),
112
143
  ...(note ? { notes: [note] } : {}),
113
- ...(form ? { empty: `No ${form} filings found for ${symbol}.` } : {}),
144
+ ...(form ? { empty: `No ${form} filings found for ${symbol}.` }
145
+ : page ? { empty: `${symbol} files no SEC reports. ${page.name}: ${page.url}` } : {}),
114
146
  metadata: {
115
147
  acceptanceNote: SEC_ACCEPTANCE_NOTE,
116
148
  symbol,
@@ -128,13 +160,43 @@ export const secHeadless = createSecHeadless();
128
160
 
129
161
  export interface FundHeadlessDependencies extends SecHeadlessDependencies {
130
162
  loadFacts(symbol: string, ctx: HeadlessPaneContext): Promise<FundFactsPayload>;
163
+ loadAbroadProfile?(key: string, ctx: HeadlessPaneContext): Promise<FundAbroadProfile | null>;
131
164
  }
132
165
 
133
- const defaultFundDependencies: FundHeadlessDependencies = {
166
+ const defaultFundDependencies = {
134
167
  ...defaultDependencies,
135
- loadFacts: (symbol, ctx) => fetchFundFacts(symbol, ctx.apiClient),
168
+ loadFacts: (symbol: string, ctx: HeadlessPaneContext) => fetchFundFacts(symbol, ctx.apiClient),
169
+ async loadAbroadProfile(key: string, ctx: HeadlessPaneContext): Promise<FundAbroadProfile | null> {
170
+ const { symbol, exchange } = parsePublicTickerKey(key);
171
+ return fundAbroadProfile(await ctx.marketData.getTickerFinancials(symbol, exchange));
172
+ },
136
173
  };
137
174
 
175
+ /**
176
+ * ETF for a fund listed abroad (3042:HKEX): what `ticker` says, that the
177
+ * facts cover US-listed funds only, and the fund's page at its issuer where
178
+ * the profile has one. No SEC request: the SEC knows no listing abroad, and
179
+ * its "Unknown ticker" said nothing of the fund.
180
+ */
181
+ function fundAbroadResult(symbol: string, venue: string, profile: FundAbroadProfile | null): HeadlessBundleResult {
182
+ const entries = [
183
+ ...profile?.name ? [{ label: "Name", value: profile.name }] : [],
184
+ ...profile?.page ? [{ label: "Issuer page", value: profile.page }] : [],
185
+ ...profile?.descriptionSource
186
+ ? [{ label: "Description from", value: `${profile.descriptionSource.publisher}: ${profile.descriptionSource.url}` }]
187
+ : [],
188
+ ];
189
+ return {
190
+ sections: [
191
+ { title: "Fund facts", rows: [], empty: US_FUND_FACTS_ONLY },
192
+ ...entries.length ? [{ title: "Fund", entries }] : [],
193
+ ],
194
+ complete: true,
195
+ freshness: { source: profile?.page ? "Fund issuer" : "Gloom", status: "not-a-feed", basis: "published fund data" },
196
+ metadata: { symbol, venue, usListedOnly: true, issuerPage: profile?.page ?? null },
197
+ };
198
+ }
199
+
138
200
  /**
139
201
  * ETF: a US-listed fund's facts (fee, NAV, premium or discount, net assets,
140
202
  * sponsor, inception, index) as its sponsor publishes them, then its fund
@@ -145,7 +207,7 @@ export function createFundHeadless(dependencies: FundHeadlessDependencies = defa
145
207
  return {
146
208
  shape: "bundle",
147
209
  freshness: { source: "Fund sponsors and SEC EDGAR", status: "not-a-feed", basis: "published fund data" },
148
- argument: { kind: "ticker", placeholder: "ticker", description: "US-listed fund ticker." },
210
+ argument: { kind: "ticker", placeholder: "ticker", description: "US-listed fund ticker. A fund listed abroad gets its issuer's page." },
149
211
  options: [{
150
212
  key: "limit",
151
213
  shot: REPORT_ROWS,
@@ -160,6 +222,19 @@ export function createFundHeadless(dependencies: FundHeadlessDependencies = defa
160
222
  describe: (args) => `ETF | ${args.symbols[0]}`,
161
223
  async load(args, ctx) {
162
224
  const symbol = args.symbols[0]!;
225
+ const abroad = venueAbroad(symbol);
226
+ if (abroad) {
227
+ try {
228
+ const profile = await (dependencies.loadAbroadProfile ?? defaultFundDependencies.loadAbroadProfile)(symbol, ctx);
229
+ return fundAbroadResult(symbol, abroad, profile);
230
+ } catch (error) {
231
+ return {
232
+ ...fundAbroadResult(symbol, abroad, null),
233
+ complete: false,
234
+ errors: [`Fund profile unavailable: ${errorMessage(error)}`],
235
+ };
236
+ }
237
+ }
163
238
  const limit = Number(args.options.limit);
164
239
  const [factsResult, filingsResult] = await Promise.allSettled([
165
240
  dependencies.loadFacts(symbol, ctx),
@@ -168,7 +243,8 @@ export function createFundHeadless(dependencies: FundHeadlessDependencies = defa
168
243
  if (factsResult.status === "rejected" && filingsResult.status === "rejected") throw filingsResult.reason;
169
244
  const facts = factsResult.status === "fulfilled" ? factsResult.value : null;
170
245
  const issuerFilings = filingsResult.status === "fulfilled" ? filingsResult.value : [];
171
- const filings = filterFilingsByForms(issuerFilings, ETF_FILING_FORMS).slice(0, limit);
246
+ // A trust's list holds every fund it runs; the fund's own series is the view.
247
+ const filings = filterFilingsByForms(fundSeriesFilings(issuerFilings), ETF_FILING_FORMS).slice(0, limit);
172
248
  const searchedAll = issuerFilings.length < SEC_FILING_FETCH_LIMIT;
173
249
  const filingsEmpty = filingsResult.status === "rejected"
174
250
  ? `Fund filings unavailable: ${errorMessage(filingsResult.reason)}`
@@ -181,10 +257,11 @@ export function createFundHeadless(dependencies: FundHeadlessDependencies = defa
181
257
  ? fundFactsErrorText(factsResult.reason)
182
258
  : fundFactsEmpty(symbol, facts, !filingsPointToSec) };
183
259
  const publishers = facts?.covered ? fundFactPublishers(facts) : [];
260
+ const filingRows = buildSecFilingRows(filings);
184
261
  return {
185
262
  sections: [
186
263
  factsSection,
187
- { title: "Fund filings", columns: SEC_COLUMNS, rows: buildSecFilingRows(filings), ...(filings.length === 0 ? { empty: filingsEmpty } : {}) },
264
+ { title: "Fund filings", columns: SEC_COLUMNS, textColumns: fundFilingTextColumns(filingRows), rows: filingRows, ...(filings.length === 0 ? { empty: filingsEmpty } : {}) },
188
265
  ],
189
266
  complete: !!facts?.covered && filingsResult.status === "fulfilled" && searchedAll,
190
267
  errors: [
@@ -1,24 +1,26 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
2
2
  import type { PluginModule } from "../plugin-module";
3
3
  import type { SecFilingDocument, SecFilingItem } from "../../../types/data-provider";
4
- import { useResolvedEntryValue, useSecFilingDocuments, useSecFilingsQuery } from "../../../market-data/hooks";
4
+ import { useResolvedEntryValue, useSecFilingDocuments, useSecFilingsQuery, useTickerFinancials } from "../../../market-data/hooks";
5
5
  import { getSharedMarketDataCoordinator } from "../../../market-data/coordinator";
6
6
  import { useShortcut } from "../../../react/input";
7
7
  import { isPlainKey } from "../../../utils/keyboard";
8
8
  import { instrumentFromTicker } from "../../../market-data/request-types";
9
9
  import { useDebouncedPluginPaneState, usePluginPaneState } from "../../runtime";
10
10
  import { usePaneSettingValue } from "../../../state/app/context";
11
- import { Box, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
11
+ import { Box, Text, useUiCapabilities, type ScrollBoxRenderable } from "../../../ui";
12
12
  import { FILL_REST } from "../../../components/ui/fill";
13
13
  import { t, tf } from "../../../i18n";
14
- import { EmptyState, FeedDataTableStackView, QueryBar, Spinner, TickerBadgeList, usePaneNoticeFooter, useTableLoadMore, type FeedDataTableItem, type PaneHint, type QueryBarFilter } from "../../../components";
14
+ import { EmptyState, ExternalLinkText, FeedDataTableStackView, PaneLinkMenu, QueryBar, Spinner, TickerBadgeList, usePaneNoticeFooter, useTableLoadMore, type FeedDataTableItem, type PaneHint, type QueryBarFilter } from "../../../components";
15
15
  import { displayWidth } from "../../../utils/format";
16
16
  import type { DetailFact } from "../../../components/reader/detail-reader";
17
17
  import type { ThemeColors } from "../../../theme/colors";
18
18
  import { useThemeColors } from "../../../theme/theme-context";
19
19
  import { useOpenDescription } from "../shared/open-description";
20
20
  import { toneColor } from "../shared/research-cells";
21
- import { mayBeUsEquityOrFundTicker, mayBeUsEquityTicker, secFilingItemCodes } from "../../../utils/sec";
21
+ import { mayBeUsEquityOrFundTicker, mayBeUsEquityTicker, secFilingItemCodes, US_FUND_FACTS_ONLY } from "../../../utils/sec";
22
+ import { fundAbroadProfile, venueAbroad, type FundAbroadProfile } from "./fund-abroad";
23
+ import { listingAnnouncementsPage } from "../../../utils/exchange-announcements";
22
24
  import { pricingSupplementTest } from "../../../utils/sec-filings";
23
25
  import { parseForm4Xml } from "../insider/insider-data";
24
26
  import { createTickerSurfacePaneTemplate } from "../shared/ticker-surface";
@@ -42,7 +44,7 @@ import {
42
44
  import { usePaneStatusLinkFooter } from "../../../components/layout/pane/status-footer";
43
45
  import { isCloudSessionRequired, useResearchCloudSession } from "../shared/research-cloud-session";
44
46
  import { SignInWall } from "../cloud/auth-actions";
45
- import { ETF_FORMS_SETTING, filterFilingsByForms, parseFormsSetting, SEC_FILING_FETCH_LIMIT } from "./forms";
47
+ import { ETF_FORMS_SETTING, filterFilingsByForms, fundSeriesFilings, parseFormsSetting, SEC_FILING_FETCH_LIMIT } from "./forms";
46
48
  import { fundHeadless, secHeadless } from "./headless";
47
49
  import { FundFactsSummary, FundViewNotice, useFundFacts } from "./fund-facts-view";
48
50
  import { fundFactPublishers, fundFactsCache, listNames } from "./fund-facts";
@@ -272,6 +274,15 @@ function SecView({ width, height, focused, paneType }: { width: number; height:
272
274
  useSecFilingFocusRequest(forms ? null : ticker?.metadata.ticker, setOpenItemId);
273
275
  // A form list is the fund filings view (ETF), which US-listed funds open too.
274
276
  const eligibleTicker = forms ? mayBeUsEquityOrFundTicker(ticker) : mayBeUsEquityTicker(ticker);
277
+ // A fund listed abroad (3042.HK) gets what `ticker` says of it and its issuer's page, as `fn ETF` does.
278
+ const abroadVenue = forms && !eligibleTicker && ticker ? venueAbroad(ticker.metadata.ticker) : null;
279
+ const abroadFinancials = useTickerFinancials(abroadVenue ? ticker?.metadata.ticker : null, abroadVenue ? ticker : null);
280
+ const abroad = abroadVenue ? fundAbroadProfile(abroadFinancials) : null;
281
+ const abroadPage = abroad?.page ?? null;
282
+ // An equity listed abroad links the page its exchange publishes its announcements on (ASX's for NST.AX).
283
+ const announcements = !forms && !eligibleTicker && ticker
284
+ ? listingAnnouncementsPage(ticker.metadata.ticker, ticker.metadata.exchange)
285
+ : null;
275
286
  // The fund view (ETF) leads with the fund's facts, which load apart from its filings, so a filings wall or failure leaves them on screen.
276
287
  const fundFacts = useFundFacts(forms && eligibleTicker ? ticker?.metadata.ticker : null);
277
288
  const facts = fundFacts.data?.payload ?? null;
@@ -285,8 +296,9 @@ function SecView({ width, height, focused, paneType }: { width: number; height:
285
296
  const issuerFilings = useResolvedEntryValue(filingsEntry) ?? NO_FILINGS;
286
297
  // The filter runs over every filing the service returned for the issuer,
287
298
  // the same list the unfiltered pane shows, not over a first page of it.
299
+ // The fund view keeps the fund's own series out of its trust's filings.
288
300
  const formFilings = useMemo(
289
- () => (forms ? filterFilingsByForms(issuerFilings, forms) : issuerFilings),
301
+ () => (forms ? filterFilingsByForms(fundSeriesFilings(issuerFilings), forms) : issuerFilings),
290
302
  [forms, issuerFilings],
291
303
  );
292
304
  // The fund view (ETF) has its own groups; each view keeps its own choice.
@@ -444,14 +456,14 @@ function SecView({ width, height, focused, paneType }: { width: number; height:
444
456
  usePaneStatusLinkFooter({
445
457
  registrationId: "sec",
446
458
  focused,
447
- url: openFiling ? openFiling.filingUrl : factsUrl,
448
- source: openFiling ? openFiling.form : facts?.covered ? listNames(fundFactPublishers(facts)) : null,
449
- label: openFiling || !factsUrl ? "filing" : "source",
459
+ url: openFiling ? openFiling.filingUrl : factsUrl ?? abroadPage ?? announcements?.url,
460
+ source: openFiling ? openFiling.form : facts?.covered ? listNames(fundFactPublishers(facts)) : announcements?.name ?? null,
461
+ label: openFiling ? "filing" : factsUrl ? "source" : abroadPage ? "issuer page" : announcements ? "announcements" : "filing",
450
462
  // Rows read in the background for their insiders do not hold up the pane.
451
463
  loading: loading || loadingDocuments || (!!loadingKey && viewedTargets.some((target) => target.accessionNumber === loadingKey)),
452
464
  error: authWall ? null : error ?? detailError,
453
465
  hints,
454
- showOpenHint: !!(openFiling ? openFiling.filingUrl : factsUrl),
466
+ showOpenHint: !!(openFiling ? openFiling.filingUrl : factsUrl ?? abroadPage ?? announcements),
455
467
  });
456
468
 
457
469
  usePaneNoticeFooter({
@@ -507,6 +519,7 @@ function SecView({ width, height, focused, paneType }: { width: number; height:
507
519
  if (!ticker) {
508
520
  return <EmptyState title="No ticker selected." message="Select a ticker to view SEC filings." />;
509
521
  }
522
+ if (abroadVenue) return <FundAbroadNotice profile={abroad} />;
510
523
  if (!eligibleTicker) {
511
524
  return renderFilingNotice(forms ? "Fund filings are only shown for US-listed funds and equities." : "SEC filings are only shown for US equities.");
512
525
  }
@@ -614,8 +627,9 @@ export const secModule: PluginModule = {
614
627
  id: "sec-etf-pane",
615
628
  paneId: "sec",
616
629
  label: "Fund Facts",
617
- description: "A US-listed fund's fee, NAV, premium or discount, net assets, sponsor, inception and index, then its SEC filings: prospectus updates, shareholder reports, N-CEN and N-PORT.",
618
- keywords: ["etf", "fund", "expense ratio", "fee", "nav", "premium", "discount", "aum", "net assets", "n-1a", "485bpos", "497", "n-csr", "n-cen", "n-port", "prospectus"],
630
+ description: "A US-listed fund's fee, NAV, premium or discount, net assets, sponsor, inception and index, a leveraged or inverse fund's daily objective, then the fund's own SEC filings: prospectus updates, shareholder reports, N-CEN and N-PORT.",
631
+ keywords: ["etf", "fund", "expense ratio", "fee", "nav", "premium", "discount", "aum", "net assets", "n-1a", "485bpos", "497", "n-csr", "n-cen", "n-port", "prospectus",
632
+ "leveraged", "inverse", "daily objective", "daily-reset", "decay"],
619
633
  shortcut: "ETF",
620
634
  viewKey: "etf",
621
635
  canCreate: (_context, options) => !options?.ticker || mayBeUsEquityOrFundTicker(options.ticker),
@@ -642,3 +656,35 @@ export const secModule: PluginModule = {
642
656
  resetSecFilingFocusRequests();
643
657
  },
644
658
  };
659
+
660
+ /** A link under its label, as the CLI prints it ("Issuer page: ..."). */
661
+ function LabelledLink({ label, url, text }: { label: string; url: string; text: string }) {
662
+ const colors = useThemeColors();
663
+ return (
664
+ <Box flexDirection="row">
665
+ <Text flexShrink={0} fg={colors.textDim}>{`${t(label)}: `}</Text>
666
+ <ExternalLinkText url={url} label={text} />
667
+ </Box>
668
+ );
669
+ }
670
+
671
+ /**
672
+ * ETF for a fund listed abroad (3042.HK): what `fn ETF` prints of it, its
673
+ * name, its page at its issuer and where its description is from, the last
674
+ * two as links the pane menu lists too. The footer's `o` opens the issuer page.
675
+ */
676
+ function FundAbroadNotice({ profile }: { profile: FundAbroadProfile | null }) {
677
+ const page = profile?.page;
678
+ const source = profile?.descriptionSource;
679
+ const links = page || source
680
+ ? (
681
+ <PaneLinkMenu>
682
+ <Box flexDirection="column">
683
+ {page && <LabelledLink label="Issuer page" url={page} text={new URL(page).hostname.replace(/^www\./, "")} />}
684
+ {source && <LabelledLink label="Description from" url={source.url} text={source.publisher} />}
685
+ </Box>
686
+ </PaneLinkMenu>
687
+ )
688
+ : undefined;
689
+ return <EmptyState title={US_FUND_FACTS_ONLY} message={profile?.name} actions={links} />;
690
+ }
@@ -8,6 +8,7 @@ import {
8
8
  historySessionBefore,
9
9
  latestHistoryDate,
10
10
  sectorExtendedFields,
11
+ SECTOR_RETURN_BASE_MAX_GAP_DAYS,
11
12
  sectorReturnTargetDate,
12
13
  sectorQuoteSessionDate,
13
14
  sectorReturnStartDate,
@@ -92,7 +93,7 @@ export async function loadSectorRows(
92
93
  if (asOfDate && computeTrailingReturn(history, "1Y", price, asOfDate)?.value == null
93
94
  && provider.getDetailedPriceHistory) {
94
95
  const start = new Date(`${sectorReturnTargetDate(asOfDate, "1Y")}T00:00:00Z`);
95
- start.setUTCDate(start.getUTCDate() - 7);
96
+ start.setUTCDate(start.getUTCDate() - SECTOR_RETURN_BASE_MAX_GAP_DAYS);
96
97
  const end = new Date(`${asOfDate}T00:00:00Z`);
97
98
  end.setUTCDate(end.getUTCDate() + 1);
98
99
  const extended = await provider.getDetailedPriceHistory(sector.etf, "", start, end, "1d").catch(logFailure("sectors", "Sector extended price history failed", []));
@@ -3,6 +3,7 @@ import { getTableWidth, tableColumnWidth } from "../../../components/ui/table-la
3
3
  import type { PricePoint, Quote } from "../../../types/financials";
4
4
  import { compareSortValues, type SortDirection } from "../../../utils/sort-values";
5
5
  import { getPricePointTimestamp } from "../../../utils/price-history";
6
+ import { periodBaseDay, periodBaseIndex } from "../../../market-data/market/period-return";
6
7
  import { mergePriceHistoryIntegrity, pricePointIntegrity, type PriceHistoryIntegrity } from "../../../utils/price-history-integrity";
7
8
  import {
8
9
  getCompletedRegularSessionDisplay,
@@ -17,7 +18,6 @@ import {
17
18
  type SectorDef,
18
19
  } from "./sector-data";
19
20
 
20
- const DAY_MS = 24 * 60 * 60 * 1000;
21
21
  export const DEFAULT_COLLECTION_ID: SectorCollectionId = "sectors";
22
22
 
23
23
  /**
@@ -274,24 +274,20 @@ export function historySessionBefore(history: readonly PricePoint[], beforeDate:
274
274
 
275
275
  export type SectorReturnRange = "1M" | "1Y";
276
276
 
277
- /** Clamp calendar subtraction so March 31 maps to February's final day. */
277
+ /** The calendar date a sector's 1M or 1Y return is measured back to (periodBaseDay): 31 Mar's month is 28 Feb. */
278
278
  export function sectorReturnTargetDate(asOfDate: string, range: SectorReturnRange): string {
279
- const shifted = new Date(`${asOfDate}T00:00:00Z`);
280
- const day = shifted.getUTCDate();
281
- shifted.setUTCDate(1);
282
- shifted.setUTCMonth(shifted.getUTCMonth() - (range === "1M" ? 1 : 12));
283
- const lastDay = new Date(Date.UTC(shifted.getUTCFullYear(), shifted.getUTCMonth() + 1, 0)).getUTCDate();
284
- shifted.setUTCDate(Math.min(day, lastDay));
285
- return shifted.toISOString().slice(0, 10);
279
+ return periodBaseDay(asOfDate, range);
286
280
  }
287
281
 
282
+ /** A sector's base close is at most a week before its target date; further back is a hole in the history. */
283
+ export const SECTOR_RETURN_BASE_MAX_GAP_DAYS = 7;
284
+
285
+ /** The close on or before that date, within a week of it (periodBaseIndex). */
288
286
  function returnBaseline(history: readonly PricePoint[], asOfDate: string, range: SectorReturnRange) {
289
- const target = sectorReturnTargetDate(asOfDate, range);
290
- const baseline = getSortedHistory(history).findLast(({ timestamp }) => new Date(timestamp).toISOString().slice(0, 10) <= target);
291
- if (!baseline) return null;
292
- const startDate = new Date(baseline.timestamp).toISOString().slice(0, 10);
293
- if (Date.parse(target) - Date.parse(startDate) > 7 * DAY_MS) return null;
294
- return { ...baseline, startDate };
287
+ const points = getSortedHistory(history);
288
+ const days = points.map(({ timestamp }) => new Date(timestamp).toISOString().slice(0, 10));
289
+ const index = periodBaseIndex(days, sectorReturnTargetDate(asOfDate, range), SECTOR_RETURN_BASE_MAX_GAP_DAYS);
290
+ return index < 0 ? null : { ...points[index]!, startDate: days[index]! };
295
291
  }
296
292
 
297
293
  /** A reported session establishes the calendar even when its price or the ending observation is unavailable. */
@@ -61,6 +61,7 @@ export const SERIES_INVENTORY: readonly SeriesInventoryEntry[] = [
61
61
  { module: "futures-curve", chart: "Futures curve by contract month", notInCatalog: "not-a-time-series", reason: "Plotted by delivery month; each front month is in the catalog as FUT:code." },
62
62
  { module: "crypto-board", chart: "Price sparklines for the large coins", series: ["crypto:*"] },
63
63
  { module: "perps", chart: "Perpetual funding, open interest, premium and long/short account share", series: ["perps:*"] },
64
+ { module: "crypto-etf-flows", chart: "The running net flow of the US spot bitcoin or ether ETFs since launch", notInCatalog: "not-yet", reason: "Daily and dated: the running total and each fund's daily flow could be crypto ETF series, and none is registered for the composer yet." },
64
65
  { module: "perps", chart: "Perpetual mark price", notInCatalog: "not-yet", reason: "The pair's price is in the catalog; the perpetual's own mark price could be a crypto series." },
65
66
  { module: "primary-dealers", chart: "A primary dealer position's weekly net level, the sum of the release's series behind the row", notInCatalog: "not-yet", reason: "Weekly and dated, one series per row of the board; the pane reads each only when its row is selected, and none is registered for the composer yet." },
66
67
  { module: "short-interest", chart: "A ticker's short interest and days to cover", series: ["short-interest:*"] },
@@ -77,6 +78,7 @@ export const SERIES_INVENTORY: readonly SeriesInventoryEntry[] = [
77
78
  { module: "power", chart: "European gas storage by area: % full, TWh and net injection", series: ["gas-storage:*", "gas-storage-twh:*", "gas-injection:*"] },
78
79
  { module: "awards", chart: "A company's government award totals by period", series: ["awards:*"] },
79
80
  { module: "company-kpis", chart: "A company's reported operating metrics", notInCatalog: "per-item", reason: "Each company reports its own metrics, with no shared list to register." },
81
+ { module: "supply-chain", chart: "The largest customer's share of a company's receivables at each period end", notInCatalog: "not-yet", reason: "A dated per-company series from filings that could be registered; it needs three disclosed period ends, so most tickers have none." },
80
82
  { module: "estimate-revisions", chart: "Consensus estimate for one fiscal period over time", notInCatalog: "per-item", reason: "One fiscal period of one company." },
81
83
  { module: "earnings", chart: "Implied and actual moves around past earnings", notInCatalog: "per-item", reason: "One bar per earnings event." },
82
84
  { module: "dividend-yield", chart: "A ticker's trailing 12-month cash dividends", series: ["dividends:*"] },
@@ -16,12 +16,79 @@ export interface OfflineBroker {
16
16
  syncedAt: number | null;
17
17
  /** Why it is offline, in the broker's words when it gave some. */
18
18
  reason: string;
19
- /** False when no plugin connects it, so pressing a key could not help. */
19
+ /**
20
+ * False when no plugin connects it, so pressing a key could not help. For a
21
+ * disabled profile: whether enabling it can sync it too.
22
+ */
20
23
  reconnectable: boolean;
24
+ /**
25
+ * The profile is turned off. Nothing syncs or reconnects it while it is
26
+ * (`syncBrokerInstance` refuses it); its one key enables it.
27
+ */
28
+ disabled?: boolean;
21
29
  }
22
30
 
23
- /** The key onboarding gives "Connect a broker". */
24
- const RECONNECT_BROKER_KEY = "b";
31
+ /** The key onboarding gives "Connect a broker": it reconnects an offline broker and enables a disabled one. */
32
+ const BROKER_KEY = "b";
33
+
34
+ /** `[b] enable`: one look for every pane that shows a disabled broker profile. */
35
+ export function enableBrokerHint(brokerName: string, onPress: () => void, disabled = false): PaneHint {
36
+ return {
37
+ id: "enable-broker",
38
+ key: BROKER_KEY,
39
+ label: " enable",
40
+ title: tf("Enable {broker}", { broker: brokerName }),
41
+ onPress,
42
+ disabled,
43
+ };
44
+ }
45
+
46
+ /** Which step of enabling a profile failed, said in full: the enabling, or the sync after it. */
47
+ export interface BrokerEnableFailure {
48
+ step: "enable" | "sync";
49
+ text: string;
50
+ }
51
+
52
+ function reasonOf(error: unknown): string | null {
53
+ return error instanceof Error && error.message.trim() ? error.message.trim() : null;
54
+ }
55
+
56
+ /**
57
+ * Turns a disabled broker profile back on, then syncs it when a plugin
58
+ * connects it, as the app syncs every enabled profile when it starts. Resolves
59
+ * to null when both worked, or to the step that failed and why: a sync that
60
+ * fails leaves the profile enabled, and says so.
61
+ */
62
+ export async function enableBrokerProfile(
63
+ actions: Pick<ReturnType<typeof usePluginBrokerActions>, "updateBrokerInstance" | "syncBrokerInstance">,
64
+ instanceId: string,
65
+ { sync, label }: { sync: boolean; label: string },
66
+ ): Promise<BrokerEnableFailure | null> {
67
+ try {
68
+ await actions.updateBrokerInstance(instanceId, {}, { enabled: true });
69
+ } catch (error) {
70
+ const reason = reasonOf(error);
71
+ return {
72
+ step: "enable",
73
+ text: reason
74
+ ? tf("Could not enable {label}: {reason}", { label, reason })
75
+ : tf("Could not enable {label}.", { label }),
76
+ };
77
+ }
78
+ if (!sync) return null;
79
+ try {
80
+ await actions.syncBrokerInstance(instanceId);
81
+ } catch (error) {
82
+ const reason = reasonOf(error);
83
+ return {
84
+ step: "sync",
85
+ text: reason
86
+ ? tf("Enabled {label}, but it did not sync: {reason}", { label, reason })
87
+ : tf("Enabled {label}, but it did not sync.", { label }),
88
+ };
89
+ }
90
+ return null;
91
+ }
25
92
 
26
93
  /** `as of 14:02` today, `as of Oct 17 14:02` before. */
27
94
  function formatBrokerSyncedAt(syncedAt: number, now = Date.now()): string {
@@ -36,7 +103,7 @@ function formatBrokerSyncedAt(syncedAt: number, now = Date.now()): string {
36
103
  export interface OfflineBrokerFooter {
37
104
  /** `as of …`, when the profile has synced. */
38
105
  asOf: PaneFooterSegment[];
39
- /** Why the broker is offline, or that it is reconnecting. */
106
+ /** Why the broker is offline or disabled, or that it is reconnecting. */
40
107
  status: PaneFooterSegment[];
41
108
  hints: PaneHint[];
42
109
  }
@@ -49,21 +116,36 @@ const ONLINE: OfflineBrokerFooter = { asOf: [], status: [], hints: [] };
49
116
  * does what Connect does in Brokers (a signed-in broker asks for a new
50
117
  * sign-in, any other connects), then syncs the profile so the positions are
51
118
  * current again. Nothing changes on screen until that sync lands.
119
+ *
120
+ * A disabled profile is never reconnected or synced: the footer says it is
121
+ * disabled, and `[b] enable` turns it back on and syncs it.
52
122
  */
53
123
  export function useOfflineBrokerFooter(offline: OfflineBroker | null): OfflineBrokerFooter {
54
- const { connectBrokerInstance, syncBrokerInstance } = usePluginBrokerActions();
124
+ const brokerActions = usePluginBrokerActions();
125
+ const { connectBrokerInstance, syncBrokerInstance } = brokerActions;
55
126
  const { notify } = usePluginAppActions();
56
- const [reconnecting, setReconnecting] = useState(false);
127
+ const [working, setWorking] = useState(false);
57
128
  const runningRef = useRef(false);
58
129
  const offlineRef = useRef(offline);
59
130
  offlineRef.current = offline;
131
+ const brokerActionsRef = useRef(brokerActions);
132
+ brokerActionsRef.current = brokerActions;
60
133
 
61
134
  const reconnect = useCallback(async () => {
62
135
  const target = offlineRef.current;
63
- if (!target?.reconnectable || runningRef.current) return;
136
+ if (!target || runningRef.current) return;
137
+ if (!target.disabled && !target.reconnectable) return;
64
138
  runningRef.current = true;
65
- setReconnecting(true);
139
+ setWorking(true);
66
140
  try {
141
+ if (target.disabled) {
142
+ const failure = await enableBrokerProfile(brokerActionsRef.current, target.instance.id, {
143
+ sync: target.reconnectable,
144
+ label: target.brokerName,
145
+ });
146
+ if (failure) notify({ type: "error", body: failure.text });
147
+ return;
148
+ }
67
149
  if (isSignedInBrokerProfile(target.instance)) {
68
150
  if (!await requestBrokerSignIn(signedInBrokerForProfile(target.instance, target.brokerName))) return;
69
151
  } else {
@@ -77,7 +159,7 @@ export function useOfflineBrokerFooter(offline: OfflineBroker | null): OfflineBr
77
159
  });
78
160
  } finally {
79
161
  runningRef.current = false;
80
- setReconnecting(false);
162
+ setWorking(false);
81
163
  }
82
164
  }, [connectBrokerInstance, notify, syncBrokerInstance]);
83
165
 
@@ -87,19 +169,22 @@ export function useOfflineBrokerFooter(offline: OfflineBroker | null): OfflineBr
87
169
  const asOf: PaneFooterSegment[] = offline.syncedAt != null
88
170
  ? [{ id: "broker-as-of", asOf: false, parts: [{ text: formatBrokerSyncedAt(offline.syncedAt), tone: "muted" }] }]
89
171
  : [];
90
- const status: PaneFooterSegment[] = [reconnecting
91
- ? { id: "broker-status", parts: [{ text: t("Reconnecting…"), tone: "muted" }] }
172
+ const status: PaneFooterSegment[] = [working
173
+ ? { id: "broker-status", parts: [{ text: offline.disabled ? t("Enabling…") : t("Reconnecting…"), tone: "muted" }] }
92
174
  : { id: "broker-status", parts: [{ text: offline.reason, tone: "warning" }] }];
93
- const hints: PaneHint[] = offline.reconnectable
94
- ? [{
95
- id: "reconnect-broker",
96
- key: RECONNECT_BROKER_KEY,
97
- label: " reconnect",
98
- title: tf("Reconnect {broker}", { broker: offline.brokerName }),
99
- onPress: () => { void reconnect(); },
100
- disabled: reconnecting,
101
- }]
102
- : [];
175
+ const press = () => { void reconnect(); };
176
+ const hints: PaneHint[] = offline.disabled
177
+ ? [enableBrokerHint(offline.brokerName, press, working)]
178
+ : offline.reconnectable
179
+ ? [{
180
+ id: "reconnect-broker",
181
+ key: BROKER_KEY,
182
+ label: " reconnect",
183
+ title: tf("Reconnect {broker}", { broker: offline.brokerName }),
184
+ onPress: press,
185
+ disabled: working,
186
+ }]
187
+ : [];
103
188
  return { asOf, status, hints };
104
- }, [offline, reconnect, reconnecting]);
189
+ }, [offline, reconnect, working]);
105
190
  }