gloomberb 0.16.4 → 0.16.6

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 (852) hide show
  1. package/README.md +14 -91
  2. package/package.json +5 -1
  3. package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
  4. package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
  5. package/src/account/billing.ts +57 -0
  6. package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
  7. package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
  8. package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
  9. package/src/account/session.ts +16 -0
  10. package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
  11. package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
  12. package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
  13. package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
  14. package/src/api-client/central-bank-rates.ts +6 -1
  15. package/src/api-client/chat.ts +26 -0
  16. package/src/api-client/credit-boards.ts +2 -0
  17. package/src/api-client/data.ts +73 -3
  18. package/src/api-client/earnings.ts +6 -0
  19. package/src/api-client/europe-energy.ts +106 -0
  20. package/src/api-client/futures-curve.ts +56 -0
  21. package/src/api-client/index.ts +13 -1
  22. package/src/api-client/market-discovery.ts +13 -1
  23. package/src/api-client/normalizers.ts +32 -0
  24. package/src/api-client/paths.ts +7 -0
  25. package/src/api-client/perps.ts +8 -0
  26. package/src/api-client/request.ts +9 -2
  27. package/src/api-client/research-activity.ts +15 -10
  28. package/src/api-client/socket.ts +29 -0
  29. package/src/api-client/themes.ts +22 -1
  30. package/src/api-client/types.ts +78 -2
  31. package/src/api-client/yield-curves.ts +8 -0
  32. package/src/app/global-shortcuts.ts +50 -2
  33. package/src/app/keybindings/actions.ts +12 -1
  34. package/src/app/pane-runtime/plugin-bindings.ts +2 -2
  35. package/src/app/pane-runtime/ticker-open-runtime.ts +16 -6
  36. package/src/app/runtime/desktop-deeplink.ts +10 -5
  37. package/src/app/runtime/startup.ts +1 -1
  38. package/src/app.tsx +6 -0
  39. package/src/architecture/core-builtin-allowlist.json +8 -26
  40. package/src/ask-gloom/pane-context.ts +114 -0
  41. package/src/ask-gloom/pane-request.ts +70 -0
  42. package/src/ask-gloom/pane-text.ts +201 -0
  43. package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
  44. package/src/capabilities/chart-series.ts +19 -2
  45. package/src/capabilities/factories.ts +1 -0
  46. package/src/cli/central-bank-events.ts +23 -0
  47. package/src/cli/command-options.ts +17 -5
  48. package/src/cli/commands/crypto-hints.ts +35 -2
  49. package/src/cli/commands/fred-series.ts +146 -0
  50. package/src/cli/commands/market.ts +501 -115
  51. package/src/cli/commands/news-hints.ts +62 -0
  52. package/src/cli/commands/news-search.ts +53 -0
  53. package/src/cli/commands/options-leaps.ts +5 -2
  54. package/src/cli/commands/overview.ts +132 -26
  55. package/src/cli/commands/remote.ts +2 -1
  56. package/src/cli/commands/search.ts +317 -13
  57. package/src/cli/commands/system.ts +55 -8
  58. package/src/cli/commands/ticker.ts +155 -18
  59. package/src/cli/context.ts +45 -14
  60. package/src/cli/desktop-pane-shot.ts +76 -7
  61. package/src/cli/earnings-calendar.ts +71 -0
  62. package/src/cli/errors.ts +7 -5
  63. package/src/cli/exit-codes.ts +8 -0
  64. package/src/cli/export-source.ts +58 -0
  65. package/src/cli/freshness.ts +18 -7
  66. package/src/cli/glossary.ts +483 -0
  67. package/src/cli/help.ts +10 -0
  68. package/src/cli/helpers.ts +2 -5
  69. package/src/cli/history-rows.ts +118 -7
  70. package/src/cli/index-roots.ts +7 -0
  71. package/src/cli/index.ts +29 -9
  72. package/src/cli/known-gaps.ts +84 -0
  73. package/src/cli/listing-arg.ts +551 -97
  74. package/src/cli/not-a-ticker.ts +24 -9
  75. package/src/cli/pane-functions/access-gate.ts +13 -2
  76. package/src/cli/pane-functions/capabilities.ts +4 -3
  77. package/src/cli/pane-functions/catalog.ts +214 -40
  78. package/src/cli/pane-functions/data.ts +42 -8
  79. package/src/cli/pane-functions/discovery.ts +1 -0
  80. package/src/cli/pane-functions/dom.ts +37 -8
  81. package/src/cli/pane-functions/freshness.ts +393 -49
  82. package/src/cli/pane-functions/function-help.ts +31 -15
  83. package/src/cli/pane-functions/headless.ts +98 -30
  84. package/src/cli/pane-functions/index.ts +101 -19
  85. package/src/cli/pane-functions/market-session.ts +22 -8
  86. package/src/cli/pane-functions/options.ts +71 -22
  87. package/src/cli/pane-functions/report-notices.ts +25 -7
  88. package/src/cli/pane-functions/report.ts +15 -8
  89. package/src/cli/pane-functions/resolver.ts +74 -19
  90. package/src/cli/pane-functions/screenshot.ts +250 -27
  91. package/src/cli/perpetual-contract.ts +60 -0
  92. package/src/cli/registry.ts +3 -1
  93. package/src/cli/report-tables.ts +26 -7
  94. package/src/cli/result.ts +45 -11
  95. package/src/cli/series-search.ts +111 -0
  96. package/src/cli/staged-tickers.ts +52 -0
  97. package/src/cli/symbol-args.ts +27 -0
  98. package/src/cli/symbol-list.ts +154 -0
  99. package/src/cli/symbol-rows.ts +154 -0
  100. package/src/cli/ticker-resolution.ts +311 -27
  101. package/src/cli/types.ts +5 -0
  102. package/src/components/chart/composite/axis-overlays.tsx +14 -3
  103. package/src/components/chart/composite/composite-chart.tsx +71 -11
  104. package/src/components/chart/composite/crosshair-readout.tsx +150 -0
  105. package/src/components/chart/composite/downsample.ts +1 -1
  106. package/src/components/chart/composite/format.ts +29 -0
  107. package/src/components/chart/composite/interactions.ts +9 -2
  108. package/src/components/chart/composite/legend.tsx +100 -33
  109. package/src/components/chart/composite/panel-bitmap.ts +70 -35
  110. package/src/components/chart/composite/panel-labels.ts +18 -17
  111. package/src/components/chart/composite/panel-series.ts +1 -0
  112. package/src/components/chart/composite/panel-surface.tsx +46 -21
  113. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  114. package/src/components/chart/composite/rasterizer.ts +50 -8
  115. package/src/components/chart/composite/scene.ts +2 -1
  116. package/src/components/chart/composite/time-scale.ts +26 -9
  117. package/src/components/chart/composite/types.ts +18 -0
  118. package/src/components/chart/composite/use-composite-viewport.ts +30 -2
  119. package/src/components/chart/native/raster/crosshair.ts +8 -3
  120. package/src/components/chart/native/raster/primitives.ts +85 -21
  121. package/src/components/chart/native/surface/manager.ts +33 -8
  122. package/src/components/chart/surface3d/chart.tsx +1 -1
  123. package/src/components/command-bar/action-runtime.ts +1 -1
  124. package/src/components/command-bar/commands/collection-list.ts +210 -0
  125. package/src/components/command-bar/commands/collection.ts +40 -1
  126. package/src/components/command-bar/commands/direct/index.ts +4 -0
  127. package/src/components/command-bar/commands/registry.ts +8 -0
  128. package/src/components/command-bar/panel/index.tsx +11 -3
  129. package/src/components/command-bar/panel/runtime.ts +3 -0
  130. package/src/components/command-bar/panel/types.ts +2 -0
  131. package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
  132. package/src/components/command-bar/routes/root/provider-search.ts +4 -3
  133. package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
  134. package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
  135. package/src/components/command-bar/routing/actions.ts +1 -1
  136. package/src/components/command-bar/workflow/tickers.ts +42 -17
  137. package/src/components/layout/detached-pane-shell.tsx +68 -39
  138. package/src/components/layout/floating-pane.tsx +10 -1
  139. package/src/components/layout/header.tsx +25 -5
  140. package/src/components/layout/missing-pane.tsx +3 -3
  141. package/src/components/layout/pane/capture-stamp.ts +41 -0
  142. package/src/components/layout/pane/capture-status.ts +12 -0
  143. package/src/components/layout/pane/content.tsx +7 -13
  144. package/src/components/layout/pane/footer/index.tsx +6 -2
  145. package/src/components/layout/pane/footer/keyboard.ts +3 -0
  146. package/src/components/layout/pane/footer/model.ts +41 -1
  147. package/src/components/layout/pane/header.tsx +50 -1
  148. package/src/components/layout/pane/index.tsx +21 -3
  149. package/src/components/layout/pane/sidebar.tsx +88 -21
  150. package/src/components/layout/shell/active-drag.ts +21 -5
  151. package/src/components/layout/shell/cursor-occlusion.ts +2 -1
  152. package/src/components/layout/shell/drag/index.ts +39 -9
  153. package/src/components/layout/shell/drag/live.ts +61 -51
  154. package/src/components/layout/shell/drag/runtime.ts +54 -12
  155. package/src/components/layout/shell/index.tsx +84 -65
  156. package/src/components/layout/shell/menu.ts +14 -1
  157. package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
  158. package/src/components/layout/shell/pane/actions.ts +32 -10
  159. package/src/components/layout/shell/pane/ask.ts +131 -0
  160. package/src/components/layout/shell/pane/capture.ts +162 -0
  161. package/src/components/layout/shell/pane/layers.tsx +218 -50
  162. package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
  163. package/src/components/layout/shell/shortcuts.ts +21 -4
  164. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
  165. package/src/components/markdown-text.tsx +62 -20
  166. package/src/components/metric-treemap/heat-surface.tsx +8 -1
  167. package/src/components/onboarding/account-step/form-panel.tsx +1 -1
  168. package/src/components/onboarding/account-step/index.tsx +1 -1
  169. package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
  170. package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
  171. package/src/components/onboarding/onboarding-keyboard.ts +1 -1
  172. package/src/components/onboarding/onboarding-wizard.tsx +2 -2
  173. package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
  174. package/src/components/onboarding/wizard-account.ts +2 -2
  175. package/src/components/pane-template-wizard.tsx +9 -1
  176. package/src/components/price-selector-dialog.tsx +11 -2
  177. package/src/components/reader/article-reader.tsx +642 -0
  178. package/src/components/reader/article-text.ts +527 -0
  179. package/src/components/sign-in-gate.tsx +3 -3
  180. package/src/components/ticker/list-table-view.tsx +43 -2
  181. package/src/components/ui/action-row.tsx +2 -1
  182. package/src/components/ui/button.tsx +7 -1
  183. package/src/components/ui/choice-dialog.tsx +6 -4
  184. package/src/components/ui/confirm-dialog.tsx +28 -18
  185. package/src/components/ui/data-table/index.tsx +18 -6
  186. package/src/components/ui/data-table/opentui/index.tsx +37 -6
  187. package/src/components/ui/data-table/types.ts +12 -0
  188. package/src/components/ui/dialog-actions.tsx +64 -0
  189. package/src/components/ui/display.tsx +17 -3
  190. package/src/components/ui/frame.tsx +35 -2
  191. package/src/components/ui/icon.tsx +6 -1
  192. package/src/components/ui/query-bar.tsx +10 -1
  193. package/src/components/ui/text-prompt-dialog.tsx +11 -9
  194. package/src/data/cached-query.ts +2 -0
  195. package/src/data/config/store/migrations.ts +7 -0
  196. package/src/data/config/store/normalize.ts +7 -2
  197. package/src/data/config/store/portfolio-as-of-column.ts +57 -0
  198. package/src/data/ticker-repository.ts +5 -0
  199. package/src/data/ticker-store.ts +15 -0
  200. package/src/docs/content.ts +215 -0
  201. package/src/docs/load.ts +139 -0
  202. package/src/docs/requests.ts +39 -0
  203. package/src/docs/snapshot.chunk.ts +8 -0
  204. package/src/docs/snapshot.json +7555 -0
  205. package/src/docs/topics.ts +216 -0
  206. package/src/i18n/es.ts +65 -5
  207. package/src/i18n/ja.ts +65 -5
  208. package/src/i18n/ko.ts +65 -5
  209. package/src/i18n/zh-cn.ts +65 -5
  210. package/src/i18n/zh-tw.ts +65 -5
  211. package/src/layout/desks.ts +1 -1
  212. package/src/layout/pane-manager/dock-tree.ts +18 -0
  213. package/src/layout/pane-manager/index.ts +1 -0
  214. package/src/layout-marketplace/gallery.tsx +1 -1
  215. package/src/market-data/coordinator/chart.ts +10 -4
  216. package/src/market-data/coordinator/index.ts +6 -3
  217. package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
  218. package/src/market-data/futures-contract.ts +151 -0
  219. package/src/market-data/hooks.tsx +10 -2
  220. package/src/market-data/market/format.ts +39 -21
  221. package/src/market-data/market/freshness.ts +84 -20
  222. package/src/market-data/market/session-close-note.ts +3 -2
  223. package/src/market-data/market/status.ts +19 -23
  224. package/src/market-data/published-apac-sessions.ts +23 -1
  225. package/src/market-data/quotes/contributions.ts +5 -0
  226. package/src/market-data/quotes/metadata.ts +19 -24
  227. package/src/market-data/quotes/resolution.ts +5 -0
  228. package/src/market-data/quotes/screener-live-quotes.ts +5 -4
  229. package/src/market-data/result-types.ts +2 -0
  230. package/src/notifications/app-notifier.ts +17 -1
  231. package/src/notifications/notification-log.ts +180 -0
  232. package/src/plugins/auto-update-node.ts +2 -2
  233. package/src/plugins/auto-update.ts +2 -2
  234. package/src/plugins/builtin/account-management/index.tsx +1 -0
  235. package/src/plugins/builtin/account-management/model.ts +1 -56
  236. package/src/plugins/builtin/account-management/pane.tsx +6 -4
  237. package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
  238. package/src/plugins/builtin/alerts/catalysts.ts +1 -1
  239. package/src/plugins/builtin/alerts/cli.ts +313 -47
  240. package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
  241. package/src/plugins/builtin/alerts/events.ts +23 -2
  242. package/src/plugins/builtin/alerts/focus.ts +27 -0
  243. package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
  244. package/src/plugins/builtin/alerts/history.ts +2 -0
  245. package/src/plugins/builtin/alerts/index.tsx +47 -11
  246. package/src/plugins/builtin/alerts/pane.tsx +27 -1
  247. package/src/plugins/builtin/alerts/research-builder.ts +8 -3
  248. package/src/plugins/builtin/alerts/research-rules.ts +18 -2
  249. package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
  250. package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
  251. package/src/plugins/builtin/alerts/scheduled.ts +254 -0
  252. package/src/plugins/builtin/alerts/targets.ts +92 -0
  253. package/src/plugins/builtin/analytics/index.tsx +8 -3
  254. package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
  255. package/src/plugins/builtin/analytics/risk-math.ts +91 -27
  256. package/src/plugins/builtin/analytics/risk-model.ts +35 -5
  257. package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
  258. package/src/plugins/builtin/attention/headless.ts +1 -1
  259. package/src/plugins/builtin/attention/index.tsx +2 -0
  260. package/src/plugins/builtin/attention/pane.tsx +3 -1
  261. package/src/plugins/builtin/attention/series.ts +26 -0
  262. package/src/plugins/builtin/awards/headless.ts +88 -18
  263. package/src/plugins/builtin/awards/index.tsx +2 -0
  264. package/src/plugins/builtin/awards/model.ts +41 -1
  265. package/src/plugins/builtin/awards/pane.tsx +22 -13
  266. package/src/plugins/builtin/awards/series.ts +29 -0
  267. package/src/plugins/builtin/backtest/headless.ts +2 -2
  268. package/src/plugins/builtin/bond-calculator/model.ts +2 -1
  269. package/src/plugins/builtin/broker-manager/index.tsx +1 -0
  270. package/src/plugins/builtin/catalysts/headless.ts +1 -1
  271. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  272. package/src/plugins/builtin/cds/client.ts +49 -12
  273. package/src/plugins/builtin/cds/headless.ts +119 -19
  274. package/src/plugins/builtin/cds/index.tsx +3 -1
  275. package/src/plugins/builtin/cds/model.ts +214 -32
  276. package/src/plugins/builtin/cds/pane.tsx +58 -14
  277. package/src/plugins/builtin/cds/series.ts +19 -0
  278. package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
  279. package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
  280. package/src/plugins/builtin/central-bank-rates/index.tsx +3 -1
  281. package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
  282. package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
  283. package/src/plugins/builtin/central-bank-rates/series.ts +36 -0
  284. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -255
  285. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
  286. package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
  287. package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
  288. package/src/plugins/builtin/chart-composer/headless-schema.ts +1 -1
  289. package/src/plugins/builtin/chart-composer/headless.ts +70 -5
  290. package/src/plugins/builtin/chart-composer/index.tsx +15 -3
  291. package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
  292. package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
  293. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
  294. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
  295. package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
  296. package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
  297. package/src/plugins/builtin/chat/content/composer.tsx +5 -1
  298. package/src/plugins/builtin/chat/content/footer.tsx +12 -0
  299. package/src/plugins/builtin/chat/content/index.tsx +89 -5
  300. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
  301. package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
  302. package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
  303. package/src/plugins/builtin/chat/content/scroll.ts +127 -27
  304. package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
  305. package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
  306. package/src/plugins/builtin/chat/content/types.ts +1 -0
  307. package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
  308. package/src/plugins/builtin/chat/controller/index.ts +123 -1
  309. package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
  310. package/src/plugins/builtin/chat/controller/messages.ts +7 -2
  311. package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
  312. package/src/plugins/builtin/chat/controller/send.ts +61 -1
  313. package/src/plugins/builtin/chat/controller/state.ts +8 -0
  314. package/src/plugins/builtin/chat/ghost-user.ts +20 -0
  315. package/src/plugins/builtin/chat/index.tsx +23 -5
  316. package/src/plugins/builtin/chat/layout.ts +78 -5
  317. package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
  318. package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
  319. package/src/plugins/builtin/chat/message/header.tsx +16 -4
  320. package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
  321. package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
  322. package/src/plugins/builtin/chat/message/render-state.ts +18 -2
  323. package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
  324. package/src/plugins/builtin/chat/message/types.ts +12 -0
  325. package/src/plugins/builtin/chat/reactions.ts +197 -0
  326. package/src/plugins/builtin/chat/share/flow.tsx +87 -0
  327. package/src/plugins/builtin/chat/share/targets.ts +27 -0
  328. package/src/plugins/builtin/chat/status-widget.tsx +6 -3
  329. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
  330. package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
  331. package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
  332. package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
  333. package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
  334. package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
  335. package/src/plugins/builtin/cloud/askg/model.ts +27 -8
  336. package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
  337. package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
  338. package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
  339. package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
  340. package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
  341. package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
  342. package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
  343. package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
  344. package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
  345. package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
  346. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
  347. package/src/plugins/builtin/cloud/plugin.tsx +19 -2
  348. package/src/plugins/builtin/cloud/team/model.ts +5 -0
  349. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  350. package/src/plugins/builtin/cloud/team/store.ts +8 -3
  351. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
  352. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
  353. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
  354. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
  355. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
  356. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  357. package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
  358. package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
  359. package/src/plugins/builtin/company-attention/headless.ts +21 -7
  360. package/src/plugins/builtin/company-attention/index.tsx +2 -0
  361. package/src/plugins/builtin/company-attention/model.ts +26 -7
  362. package/src/plugins/builtin/company-attention/pane.tsx +12 -9
  363. package/src/plugins/builtin/company-attention/series.ts +52 -0
  364. package/src/plugins/builtin/company-kpis/headless.ts +97 -10
  365. package/src/plugins/builtin/company-kpis/model.ts +24 -2
  366. package/src/plugins/builtin/company-kpis/pane.tsx +17 -16
  367. package/src/plugins/builtin/composite-plugins.ts +19 -13
  368. package/src/plugins/builtin/connections/index.ts +1 -0
  369. package/src/plugins/builtin/cot/headless.ts +1 -1
  370. package/src/plugins/builtin/cot/index.tsx +3 -1
  371. package/src/plugins/builtin/cot/model.ts +40 -11
  372. package/src/plugins/builtin/cot/series.ts +27 -0
  373. package/src/plugins/builtin/cpi/headless.ts +3 -3
  374. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
  375. package/src/plugins/builtin/credit-boards/client.ts +6 -2
  376. package/src/plugins/builtin/credit-boards/headless.ts +108 -31
  377. package/src/plugins/builtin/credit-boards/index.tsx +2 -0
  378. package/src/plugins/builtin/credit-boards/model.ts +11 -1
  379. package/src/plugins/builtin/credit-boards/series.ts +66 -0
  380. package/src/plugins/builtin/credit-conditions/client.ts +12 -9
  381. package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
  382. package/src/plugins/builtin/credit-conditions/index.tsx +18 -9
  383. package/src/plugins/builtin/credit-conditions/model.ts +19 -11
  384. package/src/plugins/builtin/credit-conditions/series.ts +16 -0
  385. package/src/plugins/builtin/credit-documents/headless.ts +33 -3
  386. package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
  387. package/src/plugins/builtin/crypto-board/headless.ts +2 -3
  388. package/src/plugins/builtin/crypto-board/index.tsx +2 -0
  389. package/src/plugins/builtin/crypto-board/model.ts +12 -0
  390. package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
  391. package/src/plugins/builtin/crypto-board/series.ts +48 -0
  392. package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
  393. package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
  394. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  395. package/src/plugins/builtin/debt-maturities/series.ts +45 -0
  396. package/src/plugins/builtin/dividend-yield/client.ts +3 -0
  397. package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
  398. package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
  399. package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
  400. package/src/plugins/builtin/dividend-yield/series.ts +20 -0
  401. package/src/plugins/builtin/dividend-yield/types.ts +2 -0
  402. package/src/plugins/builtin/docs/blocks.tsx +181 -0
  403. package/src/plugins/builtin/docs/index.tsx +68 -0
  404. package/src/plugins/builtin/docs/pane.tsx +426 -0
  405. package/src/plugins/builtin/docs/targets.ts +72 -0
  406. package/src/plugins/builtin/docs/use-docs.ts +60 -0
  407. package/src/plugins/builtin/doe/headless.ts +12 -8
  408. package/src/plugins/builtin/doe/index.tsx +2 -0
  409. package/src/plugins/builtin/doe/series.ts +62 -0
  410. package/src/plugins/builtin/earnings/client.ts +3 -2
  411. package/src/plugins/builtin/earnings/format.ts +1 -5
  412. package/src/plugins/builtin/earnings/headless.ts +58 -6
  413. package/src/plugins/builtin/earnings/history-model.ts +15 -1
  414. package/src/plugins/builtin/earnings/history-table.ts +13 -2
  415. package/src/plugins/builtin/earnings/history.tsx +7 -3
  416. package/src/plugins/builtin/earnings/index.tsx +9 -0
  417. package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
  418. package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
  419. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
  420. package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
  421. package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
  422. package/src/plugins/builtin/econ/index.tsx +2 -0
  423. package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
  424. package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
  425. package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
  426. package/src/plugins/builtin/equity-screener/headless.ts +3 -3
  427. package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
  428. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
  429. package/src/plugins/builtin/exposure/drivers.ts +13 -0
  430. package/src/plugins/builtin/exposure/headless.ts +205 -13
  431. package/src/plugins/builtin/exposure/holdings.ts +1 -1
  432. package/src/plugins/builtin/exposure/index.tsx +1 -0
  433. package/src/plugins/builtin/exposure/model.ts +23 -3
  434. package/src/plugins/builtin/exposure/pane.tsx +14 -12
  435. package/src/plugins/builtin/fear-greed/index.tsx +18 -10
  436. package/src/plugins/builtin/fear-greed/series.ts +52 -0
  437. package/src/plugins/builtin/futures/index.tsx +43 -3
  438. package/src/plugins/builtin/futures/model.ts +1 -1
  439. package/src/plugins/builtin/futures/returns.ts +1 -1
  440. package/src/plugins/builtin/futures/series.ts +13 -0
  441. package/src/plugins/builtin/futures/table.tsx +1 -1
  442. package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
  443. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  444. package/src/plugins/builtin/futures-curve/headless.ts +71 -10
  445. package/src/plugins/builtin/futures-curve/index.tsx +1 -1
  446. package/src/plugins/builtin/futures-curve/model.ts +66 -11
  447. package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
  448. package/src/plugins/builtin/fx-matrix/client.ts +63 -0
  449. package/src/plugins/builtin/fx-matrix/export.ts +2 -1
  450. package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
  451. package/src/plugins/builtin/fx-matrix/index.tsx +4 -4
  452. package/src/plugins/builtin/gpu/board.tsx +13 -10
  453. package/src/plugins/builtin/gpu/changes.tsx +4 -4
  454. package/src/plugins/builtin/gpu/client.ts +19 -1
  455. package/src/plugins/builtin/gpu/equities.tsx +14 -10
  456. package/src/plugins/builtin/gpu/headless.ts +58 -27
  457. package/src/plugins/builtin/gpu/history.tsx +3 -3
  458. package/src/plugins/builtin/gpu/index.tsx +2 -0
  459. package/src/plugins/builtin/gpu/model.ts +101 -16
  460. package/src/plugins/builtin/gpu/pane.tsx +28 -12
  461. package/src/plugins/builtin/gpu/series.ts +38 -0
  462. package/src/plugins/builtin/help/function-card.tsx +25 -6
  463. package/src/plugins/builtin/help/function-index.ts +2 -0
  464. package/src/plugins/builtin/help/index.tsx +31 -9
  465. package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
  466. package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
  467. package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
  468. package/src/plugins/builtin/holders/client.ts +22 -3
  469. package/src/plugins/builtin/holders/format.ts +18 -3
  470. package/src/plugins/builtin/holders/headless.ts +36 -133
  471. package/src/plugins/builtin/holders/pane.tsx +11 -4
  472. package/src/plugins/builtin/holders/report-header.ts +40 -5
  473. package/src/plugins/builtin/holders/report-rows.ts +240 -0
  474. package/src/plugins/builtin/insider/client.ts +35 -20
  475. package/src/plugins/builtin/insider/headless.ts +41 -11
  476. package/src/plugins/builtin/insider/index.tsx +26 -9
  477. package/src/plugins/builtin/insider/insider-data.ts +10 -0
  478. package/src/plugins/builtin/insider/issuer.ts +49 -0
  479. package/src/plugins/builtin/insider/model.ts +3 -0
  480. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
  481. package/src/plugins/builtin/iv-history/client.ts +20 -6
  482. package/src/plugins/builtin/iv-history/format.ts +9 -0
  483. package/src/plugins/builtin/iv-history/headless.ts +56 -21
  484. package/src/plugins/builtin/iv-history/index.tsx +2 -0
  485. package/src/plugins/builtin/iv-history/model.ts +143 -8
  486. package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
  487. package/src/plugins/builtin/iv-history/series.ts +29 -0
  488. package/src/plugins/builtin/jobs/headless.ts +26 -3
  489. package/src/plugins/builtin/jobs/index.tsx +3 -1
  490. package/src/plugins/builtin/jobs/series.ts +19 -0
  491. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  492. package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
  493. package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
  494. package/src/plugins/builtin/macro-day/client.ts +44 -3
  495. package/src/plugins/builtin/macro-day/headless.ts +13 -10
  496. package/src/plugins/builtin/macro-day/model.ts +56 -10
  497. package/src/plugins/builtin/macro-day/pane.tsx +30 -20
  498. package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
  499. package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
  500. package/src/plugins/builtin/market-heatmap/model.ts +19 -11
  501. package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
  502. package/src/plugins/builtin/market-movers/client.ts +7 -5
  503. package/src/plugins/builtin/market-movers/index.tsx +3 -2
  504. package/src/plugins/builtin/market-movers/model.ts +30 -0
  505. package/src/plugins/builtin/market-movers/screener.ts +31 -0
  506. package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
  507. package/src/plugins/builtin/market-valuation/index.tsx +3 -3
  508. package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
  509. package/src/plugins/builtin/members/headless.ts +8 -3
  510. package/src/plugins/builtin/members/model.ts +31 -3
  511. package/src/plugins/builtin/members/pane.tsx +6 -8
  512. package/src/plugins/builtin/mna/distress/headless.ts +4 -4
  513. package/src/plugins/builtin/mna/headless.ts +18 -6
  514. package/src/plugins/builtin/money-markets/headless.ts +5 -4
  515. package/src/plugins/builtin/money-markets/index.tsx +2 -0
  516. package/src/plugins/builtin/money-markets/series.ts +41 -0
  517. package/src/plugins/builtin/news/index.tsx +0 -2
  518. package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
  519. package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
  520. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
  521. package/src/plugins/builtin/notes/cli.ts +12 -7
  522. package/src/plugins/builtin/notes/index.tsx +1 -0
  523. package/src/plugins/builtin/options/index.tsx +3 -0
  524. package/src/plugins/builtin/options/view.tsx +1 -1
  525. package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
  526. package/src/plugins/builtin/options-positioning/client.ts +7 -3
  527. package/src/plugins/builtin/options-positioning/headless.ts +4 -3
  528. package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
  529. package/src/plugins/builtin/options-scenario/client.ts +2 -1
  530. package/src/plugins/builtin/options-scenario/headless.ts +1 -0
  531. package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
  532. package/src/plugins/builtin/perps/client.ts +90 -16
  533. package/src/plugins/builtin/perps/equity-row.tsx +52 -17
  534. package/src/plugins/builtin/perps/freshness.ts +66 -0
  535. package/src/plugins/builtin/perps/headless.ts +47 -32
  536. package/src/plugins/builtin/perps/index.tsx +23 -4
  537. package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
  538. package/src/plugins/builtin/perps/model.ts +20 -5
  539. package/src/plugins/builtin/perps/open-market.ts +15 -0
  540. package/src/plugins/builtin/perps/pane.tsx +76 -20
  541. package/src/plugins/builtin/perps/series.ts +76 -0
  542. package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
  543. package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
  544. package/src/plugins/builtin/plugin-module.ts +3 -0
  545. package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
  546. package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
  547. package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
  548. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +161 -0
  549. package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
  550. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
  551. package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
  552. package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
  553. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
  554. package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
  555. package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
  556. package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
  557. package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
  558. package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
  559. package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
  560. package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
  561. package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
  562. package/src/plugins/builtin/portfolio-list/pane/index.tsx +52 -9
  563. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
  564. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
  565. package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
  566. package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
  567. package/src/plugins/builtin/portfolio-list/summary/totals.ts +9 -4
  568. package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
  569. package/src/plugins/builtin/power/client.ts +16 -0
  570. package/src/plugins/builtin/power/evidence.ts +63 -10
  571. package/src/plugins/builtin/power/headless.ts +77 -9
  572. package/src/plugins/builtin/power/index.tsx +28 -3
  573. package/src/plugins/builtin/power/model.ts +73 -2
  574. package/src/plugins/builtin/power/pane.tsx +37 -9
  575. package/src/plugins/builtin/power/prices-client.ts +139 -0
  576. package/src/plugins/builtin/power/prices-headless.ts +137 -0
  577. package/src/plugins/builtin/power/prices-model.ts +103 -0
  578. package/src/plugins/builtin/power/prices.tsx +179 -0
  579. package/src/plugins/builtin/rate-path/headless.ts +46 -18
  580. package/src/plugins/builtin/realized-vol/headless.ts +5 -0
  581. package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
  582. package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
  583. package/src/plugins/builtin/research/event-model.ts +68 -24
  584. package/src/plugins/builtin/research/events-headless.ts +2 -1
  585. package/src/plugins/builtin/research/headless.ts +2 -1
  586. package/src/plugins/builtin/research/index.tsx +2 -0
  587. package/src/plugins/builtin/research-search/article.ts +65 -0
  588. package/src/plugins/builtin/research-search/document-view.tsx +33 -215
  589. package/src/plugins/builtin/research-search/model.ts +0 -9
  590. package/src/plugins/builtin/research-search/pane.tsx +41 -30
  591. package/src/plugins/builtin/research-search/snippet.ts +0 -29
  592. package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
  593. package/src/plugins/builtin/seasonality/client.ts +15 -7
  594. package/src/plugins/builtin/seasonality/headless.ts +36 -12
  595. package/src/plugins/builtin/seasonality/index.tsx +2 -2
  596. package/src/plugins/builtin/seasonality/model.ts +119 -0
  597. package/src/plugins/builtin/seasonality/pane.tsx +108 -37
  598. package/src/plugins/builtin/sec/headless.ts +25 -3
  599. package/src/plugins/builtin/sec/index.tsx +2 -1
  600. package/src/plugins/builtin/series-inventory.ts +93 -0
  601. package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
  602. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
  603. package/src/plugins/builtin/shared/command-tab.ts +30 -12
  604. package/src/plugins/builtin/shared/earnings-report.ts +55 -0
  605. package/src/plugins/builtin/shared/fred-points.ts +20 -0
  606. package/src/plugins/builtin/shared/free-preview.ts +47 -0
  607. package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
  608. package/src/plugins/builtin/shared/open-description.ts +29 -0
  609. package/src/plugins/builtin/shared/report-freshness.ts +12 -1
  610. package/src/plugins/builtin/shared/series-warning.ts +5 -0
  611. package/src/plugins/builtin/shared/volatility/options.ts +4 -1
  612. package/src/plugins/builtin/short-interest/headless.ts +1 -0
  613. package/src/plugins/builtin/short-interest/index.tsx +2 -0
  614. package/src/plugins/builtin/short-interest/series.ts +36 -0
  615. package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
  616. package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
  617. package/src/plugins/builtin/short-volume/headless.ts +2 -1
  618. package/src/plugins/builtin/short-volume/index.tsx +2 -0
  619. package/src/plugins/builtin/short-volume/series.ts +23 -0
  620. package/src/plugins/builtin/social-mentions/headless.ts +1 -1
  621. package/src/plugins/builtin/social-mentions/index.tsx +2 -0
  622. package/src/plugins/builtin/social-mentions/series.ts +23 -0
  623. package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
  624. package/src/plugins/builtin/supply-chain/headless.ts +43 -11
  625. package/src/plugins/builtin/supply-chain/model.ts +13 -0
  626. package/src/plugins/builtin/supply-chain/pane.tsx +8 -6
  627. package/src/plugins/builtin/themes/headless.ts +74 -10
  628. package/src/plugins/builtin/themes/model.ts +71 -4
  629. package/src/plugins/builtin/themes/pane.tsx +22 -5
  630. package/src/plugins/builtin/thirteenf/api.ts +1 -0
  631. package/src/plugins/builtin/thirteenf/data.ts +6 -4
  632. package/src/plugins/builtin/thirteenf/headless.ts +217 -36
  633. package/src/plugins/builtin/thirteenf/model.ts +39 -1
  634. package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
  635. package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
  636. package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
  637. package/src/plugins/builtin/thirteenf/types.ts +2 -0
  638. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +114 -0
  639. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
  640. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
  641. package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
  642. package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
  643. package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
  644. package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
  645. package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
  646. package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
  647. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
  648. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +49 -5
  649. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
  650. package/src/plugins/builtin/time-sales/headless.ts +2 -1
  651. package/src/plugins/builtin/time-sales/index.tsx +2 -1
  652. package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
  653. package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
  654. package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
  655. package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
  656. package/src/plugins/builtin/vol-surface/headless.ts +51 -17
  657. package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
  658. package/src/plugins/builtin/vol-surface/model.ts +39 -6
  659. package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
  660. package/src/plugins/builtin/vol-surface/stored.ts +63 -3
  661. package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
  662. package/src/plugins/builtin/volatility/index.tsx +2 -0
  663. package/src/plugins/builtin/volatility/series.ts +84 -0
  664. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
  665. package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
  666. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
  667. package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
  668. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
  669. package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
  670. package/src/plugins/builtin/world-venue-map/index.ts +2 -1
  671. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
  672. package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
  673. package/src/plugins/builtin/world-venue-map/map.tsx +144 -13
  674. package/src/plugins/builtin/world-venue-map/model.ts +56 -19
  675. package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
  676. package/src/plugins/builtin/yield-curve/chart.ts +2 -2
  677. package/src/plugins/builtin/yield-curve/curves.ts +21 -8
  678. package/src/plugins/builtin/yield-curve/headless.ts +71 -18
  679. package/src/plugins/builtin/yield-curve/index.tsx +4 -2
  680. package/src/plugins/builtin/yield-curve/series.ts +86 -0
  681. package/src/plugins/catalog-browser.ts +2 -1
  682. package/src/plugins/installer.ts +2 -2
  683. package/src/plugins/loader.ts +15 -0
  684. package/src/plugins/manager-node.ts +1 -1
  685. package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
  686. package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +6 -6
  687. package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
  688. package/src/plugins/registry/host-actions.ts +11 -0
  689. package/src/plugins/registry/index.ts +89 -4
  690. package/src/portfolio/collection-name.ts +31 -0
  691. package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
  692. package/src/portfolio/position-value.ts +40 -0
  693. package/src/portfolio/valuation-basis.ts +79 -0
  694. package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
  695. package/src/public/time-series.ts +17 -0
  696. package/src/react/auto-refresh.ts +13 -3
  697. package/src/react/input.ts +33 -1
  698. package/src/react/key-repeat.ts +86 -0
  699. package/src/remote/app-host.tsx +20 -4
  700. package/src/remote/confirm-change.tsx +85 -0
  701. package/src/remote/controller-utils.ts +8 -1
  702. package/src/remote/controller.ts +144 -7
  703. package/src/remote/pane-screenshot.ts +47 -0
  704. package/src/remote/schema.ts +65 -2
  705. package/src/remote/types.ts +30 -0
  706. package/src/remote/watchlist.ts +306 -0
  707. package/src/renderers/browser/main.tsx +4 -3
  708. package/src/renderers/browser/research-entry.ts +4 -2
  709. package/src/renderers/cloudflare/worker.ts +1 -1
  710. package/src/renderers/dom/data-table/frozen-column.ts +3 -1
  711. package/src/renderers/dom/data-table/index.tsx +33 -6
  712. package/src/renderers/dom/data-table/row.tsx +30 -1
  713. package/src/renderers/dom/desktop/control-styles.ts +63 -1
  714. package/src/renderers/dom/desktop/controls.tsx +30 -23
  715. package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
  716. package/src/renderers/dom/desktop/icons.tsx +16 -0
  717. package/src/renderers/dom/dom-ui-host.tsx +3 -0
  718. package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
  719. package/src/renderers/dom/host/box.tsx +8 -0
  720. package/src/renderers/dom/host/chart-surface.tsx +33 -2
  721. package/src/renderers/dom/host/live-frame.ts +6 -2
  722. package/src/renderers/dom/host/overflow-fade.ts +14 -1
  723. package/src/renderers/dom/host/scroll-box.tsx +32 -0
  724. package/src/renderers/dom/host/size-observer.ts +41 -0
  725. package/src/renderers/dom/host/sticky-scroll.ts +128 -0
  726. package/src/renderers/dom/host/style.ts +1 -1
  727. package/src/renderers/dom/host/surface-3d.tsx +19 -7
  728. package/src/renderers/dom/host/surface-fit.ts +406 -0
  729. package/src/renderers/dom/host/text.tsx +1 -1
  730. package/src/renderers/dom/input-host.tsx +1 -0
  731. package/src/renderers/dom/styles.css +102 -5
  732. package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
  733. package/src/renderers/electrobun/bun/index.ts +3 -2
  734. package/src/renderers/electrobun/shared/protocol.ts +1 -1
  735. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
  736. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
  737. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
  738. package/src/renderers/electrobun/view/main.tsx +5 -3
  739. package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
  740. package/src/renderers/opentui/chart-surface.tsx +1 -0
  741. package/src/renderers/opentui/frame-capture.ts +33 -0
  742. package/src/renderers/opentui/host.tsx +10 -13
  743. package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
  744. package/src/renderers/opentui/pane-image/glyphs.json +1 -0
  745. package/src/renderers/opentui/pane-image/index.ts +107 -0
  746. package/src/renderers/opentui/pane-image/raster.ts +428 -0
  747. package/src/renderers/opentui/start.tsx +3 -3
  748. package/src/renderers/opentui/test-utils.tsx +3 -0
  749. package/src/renderers/opentui/ui-host.tsx +29 -1
  750. package/src/series/capability.ts +75 -0
  751. package/src/series/csv.ts +160 -0
  752. package/src/series/files.ts +107 -0
  753. package/src/series/registry.ts +198 -0
  754. package/src/series/resolve.ts +108 -0
  755. package/src/series/standalone.ts +48 -0
  756. package/src/series/types.ts +153 -0
  757. package/src/series/validate.ts +171 -0
  758. package/src/shares/chat.ts +34 -0
  759. package/src/shares/dialog.tsx +295 -0
  760. package/src/shares/flow.tsx +56 -0
  761. package/src/shares/live.ts +14 -22
  762. package/src/shares/pane-image.ts +152 -0
  763. package/src/shares/personal-pane.ts +64 -0
  764. package/src/shares/portable-layout.ts +4 -2
  765. package/src/shares/prepare.ts +20 -0
  766. package/src/sources/gloomberb-cloud/index.ts +109 -10
  767. package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
  768. package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
  769. package/src/sources/history-result.ts +1 -0
  770. package/src/sources/history-retention.ts +11 -0
  771. package/src/sources/listing-symbols.ts +4 -1
  772. package/src/sources/listing-target.ts +4 -0
  773. package/src/sources/provider-router/batches.ts +4 -1
  774. package/src/sources/provider-router/cache.ts +4 -2
  775. package/src/sources/provider-router/cached-routes.ts +1 -1
  776. package/src/sources/provider-router/financial-routes.ts +1 -0
  777. package/src/sources/provider-router/financials.ts +13 -0
  778. package/src/sources/provider-router/history.ts +43 -25
  779. package/src/sources/provider-router/index.ts +14 -0
  780. package/src/sources/provider-router/search.ts +1 -0
  781. package/src/state/hooks/inline-tickers.ts +49 -11
  782. package/src/sync/core-contributors.ts +1 -0
  783. package/src/test-support/shell-pane-keys.tsx +1 -0
  784. package/src/theme/theme-context.tsx +15 -1
  785. package/src/tickers/company-name.ts +75 -0
  786. package/src/tickers/instrument-kind.ts +34 -1
  787. package/src/tickers/listing-name.ts +34 -0
  788. package/src/tickers/listing-venues.ts +132 -0
  789. package/src/tickers/open-target.ts +13 -4
  790. package/src/tickers/perpetual-listing.ts +151 -0
  791. package/src/tickers/prediction-listing.ts +26 -0
  792. package/src/tickers/search/index.ts +72 -11
  793. package/src/tickers/search/ranking.ts +98 -20
  794. package/src/tickers/search/types.ts +7 -1
  795. package/src/tickers/ticker-changes.ts +213 -0
  796. package/src/tickers/us-listing.ts +34 -0
  797. package/src/time-series/economic.ts +2 -6
  798. package/src/time-series/hooks.ts +9 -0
  799. package/src/time-series/ice-credit.ts +39 -0
  800. package/src/time-series/resolve.ts +211 -29
  801. package/src/time-series/studies.ts +1 -0
  802. package/src/time-series/types.ts +12 -2
  803. package/src/time-series/use-chart-resolution.ts +32 -0
  804. package/src/types/config.ts +10 -2
  805. package/src/types/data-provider.ts +11 -0
  806. package/src/types/financials.ts +62 -1
  807. package/src/types/headless.ts +113 -0
  808. package/src/types/instrument.ts +4 -0
  809. package/src/types/plugin.ts +52 -2
  810. package/src/types/price-history.ts +7 -0
  811. package/src/types/ticker-changes.ts +26 -0
  812. package/src/types/ticker.ts +14 -0
  813. package/src/ui/context-menu.tsx +13 -1
  814. package/src/ui/host.tsx +57 -3
  815. package/src/ui/live-resize.ts +91 -0
  816. package/src/ui/live-stretch.ts +153 -0
  817. package/src/ui/measured-cells.ts +58 -0
  818. package/src/ui/sticky-scroll.ts +7 -0
  819. package/src/utils/basis-points.ts +17 -0
  820. package/src/utils/central-banks.ts +76 -0
  821. package/src/utils/cli-output.ts +131 -15
  822. package/src/utils/concurrency.ts +25 -0
  823. package/src/utils/crypto-pair.ts +20 -0
  824. package/src/utils/currency-pair.ts +19 -0
  825. package/src/utils/currency-units.ts +11 -0
  826. package/src/utils/datetime-format.ts +27 -6
  827. package/src/utils/decimal-comma.ts +19 -0
  828. package/src/utils/dom-screenshot-css.ts +265 -0
  829. package/src/utils/dom-screenshot-rasters.ts +276 -0
  830. package/src/utils/dom-screenshot.ts +439 -52
  831. package/src/utils/double-escape-close.ts +15 -1
  832. package/src/utils/exchange-rate-snapshot.ts +6 -2
  833. package/src/utils/exchanges.ts +143 -1
  834. package/src/utils/format.ts +35 -5
  835. package/src/utils/forward-dividend.ts +14 -0
  836. package/src/utils/fundamentals.ts +66 -0
  837. package/src/utils/futures-generic.ts +6 -12
  838. package/src/utils/fx-market-hours.ts +15 -5
  839. package/src/utils/fx-status.ts +6 -1
  840. package/src/utils/inline-content-tokenizer.ts +22 -3
  841. package/src/utils/market-capitalization.ts +8 -0
  842. package/src/utils/one-shot.ts +73 -0
  843. package/src/utils/options.ts +37 -8
  844. package/src/utils/price-history.ts +99 -42
  845. package/src/utils/sec-eps-basis.ts +24 -11
  846. package/src/utils/sec.ts +61 -7
  847. package/src/utils/utc-time.ts +63 -4
  848. package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
  849. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
  850. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
  851. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
  852. /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
