gloomberb 0.16.1 → 0.16.3

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 (643) hide show
  1. package/README.md +2 -1
  2. package/package.json +2 -1
  3. package/src/api-client/beneficial-owners.ts +92 -0
  4. package/src/api-client/data.ts +26 -8
  5. package/src/api-client/errors.ts +12 -0
  6. package/src/api-client/geo.ts +363 -0
  7. package/src/api-client/index.ts +2 -0
  8. package/src/api-client/market-discovery.ts +10 -0
  9. package/src/api-client/paths.ts +30 -1
  10. package/src/api-client/perps.ts +37 -0
  11. package/src/api-client/request.ts +5 -2
  12. package/src/api-client/types.ts +2 -0
  13. package/src/brokers/account-cache.ts +69 -0
  14. package/src/cli/command-options.ts +74 -0
  15. package/src/cli/commands/command-utils.ts +37 -0
  16. package/src/cli/commands/crypto-hints.ts +75 -0
  17. package/src/cli/commands/market.ts +560 -136
  18. package/src/cli/commands/overview.ts +136 -48
  19. package/src/cli/commands/ticker.ts +220 -67
  20. package/src/cli/desktop-pane-shot.ts +37 -4
  21. package/src/cli/freshness.ts +61 -0
  22. package/src/cli/help.ts +27 -6
  23. package/src/cli/helpers.ts +4 -8
  24. package/src/cli/history-rows.ts +187 -15
  25. package/src/cli/index.ts +23 -8
  26. package/src/cli/listing-arg.ts +321 -0
  27. package/src/cli/options.ts +5 -1
  28. package/src/cli/pane-functions/access-gate.ts +42 -0
  29. package/src/cli/pane-functions/capabilities.ts +5 -0
  30. package/src/cli/pane-functions/catalog.ts +28 -1
  31. package/src/cli/pane-functions/data.ts +3 -1
  32. package/src/cli/pane-functions/dom.ts +87 -16
  33. package/src/cli/pane-functions/freshness.ts +400 -0
  34. package/src/cli/pane-functions/function-help.ts +31 -22
  35. package/src/cli/pane-functions/headless.ts +201 -41
  36. package/src/cli/pane-functions/index.ts +24 -6
  37. package/src/cli/pane-functions/options.ts +3 -0
  38. package/src/cli/pane-functions/report.ts +12 -1
  39. package/src/cli/pane-functions/resolver.ts +63 -9
  40. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  41. package/src/cli/pane-functions/screenshot.ts +11 -3
  42. package/src/cli/registry.ts +6 -3
  43. package/src/cli/report-tables.ts +460 -0
  44. package/src/cli/result.ts +53 -29
  45. package/src/cli/ticker-resolution.ts +7 -5
  46. package/src/components/chart/composite/composite-chart.tsx +88 -2536
  47. package/src/components/chart/composite/drawing-store.ts +59 -0
  48. package/src/components/chart/composite/legend.tsx +319 -0
  49. package/src/components/chart/composite/panel-bitmap.ts +139 -0
  50. package/src/components/chart/composite/panel-gestures.ts +59 -0
  51. package/src/components/chart/composite/panel-labels.ts +107 -0
  52. package/src/components/chart/composite/panel-surface.tsx +876 -0
  53. package/src/components/chart/composite/tool-catalog.ts +98 -0
  54. package/src/components/chart/composite/toolbar.tsx +186 -0
  55. package/src/components/chart/composite/tools.ts +8 -0
  56. package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
  57. package/src/components/chart/composite/use-composite-viewport.ts +143 -0
  58. package/src/components/command-bar/list/model.ts +5 -0
  59. package/src/components/command-bar/list/view.tsx +16 -3
  60. package/src/components/command-bar/pane-templates/workflow.ts +1 -0
  61. package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
  62. package/src/components/command-bar/workflow/ops.ts +1 -1
  63. package/src/components/command-bar/workflow/tickers.ts +6 -0
  64. package/src/components/data-table/export.ts +6 -51
  65. package/src/components/data-table/view.tsx +32 -11
  66. package/src/components/feedback-dialog.tsx +2 -1
  67. package/src/components/form-modal/field-row.tsx +2 -2
  68. package/src/components/layout/detached-pane-shell.tsx +6 -3
  69. package/src/components/layout/pane/content.tsx +23 -10
  70. package/src/components/layout/pane/error-boundary.tsx +103 -0
  71. package/src/components/layout/pane/footer/registration.tsx +68 -23
  72. package/src/components/layout/pane/header.tsx +11 -11
  73. package/src/components/layout/shell/active-drag.ts +67 -35
  74. package/src/components/layout/shell/cursor-occlusion.ts +6 -5
  75. package/src/components/layout/shell/drag/index.ts +12 -7
  76. package/src/components/layout/shell/drag/live.ts +122 -0
  77. package/src/components/layout/shell/drag/overlays.tsx +179 -35
  78. package/src/components/layout/shell/drag/runtime.ts +62 -50
  79. package/src/components/layout/shell/drag/slide.ts +10 -0
  80. package/src/components/layout/shell/index.tsx +37 -51
  81. package/src/components/layout/shell/menu.ts +2 -1
  82. package/src/components/layout/shell/native/pointer-runtime.ts +13 -13
  83. package/src/components/layout/shell/native/surfaces.ts +30 -14
  84. package/src/components/layout/shell/pane/actions.ts +2 -1
  85. package/src/components/layout/shell/pane/layers.tsx +419 -168
  86. package/src/components/layout/shell/terminal-pointer-runtime.ts +18 -18
  87. package/src/components/layout/shell/window-mode/overlays.tsx +12 -4
  88. package/src/components/metric-treemap/heat-surface.tsx +43 -16
  89. package/src/components/metric-treemap/heat-tiles.ts +18 -0
  90. package/src/components/metric-treemap/layout.ts +2 -0
  91. package/src/components/onboarding/onboarding-keyboard.ts +311 -0
  92. package/src/components/onboarding/onboarding-wizard.tsx +101 -788
  93. package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
  94. package/src/components/onboarding/use-onboarding-progress.ts +298 -0
  95. package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
  96. package/src/components/ticker/list-table-view.tsx +13 -1
  97. package/src/components/ui/fields.tsx +8 -0
  98. package/src/components/ui/range-track.tsx +10 -3
  99. package/src/components/ui/status.tsx +8 -2
  100. package/src/components/ui/tabs.tsx +7 -4
  101. package/src/components/ui/text-prompt-dialog.tsx +4 -2
  102. package/src/data/config/store/normalize.ts +17 -1
  103. package/src/data/json-persistence.ts +17 -3
  104. package/src/data/json-storage.ts +2 -0
  105. package/src/data/memory-resource-store.ts +46 -0
  106. package/src/i18n/es.ts +19 -1
  107. package/src/i18n/ja.ts +19 -1
  108. package/src/i18n/ko.ts +19 -1
  109. package/src/i18n/zh-cn.ts +19 -1
  110. package/src/i18n/zh-tw.ts +19 -1
  111. package/src/market-data/coordinator/chart.ts +1 -1
  112. package/src/market-data/coordinator/quotes.ts +23 -4
  113. package/src/market-data/fx-closes.ts +72 -0
  114. package/src/market-data/market/freshness.ts +123 -6
  115. package/src/market-data/market/session-close-note.ts +57 -0
  116. package/src/market-data/market/status.ts +151 -0
  117. package/src/market-data/published-apac-sessions.ts +66 -0
  118. package/src/market-data/quotes/contributions.ts +2 -0
  119. package/src/market-data/quotes/freshness.ts +5 -0
  120. package/src/market-data/quotes/resolution.ts +2 -0
  121. package/src/market-data/quotes/screener-live-quotes.ts +49 -4
  122. package/src/plugins/builtin/account-management/pane.tsx +4 -0
  123. package/src/plugins/builtin/alerts/cli.ts +10 -5
  124. package/src/plugins/builtin/alerts/index.tsx +1 -0
  125. package/src/plugins/builtin/analytics/metrics.ts +8 -3
  126. package/src/plugins/builtin/analytics/pane-model.ts +10 -6
  127. package/src/plugins/builtin/analytics/risk-client.ts +191 -66
  128. package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
  129. package/src/plugins/builtin/analytics/risk-headless.ts +19 -13
  130. package/src/plugins/builtin/analytics/risk-model.ts +45 -17
  131. package/src/plugins/builtin/analytics/risk-pane.tsx +1 -0
  132. package/src/plugins/builtin/analytics/risk-test-data.ts +25 -1
  133. package/src/plugins/builtin/attention/headless.ts +6 -4
  134. package/src/plugins/builtin/attention/index.tsx +1 -1
  135. package/src/plugins/builtin/attention/pane.tsx +2 -2
  136. package/src/plugins/builtin/awards/headless.ts +1 -0
  137. package/src/plugins/builtin/awards/pane.tsx +1 -1
  138. package/src/plugins/builtin/backtest/headless.ts +1 -0
  139. package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
  140. package/src/plugins/builtin/buildout/index.tsx +1 -0
  141. package/src/plugins/builtin/catalysts/detail.tsx +1 -1
  142. package/src/plugins/builtin/catalysts/headless.ts +3 -1
  143. package/src/plugins/builtin/cds/headless.ts +2 -0
  144. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
  145. package/src/plugins/builtin/chart-composer/headless.ts +38 -3
  146. package/src/plugins/builtin/chart-composer/index.tsx +3 -1
  147. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
  148. package/src/plugins/builtin/chat/channels.ts +19 -3
  149. package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
  150. package/src/plugins/builtin/chat/content/footer.tsx +15 -6
  151. package/src/plugins/builtin/chat/content/index.tsx +120 -21
  152. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
  153. package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
  154. package/src/plugins/builtin/chat/direct-messages.ts +200 -0
  155. package/src/plugins/builtin/chat/index.tsx +1 -0
  156. package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
  157. package/src/plugins/builtin/chat/message/header.tsx +16 -6
  158. package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
  159. package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
  160. package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
  161. package/src/plugins/builtin/chat/message/types.ts +14 -2
  162. package/src/plugins/builtin/chat/profile-popover.ts +18 -13
  163. package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
  164. package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
  165. package/src/plugins/builtin/cloud/plugin.tsx +1 -0
  166. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  167. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  168. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  169. package/src/plugins/builtin/comment-letters/index.tsx +1 -0
  170. package/src/plugins/builtin/company-attention/headless.ts +5 -1
  171. package/src/plugins/builtin/company-attention/pane.tsx +2 -2
  172. package/src/plugins/builtin/company-kpis/headless.ts +1 -0
  173. package/src/plugins/builtin/congress-trades/headless.ts +1 -0
  174. package/src/plugins/builtin/correlation/compute.ts +59 -16
  175. package/src/plugins/builtin/correlation/geo.ts +34 -0
  176. package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
  177. package/src/plugins/builtin/correlation/headless.ts +42 -8
  178. package/src/plugins/builtin/correlation/history.ts +2 -0
  179. package/src/plugins/builtin/correlation/index.tsx +68 -14
  180. package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
  181. package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
  182. package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
  183. package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
  184. package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
  185. package/src/plugins/builtin/correlation/settings.ts +1 -1
  186. package/src/plugins/builtin/cot/headless.ts +6 -3
  187. package/src/plugins/builtin/cot/index.tsx +3 -3
  188. package/src/plugins/builtin/cot/model.ts +36 -3
  189. package/src/plugins/builtin/cpi/headless.ts +4 -0
  190. package/src/plugins/builtin/credit-boards/headless.ts +2 -0
  191. package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
  192. package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
  193. package/src/plugins/builtin/credit-documents/headless.ts +2 -0
  194. package/src/plugins/builtin/crypto-board/headless.ts +3 -0
  195. package/src/plugins/builtin/custom-view/loader.ts +1 -1
  196. package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
  197. package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
  198. package/src/plugins/builtin/doe/headless.ts +7 -0
  199. package/src/plugins/builtin/doe/range-bar.tsx +7 -37
  200. package/src/plugins/builtin/earnings/headless.ts +5 -0
  201. package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
  202. package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
  203. package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
  204. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
  205. package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
  206. package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
  207. package/src/plugins/builtin/econ/index.tsx +1 -0
  208. package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
  209. package/src/plugins/builtin/equity-screener/headless.ts +2 -0
  210. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  211. package/src/plugins/builtin/executives/index.tsx +1 -0
  212. package/src/plugins/builtin/exposure/headless.ts +3 -1
  213. package/src/plugins/builtin/fear-greed/headless.ts +2 -0
  214. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  215. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  216. package/src/plugins/builtin/futures-curve/headless.ts +39 -10
  217. package/src/plugins/builtin/futures-curve/index.tsx +3 -3
  218. package/src/plugins/builtin/futures-curve/model.ts +188 -4
  219. package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
  220. package/src/plugins/builtin/gpu/headless.ts +7 -3
  221. package/src/plugins/builtin/gpu/ladder.tsx +26 -30
  222. package/src/plugins/builtin/gpu/model.ts +27 -1
  223. package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
  224. package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
  225. package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
  226. package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
  227. package/src/plugins/builtin/holders/client.ts +3 -6
  228. package/src/plugins/builtin/holders/format.ts +31 -1
  229. package/src/plugins/builtin/holders/headless.ts +161 -6
  230. package/src/plugins/builtin/holders/index.tsx +10 -3
  231. package/src/plugins/builtin/holders/pane.tsx +42 -16
  232. package/src/plugins/builtin/holders/report-header.ts +136 -0
  233. package/src/plugins/builtin/holders/table-model.ts +20 -5
  234. package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
  235. package/src/plugins/builtin/holders/types.ts +2 -1
  236. package/src/plugins/builtin/insider/headless.ts +2 -0
  237. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
  238. package/src/plugins/builtin/iv-history/headless.ts +4 -1
  239. package/src/plugins/builtin/jobs/headless.ts +1 -0
  240. package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
  241. package/src/plugins/builtin/kelly-sizer/pane.tsx +12 -6
  242. package/src/plugins/builtin/kelly-sizer/portfolio.ts +25 -0
  243. package/src/plugins/builtin/macro-day/headless.ts +2 -0
  244. package/src/plugins/builtin/market-halts/index.tsx +1 -0
  245. package/src/plugins/builtin/market-heatmap/data.ts +2 -0
  246. package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
  247. package/src/plugins/builtin/market-heatmap/index.tsx +39 -46
  248. package/src/plugins/builtin/market-heatmap/model.ts +146 -0
  249. package/src/plugins/builtin/market-heatmap/portfolio.ts +23 -4
  250. package/src/plugins/builtin/market-movers/headless.ts +2 -0
  251. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  252. package/src/plugins/builtin/members/client.ts +20 -3
  253. package/src/plugins/builtin/members/headless.ts +5 -3
  254. package/src/plugins/builtin/members/model.ts +10 -2
  255. package/src/plugins/builtin/members/pane.tsx +23 -6
  256. package/src/plugins/builtin/mna/distress/headless.ts +1 -0
  257. package/src/plugins/builtin/mna/headless.ts +1 -0
  258. package/src/plugins/builtin/money-markets/headless.ts +1 -0
  259. package/src/plugins/builtin/news/headless.ts +2 -0
  260. package/src/plugins/builtin/news/wire/index.tsx +8 -1
  261. package/src/plugins/builtin/notes/cli.ts +14 -6
  262. package/src/plugins/builtin/notes/index.tsx +1 -0
  263. package/src/plugins/builtin/openfda/index.tsx +1 -0
  264. package/src/plugins/builtin/options-calculator/headless.ts +2 -0
  265. package/src/plugins/builtin/options-positioning/headless.ts +3 -0
  266. package/src/plugins/builtin/options-scenario/headless.ts +5 -0
  267. package/src/plugins/builtin/pe-band/client.ts +48 -3
  268. package/src/plugins/builtin/pe-band/headless.ts +25 -7
  269. package/src/plugins/builtin/pe-band/model.ts +92 -16
  270. package/src/plugins/builtin/pe-band/pane.tsx +33 -16
  271. package/src/plugins/builtin/perps/client.ts +50 -3
  272. package/src/plugins/builtin/perps/headless.ts +144 -16
  273. package/src/plugins/builtin/perps/index.tsx +6 -6
  274. package/src/plugins/builtin/perps/model.ts +189 -12
  275. package/src/plugins/builtin/perps/pane.tsx +249 -48
  276. package/src/plugins/builtin/portfolio-list/account-metrics.ts +16 -1
  277. package/src/plugins/builtin/portfolio-list/allocation.ts +248 -0
  278. package/src/plugins/builtin/portfolio-list/cached-account.ts +42 -0
  279. package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
  280. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
  281. package/src/plugins/builtin/portfolio-list/cli/render.ts +232 -39
  282. package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
  283. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
  284. package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
  285. package/src/plugins/builtin/portfolio-list/headless.ts +100 -16
  286. package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
  287. package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
  288. package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
  289. package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
  290. package/src/plugins/builtin/portfolio-list/pane/index.tsx +53 -16
  291. package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
  292. package/src/plugins/builtin/portfolio-list/summary/index.tsx +46 -5
  293. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +11 -1
  294. package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
  295. package/src/plugins/builtin/power/headless.ts +3 -1
  296. package/src/plugins/builtin/rate-path/headless.ts +2 -0
  297. package/src/plugins/builtin/realized-vol/headless.ts +2 -0
  298. package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
  299. package/src/plugins/builtin/research/analyst-headless.ts +3 -0
  300. package/src/plugins/builtin/research/events-headless.ts +2 -0
  301. package/src/plugins/builtin/research/headless.ts +2 -0
  302. package/src/plugins/builtin/research/index.tsx +1 -0
  303. package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
  304. package/src/plugins/builtin/research/relative-valuation-model.ts +18 -6
  305. package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
  306. package/src/plugins/builtin/research-search/index.tsx +1 -0
  307. package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
  308. package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
  309. package/src/plugins/builtin/reverse-dcf/model.ts +2 -1
  310. package/src/plugins/builtin/risk-factors/headless.ts +2 -0
  311. package/src/plugins/builtin/scanner/flow-history.ts +2 -13
  312. package/src/plugins/builtin/scanner/headless.ts +14 -0
  313. package/src/plugins/builtin/seasonality/headless.ts +2 -0
  314. package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
  315. package/src/plugins/builtin/sec/filing-content.ts +42 -17
  316. package/src/plugins/builtin/sec/forms.ts +12 -0
  317. package/src/plugins/builtin/sec/headless.ts +2 -0
  318. package/src/plugins/builtin/sectors/client.ts +1 -0
  319. package/src/plugins/builtin/sectors/headless.ts +9 -1
  320. package/src/plugins/builtin/sectors/sector-model.ts +2 -0
  321. package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
  322. package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
  323. package/src/plugins/builtin/shared/members-menu.tsx +260 -0
  324. package/src/plugins/builtin/shared/report-freshness.ts +57 -0
  325. package/src/plugins/builtin/shared/research-cells.tsx +4 -9
  326. package/src/plugins/builtin/short-interest/headless.ts +2 -0
  327. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  328. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  329. package/src/plugins/builtin/short-volume/pane.tsx +1 -1
  330. package/src/plugins/builtin/social-mentions/headless.ts +1 -0
  331. package/src/plugins/builtin/social-mentions/pane.tsx +1 -1
  332. package/src/plugins/builtin/supply-chain/headless.ts +7 -1
  333. package/src/plugins/builtin/supply-chain/index.tsx +10 -1
  334. package/src/plugins/builtin/supply-chain/model.ts +27 -2
  335. package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
  336. package/src/plugins/builtin/themes/headless.ts +3 -0
  337. package/src/plugins/builtin/themes/pane.tsx +3 -0
  338. package/src/plugins/builtin/thirteenf/headless.ts +110 -25
  339. package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
  340. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +4 -0
  341. package/src/plugins/builtin/ticker-detail/financials/model.ts +25 -2
  342. package/src/plugins/builtin/ticker-detail/headless.ts +27 -5
  343. package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
  344. package/src/plugins/builtin/ticker-detail/overview/model.ts +17 -5
  345. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +27 -26
  346. package/src/plugins/builtin/time-sales/headless.ts +5 -1
  347. package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
  348. package/src/plugins/builtin/volatility/headless.ts +6 -1
  349. package/src/plugins/builtin/world-indices/headless.ts +2 -0
  350. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +159 -0
  351. package/src/plugins/builtin/world-venue-map/basemap.ts +232 -0
  352. package/src/plugins/builtin/world-venue-map/client.ts +45 -0
  353. package/src/plugins/builtin/world-venue-map/country-labels.ts +78 -0
  354. package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
  355. package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
  356. package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
  357. package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
  358. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
  359. package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
  360. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +448 -0
  361. package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
  362. package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
  363. package/src/plugins/builtin/world-venue-map/index.ts +69 -6
  364. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +565 -0
  365. package/src/plugins/builtin/world-venue-map/layers.ts +406 -0
  366. package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
  367. package/src/plugins/builtin/world-venue-map/map.tsx +557 -85
  368. package/src/plugins/builtin/world-venue-map/model.ts +23 -4
  369. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +202 -0
  370. package/src/plugins/builtin/world-venue-map/natural-earth/labels.chunk.ts +244 -0
  371. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
  372. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
  373. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
  374. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
  375. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
  376. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
  377. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
  378. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
  379. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
  380. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
  381. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
  382. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
  383. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
  384. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
  385. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
  386. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
  387. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
  388. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
  389. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
  390. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
  391. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
  392. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
  393. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
  394. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
  395. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
  396. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
  397. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
  398. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
  399. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
  400. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
  401. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
  402. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
  403. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
  404. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
  405. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
  406. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
  407. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
  408. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
  409. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
  410. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
  411. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
  412. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
  413. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
  414. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
  415. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
  416. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
  417. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
  418. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
  419. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
  420. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
  421. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
  422. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
  423. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
  424. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
  425. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
  426. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
  429. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
  430. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
  431. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
  432. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
  433. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
  434. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
  435. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
  436. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
  437. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
  438. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
  439. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
  440. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
  441. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
  442. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
  443. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
  444. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
  445. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
  446. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
  447. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
  448. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
  449. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
  450. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
  451. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
  452. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
  453. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
  454. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
  455. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
  456. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
  457. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
  458. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
  459. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
  460. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
  461. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
  462. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
  463. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
  464. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
  465. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
  466. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
  467. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
  468. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
  469. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
  470. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
  471. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
  472. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
  473. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
  474. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
  475. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
  476. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
  477. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
  478. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
  479. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
  480. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
  481. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
  482. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
  483. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
  484. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
  485. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
  486. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
  487. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
  488. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
  489. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
  490. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
  491. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
  492. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
  493. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
  494. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
  495. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
  496. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
  497. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
  498. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
  499. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
  500. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
  501. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
  502. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
  503. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
  504. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
  505. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
  506. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
  507. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
  508. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
  509. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
  510. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
  511. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
  512. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
  513. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
  514. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
  515. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
  516. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
  517. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
  518. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
  519. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
  520. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
  521. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
  522. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
  523. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
  524. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
  525. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
  526. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
  527. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
  528. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
  529. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
  530. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
  531. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
  532. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
  533. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
  534. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
  535. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
  536. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
  537. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
  538. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
  539. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
  540. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
  541. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
  542. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
  543. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
  544. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
  545. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
  546. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
  547. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
  548. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
  549. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
  550. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
  551. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
  552. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
  553. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
  554. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
  555. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
  556. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
  557. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
  558. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
  559. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
  560. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
  561. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
  562. package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
  563. package/src/plugins/builtin/world-venue-map/pane.tsx +35 -44
  564. package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
  565. package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
  566. package/src/plugins/builtin/yield-curve/headless.ts +16 -0
  567. package/src/plugins/loader.ts +13 -1
  568. package/src/plugins/registry/pane-settings.ts +1 -0
  569. package/src/renderers/browser/app-services.ts +3 -1
  570. package/src/renderers/dom/build-assets.ts +81 -3
  571. package/src/renderers/dom/data-table/dom.ts +31 -0
  572. package/src/renderers/dom/data-table/index.tsx +5 -0
  573. package/src/renderers/dom/data-table/row.tsx +2 -0
  574. package/src/renderers/dom/desktop/controls.tsx +7 -3
  575. package/src/renderers/dom/desktop/list-view.tsx +35 -10
  576. package/src/renderers/dom/desktop/popover.tsx +73 -14
  577. package/src/renderers/dom/host/box.tsx +113 -17
  578. package/src/renderers/dom/host/drag-shield.ts +24 -0
  579. package/src/renderers/dom/host/input.tsx +14 -3
  580. package/src/renderers/dom/host/live-frame.ts +54 -0
  581. package/src/renderers/dom/host/mouse.ts +8 -1
  582. package/src/renderers/dom/host/scroll-box.tsx +6 -5
  583. package/src/renderers/dom/host/tabs.tsx +3 -2
  584. package/src/renderers/dom/styles.css +16 -9
  585. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +7 -0
  586. package/src/renderers/electrobun/bun/desktop/backend.ts +2 -0
  587. package/src/renderers/electrobun/bun/desktop/initialization.ts +13 -0
  588. package/src/renderers/electrobun/shared/protocol.ts +10 -1
  589. package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
  590. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +4 -0
  591. package/src/renderers/electrobun/view/host/native.ts +0 -10
  592. package/src/renderers/electrobun/view/host/window-move.ts +28 -0
  593. package/src/renderers/electrobun/view/remote/persistence.ts +15 -2
  594. package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
  595. package/src/renderers/electrobun/view/ui-host.tsx +2 -5
  596. package/src/renderers/opentui/host.tsx +5 -0
  597. package/src/renderers/opentui/ui-host.tsx +7 -1
  598. package/src/sources/gloomberb-cloud/index.ts +25 -4
  599. package/src/sources/gloomberb-cloud/normalizers.ts +43 -23
  600. package/src/sources/provider-router/batches.ts +3 -3
  601. package/src/sources/provider-router/cached-routes.ts +4 -1
  602. package/src/sources/provider-router/financial-routes.ts +2 -2
  603. package/src/sources/provider-router/financials.ts +76 -12
  604. package/src/sources/provider-router/history.ts +15 -10
  605. package/src/sources/provider-router/primary.ts +2 -2
  606. package/src/sources/sec-registrant.ts +75 -0
  607. package/src/state/app/context/index.tsx +24 -8
  608. package/src/state/hooks/quote-streaming.ts +41 -26
  609. package/src/state/pane-scroll-registry.tsx +67 -35
  610. package/src/sync/core-contributors.ts +4 -0
  611. package/src/telemetry/crash-reports.ts +4 -1
  612. package/src/test-support/cli-context.ts +10 -2
  613. package/src/test-support/margin-account.ts +108 -0
  614. package/src/theme/heat-colors.ts +266 -84
  615. package/src/time-series/resolution.ts +15 -0
  616. package/src/time-series/resolve.ts +1 -1
  617. package/src/time-series/use-chart-resolution.ts +1 -1
  618. package/src/types/context-menu.ts +6 -0
  619. package/src/types/data-provider.ts +2 -0
  620. package/src/types/financials.ts +35 -3
  621. package/src/types/headless.ts +79 -2
  622. package/src/types/plugin.ts +20 -1
  623. package/src/types/ticker.ts +15 -0
  624. package/src/ui/host.tsx +26 -0
  625. package/src/ui/index.tsx +8 -3
  626. package/src/ui/scroll-box-axis.ts +26 -0
  627. package/src/updater/index.ts +9 -11
  628. package/src/utils/async-deadline.ts +21 -0
  629. package/src/utils/cli-output.ts +5 -1
  630. package/src/utils/crypto-pair.ts +41 -0
  631. package/src/utils/currency-units.ts +19 -0
  632. package/src/utils/depositary-receipt.ts +70 -0
  633. package/src/utils/display-number.ts +63 -0
  634. package/src/utils/exchanges.ts +72 -0
  635. package/src/utils/fire-and-forget.ts +24 -0
  636. package/src/utils/format.ts +13 -0
  637. package/src/utils/fundamentals.ts +17 -1
  638. package/src/utils/price-earnings.ts +70 -3
  639. package/src/utils/price-history-integrity.ts +19 -6
  640. package/src/utils/price-history.ts +58 -13
  641. package/src/utils/rpc-timeout-error.ts +27 -0
  642. package/src/utils/sec.ts +13 -1
  643. package/src/utils/utc-time.ts +79 -0
