gloomberb 0.18.3 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -0,0 +1,44 @@
1
+ import { useCallback, useRef, useState } from "react";
2
+ import type { CompositeAxisSide } from "./types";
3
+ import { NO_VALUE_SCALES, valueScaleSlot, type CompositeValueRange, type CompositeValueScales } from "./value-scale";
4
+
5
+ /**
6
+ * The chart's manual value scales: set by a drag or the wheel on an axis, or
7
+ * a drag on the plot of a panel already scaled by hand; cleared per panel or
8
+ * all at once, and whenever `resetKey` changes (in the same render, so a new
9
+ * view never draws in the old one's scale).
10
+ */
11
+ export function useCompositeValueScales(resetKey: unknown) {
12
+ const [state, setState] = useState<{ resetKey: unknown; scales: CompositeValueScales }>(() => ({ resetKey, scales: NO_VALUE_SCALES }));
13
+ const resetKeyRef = useRef(resetKey);
14
+ resetKeyRef.current = resetKey;
15
+ const scales = Object.is(state.resetKey, resetKey) ? state.scales : NO_VALUE_SCALES;
16
+ const update = useCallback((change: (scales: CompositeValueScales) => CompositeValueScales) => {
17
+ setState((current) => {
18
+ const key = resetKeyRef.current;
19
+ const fresh = Object.is(current.resetKey, key);
20
+ const base = fresh ? current.scales : NO_VALUE_SCALES;
21
+ const next = change(base);
22
+ return fresh && next === base ? current : { resetKey: key, scales: next };
23
+ });
24
+ }, []);
25
+ const setValueScale = useCallback((panelId: string, side: CompositeAxisSide, key: string, range: CompositeValueRange) => {
26
+ const slot = valueScaleSlot(panelId, side);
27
+ update((current) => {
28
+ const previous = current[slot];
29
+ if (previous && previous.key === key && previous.min === range.min && previous.max === range.max) return current;
30
+ return { ...current, [slot]: { key, min: range.min, max: range.max } };
31
+ });
32
+ }, [update]);
33
+ const resetPanelValueScale = useCallback((panelId: string) => {
34
+ update((current) => {
35
+ const slots = (["left", "right"] as const).map((side) => valueScaleSlot(panelId, side)).filter((slot) => slot in current);
36
+ if (slots.length === 0) return current;
37
+ const next = { ...current };
38
+ for (const slot of slots) delete next[slot];
39
+ return Object.keys(next).length === 0 ? NO_VALUE_SCALES : next;
40
+ });
41
+ }, [update]);
42
+ const resetValueScales = useCallback(() => update(() => NO_VALUE_SCALES), [update]);
43
+ return { valueScales: scales, setValueScale, resetPanelValueScale, resetValueScales };
44
+ }
@@ -99,9 +99,13 @@ export function useCompositeViewport({
99
99
  );
100
100
  }, [onViewportChange, userViewportEnd, userViewportStart]);
101
101
 