@@ -1,110 +1,36 @@
1
1
  import type {
2
- HeadlessPaneColumn,
3
2
  HeadlessPaneContext,
4
3
  HeadlessPaneDefinition,
5
4
  HeadlessPaneLoadArgs,
6
5
  } from "../../../types/plugin";
7
- import { formatCompact } from "../../../utils/format";
8
6
  import { loadHolderSnapshot } from "./client";
9
- import {
10
- displayDate,
11
- formatHolderOwnershipPercent,
12
- formatMaybePercent,
13
- formatMoneyCompact,
14
- formatSignedCompact,
15
- holderValueCurrency,
16
- resolveHolderOwnershipPercent,
17
- } from "./format";
18
- import { buildRows, sortRows } from "./table-model";
7
+ import { holderValueCurrency } from "./format";
19
8
  import type { HolderData } from "../../../types/financials";
20
- import type { HolderColumnId } from "./types";
21
9
  import { SEC_FILINGS } from "../shared/report-freshness";
22
- import {
23
- holderShareBasisMarker,
24
- holderShareBasisNote,
25
- holderValueBasis,
26
- holdersHeaderLine,
27
- moneyColumnHeader,
28
- nonUsHolderCaveat,
29
- sharedReportDate,
30
- } from "./report-header";
31
-
32
- /** Columns a source fills only when it reports the quarter's change. */
33
- const CHANGE_COLUMN_KEYS = new Set(["changeShares", "changePercent"]);
34
- /** Shown only when some row is held as depositary receipts, as on a home line abroad. */
35
- const BASIS_COLUMN_KEY = "shareBasis";
36
10
  import type { BeneficialOwnersPayload } from "../../../api-client/beneficial-owners";