@@ -1,4 +1,5 @@
1
1
  import { getSharedRegistry } from "../../plugins/registry";
2
+ import { findCachedPortfolioAccount } from "../../plugins/builtin/portfolio-list/cached-account";
2
3
  import { parsePublicTickerKey } from "../../utils/exchanges";
3
4
  import { apiClient } from "../../api-client";
4
5
  import type { MarketContext } from "../types";
@@ -19,11 +20,23 @@ import type {
19
20
  } from "../../types/plugin";
20
21
  import { cliStyles, renderSection, renderStats, renderTable } from "../../utils/cli-output";
21
22
  import { humanizeCliKey } from "../result";
23
+ import {
24
+ exportEntriesTable,
25
+ exportNumber,
26
+ exportRowsTable,
27
+ float32Shortest,
28
+ reportFooterLines,
29
+ type CliReportTable,
30
+ type CliReportTables,
31
+ } from "../report-tables";
32
+ import { labelWithUnit } from "../../utils/display-number";
22
33
  import { observationDate } from "../../time-series/price-comparison";
23
34
  import type { ResolvedSeries } from "../../time-series/types";
24
35
  import type { PaneFunctionReport } from "./report";
25
36
  import type { ResolvedPaneFunction } from "./resolver";
26
37
  import { isRecord } from "../../utils/guards";