102
+ // Counts authored views, so what belongs to one (values scaled by hand) can
103
+ // go with it; `authoredViewportChanged` covers the render before it counts.
104
+ const [authoredGeneration, setAuthoredGeneration] = useState(0);
102
105
  useEffect(() => {
103
106
  previousAuthoredViewportRef.current = viewport ?? null;
104
107
  previousViewportResetKeyRef.current = viewportResetKey;
108
+ if (authoredViewportChanged) setAuthoredGeneration((generation) => generation + 1);
105
109
  if (authoredViewportChanged && userViewport) {
106
110
  viewportInteractionRef.current = "reset";
107
111
  setUserViewport(null);
@@ -154,8 +158,13 @@ export function useCompositeViewport({
154
158
  if (!positions) return;
155
159
  panViewport(shiftRatio * Math.max(positions.end - positions.start, Number.EPSILON));
156
160
  }, [effectiveViewport, navigationFrame, panViewport]);
157
- const zoomViewport = useCallback((zoomFactor: number, anchorRatio = 1) => {
158
- navigate("zoom", (base, frame) => zoomCompositeViewport(frame, base, zoomFactor, anchorRatio));
161
+ /** A gesture (a drag on the time axis) zooms from the view and frame it started in, by its whole travel so far. */
162
+ const zoomViewport = useCallback((
163
+ zoomFactor: number,
164
+ anchorRatio = 1,
165
+ gesture?: { frame: CompositeNavigationFrame; from: CompositeViewportRange },
166
+ ) => {
167
+ navigate("zoom", (base, frame) => zoomCompositeViewport(frame, base, zoomFactor, anchorRatio), gesture);
159
168
  }, [navigate]);
160
169
  const setViewportRange = useCallback((range: CompositeViewportRange) => {
161
170
  navigate("zoom", (_base, frame) => fitCompositeViewport(frame, range));
@@ -165,7 +174,7 @@ export function useCompositeViewport({
165
174
  setUserViewport(null);
166
175
  }, []);
167
176
  return {
168
- navigationFrame, activeUserViewport, effectiveViewport,
177
+ navigationFrame, activeUserViewport, effectiveViewport, authoredViewportChanged, authoredGeneration,
169
178
  panViewport, panViewportByRatio, zoomViewport, setViewportRange, resetViewport,
170
179
  };
171
180
  }
@@ -0,0 +1,149 @@
1
+ import type { PanelScale, ResolvedSeries } from "../../../time-series/types";
2
+ import type { CompositeAxisSide } from "./types";
3
+ import { clamp } from "../../../utils/math";
4
+
5
+ /** What a value axis shows, in its own values. */
6
+ export interface CompositeValueRange {
7
+ min: number;
8
+ max: number;
9
+ }
10
+
11
+ /**
12
+ * A value axis stretched or squeezed by hand, and what it plots: a range set
13
+ * for one listing's prices means nothing for another's, so it holds only
14
+ * while the axis plots the same series in the same unit and scale.
15
+ */
16
+ export interface CompositeManualValueScale extends CompositeValueRange {
17
+ key: string;
18
+ }
19
+
20
+ /** Manual value scales by panel and side (`valueScaleSlot`). */
21
+ export type CompositeValueScales = Readonly<Record<string, CompositeManualValueScale>>;
22
+
23
+ export const NO_VALUE_SCALES: CompositeValueScales = Object.freeze({});
24
+
25
+ export function valueScaleSlot(panelId: string, side: CompositeAxisSide): string {
26
+ return `${panelId}\u0000${side}`;
27
+ }
28
+
29
+ /** Identifies what an axis plots, for `CompositeManualValueScale.key`. */
30
+ export function valueScaleKey(scale: PanelScale, axisSeries: readonly ResolvedSeries[]): string {
31
+ return [
32
+ scale,
33
+ ...axisSeries.map((entry) => [entry.id, entry.label, entry.unit, entry.listing?.symbol ?? ""].join("\u0001")),
34
+ ].join("\u0000");
35
+ }
36
+
37
+ /** Pixels of drag along an axis that stretch or squeeze it by a factor of e. */
38
+ const AXIS_DRAG_PIXELS_PER_E = 200;
39
+ /** The finest and coarsest a linear axis may get, against the size of the values it shows. */
40
+ const MIN_LINEAR_SPAN_RATIO = 1e-9;
41
+ const MAX_LINEAR_SPAN = 1e15;
42
+ /** The same for a log axis, in natural-log units. */
43
+ const MIN_LOG_SPAN = 1e-9;
44
+ const MAX_LOG_SPAN = 60;
45
+
46
+ /**
47
+ * How much a drag of `deltaPx` along an axis multiplies the span it shows.
48
+ * Down a value axis or right along the time axis shows more (a factor above
49
+ * one), the other way less, and the way back undoes it exactly.
50
+ */
51
+ export function resolveAxisDragSpanFactor(deltaPx: number): number {
52
+ return Number.isFinite(deltaPx) ? Math.exp(deltaPx / AXIS_DRAG_PIXELS_PER_E) : 1;
53
+ }
54
+
55
+ function toAxis(value: number, scale: PanelScale): number {
56
+ return scale === "log" ? Math.log(value) : value;
57
+ }
58
+
59
+ function fromAxis(value: number, scale: PanelScale): number {
60
+ return scale === "log" ? Math.exp(value) : value;
61
+ }
62
+
63
+ /** The range as top and bottom in the axis's own space: values, or their logs. */
64
+ function axisEnds(range: CompositeValueRange, scale: PanelScale): { top: number; bottom: number } | null {
65
+ if (scale === "log" && (range.min <= 0 || range.max <= 0)) return null;
66
+ const top = toAxis(range.max, scale);
67
+ const bottom = toAxis(range.min, scale);
68
+ return Number.isFinite(top) && Number.isFinite(bottom) && top > bottom ? { top, bottom } : null;
69
+ }
70
+
71
+ function rangeFromEnds(top: number, bottom: number, scale: PanelScale): CompositeValueRange {
72
+ return { min: fromAxis(bottom, scale), max: fromAxis(top, scale) };
73
+ }
74
+
75
+ /**
76
+ * The range after multiplying its span by `spanFactor` (above one shows more)
77
+ * around the value at `anchorRatio`, 0 the top of the panel and 1 the bottom,
78
+ * which stays where it is. A log axis stretches in its own, logarithmic space.
79
+ */
80
+ export function zoomValueRange(
81
+ range: CompositeValueRange,
82
+ scale: PanelScale,
83
+ spanFactor: number,
84
+ anchorRatio: number,
85
+ ): CompositeValueRange {
86
+ const ends = axisEnds(range, scale);
87
+ if (!ends || !(spanFactor > 0) || !Number.isFinite(spanFactor)) return range;
88
+ const ratio = clamp(Number.isFinite(anchorRatio) ? anchorRatio : 0.5, 0, 1);
89
+ const span = ends.top - ends.bottom;
90
+ const anchor = ends.top - span * ratio;
91
+ const nextSpan = scale === "log"
92
+ ? clamp(span * spanFactor, MIN_LOG_SPAN, MAX_LOG_SPAN)
93
+ : clamp(span * spanFactor, Math.max(Math.abs(anchor), Number.MIN_VALUE) * MIN_LINEAR_SPAN_RATIO, MAX_LINEAR_SPAN);
94
+ const top = anchor + nextSpan * ratio;
95
+ return rangeFromEnds(top, top - nextSpan, scale);
96
+ }
97
+
98
+ /**
99
+ * The range moved with a drag of `deltaRatio` of the panel's height, positive
100
+ * downward: what was under the pointer stays under it.
101
+ */
102
+ export function panValueRange(
103
+ range: CompositeValueRange,
104
+ scale: PanelScale,
105
+ deltaRatio: number,
106
+ ): CompositeValueRange {
107
+ const ends = axisEnds(range, scale);
108
+ if (!ends || !Number.isFinite(deltaRatio) || deltaRatio === 0) return range;
109
+ const shift = (ends.top - ends.bottom) * deltaRatio;
110
+ return rangeFromEnds(ends.top + shift, ends.bottom + shift, scale);
111
+ }
112
+
113
+ /** A manual range holds while some of the data is in it; pushed clear of the data it fits the data again. */
114
+ export function manualValueRangeApplies(
115
+ manual: CompositeValueRange,
116
+ data: CompositeValueRange,
117
+ scale: PanelScale,
118
+ ): boolean {
119
+ const ends = axisEnds(manual, scale);
120
+ return !!ends && manual.max > data.min && manual.min < data.max;
121
+ }
122
+
123
+ /**
124
+ * Keeps an end of a segment that leaves the band from `minY` to `maxY` on the
125
+ * band's edge, along the segment: what is drawn of it inside stays exact and
126
+ * nothing is drawn far outside. Null when it misses the band.
127
+ */
128
+ export function clipSegmentToBand(
129
+ x0: number,
130
+ y0: number,
131
+ x1: number,
132
+ y1: number,
133
+ minY: number,
134
+ maxY: number,
135
+ ): [number, number, number, number] | null {
136
+ if ((y0 < minY && y1 < minY) || (y0 > maxY && y1 > maxY)) return null;
137
+ if (y0 >= minY && y0 <= maxY && y1 >= minY && y1 <= maxY) return [x0, y0, x1, y1];
138
+ const at = (y: number) => {
139
+ const t = (y - y0) / (y1 - y0);
140
+ return x0 + (x1 - x0) * t;
141
+ };
142
+ let startX = x0;
143
+ let startY = y0;
144
+ let endX = x1;
145
+ let endY = y1;
146
+ if (startY < minY) { startX = at(minY); startY = minY; } else if (startY > maxY) { startX = at(maxY); startY = maxY; }
147
+ if (endY < minY) { endX = at(minY); endY = minY; } else if (endY > maxY) { endX = at(maxY); endY = maxY; }
148
+ return [startX, startY, endX, endY];
149
+ }
@@ -27,7 +27,8 @@ export function paintVolumeProfile(
27
27
  row.volume > (profile.rows[best]?.volume ?? -1) ? index : best
28
28
  ), 0);
29
29
  profile.rows.forEach((row, index) => {
30
- if (row.volume <= 0) return;
30
+ // Rows a hand-scaled axis leaves off the panel are not piled on its edge.
31
+ if (row.volume <= 0 || row.highRatio > 1 || row.lowRatio < 0) return;
31
32
  const top = Math.round(clamp(row.highRatio, 0, 1) * maxY);
32
33
  const edge = Math.round(clamp(row.lowRatio, 0, 1) * maxY);
33
34
  // A pixel between rows keeps tall bars apart; thin ones would vanish.
@@ -36,7 +37,8 @@ export function paintVolumeProfile(
36
37
  const opacity = index === pocRow ? POC_OPACITY : row.valueArea ? VALUE_AREA_OPACITY : OUTSIDE_OPACITY;
37
38
  fillRect(data, width, height, width - length, top, width - 1, bottom, color, opacity);
38
39
  });
39
- const y = Math.round(clamp(profile.pocRatio, 0, 1) * maxY);
40
+ if (profile.pocRatio < 0 || profile.pocRatio > 1) return;
41
+ const y = Math.round(profile.pocRatio * maxY);
40
42
  for (let x = 0; x < width; x += 5) {
41
43
  fillRect(data, width, height, x, y, Math.min(x + 1, width - 1), y, color, 0.7);
42
44
  }
@@ -57,13 +59,14 @@ export function writeVolumeProfileText(
57
59
  const volumes = new Array<number>(height).fill(0);
58
60
  const valueArea = new Array<boolean>(height).fill(false);
59
61
  for (const row of profile.rows) {
62
+ if (row.highRatio > 1 || row.lowRatio < 0) continue;
60
63
  const line = clamp(Math.round(((row.highRatio + row.lowRatio) / 2) * (height - 1)), 0, height - 1);
61
64
  volumes[line]! += row.volume;
62
65
  if (row.valueArea) valueArea[line] = true;
63
66
  }
64
67
  const peak = Math.max(...volumes);
65
68
  if (peak <= 0) return;
66
- const pocLine = clamp(Math.round(profile.pocRatio * (height - 1)), 0, height - 1);
69
+ const pocLine = profile.pocRatio < 0 || profile.pocRatio > 1 ? -1 : Math.round(profile.pocRatio * (height - 1));
67
70
  const maxLength = Math.max(1, Math.floor(width * PROFILE_WIDTH_RATIO));
68
71
  volumes.forEach((volume, line) => {
69
72
  if (volume <= 0) return;
@@ -21,6 +21,8 @@ export interface ChartMouseEvent {
21
21
  y: number;
22
22
  /** DOM target on the desktop host; absent in the terminal. */
23
23
  target?: { closest?: (selector: string) => unknown } | null;
24
+ /** The press's click count on the desktop host (2 on a double click); absent in the terminal. */
25
+ detail?: number;
24
26
  preciseX?: number;
25
27
  preciseY?: number;
26
28
  pixelX?: number;
@@ -6,6 +6,8 @@ export {
6
6
  fitChartTableColumns,
7
7
  } from "./layout";
8
8
  export type { ChartBandMode, ChartTableLayout } from "./layout";
9
+ export { ChartRead, useChartReadRows } from "./read";
10
+ export type { ChartReadProps } from "./read";
9
11
  export { useChartTableSelection } from "./selection";
10
12
  export type { ChartTableSelection } from "./selection";
11
13
  export { formatBpAxis, formatCompactAxis, formatPercentAxis, spanAxisFormatter, spanDigits } from "./axis";
@@ -0,0 +1,74 @@
1
+ import { useThemeColors } from "../../theme/theme-context";
2
+ import { Box, Text, useUiCapabilities } from "../../ui";
3
+ import { displayWidth, truncateToDisplayWidth } from "../../utils/format";
4
+ import { wrapTextLines } from "../../utils/text-wrap";
5
+ import { ClippedText } from "../ui/display";
6
+
7
+ /** The terminal wraps a read onto at most this many rows; a longer one ends in an ellipsis on the last. */
8
+ export const CHART_READ_MAX_ROWS = 3;
9
+ /** The read's inset on each side, as on the query bar and the legend above it. */
10
+ const READ_INSET = 1;
11
+
12
+ /**
13
+ * The terminal's lines for a read under a chart at a pane `width`: the whole
14
+ * sentence on one row when it fits, otherwise wrapped at words onto up to
15
+ * `CHART_READ_MAX_ROWS` rows. None when there is no read or no room for one.
16
+ */
17
+ export function chartReadLines(text: string | null | undefined, width: number): string[] {
18
+ const room = Math.floor(width) - 2 * READ_INSET;
19
+ const read = text?.trim();
20
+ if (!read || room <= 0) return [];
21
+ if (displayWidth(read) <= room) return [read];
22
+ const lines = wrapTextLines(read, room);
23
+ if (lines.length <= CHART_READ_MAX_ROWS) return lines;
24
+ return [
25
+ ...lines.slice(0, CHART_READ_MAX_ROWS - 1),
26
+ truncateToDisplayWidth(lines.slice(CHART_READ_MAX_ROWS - 1).join(" "), room),
27
+ ];
28
+ }
29
+
30
+ /**
31
+ * The rows the longest of these reads needs under a chart at a pane `width`
32
+ * (none when none has one). A pane puts it in `minRows` so the band does not
33
+ * flip between a chart and a strip as the selection moves between a short
34
+ * read and a long one. The desktop and the web cut a read by CSS on one row.
35
+ */
36
+ export function useChartReadRows(texts: ReadonlyArray<string | null | undefined>, width: number): number {
37
+ const { nativePaneChrome } = useUiCapabilities();
38
+ let rows = 0;
39
+ for (const text of texts) {
40
+ const lines = chartReadLines(text, width).length;
41
+ rows = Math.max(rows, nativePaneChrome ? Math.min(1, lines) : lines);
42
+ }
43
+ return rows;
44
+ }
45
+
46
+ export interface ChartReadProps {
47
+ /** The plain sentence worked out from the numbers, as the server wrote it. */
48
+ text: string | null | undefined;
49
+ /** The pane's width: the read sits one cell in from each edge. */
50
+ width: number;
51
+ }
52
+
53
+ /**
54
+ * The plain read under a chart's axis. In the terminal the whole sentence is
55
+ * wrapped onto up to `CHART_READ_MAX_ROWS` rows (take its rows from the chart
56
+ * with `useChartReadRows`); the desktop and the web keep one row and cut it
57
+ * by CSS where its box ends.
58
+ */
59
+ export function ChartRead({ text, width }: ChartReadProps) {
60
+ const colors = useThemeColors();
61
+ const { nativePaneChrome } = useUiCapabilities();
62
+ const lines = chartReadLines(text, width);
63
+ if (lines.length === 0) return null;
64
+ if (nativePaneChrome) {
65
+ return <Box height={1} paddingX={READ_INSET}><ClippedText fg={colors.textMuted} text={text!.trim()} width={width - 2 * READ_INSET} /></Box>;
66
+ }
67
+ return (
68
+ <Box flexDirection="column" height={lines.length} flexShrink={0}>
69
+ {lines.map((line, index) => (
70
+ <Box key={index} height={1} paddingX={READ_INSET}><Text fg={colors.textMuted}>{line}</Text></Box>
71
+ ))}
72
+ </Box>
73
+ );
74
+ }
@@ -1,6 +1,8 @@
1
1
  import type { AppState } from "../../../state/app/context";
2
2
  import type { TickerRecord } from "../../../types/ticker";
3
3
  import { splitSymbolArgs, splitSymbolWords, symbolInputKey, uniqueSymbols } from "../../../cli/symbol-args";
4
+ import { protectFigureCommas } from "../../../cli/symbol-cells";
5
+ import { readSymbolList } from "../../../cli/symbol-list";
4
6
  import { readNameEntries } from "../../../cli/name-entries";
5
7
  import {
6
8
  addSymbols,
@@ -42,17 +44,17 @@ export interface PastedSymbolList {
42
44
  }
43
45
 
44
46
  /**
45
- * The entries of text typed or pasted after `AW`, split as `gloomberb quote`
47
+ * The entries of text typed or pasted after `AW`, split as `gloom quote`
46
48
  * splits its arguments (`splitSymbolArgs`): on commas, semicolons, tabs and
47
49
  * lines when it has them, where an entry with spaces may be a company's name
48
- * or several symbols, else on spaces. Null for one word or none, which keep
49
- * the single add. Spaces alone also separate a company's name (`Palo Alto
50
- * Networks`), which is why `separated` says when the text left no doubt it is
51
- * a list.
50
+ * or several symbols, else on spaces. A decimal comma (`2.582,52`) splits
51
+ * nothing. Null for one word or none, which keep the single add. Spaces alone
52
+ * also separate a company's name (`Palo Alto Networks`), which is why
53
+ * `separated` says when the text left no doubt it is a list.
52
54
  */
53
55
  export function pastedSymbolList(raw: string | undefined): PastedSymbolList | null {
54
56
  if (!raw || splitSymbolWords([raw]).length < 2) return null;
55
- return { ...uniqueSymbols(splitSymbolArgs([raw])), separated: /[,;\t\r\n]/.test(raw) };
57
+ return { ...uniqueSymbols(splitSymbolArgs([raw])), separated: /[,;\t\r\n]/.test(protectFigureCommas(raw)) };
56
58
  }
57
59
 
58
60
  /**
@@ -86,30 +88,45 @@ function reasonLine(row: SymbolRow): string | null {
86
88
  if (row.hint && row.status === "added") return row.hint;
87
89
  // Another company had the symbol: say which, beside the listing added.
88
90
  if (row.changeNote && row.status === "added") return row.changeNote;
91
+ // Listed only abroad: the venue and currency it was added on.
92
+ if (row.abroad && row.status === "added") return row.abroad;
89
93
  if (row.readAs && (row.status === "added" || row.status === "already_listed")) return row.readAs;
90
94
  // Why the match was left out, and the symbol it trades as now when there is one.
91
95
  if (row.status === "needs_choice") return row.message ?? typed;
96
+ // Not a symbol, or not looked up: the summary names them, and the notice says what to do about the second.
92
97
  if (row.status !== "failed" && !(row.status === "not_found" && row.message && !NO_MATCH.test(row.message))) return null;
93
98
  const text = reason(row.message ?? "", typed);
94
99
  return text.includes(typed) ? text : `${typed}: ${text}`;
95
100
  }
96
101
 
102
+ /** Rows that did not join the watchlist and say why, which keep the report up longer. */
103
+ const UNRESOLVED = new Set<SymbolRow["status"]>(["not_found", "needs_choice", "failed", "not_a_symbol", "not_looked_up"]);
104
+
97
105
  /**
98
106
  * What a list add says, in the words the CLI's summary uses: the counts, the
99
107
  * symbols that found nothing or were not added, and under it the reason for
100
- * each that has one. Skipped symbols keep the report up longer.
108
+ * each that has one, what the reader left out (the prices beside the
109
+ * symbols, in one line), and one line for the symbols Gloom Cloud did not
110
+ * answer for. Skipped symbols keep the report up longer.
101
111
  */
102
112
  function describeListAdd(
103
113
  rows: readonly SymbolRow[],
104
114
  watchlistName: string,
105
115
  repeated: number,
116
+ notes: readonly string[] = [],
106
117
  ): { body: string; type: "success" | "info" | "error"; duration?: number } {
107
118
  const summary = `Watchlist "${watchlistName}": ${summarizeSymbolRows(rows, "add", repeated)}`;
108
119
  const reasons = rows.map(reasonLine).filter((line): line is string => !!line);
120
+ const unanswered = rows.filter((row) => row.status === "not_looked_up").length;
109
121
  const added = rows.some((row) => row.status === "added");
110
- const unresolved = rows.some((row) => row.status === "not_found" || row.status === "needs_choice" || row.status === "failed");
122
+ const unresolved = rows.some((row) => UNRESOLVED.has(row.status));
111
123
  return {
112
- body: [summary, ...reasons].join("\n"),
124
+ body: [
125
+ summary,
126
+ ...reasons,
127
+ ...notes,
128
+ ...unanswered > 0 ? [`Gloom Cloud did not answer for ${unanswered === 1 ? "one symbol" : `${unanswered} symbols`}; add ${unanswered === 1 ? "it" : "them"} again in a minute.`] : [],
129
+ ].join("\n"),
113
130
  type: added && !unresolved ? "success" : unresolved && !added ? "error" : "info",
114
131
  duration: unresolved ? SKIPPED_REPORT_MS : undefined,
115
132
  };
@@ -118,12 +135,14 @@ function describeListAdd(
118
135
  /**
119
136
  * A symbol typed to add on its own that a pasted list would leave for a
120
137
  * choice (`typedSymbolChoice`: its company moved or merged away, the match is
121
- * abroad or stopped trading) is not added either. The notice says why, and
122
- * what to add instead or to keep the match. Resolves true when it said so.
138
+ * abroad while the symbol names a US listing, or it stopped trading) is not
139
+ * added either. The notice says why, and what to add instead or to keep the
140
+ * match; `refused` says it did. One listed only abroad is added, and `abroad`
141
+ * is the line naming its venue and currency, for the add to say.
123
142
  */
124
- export async function refuseTypedChoice(rawInput: string, deps: SharedWorkflowDeps, notify: Notify): Promise<boolean> {
143
+ export async function refuseTypedChoice(rawInput: string, deps: SharedWorkflowDeps, notify: Notify): Promise<{ refused: boolean; abroad: string | null }> {
125
144
  const row = await typedSymbolChoice(rawInput, deps.tickerRepository, deps.dataProvider);
126
- if (!row) return false;
145
+ if (row?.status !== "needs_choice") return { refused: false, abroad: row?.abroad ?? null };
127
146
  const message = row.message ?? symbolInputKey(row.input);
128
147
  const offers = [
129
148
  ...row.tradesAs ? [`${row.tradesAs} for what it trades as now`] : [],
@@ -131,12 +150,12 @@ export async function refuseTypedChoice(rawInput: string, deps: SharedWorkflowDe
131
150
  ];
132
151
  notify([/[.!?]$/.test(message) ? message : `${message}.`, ...offers.length > 0 ? [`Add ${offers.join(", or ")}.`] : []].join("\n"),
133
152
  { type: "error", duration: SKIPPED_REPORT_MS });
134
- return true;
153
+ return { refused: true, abroad: null };
135
154
  }
136
155
 
137
156
  /**
138
157
  * Adds every symbol of a pasted list to a watchlist in one step. Each symbol
139
- * resolves as `gloomberb watchlist add` resolves it (Gloom Cloud search and
158
+ * resolves as `gloom watchlist add` resolves it (Gloom Cloud search and
140
159
  * quote, the venue its own quote is on), except that a symbol several listings
141
160
  * carry is never given the first: it is left out and named, for the single add
142
161
  * to ask which. One that is unknown or already listed does not stop the rest.
@@ -159,10 +178,13 @@ export async function addPastedListToWatchlist(options: {
159
178
  const deps = options.buildWorkflowDeps();
160
179
  // Spaces alone also separate the words of a name, which belongs to search.
161
180
  if (!list.separated && await namesOneCompany(list.symbols, deps.dataProvider)) return false;
162
- // An entry with spaces is a company's name search finds, or the symbols it holds.
163
- const read = uniqueSymbols(await readNameEntries(list.symbols, deps.dataProvider));
181
+ // Read as `watchlist add` reads a list: an entry with spaces is a company's name search finds, or the symbols it
182
+ // holds, and a price beside a symbol (`ED 2.582,52`) is left out and named.
183
+ const read = await readSymbolList({
184
+ args: [options.rawInput], stdinPiped: false, readEntries: (entries) => readNameEntries(entries, deps.dataProvider),
185
+ });
164
186
  const symbols = read.symbols;
165
- const repeated = list.repeated + read.repeated;
187
+ const repeated = read.repeated;
166
188
  const state = options.getState();
167
189
  const known = options.explicitTargetId && state.config.watchlists.some((entry) => entry.id === options.explicitTargetId)
168
190
  ? options.explicitTargetId
@@ -233,7 +255,7 @@ export async function addPastedListToWatchlist(options: {
233
255
  recordAttention(publicTickerKey(ticker.metadata.ticker, ticker.metadata.exchange), "watchlist_add");
234
256
  }
235
257
  }
236
- const report = describeListAdd(rows, watchlistName, repeated);
258
+ const report = describeListAdd(rows, watchlistName, repeated, read.notes);
237
259
  notify(report.body, { type: report.type, duration: report.duration });
238
260
  options.closeAll({ revertThemePreview: false });
239
261
  return true;
@@ -62,8 +62,10 @@ export async function executeCollectionCommandAction(options: {
62
62
  });
63
63
  if (list?.separated && await addList(list)) return;
64
64
  // One typed symbol is decided as a symbol of a pasted list is: a match the list would leave for a choice is not added.
65
- if (action === "add" && !options.selectedTicker && !list && options.rawInput?.trim()
66
- && await refuseTypedChoice(options.rawInput, deps, options.notify)) {
65
+ const typed = action === "add" && !options.selectedTicker && !list && options.rawInput?.trim()
66
+ ? await refuseTypedChoice(options.rawInput, deps, options.notify)
67
+ : null;
68
+ if (typed?.refused) {
67
69
  options.closeAll({ revertThemePreview: false });
68
70
  return;
69
71
  }
@@ -246,7 +248,11 @@ export async function executeCollectionCommandAction(options: {
246
248
  `${action === "add" ? "Added" : "Removed"} ${resolvedTicker.symbol} ${action === "add" ? "to" : "from"} "${targetName}".`,
247
249
  { type: "success" },
248
250
  );
249
- if (action === "add") notifyTickerChange(deps.dataProvider, resolvedTicker.ticker, options.notify);
251
+ if (action === "add") {
252
+ // Listed only abroad: the venue and currency it went to, as `watchlist add` says it.
253
+ if (typed?.abroad) options.notify(typed.abroad, { type: "info" });
254
+ notifyTickerChange(deps.dataProvider, resolvedTicker.ticker, options.notify);
255
+ }
250
256
  } else {
251
257
  options.notify(
252
258
  action === "add"
@@ -220,7 +220,7 @@ export function runDirectCommandAction(options: {
220
220
  title: "Reset All Data",
221
221
  body: [
222
222
  "This will permanently delete all portfolios, tickers, notes, broker credentials, and settings.",
223
- "Gloomberb will quit and show the setup wizard on next launch.",
223
+ "Gloom will quit and show the setup wizard on next launch.",
224
224
  ],
225
225
  confirmLabel: "Reset Everything",
226
226
  cancelLabel: "Back",
@@ -81,12 +81,12 @@ export function useCommandBarDirectCommandRuntime({
81
81
  // A confirm it opens (Reset All Data) runs after the bar closed.
82
82
  const getState = useAppGetState();
83
83
  const rendererHost = useRendererHost();
84
- const runSecurityDescriptionShortcut = useCallback(async (query?: string) => {
84
+ const runSecurityDescriptionShortcut = useCallback(async (query?: string, options?: { forceNewPane?: boolean }) => {
85
85
  const trimmed = query?.trim() || "";
86
86
  if (!trimmed) {
87
87
  const inferred = normalizeTickerInput(activeTickerSymbol, query);
88
88
  if (inferred) {
89
- focusTicker(inferred);
89
+ focusTicker(inferred, options);
90
90
  closeAll({ revertThemePreview: false });
91
91
  return;
92
92
  }
@@ -103,6 +103,7 @@ export function useCommandBarDirectCommandRuntime({
103
103
  );
104
104
  if (resolvedTicker) {
105
105
  focusTicker(resolvedTicker.symbol, {
106
+ ...options,
106
107
  instrument: resolvedTicker.instrument,
107
108
  listing: resolvedTicker.listing,
108
109
  });