37
11
  import { fetchBeneficialOwners, type BeneficialOwnersRequest } from "./beneficial-client";
38
12
  import { resolveHeadlessIssuerListing } from "../shared/headless-market-data";
39
13
  import type { BeneficialColumnId } from "./beneficial-model";
40
14
  import {
41
- BENEFICIAL_REPORT_COLUMNS,
42
15
  beneficialCoverageNotices,
43
16
  beneficialListComplete,
44
17
  beneficialListFacts,
18
+ beneficialReportColumns,
19
+ beneficialReportLegend,
45
20
  beneficialRouteForm,
46
21
  buildBeneficialReportRows,
47
22
  HOLDER_FORMS,
48
23
  parseHolderForm,
49
24
  } from "./beneficial-report";
50
-
51
- const HOLDER_COLUMNS: HeadlessPaneColumn[] = [
52
- { key: "name", header: "Holder" },
53
- { key: "ownerType", header: "Type" },
54
- {
55
- key: "value",
56
- header: "Mkt value",
57
- align: "right",
58
- format: (value, row) => formatMoneyCompact(
59
- value == null ? undefined : Number(value),
60
- String(row.currency ?? "USD"),
61
- ),
62
- },
63
- {
64
- key: "shares",
65
- header: "Amount",
66
- align: "right",
67
- format: (value) => value == null ? "-" : formatCompact(Number(value)),
68
- },
69
- {
70
- key: BASIS_COLUMN_KEY,
71
- header: "Basis",
72
- format: (_value, row) => holderShareBasisMarker(row),
73
- },
74
- {
75
- key: "changeShares",
76
- header: "Chg",
77
- align: "right",
78
- format: (value) => formatSignedCompact(value == null ? undefined : Number(value)),
79
- },
80
- {
81
- key: "changePercent",
82
- header: "Chg%",
83
- align: "right",
84
- format: (value) => formatMaybePercent(value == null ? undefined : Number(value)),
85
- },
86
- {
87
- key: "percentHeld",
88
- header: "Held",
89
- align: "right",
90
- format: (value) => formatHolderOwnershipPercent(value == null ? undefined : Number(value)),
91
- },
92
- {
93
- key: "reportDate",
94
- header: "Period",
95
- format: (value) => displayDate(typeof value === "string" ? value : undefined),
96
- },
97
- ];
98
-
99
- const SORT_COLUMNS: Record<string, HolderColumnId> = {
100
- holder: "holder",
101
- value: "value",
102
- shares: "shares",
103
- change: "changeShares",
104
- "change-percent": "changePercent",
105
- held: "percentHeld",
106
- date: "reportDate",
107
- };
25
+ import {
26
+ HOLDER_REPORT_COLUMNS,
27
+ HOLDER_SORT_KEYS,
28
+ holderReportColumns,
29
+ holderReportNotices,
30
+ holderReportDates,
31
+ holderReportRows,
32
+ holderReportUnits,
33
+ } from "./report-rows";
108
34
 