38
+ import { formatUtcTime } from "../../utils/utc-time";
39
+ import { deriveHeadlessFreshness, formatFreshnessLine, type ReportFreshness } from "./freshness";
27
40
 
28
41
  interface SerializableHeadlessColumn {
29
42
  key: string;
@@ -149,7 +162,9 @@ async function loadHeadlessPaneModel(
149
162
  */
150
163
  export async function loadResolvedHeadlessPaneModel(
151
164
  resolved: ResolvedPaneFunction,
152
- context: Pick<MarketContext, "config" | "store" | "refresh"> & { dataProvider: HeadlessPaneContext["marketData"] },
165
+ context: Pick<MarketContext, "config" | "store" | "refresh"> & Partial<Pick<MarketContext, "persistence">> & {
166
+ dataProvider: HeadlessPaneContext["marketData"];
167
+ },
153
168
  rawArgument: string,
154
169
  signal: AbortSignal = new AbortController().signal,
155
170
  ): Promise<LoadedHeadlessPaneModel> {
@@ -168,7 +183,7 @@ export async function loadResolvedHeadlessPaneModel(
168
183
  const portfolio = context.config.portfolios.find(row => row.id === id);
169
184
  if (!portfolio) return null;
170
185
  const tickers = (await context.store.loadAllTickers()).filter(row => row.metadata.portfolios.includes(id));
171
- return { portfolio, tickers };
186
+ return { portfolio, tickers, account: findCachedPortfolioAccount(context.config, portfolio, context.persistence?.resources) };
172
187
  },
173
188
  async resolveWatchlist(id) {
174
189
  if (!context.config.watchlists.some(row => row.id === id)) return null;
@@ -244,6 +259,7 @@ export function serializeHeadlessPaneResult(
244
259
  ): Record<string, unknown> {
245
260
  const common = {
246
261
  ...(result.errors ? { errors: result.errors } : {}),
262
+ ...(result.notes?.length ? { notes: result.notes } : {}),
247
263
  ...(result.metadata ? { metadata: result.metadata } : {}),
248
264
  };
249
265
  switch (definition.shape) {
@@ -310,36 +326,43 @@ function displayNumber(value: number): string {
310
326
  return String(float32Shortest(value) ?? Number(value.toPrecision(12)));
311
327
  }
312
328
 
313
- /**
314
- * Some feeds store prices as float32, so 338.93 arrives as 338.929992676. A value
315
- * that is exactly a float32 prints as the shortest decimal that rounds back to it,
316
- * which leaves genuine doubles (never exactly float32 unless short) untouched.
317
- */
318
- function float32Shortest(value: number): number | null {
319
- if (Math.fround(value) !== value) return null;
320
- for (let digits = 1; digits <= 9; digits += 1) {
321
- const candidate = Number(value.toPrecision(digits));
322
- if (Math.fround(candidate) === value) return candidate;
323
- }
324
- return null;
325
- }
326
-
327
329
  function displayTime(time: number): string {
328
330
  if (!Number.isFinite(time)) return "-";
329
- const iso = new Date(time).toISOString();
330
- return iso.endsWith("T00:00:00.000Z") ? iso.slice(0, 10) : `${iso.slice(0, 16).replace("T", " ")} UTC`;
331
+ return formatUtcTime(new Date(time));
331
332
  }
332
333
 
333
334
  const CALENDAR_RESOLUTIONS = new Set(["1d", "1wk", "1mo"]);
334
335
 
335
- /** Session bars print the trading date the chart and comparison notice use, not the bar's open instant. */
336
- function seriesPointDate(series: HeadlessSeries, date: HeadlessSeries["points"][number]["date"]): string {
337
- const time = date instanceof Date ? date.getTime() : typeof date === "number" ? date : Date.parse(date);
338
- if (!Number.isFinite(time)) return typeof date === "string" ? date : "-";
336
+ type SeriesPointDate = HeadlessSeries["points"][number]["date"];
337
+
338
+ function seriesPointTime(date: SeriesPointDate): number {
339
+ return date instanceof Date ? date.getTime() : typeof date === "number" ? date : Date.parse(date);
340
+ }
341
+
342
+ function isDateOnly(date: SeriesPointDate): boolean {
343
+ return typeof date === "string" && /^\d{4}-\d{2}-\d{2}$/.test(date);
344
+ }
345
+
346
+ /** Session bars are dated by the trading date the chart and comparison notice use, not the bar's open instant. */
347
+ function calendarSeries(series: HeadlessSeries): (HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution" | "timeBasis">>) | null {
339
348
  const resolved = series as HeadlessSeries & Partial<Pick<ResolvedSeries, "historyResolution" | "timeBasis">>;
340
- return resolved.historyResolution && CALENDAR_RESOLUTIONS.has(resolved.historyResolution)
341
- ? observationDate(time, resolved)
342
- : displayTime(time);
349
+ return resolved.historyResolution && CALENDAR_RESOLUTIONS.has(resolved.historyResolution) ? resolved : null;
350
+ }
351
+
352
+ function seriesPointDate(series: HeadlessSeries, date: SeriesPointDate): string {
353
+ const time = seriesPointTime(date);
354
+ if (!Number.isFinite(time)) return typeof date === "string" ? date : "-";
355
+ const calendar = calendarSeries(series);
356
+ return calendar ? observationDate(time, calendar) : formatUtcTime({ time, dateOnly: isDateOnly(date) });
357
+ }
358
+
359
+ /** The same date for a spreadsheet: the trading date, the calendar date, or the ISO instant. */
360
+ function seriesPointExportDate(series: HeadlessSeries, date: SeriesPointDate): string {
361
+ const time = seriesPointTime(date);
362
+ if (!Number.isFinite(time)) return typeof date === "string" ? date : "";
363
+ const calendar = calendarSeries(series);
364
+ if (calendar) return observationDate(time, calendar);
365
+ return isDateOnly(date) ? date as string : new Date(time).toISOString().replace(".000Z", "Z");
343
366
  }
344
367
 
345
368
  function seriesValue(series: HeadlessSeries, value: number | null): string {
@@ -372,6 +395,10 @@ function renderEntries(entries: HeadlessPaneEntry[]): string {
372
395
  return renderStats(entries.map((entry) => [entry.label, entry.formatted ?? displayValue(entry.value)]));
373
396
  }
374
397
 
398
+ function statisticsEntries(stats: NonNullable<HeadlessSeriesResult["stats"]>): HeadlessPaneEntry[] {
399
+ return Array.isArray(stats) ? stats : Object.entries(stats).map(([label, value]) => ({ label, value }));
400
+ }
401
+
375
402
  function renderBundle(
376
403
  definition: HeadlessPaneDefinition,
377
404
  result: HeadlessBundleResult,
@@ -407,31 +434,150 @@ function renderSeries(result: HeadlessSeriesResult): string[] {
407
434
  ];
408
435
  const lines = [renderRows(rows, columns, undefined)];
409
436
  if (result.stats) {
410
- const entries = Array.isArray(result.stats)
411
- ? result.stats
412
- : Object.entries(result.stats).map(([label, value]) => ({ label, value }));
413
- lines.push("", renderSection("Statistics"), renderEntries(entries));
437
+ lines.push("", renderSection("Statistics"), renderEntries(statisticsEntries(result.stats)));
414
438
  }
415
439
  return lines;
416
440
  }
417
441
 
418
- function reportTitle(definition: HeadlessPaneDefinition, args: HeadlessPaneLoadArgs, fallback: string): string {
419
- if (typeof definition.describe === "function") return definition.describe(args);
442
+ /** The headers the text table prints. */
443
+ function displayedColumns(columns: HeadlessPaneColumn[]): HeadlessPaneColumn[] {
444
+ return columns.map((column) => ({ ...column, header: humanizeCliKey(column.header) }));
445
+ }
446
+
447
+ const SERIES_FIELDS = ["value", "open", "high", "low", "close", "volume"] as const;
448
+
449
+ /** Every point of a series: its date (the trading date for session bars) and its values, in the series' unit. */
450
+ function seriesTable(series: HeadlessSeries): CliReportTable {
451
+ const fields = SERIES_FIELDS.filter((field) => series.points.some((point) => point[field] != null));
452
+ const unit = series.unit?.trim() ?? "";
453
+ const dates = series.points.map((point) => seriesPointExportDate(series, point.date));
454
+ const header = (field: (typeof SERIES_FIELDS)[number]) => {
455
+ const name = `${field[0]!.toUpperCase()}${field.slice(1)}`;
456
+ return field === "volume" ? name : labelWithUnit(name, unit);
457
+ };
458
+ return {
459
+ title: series.label,
460
+ columns: [dates.every((date) => date.length <= 10) ? "Date" : "Time", ...fields.map(header)],
461
+ rows: series.points.map((point, index) => [
462
+ dates[index]!,
463
+ ...fields.map((field) => {
464
+ const value = point[field];
465
+ return typeof value === "number" && Number.isFinite(value) ? exportNumber(value) : "";
466
+ }),
467
+ ]),
468
+ };
469
+ }
470
+
471
+ /** What a report leaves out, for the closing `# incomplete` line. */
472
+ function incompleteDetail(
473
+ result: HeadlessPaneResult,
474
+ status: { complete: boolean; unavailableSymbols: string[] },
475
+ ): boolean | string {
476
+ if (status.complete) return false;
477
+ const requested = result.metadata?.requested;
478
+ const available = result.metadata?.available;
479
+ if (typeof requested === "number" && typeof available === "number" && available < requested) {
480
+ return `${available} of ${requested} available`;
481
+ }
482
+ return status.unavailableSymbols.length > 0 ? `no data for ${status.unavailableSymbols.join(", ")}` : true;
483
+ }
484
+
485
+ function textNotices(result: HeadlessPaneResult): string[] {
486
+ const notices = result.metadata?.notices;
487
+ if (!Array.isArray(notices)) return [];
488
+ return [...new Set(notices.filter((notice): notice is string => typeof notice === "string" && notice.trim().length > 0))];
489
+ }
490
+
491
+ /**
492
+ * The tables of a headless report for `--csv` and `--ndjson`, with the text
493
+ * view's columns: a rows or snapshot report is one table, a bundle one per
494
+ * section (key/value sections as `Metric,Value`), a series report one per
495
+ * series with every point, then its statistics. The footer carries the text
496
+ * view's closing line, notices, notes and errors.
497
+ */
498
+ export function headlessReportTables(
499
+ definition: HeadlessPaneDefinition,
500
+ result: HeadlessPaneResult,
501
+ args: HeadlessPaneLoadArgs,
502
+ fallbackTitle: string,
503
+ freshness: ReportFreshness,
504
+ status: { complete: boolean; unavailableSymbols: string[] },
505
+ ): CliReportTables {
506
+ const title = reportTitle(definition, args, result, fallbackTitle);
507
+ let tables: CliReportTable[];
508
+ switch (definition.shape) {
509
+ case "rows": {
510
+ const rowsResult = result as HeadlessPaneResult & { rows: HeadlessPaneRow[]; columns?: HeadlessPaneColumn[] };
511
+ const columns = displayedColumns(columnsFor(rowsResult.rows, rowsResult.columns, definition.columns));
512
+ tables = [exportRowsTable(title, columns, rowsResult.rows)];
513
+ break;
514
+ }
515
+ case "bundle":
516
+ tables = (result as HeadlessBundleResult).sections.map((section) => (
517
+ "rows" in section && section.rows
518
+ ? exportRowsTable(section.title, displayedColumns(columnsFor(section.rows, section.columns, definition.columns)), section.rows)
519
+ : exportEntriesTable(section.title, section.entries)
520
+ ));
521
+ break;
522
+ case "series": {
523
+ const seriesResult = result as HeadlessSeriesResult;
524
+ tables = seriesResult.series.map(seriesTable);
525
+ if (seriesResult.stats) tables.push(exportEntriesTable("Statistics", statisticsEntries(seriesResult.stats)));
526
+ break;
527
+ }
528
+ case "snapshot": {
529
+ const snapshot = result as HeadlessSnapshotResult;
530
+ tables = [exportRowsTable(title, displayedColumns(columnsFor(snapshot.items, undefined, definition.columns)), snapshot.items)];
531
+ break;
532
+ }
533
+ default: {
534
+ const _exhaustive: never = definition.shape;
535
+ return _exhaustive;
536
+ }
537
+ }
538
+ return {
539
+ tables,
540
+ footer: reportFooterLines({
541
+ freshness,
542
+ incomplete: incompleteDetail(result, status),
543
+ errors: result.errors,
544
+ notes: [...textNotices(result), ...(result.notes ?? [])],
545
+ }),
546
+ };
547
+ }
548
+
549
+ function reportTitle(
550
+ definition: HeadlessPaneDefinition,
551
+ args: HeadlessPaneLoadArgs,
552
+ result: HeadlessPaneResult,
553
+ fallback: string,
554
+ ): string {
555
+ if (typeof definition.describe === "function") return definition.describe(args, result);
420
556
  return definition.describe ?? fallback;
421
557
  }
422
558
 
559
+ /** One message stays on the label's line; several each get a line of their own, so none runs into the next. */
560
+ function renderMessages(label: string, messages: readonly string[]): string[] {
561
+ return messages.length === 1
562
+ ? [cliStyles.warning(`${label}: ${messages[0]}`)]
563
+ : [cliStyles.warning(`${label}:`), ...messages.map((message) => ` ${message}`)];
564
+ }
565
+
566
+ /**
567
+ * The text form of every headless report. It always ends with the source,
568
+ * as-of and status line, so no pane can leave it out; a pane can only make it
569
+ * more accurate through its `freshness` declaration.
570
+ */
423
571
  export function renderHeadlessPaneText(
424
572
  definition: HeadlessPaneDefinition,
425
573
  result: HeadlessPaneResult,
426
574
  args: HeadlessPaneLoadArgs,
427
575
  fallbackTitle: string,
576
+ freshness: ReportFreshness = deriveHeadlessFreshness(definition, result),
428
577
  ): string {
429
- const lines = [cliStyles.bold(reportTitle(definition, args, fallbackTitle)), ""];
430
- const notices = result.metadata?.notices;
431
- if (Array.isArray(notices)) {
432
- const textNotices = [...new Set(notices.filter((notice): notice is string => typeof notice === "string" && notice.trim().length > 0))];
433
- if (textNotices.length) lines.push(...textNotices, "");
434
- }
578
+ const lines = [cliStyles.bold(reportTitle(definition, args, result, fallbackTitle)), ""];
579
+ const notices = textNotices(result);
580
+ if (notices.length) lines.push(...notices, "");
435
581
  switch (definition.shape) {
436
582
  case "rows": {
437
583
  const rowsResult = result as HeadlessPaneResult & { rows: HeadlessPaneRow[]; columns?: HeadlessPaneColumn[] };
@@ -446,7 +592,8 @@ export function renderHeadlessPaneText(
446
592
  break;
447
593
  case "snapshot": {
448
594
  const snapshot = result as HeadlessSnapshotResult;
449
- lines.push(`As of: ${displayValue(snapshot.asOf)}`, "", renderRows(snapshot.items, undefined, definition.columns));
595
+ // The closing source line carries the snapshot's as-of, so it is not printed twice.
596
+ lines.push(renderRows(snapshot.items, undefined, definition.columns));
450
597
  break;
451
598
  }
452
599
  default: {
@@ -454,8 +601,9 @@ export function renderHeadlessPaneText(
454
601
  return _exhaustive;
455
602
  }
456
603
  }
457
- if (result.errors?.length) lines.push("", cliStyles.warning(`Errors: ${result.errors.join(" ")}`));
458
- return lines.join("\n").trimEnd();
604
+ if (result.notes?.length) lines.push("", ...renderMessages("Notes", result.notes));
605
+ if (result.errors?.length) lines.push("", ...renderMessages("Errors", result.errors));
606
+ return [lines.join("\n").trimEnd(), "", cliStyles.muted(formatFreshnessLine(freshness))].join("\n");
459
607
  }
460
608
 
461
609
  function resultRowCount(definition: HeadlessPaneDefinition, result: HeadlessPaneResult): number {
@@ -487,6 +635,8 @@ export async function buildHeadlessFunctionReport(
487
635
  const symbols = loaded.result.symbols ?? loaded.args.symbols;
488
636
  const unavailableSymbols = loaded.result.unavailableSymbols ?? (rowCount === 0 ? symbols : []);
489
637
  const serialized = serializeHeadlessPaneResult(loaded.definition, loaded.result);
638
+ const freshness = deriveHeadlessFreshness(loaded.definition, loaded.result);
639
+ const complete = loaded.result.complete !== false && unavailableSymbols.length === 0 && !loaded.result.errors?.length;
490
640
  return {
491
641
  data: {
492
642
  kind: loaded.definition.shape,
@@ -496,15 +646,25 @@ export async function buildHeadlessFunctionReport(
496
646
  options: resolved.options,
497
647
  rowCount,
498
648
  empty: rowCount === 0,
499
- complete: loaded.result.complete !== false && unavailableSymbols.length === 0 && !loaded.result.errors?.length,
649
+ complete,
500
650
  unavailableSymbols,
501
651
  ...serialized,
652
+ freshness,
502
653
  },
503
654
  text: renderHeadlessPaneText(
504
655
  loaded.definition,
505
656
  loaded.result,
506
657
  loaded.args,
507
658
  resolved.label,
659
+ freshness,
660
+ ),
661
+ tables: headlessReportTables(
662
+ loaded.definition,
663
+ loaded.result,
664
+ loaded.args,
665
+ resolved.label,
666
+ freshness,
667
+ { complete, unavailableSymbols },
508
668
  ),
509
669
  };
510
670
  }
@@ -14,13 +14,16 @@ import {
14
14
  parsePaneFunctionArgs,
15
15
  type ParsedPaneFunctionArgs,
16
16
  } from "./options";
17
- import { resolvePaneFunction, type ResolvedPaneFunction } from "./resolver";
17
+ import { applyListingArgument, resolvePaneFunction, type ResolvedPaneFunction } from "./resolver";
18
18
  import { buildFunctionReport } from "./report";
19
19
  import { defaultScreenshotPath, renderDesktopShot } from "./screenshot";
20
20
  import {
21
21
  buildPaneCatalogEntries,
22
22
  } from "./catalog";
23
+ import { accessGateStatus, incompleteReportGateMessage } from "./access-gate";
23
24
  import { withPersistedCloudSession } from "./cloud-session";
25
+ import { loadForListing } from "../listing-arg";
26
+ import { selectReportTables } from "../report-tables";
24
27
 
25
28
  async function withPaneRuntime<T>(
26
29
  ctx: CliCommandContext,
@@ -31,13 +34,13 @@ async function withPaneRuntime<T>(
31
34
  registry: PaneFunctionCatalog;
32
35
  resolved: ResolvedPaneFunction;
33
36
  }) => Promise<T>,
34
- settings: { strictHeadlessOptions?: boolean } = {},
37
+ settings: { strictHeadlessOptions?: boolean; tableSection?: boolean } = {},
35
38
  ): Promise<T> {
36
- const parsed = parsePaneFunctionArgs(args, ctx.cliOptions);
37
39
  return withMarketData(ctx, async (market) => {
38
40
  const context: MarketContext = ctx.cliOptions.refresh ? { ...market, refresh: true } : market;
39
41
  const registry = await createPaneCatalog(context, ctx.plugins);
40
42
  try {
43
+ const parsed = await applyListingArgument(registry, context, parsePaneFunctionArgs(args, ctx.cliOptions));
41
44
  const resolved = await resolvePaneFunction(registry, context, parsed, settings);
42
45
  return await run({ parsed, context, registry, resolved });
43
46
  } finally {
@@ -57,22 +60,37 @@ export async function runPaneFunction(args: string[], ctx: CliCommandContext) {
57
60
  + `Use "gloomberb catalog ${resolved.token}" to inspect readiness.`,
58
61
  );
59
62
  }
63
+ const tabular = ctx.cliOptions.format === "csv" || ctx.cliOptions.format === "ndjson";
64
+ if (resolved.tableSection !== undefined && !tabular) {
65
+ throw new Error("--section picks one table of --csv or --ndjson output.");
66
+ }
67
+ if (resolved.tableSection === true) throw new Error("--section needs a section title or number.");
68
+ // A report that fails or comes back empty for an exchange the symbol is not listed on says so.
60
69
  const report = await withPersistedCloudSession(
61
70
  context,
62
- () => buildFunctionReport(resolved, context, parsed.arg),
71
+ () => loadForListing(
72
+ parsed.listing ?? [],
73
+ context,
74
+ ctx,
75
+ () => buildFunctionReport(resolved, context, parsed.arg),
76
+ (built) => built.data.empty || !built.data.complete,
77
+ ),
63
78
  );
64
79
  if (parsed.requireBotSafe && (report.data.empty || !report.data.complete)) {
65
80
  const unavailable = report.data.unavailableSymbols.length > 0
66
81
  ? ` Missing data for ${report.data.unavailableSymbols.join(", ")}.`
67
82
  : "";
83
+ const gated = incompleteReportGateMessage(resolved.token, report.data.errors);
84
+ if (gated) throw new Error(gated);
68
85
  throw new Error(
69
86
  `${resolved.token} did not produce a complete bot-safe report.${unavailable}`,
70
87
  );
71
88
  }
72
89
  ctx.printResult({ data: report.data }, {
73
90
  text: () => report.text,
91
+ ...(tabular ? { tables: selectReportTables(report.tables, resolved.tableSection) } : {}),
74
92
  });
75
- }, { strictHeadlessOptions: true });
93
+ }, { strictHeadlessOptions: true, tableSection: true });
76
94
  });
77
95
  }
78
96
 
@@ -110,7 +128,7 @@ export async function runPaneScreenshot(args: string[], ctx: CliCommandContext)
110
128
  ctx.printResult({ data: result }, {
111
129
  text: (data) => {
112
130
  const issues = [
113
- data.empty ? "empty" : null,
131
+ data.render.accessGate && (data.empty || !data.usable) ? accessGateStatus(data.render.accessGate) : data.empty ? "empty" : null,
114
132
  data.complete ? null : "incomplete",
115
133
  data.semanticMismatch ? "does not match the data" : null,
116
134
  data.usable ? null : "not usable",
@@ -9,6 +9,7 @@ import {
9
9
  } from "../../plugins/builtin/ticker-detail/financials/ratios";
10
10
  import type { PaneRuntimeState } from "../../core/state/app/state";
11
11
  import type { NormalizedPaneFunctionOptions } from "./capabilities";
12
+ import type { ListingArg } from "../listing-arg";
12
13
 
13
14
  const DEFAULT_SHOT_WIDTH = 1280;
14
15
  const DEFAULT_SHOT_HEIGHT = 720;
@@ -32,6 +33,8 @@ export interface ParsedPaneFunctionArgs {
32
33
  /** Small label drawn in the pane title bar, e.g. a domain; null draws nothing. */
33
34
  watermark: string | null;
34
35
  requireBotSafe: boolean;
36
+ /** The listing a one-ticker function's argument named, once `applyListingArgument` has resolved it. */
37
+ listing?: ListingArg;
35
38
  }
36
39
 
37
40
  export interface ParsedPaneCatalogArgs {
@@ -2,7 +2,9 @@ import type { MarketContext } from "../types";
2
2
  import type { NormalizedPaneFunctionOptions } from "./capabilities";
3
3
  import type { ResolvedPaneFunction } from "./resolver";
4
4
  import { buildHeadlessFunctionReport } from "./headless";
5
- import { appendDomReportFooter, buildDomFunctionReport } from "./dom";
5
+ import { appendDomReportFooter, buildDomFunctionReport, domReportNote } from "./dom";
6
+ import type { ReportFreshness } from "./freshness";
7
+ import type { CliReportTables } from "../report-tables";
6
8
 
7
9
  export type PaneFunctionReportSource = "headless" | "dom";
8
10
 
@@ -20,12 +22,16 @@ interface PaneFunctionReportData {
20
22
  empty: boolean;
21
23
  complete: boolean;
22
24
  unavailableSymbols: string[];
25
+ /** Source, as-of in UTC and live/delayed/stale/not-a-feed status; the last line of the text report. */
26
+ freshness: ReportFreshness;
23
27
  [key: string]: unknown;
24
28
  }
25
29
 
26
30
  export interface PaneFunctionReport {
27
31
  data: PaneFunctionReportData;
28
32
  text: string;
33
+ /** What `--csv` and `--ndjson` write: the text view's tables as flat rows, and the closing `#` lines. */
34
+ tables: CliReportTables;
29
35
  }
30
36
 
31
37
  export function resolvePaneFunctionReportSource(
@@ -56,7 +62,12 @@ export async function buildFunctionReport(
56
62
  report.text,
57
63
  elapsedMs,
58
64
  report.data.truncated === true,
65
+ report.data.freshness,
59
66
  );
67
+ report.tables = {
68
+ ...report.tables,
69
+ footer: [...report.tables.footer, `note: ${domReportNote(elapsedMs, report.data.truncated === true)}`],
70
+ };
60
71
  }
61
72
  return report;
62
73
  }
@@ -10,6 +10,7 @@ import { applyChartComposerCapabilityOptions } from "../../plugins/builtin/chart
10
10
  import { parseChartSpec } from "../../plugins/builtin/chart-composer/chart-spec";
11
11
  import { normalizeTickerInput } from "../../tickers/search";
12
12
  import { slugifyName } from "../../utils/slugify";
13
+ import { resolveCliListing } from "../listing-arg";
13
14
  import type { MarketContext } from "../types";
14
15
  import {
15
16
  buildPaneFunctionLookup,
@@ -24,6 +25,7 @@ import {
24
25
  type ParsedPaneFunctionArgs,
25
26
  } from "./options";
26
27
  import {
28
+ capabilityHasOption,
27
29
  capabilityPaneSettings,
28
30
  getHeadlessPaneDefinition,
29
31
  getPaneFunctionCapability,
@@ -45,6 +47,8 @@ export interface ResolvedPaneFunction {
45
47
  optionSettings: Record<string, unknown>;
46
48
  capability: PaneFunctionCapability;
47
49
  options: NormalizedPaneFunctionOptions;
50
+ /** `--section` of a report: the table `--csv` and `--ndjson` write, when the function has no `section` option of its own. */
51
+ tableSection?: string | true;
48
52
  }
49
53
 
50
54
  async function buildPaneInstance(
@@ -94,19 +98,65 @@ async function buildPaneInstance(
94
98
  };
95
99
  }
96
100
 
97
- export async function resolvePaneFunction(
101
+ function findPaneFunction(registry: PaneFunctionCatalog, target: string): { template?: PaneTemplateDef; pane?: PaneDef } | null {
102
+ const entry = buildPaneFunctionLookup(registry).get(normalizeLookupToken(target));
103
+ if (!entry) return null;
104
+ const template = "paneId" in entry && "description" in entry ? entry as PaneTemplateDef : undefined;
105
+ return { template, pane: template ? registry.panes.get(template.paneId) : entry as PaneDef };
106
+ }
107
+
108
+ /**
109
+ * `fn ANR SAN --exchange EPA` is `fn ANR SAN:EPA`: a function that takes one
110
+ * ticker gets the listing in its argument, and an exchange the app does not
111
+ * know fails with the venues the symbol trades on.
112
+ */
113
+ export async function applyListingArgument(
98
114
  registry: PaneFunctionCatalog,
99
115
  context: MarketContext,
100
116
  args: ParsedPaneFunctionArgs,
101
- resolutionSettings: { strictHeadlessOptions?: boolean } = {},
117
+ ): Promise<ParsedPaneFunctionArgs> {
118
+ const found = args.target ? findPaneFunction(registry, args.target) : null;
119
+ if (!found?.pane || !args.arg || /\s/.test(args.arg)) return args;
120
+ const headless = getHeadlessPaneDefinition(found.template, found.pane);
121
+ const takesOneTicker = headless ? headless.argument.kind === "ticker" : found.template?.shortcut?.argKind === "ticker";
122
+ // A function with an exchange option of its own (DIST) keeps it.
123
+ if (!takesOneTicker || getPaneFunctionCapability(found.template, found.pane).options.some((option) => option.key === "exchange")) {
124
+ return args;
125
+ }
126
+ const exchange = typeof args.options.exchange === "string" ? args.options.exchange : undefined;
127
+ const listing = await resolveCliListing(args.arg, exchange, context);
128
+ const { exchange: _exchange, ...options } = args.options;
129
+ return { ...args, arg: listing.key, options, listing };
130
+ }
131
+
132
+ /**
133
+ * `--section` picks one table of a report's `--csv` or `--ndjson` output. A
134
+ * function that has a `section` option of its own (CALLS: which part of a
135
+ * transcript) keeps the flag; its report is one table, so there is nothing to
136
+ * pick there.
137
+ */
138
+ function takeTableSection(
139
+ capability: PaneFunctionCapability,
140
+ options: ParsedPaneFunctionArgs["options"],
141
+ ): { options: ParsedPaneFunctionArgs["options"]; tableSection?: string | true } {
142
+ if (!("section" in options) || capabilityHasOption(capability, "section")) return { options };
143
+ const { section, ...rest } = options;
144
+ return { options: rest, tableSection: section };
145
+ }
146
+
147
+ export async function resolvePaneFunction(
148
+ registry: PaneFunctionCatalog,
149
+ context: MarketContext,
150
+ parsedArgs: ParsedPaneFunctionArgs,
151
+ resolutionSettings: { strictHeadlessOptions?: boolean; tableSection?: boolean } = {},
102
152
  ): Promise<ResolvedPaneFunction> {
153
+ let args = parsedArgs;
103
154
  if (!args.target) {
104
155
  throw new Error("Usage: gloomberb fn <function-or-pane> [argument] [--key value]");
105
156
  }
106
157
 
107
- const lookup = buildPaneFunctionLookup(registry);
108
- const entry = lookup.get(normalizeLookupToken(args.target));
109
- if (!entry) {
158
+ const found = findPaneFunction(registry, args.target);
159
+ if (!found) {
110
160
  const shortcuts = [...registry.paneTemplates.values()]
111
161
  .map((template) => template.shortcut?.prefix)
112
162
  .filter((prefix): prefix is string => !!prefix)
@@ -114,16 +164,19 @@ export async function resolvePaneFunction(
114
164
  throw new Error(`Unknown function or pane "${args.target}". Try one of: ${shortcuts.slice(0, 18).join(", ")}`);
115
165
  }
116
166
 
117
- const template = "paneId" in entry && "description" in entry ? entry as PaneTemplateDef : undefined;
118
- const pane = template
119
- ? registry.panes.get(template.paneId)
120
- : entry as PaneDef;
167
+ const { template, pane } = found;
121
168
  if (!pane) {
122
169
  throw new Error(`Template "${template?.id}" points at missing pane "${template?.paneId}".`);
123
170
  }
124
171
  const createOptions = buildCreateOptions(template, args.arg);
125
172
  const headless = getHeadlessPaneDefinition(template, pane);
126
173
  const capability = getPaneFunctionCapability(template, pane);
174
+ let tableSection: string | true | undefined;
175
+ if (resolutionSettings.tableSection) {
176
+ const taken = takeTableSection(capability, args.options);
177
+ args = { ...args, options: taken.options };
178
+ tableSection = taken.tableSection;
179
+ }
127
180
  const normalizedOptions = normalizeCapabilityOptions(capability, args.options, {
128
181
  strict: args.requireBotSafe || (!!headless && resolutionSettings.strictHeadlessOptions === true),
129
182
  });
@@ -149,6 +202,7 @@ export async function resolvePaneFunction(
149
202
  optionSettings: settings,
150
203
  capability,
151
204
  options: normalizedOptions,
205
+ ...(tableSection !== undefined ? { tableSection } : {}),
152
206
  };
153
207
  resolved.instance = await buildPaneInstance(resolved, context, args.arg);
154
208
  return resolved;
@@ -18,6 +18,7 @@ import { scenarioScreenshotEvidence } from "../../plugins/builtin/options-scenar
18
18
  import { realizedVolScreenshotEvidence } from "../../plugins/builtin/realized-vol/evidence";
19
19
  import { volSurfaceScreenshotEvidence } from "../../plugins/builtin/vol-surface/evidence";
20
20
  import { volatilityScreenshotEvidence } from "../../plugins/builtin/volatility/evidence";
21
+ import { worldMapScreenshotEvidence } from "../../plugins/builtin/world-venue-map/evidence";
21
22
 
22
23
  /** The envelope every pane's rendered chart-data evidence carries. */
23
24
  export interface PaneScreenshotEvidence {
@@ -93,6 +94,7 @@ const PANE_SCREENSHOT_EVIDENCE: readonly PaneScreenshotEvidenceHook[] = [
93
94
  realizedVolScreenshotEvidence,
94
95
  volSurfaceScreenshotEvidence,
95
96
  volatilityScreenshotEvidence,
97
+ worldMapScreenshotEvidence,
96
98
  ];
97
99
 
98
100
  export function paneScreenshotEvidenceHook(resolved: ResolvedPaneFunction): PaneScreenshotEvidenceHook | null {