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
@@ -10,6 +10,9 @@ import {
10
10
  } from "../../../ui";
11
11
  import { colors as themeColors } from "../../../theme/colors";
12
12
  import { consumeChartMouseEvent, getGlobalMouseX, getLocalPlotPointer, type ChartMouseEvent } from "../core/pointer";
13
+ import { Button } from "../../ui/button";
14
+ import { clamp } from "../../../utils/math";
15
+ import { panValueRange, resolveAxisDragSpanFactor, zoomValueRange, type CompositeValueRange } from "./value-scale";
13
16
  import { useStaticChartBitmapSize } from "./bitmap";
14
17
  import { useMeasuredCells } from "../../../ui/measured-cells";
15
18
  import { PriceAxisLabels, placeAxisTicks } from "./price-axis-labels";
@@ -57,16 +60,21 @@ import {
57
60
  import { compositeRightOffsetRatio, unprojectCompositeTimestamp } from "./time-scale";
58
61
  import { resolveCompositeCursorDate, unprojectCompositeValue } from "./scene";
59
62
  import { compositeAxisTickLabels, renderCompositeAxisText, renderCompositePanelText } from "./text-renderer";
60
- import type { CompositeChartColors, CompositeChartScene, CompositePanelScene } from "./types";
63
+ import type { CompositeAxisSide, CompositeChartColors, CompositeChartScene, CompositePanelScene } from "./types";
61
64
  import { useCompositePanelBitmap } from "./panel-bitmap";
62
65
  import { nextDrawingId, nextLevelId } from "./drawing-store";
63
66
  import {
67
+ AXIS_DOUBLE_PRESS_MS,
68
+ PLOT_DOUBLE_CLICK_MS,
64
69
  COMPOSITE_PANEL_ROLE,
65
70
  isVerticalWheelDirection,
71
+ manualValueAxes,
66
72
  startPanGesture,
67
73
  releaseEditableFocus,
68
74
  type PanGesture,
75
+ type PendingAxisWheel,
69
76
  type PendingWheel,
77
+ type ValueAxisStart,
70
78
  } from "./panel-gestures";
71
79
  import { resolvePanelCrosshair, axisLabelRows, cursorAxisLabel, resolveSeriesCursorYRatio, resolveSeriesAxisTags } from "./panel-labels";
72
80
  import type { KeyboardToolDrag } from "./use-composite-chart-keyboard";
@@ -78,6 +86,11 @@ const webFrame = globalThis as typeof globalThis & {
78
86
 
79
87
  const NO_LEVELS: readonly ProjectedLevel[] = [];
80
88
 
89
+ /** The pointer's height in rows, to a fraction of one where the host reports it. */
90
+ function pointerRow(event: ChartMouseEvent): number {
91
+ return typeof event.preciseY === "number" ? event.preciseY : event.y;
92
+ }
93
+
81
94
  interface CompositePanelSurfaceProps {
82
95
  panel: CompositePanelScene;
83
96
  scene: CompositeChartScene;
@@ -121,13 +134,41 @@ interface CompositePanelSurfaceProps {
121
134
  showTextFallback: boolean;
122
135
  /** Set while the owner is picking a bar: a press picks instead of panning. */
123
136
  onPickTime?: (date: Date) => void;
137
+ /** Set while the owner is picking a price on the levels' series: a press picks the one under it. */
138
+ onPickPrice?: (value: number) => void;
124
139
  /** The chart's levels when they draw on this panel. */
125
140
  levels: CompositeChartLevels | null;
126
141
  selectedLevelId: string | null;
127
142
  onSelectLevel: (id: string | null) => void;
143
+ /** The value axes stretch and squeeze under a drag or the wheel, and a double click fits them again. */
144
+ valueScalable: boolean;
145
+ onSetValueScale: (panelId: string, side: CompositeAxisSide, key: string, range: CompositeValueRange) => void;
146
+ onResetValueScale: (panelId: string) => void;
147
+ /** The line above this panel, which a drag moves (desktop and web): null for the top panel. */
148
+ dividerAbove?: { active: boolean; gestures: PanelDividerGestures } | null;
149
+ /** A double click on bare plot gives this panel the whole chart, or gives the others back. */
150
+ onToggleMaximized?: () => void;
151
+ }
152
+
153
+ interface PanelDividerGestures {
154
+ onMouseDown: (event: ChartMouseEvent) => void;
155
+ onMouseDrag: (event: ChartMouseEvent) => void;
156
+ onMouseUp: (event: ChartMouseEvent) => void;
157
+ onMouseDragEnd: (event: ChartMouseEvent) => void;
128
158
  }
129
159
 
130
160
  const DESKTOP_PLOT_STYLE = { flex: "1 1 0px", width: "auto", minWidth: 0, height: "auto", alignSelf: "stretch" } as const;
161
+ /** Over a level that drags, or while one does: it moves up and down only. */
162
+ const DESKTOP_PLOT_LEVEL_STYLE = { ...DESKTOP_PLOT_STYLE, cursor: "ns-resize" } as const;
163
+ const DESKTOP_PLOT_PICK_STYLE = { ...DESKTOP_PLOT_STYLE, cursor: "crosshair" } as const;
164
+ /** The grab strip over the line between two panels: the line and a few pixels either side of it. */
165
+ const PANEL_DIVIDER_STYLE = {
166
+ left: 0,
167
+ right: 0,
168
+ width: "auto",
169
+ top: "calc(-1 * var(--gloom-space-xs))",
170
+ height: "calc(2 * var(--gloom-space-xs) + 1px)",
171
+ } as const;
131
172
 
132
173
  export function CompositePanelSurface({
133
174
  panel,
@@ -162,9 +203,15 @@ export function CompositePanelSurface({
162
203
  onPointerPress,
163
204
  showTextFallback,
164
205
  onPickTime,
206
+ onPickPrice,
165
207
  levels,
166
208
  selectedLevelId,
167
209
  onSelectLevel,
210
+ valueScalable,
211
+ onSetValueScale,
212
+ onResetValueScale,
213
+ dividerAbove = null,
214
+ onToggleMaximized,
168
215
  }: CompositePanelSurfaceProps) {
169
216
  const isDesktopWeb = useUiCapabilities().nativePaneChrome === true;
170
217
  const { cellHeightPx = 18, cellWidthPx = 8, fractionalViewport = false } = useUiCapabilities();
@@ -186,6 +233,8 @@ export function CompositePanelSurface({
186
233
  const activeCursorYRatio = scene.cursorXRatio === null
187
234
  ? null
188
235
  : heldCursorYRatio ?? seriesCursorYRatio;
236
+ // The last press on bare plot, for a double press where the host does not count clicks.
237
+ const lastPlotPressRef = useRef<{ at: number; x: number; y: number } | null>(null);
189
238
  const dragRef = useRef<
190
239
  | PanGesture
191
240
  | {
@@ -302,6 +351,13 @@ export function CompositePanelSurface({
302
351
  () => levels && levelDomain ? projectLevels(levels.items, levelDomain, levelDraft) : NO_LEVELS,
303
352
  [levelDomain, levelDraft, levels],
304
353
  );
354
+ // Over a line a plain drag moves, and while one moves, the pointer says it goes up and down.
355
+ const levelGrab = useMemo(() => {
356
+ if (levelDraft) return true;
357
+ if (!levels?.onEdit || cursorYRatio === null || onPickTime || onPickPrice || (armedTool && armedTool !== "level")) return false;
358
+ const hit = hitTestLevel(projectedLevels, cursorYRatio, levelGrabRatio(panel.height));
359
+ return !!hit?.editable && !!hit.draggable;
360
+ }, [armedTool, cursorYRatio, levelDraft, levels?.onEdit, onPickPrice, onPickTime, panel.height, projectedLevels]);
305
361
  // Drawings project through the time scale alone: the crosshair moving,
306
362
  // here or on a linked chart, must not repaint the plot, which the terminal's
307
363
  // kitty surface would upload whole again.
@@ -569,6 +625,13 @@ export function CompositePanelSurface({
569
625
  if (date) onPickTime(date);
570
626
  return;
571
627
  }
628
+ if (onPickPrice) {
629
+ // Only the levels' own panel has their prices; a press elsewhere picks nothing.
630
+ const ratios = pointerRatios(event);
631
+ const value = ratios && levelDomain ? unprojectCompositeValue(ratios.yRatio, levelDomain) : null;
632
+ if (value !== null && levelDomain) onPickPrice(roundLevelValue(value, levelDomain));
633
+ return;
634
+ }
572
635
  // A keyboard-armed tool covers terminals that never forward modifier drags.
573
636
  const tool = resolveChartToolKind(event.modifiers) ?? armedTool;
574
637
  if (tool === "level" && levels?.onEdit && levelDomain) {
@@ -626,6 +689,7 @@ export function CompositePanelSurface({
626
689
  // With no tool in hand, a press on a drawing or a level picks it so Backspace
627
690
  // or Delete can remove it; the press still pans, and one on bare plot lets go.
628
691
  const ratios = pointerRatios(event);
692
+ let bare = true;
629
693
  if (ratios) {
630
694
  const drawingHit = drawings.length > 0 ? hitTestDrawings(drawings, scene, panel, ratios, plotAspect) : null;
631
695
  const levelHit = !drawingHit && levels?.onEdit && levelDomain
@@ -633,15 +697,46 @@ export function CompositePanelSurface({
633
697
  : null;
634
698
  onSelectDrawing(drawingHit ? drawingHit.drawing.id : null);
635
699
  onSelectLevel(levelHit?.editable ? levelHit.id : null);
700
+ bare = !drawingHit && !levelHit;
701
+ // An order's line drags without the level tool; other levels keep the press for panning.
702
+ if (levelHit?.editable && levelHit.draggable) {
703
+ dragRef.current = { kind: "level-move", id: levelHit.id };
704
+ lastPlotPressRef.current = null;
705
+ updateCursor(event);
706
+ return;
707
+ }
708
+ }
709
+ // A double click on bare plot gives the panel the whole chart, or the
710
+ // others back (the terminal counts two presses on one spot). Its first
711
+ // press must have landed here too: a double click on a button that goes
712
+ // away under it (All panels) ends on this plot, and is not one of its.
713
+ if (!bare) lastPlotPressRef.current = null;
714
+ if (onToggleMaximized && bare) {
715
+ const now = Date.now();
716
+ const last = lastPlotPressRef.current;
717
+ const double = typeof event.detail === "number"
718
+ ? event.detail >= 2 && !!last && now - last.at < PLOT_DOUBLE_CLICK_MS
719
+ : !!last && now - last.at < AXIS_DOUBLE_PRESS_MS && Math.abs(last.x - event.x) <= 1 && Math.abs(last.y - event.y) <= 1;
720
+ lastPlotPressRef.current = double ? null : { at: now, x: event.x, y: event.y };
721
+ if (double) {
722
+ dragRef.current = null;
723
+ onToggleMaximized();
724
+ return;
725
+ }
636
726
  }
637
727
  if (!updateCursor(event)) return;
638
- dragRef.current = startPanGesture(
639
- frame,
640
- viewport,
641
- plotSize.width,
642
- getGlobalMouseX(event, renderer),
643
- plotSpanFactor,
644
- );
728
+ const values = manualValueAxes(panel);
729
+ dragRef.current = {
730
+ ...startPanGesture(
731
+ frame,
732
+ viewport,
733
+ plotSize.width,
734
+ getGlobalMouseX(event, renderer),
735
+ plotSpanFactor,
736
+ ),
737
+ // A panel scaled by hand moves up and down with the drag as well.
738
+ ...(values.length > 0 ? { startCellY: pointerRow(event), values } : {}),
739
+ };
645
740
  }, [
646
741
  armedTool,
647
742
  drawings,
@@ -650,6 +745,7 @@ export function CompositePanelSurface({
650
745
  levels,
651
746
  onActivate,
652
747
  onPickTime,
748
+ onPickPrice,
653
749
  onPointerPress,
654
750
  onSelectDrawing,
655
751
  onSelectLevel,
@@ -665,6 +761,7 @@ export function CompositePanelSurface({
665
761
  scene,
666
762
  updateCursor,
667
763
  viewport,
764
+ onToggleMaximized,
668
765
  ]);
669
766
  const pressCursor = useCallback((event: ChartMouseEvent) => {
670
767
  onActivate?.();
@@ -678,7 +775,11 @@ export function CompositePanelSurface({
678
775
  if (drag.kind === "level-move") {
679
776
  const ratios = pointerRatios(event);
680
777
  const value = ratios && levelDomain ? unprojectCompositeValue(ratios.yRatio, levelDomain) : null;
681
- if (value !== null && levelDomain) setLevelDraft({ id: drag.id, value: roundLevelValue(value, levelDomain) });
778
+ if (value === null || !levelDomain) return;
779
+ const draft = { id: drag.id, value: roundLevelValue(value, levelDomain) };
780
+ // The release reads the ref, and a quick drag lets go before the next render.
781
+ levelDraftRef.current = draft;
782
+ setLevelDraft(draft);
682
783
  return;
683
784
  }
684
785
  if (drag.kind === "edit") {
@@ -716,11 +817,19 @@ export function CompositePanelSurface({
716
817
  (globalX - drag.startGlobalX) * drag.positionsPerCell,
717
818
  { frame: drag.frame, from: drag.startViewport },
718
819
  );
820
+ if (drag.values && drag.startCellY !== undefined) {
821
+ const deltaRatio = (pointerRow(event) - drag.startCellY) / Math.max(plotSize.height, 1);
822
+ for (const axis of drag.values) {
823
+ onSetValueScale(panel.id, axis.side, axis.key, panValueRange(axis.start, axis.scale, deltaRatio));
824
+ }
825
+ }
719
826
  }, [
720
827
  frame,
721
828
  levelDomain,
722
829
  onEditDrawing,
723
830
  onPanViewport,
831
+ onSetValueScale,
832
+ plotSize.height,
724
833
  panel,
725
834
  plotSize.width,
726
835
  plotSpanFactor,
@@ -849,6 +958,136 @@ export function CompositePanelSurface({
849
958
  updateCursor,
850
959
  ]);
851
960
 
961
+ // A value axis under the pointer: a drag stretches (up) or squeezes (down)
962
+ // it around its middle, the wheel around the pointer, and a double click
963
+ // fits it to the data again. Read through refs, so the handlers stay put.
964
+ const axisGestureRef = useRef<(ValueAxisStart & { startRow: number; moved: boolean }) | null>(null);
965
+ const lastAxisPressRef = useRef<{ side: CompositeAxisSide; at: number } | null>(null);
966
+ const latestAxesRef = useRef({ panel, onSetValueScale, onResetValueScale, onActivate });
967
+ latestAxesRef.current = { panel, onSetValueScale, onResetValueScale, onActivate };
968
+ /** The pointer's height down the panel, 0 at the top and 1 at the bottom. */
969
+ const axisPointerRatio = useCallback((event: ChartMouseEvent): number => {
970
+ const plot = plotRef.current as unknown as { absoluteY?: number; y?: number; height?: number } | null;
971
+ const top = plot?.absoluteY ?? plot?.y;
972
+ const height = plot?.height ?? 0;
973
+ if (top === undefined || height <= 1) return 0.5;
974
+ return clamp((pointerRow(event) - top) / (fractionalViewport ? height : height - 1), 0, 1);
975
+ }, [fractionalViewport]);
976
+ const pressAxis = useCallback((side: CompositeAxisSide, event: ChartMouseEvent) => {
977
+ const latest = latestAxesRef.current;
978
+ const domain = latest.panel.axes[side];
979
+ if (!domain?.scaleKey) return;
980
+ latest.onActivate?.();
981
+ consumeChartMouseEvent(event);
982
+ // The desktop counts clicks; the terminal has two presses close together.
983
+ const now = Date.now();
984
+ const last = lastAxisPressRef.current;
985
+ const double = typeof event.detail === "number"
986
+ ? event.detail >= 2
987
+ : !!last && last.side === side && now - last.at < AXIS_DOUBLE_PRESS_MS;
988
+ if (double) {
989
+ lastAxisPressRef.current = null;
990
+ axisGestureRef.current = null;
991
+ latest.onResetValueScale(latest.panel.id);
992
+ return;
993
+ }
994
+ lastAxisPressRef.current = { side, at: now };
995
+ axisGestureRef.current = {
996
+ side,
997
+ key: domain.scaleKey,
998
+ scale: domain.scale,
999
+ start: { min: domain.min, max: domain.max },
1000
+ startRow: pointerRow(event),
1001
+ moved: false,
1002
+ };
1003
+ }, []);
1004
+ const dragAxis = useCallback((event: ChartMouseEvent) => {
1005
+ const gesture = axisGestureRef.current;
1006
+ if (!gesture) return;
1007
+ consumeChartMouseEvent(event);
1008
+ const deltaPx = (pointerRow(event) - gesture.startRow) * cellHeightPx;
1009
+ if (!gesture.moved && Math.abs(deltaPx) < 1) return;
1010
+ // A drag is not the first half of a double click.
1011
+ gesture.moved = true;
1012
+ lastAxisPressRef.current = null;
1013
+ const latest = latestAxesRef.current;
1014
+ latest.onSetValueScale(
1015
+ latest.panel.id,
1016
+ gesture.side,
1017
+ gesture.key,
1018
+ zoomValueRange(gesture.start, gesture.scale, resolveAxisDragSpanFactor(deltaPx), 0.5),
1019
+ );
1020
+ }, [cellHeightPx]);
1021
+ const releaseAxis = useCallback(() => {
1022
+ axisGestureRef.current = null;
1023
+ }, []);
1024
+ const pendingAxisWheelRef = useRef<PendingAxisWheel | null>(null);
1025
+ const axisWheelFrameRef = useRef<number | null>(null);
1026
+ const flushAxisWheel = useCallback(() => {
1027
+ axisWheelFrameRef.current = null;
1028
+ const pending = pendingAxisWheelRef.current;
1029
+ pendingAxisWheelRef.current = null;
1030
+ const latest = latestAxesRef.current;
1031
+ const domain = pending ? latest.panel.axes[pending.side] : undefined;
1032
+ if (!pending || !domain?.scaleKey || pending.spanLog === 0) return;
1033
+ latest.onSetValueScale(
1034
+ latest.panel.id,
1035
+ pending.side,
1036
+ domain.scaleKey,
1037
+ zoomValueRange({ min: domain.min, max: domain.max }, domain.scale, Math.exp(pending.spanLog), pending.anchorRatio),
1038
+ );
1039
+ }, []);
1040
+ useEffect(() => () => {
1041
+ pendingAxisWheelRef.current = null;
1042
+ if (axisWheelFrameRef.current !== null) {
1043
+ webFrame.cancelAnimationFrame?.(axisWheelFrameRef.current);
1044
+ axisWheelFrameRef.current = null;
1045
+ }
1046
+ }, []);
1047
+ const wheelAxis = useCallback((side: CompositeAxisSide, event: ChartMouseEvent) => {
1048
+ const scroll = event.scroll;
1049
+ if (!scroll || !latestAxesRef.current.panel.axes[side]?.scaleKey) return;
1050
+ latestAxesRef.current.onActivate?.();
1051
+ consumeChartMouseEvent(event);
1052
+ if (!isVerticalWheelDirection(scroll.direction)) return;
1053
+ const pending = pendingAxisWheelRef.current?.side === side
1054
+ ? pendingAxisWheelRef.current
1055
+ : { side, spanLog: 0, anchorRatio: 0.5 };
1056
+ // Up stretches, as Ctrl and the wheel zoom the plot in.
1057
+ pending.spanLog -= Math.log(resolveCompositeWheelZoom(scroll));
1058
+ pending.anchorRatio = axisPointerRatio(event);
1059
+ pendingAxisWheelRef.current = pending;
1060
+ if (!isDesktopWeb || typeof webFrame.requestAnimationFrame !== "function") {
1061
+ flushAxisWheel();
1062
+ return;
1063
+ }
1064
+ if (axisWheelFrameRef.current === null) {
1065
+ axisWheelFrameRef.current = webFrame.requestAnimationFrame(flushAxisWheel);
1066
+ }
1067
+ }, [axisPointerRatio, flushAxisWheel, isDesktopWeb]);
1068
+ const leftAxisGestures = useMemo(() => valueScalable ? {
1069
+ onMouseDown: (event: ChartMouseEvent) => pressAxis("left", event),
1070
+ onMouseDrag: dragAxis,
1071
+ onMouseUp: releaseAxis,
1072
+ onMouseDragEnd: releaseAxis,
1073
+ onMouseScroll: (event: ChartMouseEvent) => wheelAxis("left", event),
1074
+ } : undefined, [dragAxis, pressAxis, releaseAxis, valueScalable, wheelAxis]);
1075
+ const rightAxisGestures = useMemo(() => valueScalable ? {
1076
+ onMouseDown: (event: ChartMouseEvent) => pressAxis("right", event),
1077
+ onMouseDrag: dragAxis,
1078
+ onMouseUp: releaseAxis,
1079
+ onMouseDragEnd: releaseAxis,
1080
+ onMouseScroll: (event: ChartMouseEvent) => wheelAxis("right", event),
1081
+ } : undefined, [dragAxis, pressAxis, releaseAxis, valueScalable, wheelAxis]);
1082
+ // While the panel is scaled by hand, the foot of the axis scaled says so
1083
+ // and is the way back.
1084
+ const manuallyScaled = !!panel.axes.left?.manual || !!panel.axes.right?.manual;
1085
+ const manualSide: CompositeAxisSide | null = !valueScalable || !manuallyScaled ? null
1086
+ : panel.axes.right?.manual && rightAxisWidth > 0 ? "right"
1087
+ : panel.axes.left?.manual && leftAxisWidth > 0 ? "left"
1088
+ : rightAxisWidth > 0 ? "right" : leftAxisWidth > 0 ? "left" : null;
1089
+ const manualLabel = (manualSide === "left" ? leftAxisWidth : rightAxisWidth) >= 4 ? "Auto" : "A";
1090
+
852
1091
  return (
853
1092
  <Box
854
1093
  flexDirection="row"
@@ -860,6 +1099,23 @@ export function CompositePanelSurface({
860
1099
  // follows it by CSS. At rest, the size the cells give it.
861
1100
  style={isDesktopWeb ? { width: "100%", flex: `${panel.height} 1 calc(${panel.height} * var(--cell-h))`, height: "auto", minHeight: 0 } : undefined}
862
1101
  >
1102
+ {dividerAbove && isDesktopWeb ? (
1103
+ // A line too thin to grab, so the handle straddles it, as a pane
1104
+ // sidebar's does; it draws only while the pointer is on it.
1105
+ <Box
1106
+ position="absolute"
1107
+ left={0}
1108
+ top={0}
1109
+ height={1}
1110
+ zIndex={29}
1111
+ style={PANEL_DIVIDER_STYLE}
1112
+ {...dividerAbove.gestures}
1113
+ title="Drag to resize the panels, double-click for the default split"
1114
+ data-gloom-interactive="true"
1115
+ data-gloom-role="composite-chart-panel-divider"
1116
+ data-active={dividerAbove.active ? "true" : undefined}
1117
+ />
1118
+ ) : null}
863
1119
  {measureReadout ? (
864
1120
  <Box
865
1121
  position="absolute"
@@ -900,6 +1156,8 @@ export function CompositePanelSurface({
900
1156
  extraMarkers={leftAxisMarkers}
901
1157
  seriesTags={isDesktopWeb ? seriesAxisTags.filter((tag) => tag.side === "left") : undefined}
902
1158
  measuredPixelHeight={plotSize.height * cellHeightPx}
1159
+ gestures={leftAxisGestures}
1160
+ footButton={manualSide === "left"}
903
1161
  />
904
1162
  <Box width={axisGap} />
905
1163
  </>
@@ -910,7 +1168,7 @@ export function CompositePanelSurface({
910
1168
  width={plotSize.width}
911
1169
  height={plotSize.height}
912
1170
  // Desktop: the width the axes leave, and the row's height.
913
- style={isDesktopWeb ? DESKTOP_PLOT_STYLE : undefined}
1171
+ style={isDesktopWeb ? levelGrab ? DESKTOP_PLOT_LEVEL_STYLE : onPickPrice ? DESKTOP_PLOT_PICK_STYLE : DESKTOP_PLOT_STYLE : undefined}
914
1172
  flexDirection="column"
915
1173
  bitmaps={bitmapLayers}
916
1174
  crosshair={crosshair}
@@ -922,11 +1180,12 @@ export function CompositePanelSurface({
922
1180
  onMouseDragEnd={interactive && navigable ? releasePlot : undefined}
923
1181
  onMouseScroll={interactive && navigable ? panFromWheel : undefined}
924
1182
  onMouseOut={interactive ? clearCursor : undefined}
925
- cursor={interactive ? toolDrag || !navigable || onPickTime ? "crosshair" : "grab" : undefined}
1183
+ cursor={interactive ? levelGrab ? "ns-resize" : toolDrag || !navigable || onPickTime || onPickPrice ? "crosshair" : "grab" : undefined}
926
1184
  data-gloom-interactive={interactive ? "true" : undefined}
927
1185
  data-gloom-role={COMPOSITE_PANEL_ROLE}
928
1186
  data-gloom-remote-kind={remoteKind}
929
1187
  data-gloom-label={panel.label ?? panel.id}
1188
+ data-gloom-value-scale={manuallyScaled ? "manual" : undefined}
930
1189
  >
931
1190
  {textLines.map((line, index) => <Text key={index} fg={colors.text}>{line}</Text>)}
932
1191
  </ChartSurface>
@@ -970,9 +1229,44 @@ export function CompositePanelSurface({
970
1229
  extraMarkers={rightAxisMarkers}
971
1230
  seriesTags={isDesktopWeb ? seriesAxisTags.filter((tag) => tag.side === "right") : undefined}
972
1231
  measuredPixelHeight={plotSize.height * cellHeightPx}
1232
+ gestures={rightAxisGestures}
1233
+ footButton={manualSide === "right"}
973
1234
  />
974
1235
  </>
975
1236
  ) : null}
1237
+ {manualSide ? (
1238
+ <Box
1239
+ position="absolute"
1240
+ left={manualSide === "left"
1241
+ ? 0
1242
+ : leftAxisWidth + (leftAxisWidth ? axisGap : 0) + plotWidth + axisGap + Math.max(0, rightAxisWidth - manualLabel.length)}
1243
+ top={Math.max(0, panel.height - 1)}
1244
+ width={manualLabel.length}
1245
+ height={1}
1246
+ zIndex={26}
1247
+ style={isDesktopWeb
1248
+ ? {
1249
+ left: manualSide === "left" ? 0 : "auto",
1250
+ right: manualSide === "right" ? 0 : "auto",
1251
+ top: "auto",
1252
+ bottom: "var(--gloom-space-xs)",
1253
+ width: "auto",
1254
+ height: "auto",
1255
+ }
1256
+ : undefined}
1257
+ data-gloom-role="composite-chart-value-scale"
1258
+ >
1259
+ <Button
1260
+ label="Auto Scale"
1261
+ displayLabel={manualLabel}
1262
+ title="Values scaled by hand. Fit them to the data again (or double-click the axis)."
1263
+ variant="secondary"
1264
+ compact
1265
+ stopPropagation
1266
+ onPress={() => onResetValueScale(panel.id)}
1267
+ />
1268
+ </Box>
1269
+ ) : null}
976
1270
  </Box>
977
1271
  );
978
1272
  }
@@ -4,6 +4,7 @@ import { colors } from "../../../theme/colors";
4
4
  import { clamp } from "../../../utils/math";
5
5
  import type { SeriesAxisTag } from "./panel-labels";
6
6
  import { placeSeriesAxisTags, SeriesAxisTags } from "./series-axis-tags";
7
+ import type { ChartMouseEvent } from "../core/pointer";
7
8
 
8
9
  function formatAxisCell(label: string | null, width: number): string {
9
10
  if (width <= 0) return "";
@@ -39,6 +40,21 @@ interface PriceAxisLabelsProps {
39
40
  /** Desktop/web observations, separate from a drawing tool's endpoint. */
40
41
  seriesTags?: readonly SeriesAxisTag[];
41
42
  measuredPixelHeight?: number;
43
+ /** A value axis the pointer stretches and squeezes: a drag or the wheel on it, a double click back. */
44
+ gestures?: PriceAxisGestures;
45
+ /** A button sits at the foot of the axis (Auto, while scaled by hand): tick labels make room for it. */
46
+ footButton?: boolean;
47
+ }
48
+
49
+ /** The button at the foot of an axis sits this far above its bottom edge (`--gloom-space-xs`). */
50
+ const FOOT_BUTTON_INSET_PX = 4;
51
+
52
+ interface PriceAxisGestures {
53
+ onMouseDown: (event: ChartMouseEvent) => void;
54
+ onMouseDrag: (event: ChartMouseEvent) => void;
55
+ onMouseUp: (event: ChartMouseEvent) => void;
56
+ onMouseDragEnd: (event: ChartMouseEvent) => void;
57
+ onMouseScroll: (event: ChartMouseEvent) => void;
42
58
  }
43
59
 
44
60
  interface CursorPriceAxisOverlay {
@@ -141,8 +157,10 @@ export function PriceAxisLabels({
141
157
  extraMarkers,
142
158
  seriesTags,
143
159
  measuredPixelHeight,
160
+ gestures,
161
+ footButton = false,
144
162
  }: PriceAxisLabelsProps) {
145
- const { cellHeightPx = 18, fractionalViewport = false } = useUiCapabilities();
163
+ const { cellHeightPx = 18, fractionalViewport = false, nativePaneChrome } = useUiCapabilities();
146
164
  const overlay = useMemo(() => buildCursorPriceAxisOverlay({
147
165
  axisWidth,
148
166
  axisSectionWidth,
@@ -168,6 +186,7 @@ export function PriceAxisLabels({
168
186
  ...(usePixelOverlay ? [(overlay.topPercent! / 100) * (pixelHeight - 1)] : []),
169
187
  ...(visibleMarkers?.map((marker) => marker.pixelY) ?? []),
170
188
  ...placedSeriesTags.map((tag) => tag.centerY),
189
+ ...(footButton ? [pixelHeight - FOOT_BUTTON_INSET_PX - cellHeightPx / 2] : []),
171
190
  ],
172
191
  })
173
192
  : null;
@@ -196,6 +215,7 @@ export function PriceAxisLabels({
196
215
  )
197
216
  );
198
217
 
218
+ const placedStyle = usePixelOverlay || usePixelTicks ? { position: "relative", height: "auto", alignSelf: "stretch" } : undefined;
199
219
  return (
200
220
  <Box
201
221
  width={axisSectionWidth}
@@ -204,7 +224,11 @@ export function PriceAxisLabels({
204
224
  overflow="hidden"
205
225
  // Labels placed in percentages follow the row's height as a resize
206
226
  // draws the chart at a new size between renders.
207
- style={usePixelOverlay || usePixelTicks ? { position: "relative", height: "auto", alignSelf: "stretch" } : undefined}
227
+ style={gestures && nativePaneChrome ? { ...placedStyle, cursor: "ns-resize" } : placedStyle}
228
+ {...gestures}
229
+ data-gloom-interactive={gestures ? "true" : undefined}
230
+ data-gloom-role={side ? "composite-chart-value-axis" : undefined}
231
+ data-gloom-side={side}
208
232
  >
209
233
  {Array.from({ length: height }, (_, row) => {
210
234
  const isCursorRow = !usePixelOverlay && cursorLabel !== null && cursorRow === row;
@@ -213,7 +237,7 @@ export function PriceAxisLabels({
213
237
  : extraMarkers?.find((entry) => entry.row === row);
214
238
  const label = isCursorRow
215
239
  ? cursorLabel
216
- : marker?.label ?? (usePixelTicks ? null : axisLabels.get(row) ?? null);
240
+ : marker?.label ?? (usePixelTicks || (footButton && row === height - 1) ? null : axisLabels.get(row) ?? null);
217
241
  return (
218
242
  <Box key={row} height={1}>
219
243
  {renderAxisLabel(
@@ -27,6 +27,7 @@ import type {
27
27
  CompositeProjectedSeries,
28
28
  } from "./types";
29
29
  import { clamp } from "../../../utils/math";
30
+ import { clipSegmentToBand } from "./value-scale";
30
31
 
31
32
  interface RenderCompositePanelBitmapOptions {
32
33
  pixelWidth: number;
@@ -45,18 +46,29 @@ const PRIOR_CLOSE_DOT_PIXELS = 2;
45
46
  const PRIOR_CLOSE_GAP_PIXELS = 3;
46
47
  const PRIOR_CLOSE_OPACITY = 0.7;
47
48
 
48
- function pixelPoint(point: CompositeProjectedPoint, width: number, height: number): { x: number; y: number } {
49
+ /**
50
+ * Where a point falls in the bitmap. An axis fitted to the data holds every
51
+ * point; one scaled by hand can put points past the edges, which `keepY` keeps
52
+ * there for the drawing to clip, rather than flattening them onto the edge.
53
+ */
54
+ function pixelPoint(point: CompositeProjectedPoint, width: number, height: number, keepY = false): { x: number; y: number } {
55
+ const y = point.yRatio * Math.max(height - 1, 0);
49
56
  return {
50
57
  x: clamp(point.xRatio * Math.max(width - 1, 0), 0, Math.max(width - 1, 0)),
51
- y: clamp(point.yRatio * Math.max(height - 1, 0), 0, Math.max(height - 1, 0)),
58
+ y: keepY ? y : clamp(y, 0, Math.max(height - 1, 0)),
52
59
  };
53
60
  }
54
61
 
55
62
  function pixelY(value: number, domain: CompositeAxisDomain, height: number): number | null {
56
63
  const ratio = projectCompositeValue(value, domain);
57
- return ratio === null ? null : clamp(ratio * Math.max(height - 1, 0), 0, Math.max(height - 1, 0));
64
+ if (ratio === null) return null;
65
+ const y = ratio * Math.max(height - 1, 0);
66
+ return domain.manual ? y : clamp(y, 0, Math.max(height - 1, 0));
58
67
  }
59
68
 
69
+ /** Rows past the bitmap's edges a clipped stroke still reaches, so its end is not cut square. */
70
+ const CLIP_MARGIN_PIXELS = 4;
71
+
60
72
  const AREA_FILL_MAX_OPACITY = 0.3;
61
73
  const AREA_FILL_MIN_OPACITY = 0.02;
62
74
 
@@ -270,7 +282,8 @@ function drawConnectedSeries(
270
282
  area: boolean,
271
283
  cue?: SeriesLineCue,
272
284
  ): void {
273
- const points = series.points.map((point) => pixelPoint(point, width, height));
285
+ const manual = domain.manual === true;
286
+ const points = series.points.map((point) => pixelPoint(point, width, height, manual));
274
287
  if (points.length === 0) return;
275
288
  const baseline = pixelY(0, domain, height) ?? height - 1;
276
289
  const step = series.source.style === "step" || series.source.interpolation === "step-after";
@@ -278,22 +291,23 @@ function drawConnectedSeries(
278
291
  if (area) fillAreaGradient(data, width, height, series, points, baseline, step, color);
279
292
 
280
293
  const stroke = cue ? new DashedStroke(data, width, height, color, cue) : null;
294
+ // A hand-scaled axis can send a segment far past the plot: only the part
295
+ // near it is stroked, so a dash pattern never walks the rest.
296
+ const segment = (x0: number, y0: number, x1: number, y1: number, thickness: number) => {
297
+ const clipped = manual ? clipSegmentToBand(x0, y0, x1, y1, -CLIP_MARGIN_PIXELS, height - 1 + CLIP_MARGIN_PIXELS) : [x0, y0, x1, y1] as const;
298
+ if (!clipped) return;
299
+ if (stroke) stroke.segment(clipped[0], clipped[1], clipped[2], clipped[3]);
300
+ else drawLine(data, width, height, clipped[0], clipped[1], clipped[2], clipped[3], color, thickness);
301
+ };
281
302
  for (let index = 1; index < points.length; index += 1) {
282
303
  const previous = points[index - 1]!;
283
304
  const current = points[index]!;
284
305
  if (series.points[index]?.breakBefore) continue;
285
- if (stroke) {
286
- if (step) {
287
- stroke.segment(previous.x, previous.y, current.x, previous.y);
288
- stroke.segment(current.x, previous.y, current.x, current.y);
289
- } else {
290
- stroke.segment(previous.x, previous.y, current.x, current.y);
291
- }
292
- } else if (step) {
293
- drawLine(data, width, height, previous.x, previous.y, current.x, previous.y, color, 1.4);
294
- drawLine(data, width, height, current.x, previous.y, current.x, current.y, color, 1.4);
306
+ if (step) {
307
+ segment(previous.x, previous.y, current.x, previous.y, 1.4);
308
+ segment(current.x, previous.y, current.x, current.y, 1.4);
295
309
  } else {
296
- drawLine(data, width, height, previous.x, previous.y, current.x, current.y, color, 1.5);
310
+ segment(previous.x, previous.y, current.x, current.y, 1.5);
297
311
  }
298
312
  }
299
313
 
@@ -429,7 +443,7 @@ function drawColumns(
429
443
  const baseline = pixelY(0, domain, height) ?? height - 1;
430
444
  for (const projected of series.points) {
431
445
  const fill = projected.value < 0 ? negativeColor : color;
432
- const point = pixelPoint(projected, width, height);
446
+ const point = pixelPoint(projected, width, height, domain.manual);
433
447
  const geometry = columnPixelGeometry(projected, width, layout, widthByFamily);
434
448
  fillRect(
435
449
  data,
@@ -583,12 +597,23 @@ export function renderCompositePanelBitmap(
583
597
  fillBand(data, width, height, series, domain, color);
584
598
  drawConnectedSeries(data, width, height, series, domain, color, false, cue);
585
599
  break;
586
- case "points":
600
+ case "points": {
601
+ // Like candles, a point owns its full mark at the viewport edge.
602
+ // Reserve its radius and antialias fringe instead of clipping half a disc.
603
+ const radius = Math.min(2.4, (width - 1) / 2, (height - 1) / 2);
604
+ const insetX = Math.min(Math.ceil(radius + 1), (width - 1) / 2);
605
+ const insetY = Math.min(Math.ceil(radius + 1), (height - 1) / 2);
587
606
  for (const point of series.points) {
588
- const projected = pixelPoint(point, width, height);
589
- drawCircle(data, width, height, projected.x, projected.y, 2.4, color);
607
+ // Inset only visible values: a manual axis must not pull an
608
+ // out-of-range observation back onto the plot's edge.
609
+ if (domain.manual && (point.yRatio < 0 || point.yRatio > 1)) continue;
610
+ const projected = pixelPoint(point, width, height, domain.manual);
611
+ drawCircle(data, width, height,
612
+ clamp(projected.x, insetX, width - 1 - insetX),
613
+ clamp(projected.y, insetY, height - 1 - insetY), radius, color);
590
614
  }
591
615
  break;
616
+ }
592
617
  case "candles":
593
618
  case "ohlc":
594
619
  case "hlc":