109
35
  /** The same sort keys order the 13D/13G rows; `value` and `held` are the percent of class. */
110
36
  const BENEFICIAL_SORT_COLUMNS: Record<string, BeneficialColumnId> = {
@@ -120,6 +46,8 @@ const BENEFICIAL_SORT_COLUMNS: Record<string, BeneficialColumnId> = {
120
46
  interface HolderSnapshot {
121
47
  data: HolderData;
122
48
  marketCap?: number;
49
+ /** Today's shares outstanding, which a 13D/13G percent of class is set against. */
50
+ sharesOutstanding?: number | null;
123
51
  }
124
52
 
125
53
  export interface HoldersHeadlessDependencies {
@@ -164,7 +92,7 @@ export function createHoldersHeadless(
164
92
  key: "sort",
165
93
  description: "Column used to sort holder rows.",
166
94
  type: "enum",
167
- values: Object.keys(SORT_COLUMNS).map((value) => ({ value })),
95
+ values: Object.keys(HOLDER_SORT_KEYS).map((value) => ({ value })),
168
96
  defaultValue: "value",
169
97
  },
170
98
  {
@@ -205,7 +133,7 @@ export function createHoldersHeadless(
205
133
  defaultValue: false,
206
134
  },
207
135
  ],
208
- columns: HOLDER_COLUMNS,
136
+ columns: HOLDER_REPORT_COLUMNS,
209
137
  describe: (args) => `Holders | ${args.symbols[0]}`,
210
138
  async load(args, ctx) {
211
139
  const symbol = args.symbols[0]!;
@@ -219,6 +147,7 @@ export function createHoldersHeadless(
219
147
  // The 13F column is a join; the 13D/13G rows stand without it.
220
148
  dependencies.loadSnapshot(symbol, args, ctx).catch(() => null),
221
149
  ]);
150
+ const sharesOutstanding = snapshot?.sharesOutstanding ?? null;
222
151
  const rows = buildBeneficialReportRows(payload, {
223
152
  history,
224
153
  holders: snapshot?.data ?? null,
@@ -226,10 +155,12 @@ export function createHoldersHeadless(
226
155
  columnId: BENEFICIAL_SORT_COLUMNS[String(args.options.sort)] ?? "percentOfClass",
227
156
  direction: args.options.order === "asc" ? "asc" : "desc",
228
157
  },
158
+ sharesOutstanding,
229
159
  });
230
160
  const limited = rows.slice(0, Number(args.options.limit));
161
+ const legend = beneficialReportLegend(limited, sharesOutstanding);
231
162
  return {
232
- columns: BENEFICIAL_REPORT_COLUMNS,
163
+ columns: beneficialReportColumns(limited),
233
164
  rows: limited,
234
165
  // Reports that could not be read this time are missing from the rows.
235
166
  complete: beneficialListComplete(payload),
@@ -242,8 +173,10 @@ export function createHoldersHeadless(
242
173
  history,
243
174
  asOf: payload.asOf,
244
175
  coverage: payload.coverage,
176
+ sharesOutstanding,
245
177
  notices: [
246
178
  [payload.companyName || symbol, ...beneficialListFacts(payload, form, rows.length, history)].join(" · "),
179
+ ...(legend ? [legend] : []),
247
180
  ...beneficialCoverageNotices(payload.coverage),
248
181
  ],
249
182
  returned: limited.length,
@@ -255,52 +188,19 @@ export function createHoldersHeadless(
255
188
  const currency = data.currency ?? "USD";
256
189
  // A London line's values can be dollars from the 13F filings; they are labelled and formatted as such.
257
190
  const valueCurrency = holderValueCurrency(data, currency)!;
258
- const sorted = sortRows(buildRows(data), {
259
- columnId: SORT_COLUMNS[String(args.options.sort)] ?? "value",
260
- direction: args.options.order === "asc" ? "asc" : "desc",
261
- }, marketCap);
262
- const rows = sorted
263
- .slice(0, Number(args.options.limit))
264
- .map((row) => ({
265
- name: row.name,
266
- ownerType: row.ownerType,
267
- value: row.value ?? null,
268
- shares: row.shares ?? null,
269
- changeShares: row.changeShares ?? null,
270
- changePercent: row.changePercent ?? null,
271
- percentHeld: resolveHolderOwnershipPercent(row, marketCap) ?? null,
272
- reportDate: row.reportDate ?? null,
273
- currency: valueCurrency,
274
- shareBasis: row.shareBasis ?? null,
275
- }));
191
+ const sort = {
192
+ columnId: HOLDER_SORT_KEYS[String(args.options.sort)] ?? "value",
193
+ direction: args.options.order === "asc" ? "asc" as const : "desc" as const,
194
+ };
195
+ const sorted = holderReportRows(data, { marketCap, sort });
196
+ const rows = sorted.slice(0, Number(args.options.limit));
276
197
  const total = data.summary?.institutionsCount ?? null;
277
- const changeReported = rows.some((row) => row.changeShares != null || row.changePercent != null);
278
- const reportDate = sharedReportDate(rows);
279
- const valueBasis = holderValueBasis(reportDate, data.valueBasis, valueCurrency);
280
- const positionsBasis = rows.length > 0 ? nonUsHolderCaveat(data.exchange, currency) : null;
281
- const shareBasisNote = holderShareBasisNote(data, rows);
282
- const markedRows = rows.some((row) => holderShareBasisMarker(row));
283
- // The title names the ticker and the closing line carries the as-of date.
284
- const header = holdersHeaderLine({
285
- name: data.name,
286
- symbol: data.symbol && data.symbol !== symbol ? data.symbol : null,
287
- exchange: data.exchange,
288
- currency: valueCurrency,
289
- listingCurrency: data.currency,
290
- shown: rows.length,
291
- reported: sorted.length,
292
- total,
198
+ const { notices, valueBasis, positionsBasis, changeReported } = holderReportNotices({
199
+ data, requested: symbol, shown: rows, reported: sorted.length, total, sort,
293
200
  });
294
- const basis = rows.length === 0 ? null : [
295
- `Mkt value = ${valueBasis}.`,
296
- changeReported ? "" : `Change vs prior quarter: not reported by this source; see fn 13F ${symbol}`,
297
- ].filter(Boolean).join(" ");
298
201
  return {
299
- // A change column that is empty on every row says nothing; the line above explains it once.
300
- columns: HOLDER_COLUMNS
301
- .filter((column) => changeReported || !CHANGE_COLUMN_KEYS.has(column.key))
302
- .filter((column) => markedRows || column.key !== BASIS_COLUMN_KEY)
303
- .map((column) => column.key === "value" ? { ...column, header: moneyColumnHeader(column.header, valueCurrency) } : column),
202
+ // A change column that is empty on every row says nothing; the notices explain it once.
203
+ columns: holderReportColumns(rows, valueCurrency),
304
204
  rows,
305
205
  metadata: {
306
206
  symbol: data.symbol || symbol,
@@ -308,10 +208,13 @@ export function createHoldersHeadless(
308
208
  exchange: data.exchange ?? null,
309
209
  currency,
310
210
  valueCurrency,
211
+ units: holderReportUnits(valueCurrency),
311
212
  ...(data.isDepositaryReceipt != null ? { isDepositaryReceipt: data.isDepositaryReceipt } : {}),
312
213
  ...(data.shareBasis ? { shareBasis: data.shareBasis } : {}),
313
214
  ...(data.adrRatio != null ? { adrRatio: data.adrRatio } : {}),
314
215
  asOf: data.asOf ?? null,
216
+ // Each holder's latest period; several when the list mixes quarters.
217
+ reportDates: holderReportDates(rows),
315
218
  summary: data.summary ?? null,
316
219
  shown: rows.length,
317
220
  reported: sorted.length,
@@ -320,7 +223,7 @@ export function createHoldersHeadless(
320
223
  valueBasis,
321
224
  changeReported,
322
225
  positionsBasis,
323
- notices: [header, basis, positionsBasis, shareBasisNote].filter((line): line is string => !!line),
226
+ notices,
324
227
  },
325
228
  };
326
229
  },
@@ -30,7 +30,7 @@ import {
30
30
  holderValueCurrency,
31
31
  resolveHolderOwnershipPercent,
32
32
  } from "./format";
33
- import { holderShareBasisMarker } from "./report-header";
33
+ import { holderPeriodsDiffer, holderShareBasisMarker } from "./report-header";
34
34
  import {
35
35
  buildColumns,
36
36
  hasHolderChanges,
@@ -40,7 +40,7 @@ import {
40
40
  sortRows,
41
41
  VIEW_TABS,
42
42
  } from "./table-model";
43
- import { loadHolderData } from "./client";
43
+ import { classSharesToday, loadHolderData } from "./client";
44
44
  import { HoldersTreemap } from "./treemap";
45
45
  import { BeneficialOwnersView } from "./beneficial-view";
46
46
  import { useIssuerListing } from "../shared/ticker-request";
@@ -84,7 +84,10 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
84
84
  useTickerQuoteStream(ticker ? symbol : null, ticker, { surface: "detail", visible: false, weight: 30 });
85
85
  const liveMarketCap = holderStakeMarketCap(financials?.quote?.marketCap, financials?.quote?.currency, currency);
86
86
  const marketCap = useSampledValue(liveMarketCap, HOLDER_MARKET_CAP_SAMPLE_MS, `${symbol ?? ""}:${currency}`);
87
+ // Today's share count, which a 13D/13G report's own base is checked against.
88
+ const sharesOutstanding = classSharesToday(financials);
87
89
  const rows = useMemo(() => buildRows(data), [data]);
90
+ const periodsDiffer = useMemo(() => holderPeriodsDiffer(rows), [rows]);
88
91
  const sortedRows = useMemo(() => sortRows(rows, sortPreference, marketCap), [marketCap, rows, sortPreference]);
89
92
  // Change columns only when the source reports a change; otherwise they read "-" on every row.
90
93
  const showChange = useMemo(() => hasHolderChanges(rows), [rows]);
@@ -271,7 +274,10 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
271
274
  if (viewMode === "13dg") return null;
272
275
  return {
273
276
  info: [
274
- ...(data?.asOf ? [{ id: "as-of", parts: [{ text: data.asOf, tone: "value" as const }] }] : []),
277
+ // One date only when every holder's row is of it; the PERIOD column dates each row.
278
+ ...(periodsDiffer
279
+ ? [{ id: "as-of", parts: [{ text: "latest period per holder", tone: "muted" as const }] }]
280
+ : data?.asOf ? [{ id: "as-of", parts: [{ text: data.asOf, tone: "value" as const }] }] : []),
275
281
  ...loadingErrorFooterInfo(loading, data ? error : null),
276
282
  ...(fundMatching ? [{ id: "fund-matching", parts: [{ text: "13F matching", tone: "muted" as const }] }] : []),
277
283
  ],
@@ -282,7 +288,7 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
282
288
  ...(selectedFundMatch ? [{ id: "fund", key: "o", label: "pen 13F", onPress: () => openFundDetail(selectedRow) }] : []),
283
289
  ],
284
290
  };
285
- }, [data, error, fundMatching, loading, openFundDetail, selectedFundMatch, selectedRow, viewMode]);
291
+ }, [data, error, fundMatching, loading, openFundDetail, periodsDiffer, selectedFundMatch, selectedRow, viewMode]);
286
292
 
287
293
  const selectView = useCallback((value: string) => setViewMode(value as ViewMode), [setViewMode]);
288
294
  // As a research tab, h/l move between research tabs; `s` switches the view.
@@ -342,6 +348,7 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
342
348
  listing={issuerListing}
343
349
  holderRows={rows}
344
350
  fundMatches={fundMatches}
351
+ sharesOutstanding={sharesOutstanding}
345
352
  onCycleView={toggleView}
346
353
  onRefreshHolders={refresh}
347
354
  />
@@ -20,6 +20,16 @@ export interface HolderReportFacts {
20
20
  listingCurrency?: string | null;
21
21
  /** Left out when the report's closing line already carries it. */
22
22
  asOf?: string | null;
23
+ /**
24
+ * What the list is as of, in place of `asOf`: `as of <date>` when every
25
+ * row shares one report date, `latest period per holder` when they differ.
26
+ */
27
+ period?: string | null;
28
+ /**
29
+ * False when the list is not the source's largest holders but the few
30
+ * filers that report the line at all (a home line abroad): no "top".
31
+ */
32
+ ranked?: boolean;
23
33
  /** Rows printed. */
24
34
  shown: number;
25
35
  /** Rows the source returned, before any limit. */
@@ -34,15 +44,39 @@ export function moneyColumnHeader(label: string, currency?: string | null): stri
34
44
  return unit ? `${label} (${unit})` : label;
35
45
  }
36
46
 
37
- function holderCountText(shown: number, reported: number, total?: number | null): string {
47
+ function holderCountText(shown: number, reported: number, total?: number | null, ranked = true): string {
38
48
  if (total != null && Number.isFinite(total) && total >= reported) {
39
49
  return `${shown.toLocaleString("en-US")} of ${total.toLocaleString("en-US")} holders`;
40
50
  }
41
51
  if (reported === 0) return "none reported";
52
+ // A home line's few filers are all there is, not a top of anything.
53
+ if (!ranked) return shown < reported ? `${shown} of ${reported} reported` : `${reported} ${reported === 1 ? "holder" : "holders"} reported`;
42
54
  // Without a total the source's list is its largest holders, cut where it cuts it.
43
55
  return shown < reported ? `${shown} of top ${reported} reported` : `top ${reported} reported`;
44
56
  }
45
57
 
58
+ /**
59
+ * What a holder list is as of. Each holder's row is its latest filed
60
+ * period, so one date is claimed only when every row has it; rows of
61
+ * different quarters read `latest period per holder`, and an empty list
62
+ * keeps the source's date.
63
+ */
64
+ export function holderListPeriod(
65
+ rows: ReadonlyArray<{ reportDate?: unknown }>,
66
+ asOf?: string | null,
67
+ ): string | null {
68
+ const dates = new Set(rows.flatMap((row) => typeof row.reportDate === "string" && row.reportDate ? [row.reportDate] : []));
69
+ if (dates.size > 1) return "latest period per holder";
70
+ const [only] = dates;
71
+ const date = only ?? asOf;
72
+ return date ? `as of ${date}` : null;
73
+ }
74
+
75
+ /** Whether a holder list's rows are of more than one report date. */
76
+ export function holderPeriodsDiffer(rows: ReadonlyArray<{ reportDate?: unknown }>): boolean {
77
+ return holderListPeriod(rows) === "latest period per holder";
78
+ }
79
+
46
80
  /** A venue the app knows by its short name (NasdaqGS is NASDAQ); any other as the source wrote it. */
47
81
  function venueLabel(exchange?: string | null): string {
48
82
  const canonical = canonicalExchange(exchange ?? "");
@@ -51,15 +85,15 @@ function venueLabel(exchange?: string | null): string {
51
85
 
52
86
  /** What the list is, after the listing is named: its unit, date and how much of it is shown. */
53
87
  export function holderListFacts(
54
- facts: Pick<HolderReportFacts, "currency" | "listingCurrency" | "asOf" | "shown" | "reported" | "total">,
88
+ facts: Pick<HolderReportFacts, "currency" | "listingCurrency" | "asOf" | "period" | "shown" | "reported" | "total" | "ranked">,
55
89
  ): string[] {
56
90
  const unit = currencyUnitLabel(facts.currency);
57
91
  // Dollars on a London line: say they are the values' unit, not the listing's.
58
92
  const otherUnit = unit && facts.listingCurrency?.trim() && facts.listingCurrency.trim() !== facts.currency?.trim();
59
93
  return [
60
94
  otherUnit ? `values in ${unit}` : unit,
61
- facts.asOf ? `as of ${facts.asOf}` : "",
62
- holderCountText(facts.shown, facts.reported, facts.total),
95
+ facts.period ?? (facts.asOf ? `as of ${facts.asOf}` : ""),
96
+ holderCountText(facts.shown, facts.reported, facts.total, facts.ranked),
63
97
  ].filter(Boolean);
64
98
  }
65
99
 
@@ -132,5 +166,6 @@ export function nonUsHolderCaveat(exchange?: string | null, currency?: string |
132
166
  if (!isNonUsHolderListing(exchange, currency)) return null;
133
167
  const canonical = canonicalExchange(exchange ?? "");
134
168
  const venue = resolveExchangeTimeZone(canonical) ? canonical : "local";
135
- return `Positions come from institutional filings (mostly US 13F), not the ${venue} share register.`;
169
+ // Few filers report a line abroad, so a small position can lead the list.
170
+ return `Positions come from institutional filings (mostly US 13F), not the ${venue} share register, so the line's largest holders may be missing.`;
136
171
  }
@@ -0,0 +1,240 @@
1
+ import type { HeadlessPaneColumn } from "../../../types/plugin";
2
+ import type { HolderData, ShareBasis } from "../../../types/financials";
3
+ import { formatCompact, formatPercentRaw } from "../../../utils/format";
4
+ import {
5
+ displayDate,
6
+ formatMoneyCompact,
7
+ formatPercentHeld,
8
+ formatSignedCompact,
9
+ holderPercent,
10
+ holderValueCurrency,
11
+ resolveHolderOwnershipPercent,
12
+ } from "./format";
13
+ import {
14
+ holderListPeriod,
15
+ holderPeriodsDiffer,
16
+ holderShareBasisMarker,
17
+ holderShareBasisNote,
18
+ holderValueBasis,
19
+ holdersHeaderLine,
20
+ moneyColumnHeader,
21
+ nonUsHolderCaveat,
22
+ sharedReportDate,
23
+ } from "./report-header";
24
+ import { buildRows, DEFAULT_SORT, sortRows } from "./table-model";
25
+ import type { HolderColumnId, SortPreference } from "./types";
26
+
27
+ /**
28
+ * A holder as `holders` and `fn HDS` report it; the keys are the JSON
29
+ * contract. `value` is in `currency`, the values' own currency; the percents
30
+ * are in percent (0.59 is 0.59% of the shares outstanding, 13.15 a 13.15%
31
+ * change on the quarter). A figure the source did not give is null.
32
+ */
33
+ export interface HolderReportRow {
34
+ name: string;
35
+ ownerType: string;
36
+ value: number | null;
37
+ shares: number | null;
38
+ changeShares: number | null;
39
+ changePercent: number | null;
40
+ percentHeld: number | null;
41
+ reportDate: string | null;
42
+ currency: string;
43
+ shareBasis: ShareBasis | null;
44
+ [key: string]: unknown;
45
+ }
46
+
47
+ /** Columns a source fills only when it reports the quarter's change. */
48
+ const CHANGE_COLUMN_KEYS = new Set(["changeShares", "changePercent"]);
49
+ /** Shown only when some row is held as depositary receipts, as on a home line abroad. */
50
+ const BASIS_COLUMN_KEY = "shareBasis";
51
+ const num = (value: unknown) => (typeof value === "number" && Number.isFinite(value) ? value : null);
52
+
53
+ /**
54
+ * The HDS report's columns, which `holders --csv` and `--json` share. CSV
55
+ * reads `format`, so a value drawn as a plain figure exports its full number
56
+ * under a header naming the unit (`Mkt value (USD)`, `Held (%)`); the text
57
+ * report draws `textFormat`, with the currency sign and `<0.01%`.
58
+ */
59
+ export const HOLDER_REPORT_COLUMNS: HeadlessPaneColumn[] = [
60
+ { key: "name", header: "Holder" },
61
+ { key: "ownerType", header: "Type" },
62
+ {
63
+ key: "value",
64
+ header: "Mkt value",
65
+ align: "right",
66
+ format: (value) => num(value) == null ? "-" : formatCompact(num(value)!),
67
+ textFormat: (value, row) => formatMoneyCompact(num(value) ?? undefined, String(row.currency ?? "USD")),
68
+ },
69
+ {
70
+ key: "shares",
71
+ header: "Amount",
72
+ align: "right",
73
+ format: (value) => num(value) == null ? "-" : formatCompact(num(value)!),
74
+ },
75
+ {
76
+ key: BASIS_COLUMN_KEY,
77
+ header: "Basis",
78
+ format: (_value, row) => holderShareBasisMarker(row),
79
+ },
80
+ {
81
+ key: "changeShares",
82
+ header: "Chg",
83
+ align: "right",
84
+ format: (value) => formatSignedCompact(num(value) ?? undefined),
85
+ },
86
+ {
87
+ key: "changePercent",
88
+ header: "Chg%",
89
+ align: "right",
90
+ format: (value) => num(value) == null ? "-" : formatPercentRaw(num(value)!),
91
+ },
92
+ {
93
+ key: "percentHeld",
94
+ header: "Held",
95
+ align: "right",
96
+ format: (value) => num(value) == null ? "-" : `${num(value)!.toFixed(2)}%`,
97
+ textFormat: (value) => formatPercentHeld(num(value)),
98
+ },
99
+ {
100
+ key: "reportDate",
101
+ header: "Period",
102
+ format: (value) => displayDate(typeof value === "string" ? value : undefined),
103
+ },
104
+ ];
105
+
106
+ /** `--sort` values, the same for `holders` and `fn HDS`. */
107
+ export const HOLDER_SORT_KEYS: Record<string, HolderColumnId> = {
108
+ holder: "holder",
109
+ value: "value",
110
+ shares: "shares",
111
+ change: "changeShares",
112
+ "change-percent": "changePercent",
113
+ held: "percentHeld",
114
+ date: "reportDate",
115
+ };
116
+
117
+ /**
118
+ * Every holder of the list, largest value first unless another sort is
119
+ * asked for, with the stake and change in percent. A holder without a value
120
+ * sorts after those with one, whichever the direction. `ownerTypes` keeps
121
+ * only those kinds (`insider`, `13f`).
122
+ */
123
+ export function holderReportRows(
124
+ data: HolderData,
125
+ {
126
+ marketCap,
127
+ sort = DEFAULT_SORT,
128
+ ownerTypes,
129
+ }: { marketCap?: number; sort?: SortPreference; ownerTypes?: ReadonlySet<string> } = {},
130
+ ): HolderReportRow[] {
131
+ const holders = ownerTypes ? data.holders.filter((holder) => ownerTypes.has(holder.ownerType)) : data.holders;
132
+ // The values' own currency: dollars from the 13F filings on a London line.
133
+ const currency = holderValueCurrency(data, "USD")!;
134
+ return sortRows(buildRows({ ...data, holders }), sort, marketCap).map((row) => ({
135
+ name: row.name,
136
+ ownerType: row.ownerType,
137
+ value: row.value ?? null,
138
+ shares: row.shares ?? null,
139
+ changeShares: row.changeShares ?? null,
140
+ changePercent: holderPercent(row.changePercent),
141
+ percentHeld: holderPercent(resolveHolderOwnershipPercent(row, marketCap)),
142
+ reportDate: row.reportDate ?? null,
143
+ currency,
144
+ shareBasis: row.shareBasis ?? null,
145
+ }));
146
+ }
147
+
148
+ /** The report dates of the rows, newest first: one when the list is of one quarter. */
149
+ export function holderReportDates(rows: readonly HolderReportRow[]): string[] {
150
+ return [...new Set(rows.flatMap((row) => row.reportDate ? [row.reportDate] : []))].sort().reverse();
151
+ }
152
+
153
+ /** What the JSON rows' numbers are in, for `metadata.units`. */
154
+ export function holderReportUnits(valueCurrency: string): Record<string, string> {
155
+ return { value: valueCurrency, changePercent: "%", percentHeld: "%" };
156
+ }
157
+
158
+ /** Whether any holder carries the quarter's change; many sources report none. */
159
+ function holderChangeReported(rows: readonly HolderReportRow[]): boolean {
160
+ return rows.some((row) => row.changeShares != null || row.changePercent != null);
161
+ }
162
+
163
+ /**
164
+ * The report's columns for these rows: the change columns only when a row
165
+ * has a change, the basis column only when a row is held as receipts, and
166
+ * the value column named with its currency.
167
+ */
168
+ export function holderReportColumns(rows: readonly HolderReportRow[], valueCurrency: string | null | undefined): HeadlessPaneColumn[] {
169
+ const changeReported = holderChangeReported(rows);
170
+ const marked = rows.some((row) => holderShareBasisMarker(row));
171
+ return HOLDER_REPORT_COLUMNS
172
+ .filter((column) => changeReported || !CHANGE_COLUMN_KEYS.has(column.key))
173
+ .filter((column) => marked || column.key !== BASIS_COLUMN_KEY)
174
+ .map((column) => column.key === "value" ? { ...column, header: moneyColumnHeader(column.header, valueCurrency) } : column);
175
+ }
176
+
177
+ /**
178
+ * The lines above the HDS table, which `holders --csv` also closes with: the
179
+ * listing, unit and count, how a value was reached (and where the change is
180
+ * when the source gives none), and what the positions and shares are.
181
+ */
182
+ export function holderReportNotices({
183
+ data,
184
+ requested,
185
+ shown,
186
+ reported,
187
+ total,
188
+ sort = DEFAULT_SORT,
189
+ }: {
190
+ data: HolderData;
191
+ /** The symbol as asked for, which `fn 13F` takes. */
192
+ requested: string;
193
+ shown: readonly HolderReportRow[];
194
+ /** Holders on the list before a limit. */
195
+ reported: number;
196
+ total: number | null;
197
+ sort?: SortPreference;
198
+ }): { notices: string[]; valueBasis: string; positionsBasis: string | null; changeReported: boolean } {
199
+ const valueCurrency = holderValueCurrency(data, "USD")!;
200
+ const changeReported = holderChangeReported(shown);
201
+ const valueBasis = holderValueBasis(sharedReportDate(shown), data.valueBasis, valueCurrency);
202
+ const positionsBasis = shown.length > 0 ? nonUsHolderCaveat(data.exchange, data.currency ?? "USD") : null;
203
+ // The title names the ticker and the closing line carries the as-of date,
204
+ // which is one date only when every row has it.
205
+ const header = holdersHeaderLine({
206
+ name: data.name,
207
+ symbol: data.symbol && data.symbol !== requested ? data.symbol : null,
208
+ exchange: data.exchange,
209
+ currency: valueCurrency,
210
+ listingCurrency: data.currency,
211
+ period: holderPeriodsDiffer(shown) ? holderListPeriod(shown) : null,
212
+ shown: shown.length,
213
+ reported,
214
+ total,
215
+ ranked: !positionsBasis,
216
+ });
217
+ const basis = shown.length === 0 ? null : [
218
+ `Mkt value = ${valueBasis}.`,
219
+ changeReported ? "" : `Change vs prior quarter: not reported by this source; see fn 13F ${requested}`,
220
+ ].filter(Boolean).join(" ");
221
+ return {
222
+ notices: [header, basis, positionsBasis, holderShareBasisNote(data, shown), unvaluedHoldersNote(shown, sort)]
223
+ .filter((line): line is string => !!line),
224
+ valueBasis,
225
+ positionsBasis,
226
+ changeReported,
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Holders the list gives no value for (a home line's position its filing
232
+ * could not tie to a priced security) sort after every valued one, and a
233
+ * value-ordered report says so rather than ranking them silently.
234
+ */
235
+ export function unvaluedHoldersNote(rows: readonly HolderReportRow[], sort: SortPreference = DEFAULT_SORT): string | null {
236
+ if (sort.columnId !== "value") return null;
237
+ const unvalued = rows.filter((row) => row.value == null).length;
238
+ if (unvalued === 0 || unvalued === rows.length) return null;
239
+ return `${unvalued} ${unvalued === 1 ? "holder has" : "holders have"} no value and ${unvalued === 1 ? "is" : "are"} listed last.`;
240
+ }