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
@@ -0,0 +1,321 @@
1
+ import type { DataProvider } from "../types/data-provider";
2
+ import type { Quote } from "../types/financials";
3
+ import type { CliCommandContext } from "../types/plugin";
4
+ import type { TickerRecord } from "../types/ticker";
5
+ import { AmbiguousContractError, AmbiguousTickerError, listingChoiceQuery, resolveTickerSearch } from "../tickers/search";
6
+ import { cliStyles } from "../utils/cli-output";
7
+ import {
8
+ canonicalExchange,
9
+ exchangeLabel,
10
+ isKnownExchangeCode,
11
+ parsePublicTickerKey,
12
+ publicTickerKey,
13
+ } from "../utils/exchanges";
14
+ import { withMarketData } from "./scoped-context";
15
+
16
+ /** The `--exchange` option of every command that takes a ticker. */
17
+ export const EXCHANGE_OPTION = {
18
+ flags: "--exchange <code>",
19
+ description: "Listing exchange, for a symbol that trades in several places (same as SYMBOL:CODE)",
20
+ };
21
+
22
+ export class ListingArgError extends Error {
23
+ constructor(message: string, readonly details?: string) {
24
+ super(message);
25
+ this.name = "ListingArgError";
26
+ }
27
+ }
28
+
29
+ export interface ListingArg {
30
+ /** The symbol without a venue: SAN. */
31
+ symbol: string;
32
+ /** The canonical code of the exchange the user named, or "" when none was. */
33
+ exchange: string;
34
+ /** SAN:EPA, or SAN when no exchange was named. */
35
+ key: string;
36
+ }
37
+
38
+ /**
39
+ * `SAN:EPA` and `SAN --exchange EPA` name the same listing. Both spellings of
40
+ * an exchange go through the app's alias table, so `SAN:XPAR` is `SAN:EPA`.
41
+ * A symbol's own exchange and `--exchange` that disagree are an error, unless
42
+ * the command takes several symbols and `--exchange` only fills in the ones
43
+ * without an exchange of their own.
44
+ */
45
+ export function parseListingArg(
46
+ raw: string,
47
+ exchangeOption?: string | null,
48
+ { ownExchangeWins = false }: { ownExchangeWins?: boolean } = {},
49
+ ): ListingArg {
50
+ const option = canonicalExchange(exchangeOption ?? "");
51
+ let typed = raw.trim().replace(/^\$/, "").toUpperCase();
52
+ // `SAN:` asks which listing; with --exchange it has its answer.
53
+ if (option && typed.endsWith(":")) typed = typed.slice(0, -1);
54
+ const parsed = parsePublicTickerKey(typed);
55
+ if (parsed.exchange && option && parsed.exchange !== option && !ownExchangeWins) {
56
+ throw new ListingArgError(
57
+ `${typed} names exchange ${parsed.exchange}, but --exchange names ${option}.`,
58
+ `Name the exchange once, as ${parsed.symbol}:${parsed.exchange} or ${parsed.symbol} --exchange ${option}.`,
59
+ );
60
+ }
61
+ const exchange = parsed.exchange ?? option;
62
+ return { symbol: parsed.symbol, exchange, key: exchange ? `${parsed.symbol}:${exchange}` : parsed.symbol };
63
+ }
64
+
65
+ interface ListingStore {
66
+ loadTicker(symbol: string): Promise<TickerRecord | null>;
67
+ loadAllTickers(): Promise<TickerRecord[]>;
68
+ }
69
+
70
+ export interface ListingDeps {
71
+ store: ListingStore;
72
+ dataProvider: DataProvider;
73
+ }
74
+
75
+ export interface ListingVenue {
76
+ /** Canonical code. */
77
+ exchange: string;
78
+ name: string;
79
+ }
80
+
81
+ /**
82
+ * The venues a symbol trades on and the company on each, from the same
83
+ * listing picker the command bar opens for `SAN:`.
84
+ */
85
+ export async function listingVenues(symbol: string, { store, dataProvider }: ListingDeps): Promise<ListingVenue[]> {
86
+ const query = `${symbol}:`;
87
+ if (!listingChoiceQuery(query)) return [];
88
+ const tickers = new Map((await store.loadAllTickers()).map((ticker) => [ticker.metadata.ticker.toUpperCase(), ticker] as const));
89
+ let venues: ListingVenue[];
90
+ try {
91
+ const resolved = await resolveTickerSearch({ query, activeTicker: null, tickers, dataProvider });
92
+ const only = !resolved ? null
93
+ : resolved.kind === "local" ? { exchange: resolved.ticker.metadata.exchange, name: resolved.ticker.metadata.name }
94
+ : {
95
+ exchange: resolved.result.exchange === "SMART" ? resolved.result.primaryExchange ?? "" : resolved.result.exchange || resolved.result.primaryExchange || "",
96
+ name: resolved.result.name,
97
+ };
98
+ venues = only?.exchange ? [{ exchange: canonicalExchange(only.exchange), name: only.name }] : [];
99
+ } catch (error) {
100
+ // One listing settles the picker; several are its choices.
101
+ if (!(error instanceof AmbiguousTickerError) || error instanceof AmbiguousContractError) return [];
102
+ venues = error.listings.flatMap((listing) => {
103
+ const exchange = parsePublicTickerKey(listing).exchange;
104
+ return exchange ? [{ exchange, name: error.listingNames[listing] ?? "" }] : [];
105
+ });
106
+ }
107
+ return venues.filter((venue, index) => venues.findIndex((other) => other.exchange === venue.exchange) === index);
108
+ }
109
+
110
+ function tradesOn(symbol: string, venues: readonly ListingVenue[]): string {
111
+ return venues.length > 0 ? ` ${symbol} trades on: ${venues.map((venue) => venue.exchange).join(", ")}.` : "";
112
+ }
113
+
114
+ /**
115
+ * An exchange code the app does not know is accepted only when the symbol is
116
+ * listed there, so a typo never falls back to another venue's line.
117
+ */
118
+ async function checkListingExchange(listing: ListingArg, deps: ListingDeps): Promise<void> {
119
+ if (listing.symbol.endsWith(":")) {
120
+ const symbol = listing.symbol.slice(0, -1);
121
+ throw new ListingArgError(`Choose an exchange for ${symbol}.${tradesOn(symbol, await listingVenues(symbol, deps))}`);
122
+ }
123
+ if (!listing.exchange || isKnownExchangeCode(listing.exchange)) return;
124
+ const venues = await listingVenues(listing.symbol, deps);
125
+ if (venues.some((venue) => venue.exchange === listing.exchange)) return;
126
+ throw new ListingArgError(
127
+ `Unknown exchange ${listing.exchange} for ${listing.symbol}.${tradesOn(listing.symbol, venues)}`,
128
+ venues.length > 0 ? undefined : `No listings of ${listing.symbol} were found.`,
129
+ );
130
+ }
131
+
132
+ /**
133
+ * "SAN does not trade on TSX. SAN trades on: NYSE, EPA." for a listing whose
134
+ * exchange the symbol is not listed on, from the same picker `SAN:` opens.
135
+ * Null when no exchange was named, when the symbol is listed there, or when its
136
+ * venues cannot be found, so the request's own failure stands. It searches, so
137
+ * ask only after a request came back empty.
138
+ */
139
+ export async function notTradedMessage(
140
+ listing: Pick<ListingArg, "symbol" | "exchange">,
141
+ deps: ListingDeps,
142
+ ): Promise<string | null> {
143
+ if (!listing.exchange) return null;
144
+ const venues = await listingVenues(listing.symbol, deps).catch(() => []);
145
+ if (venues.length === 0 || venues.some((venue) => venue.exchange === listing.exchange)) return null;
146
+ return `${listing.symbol} does not trade on ${listing.exchange}.${tradesOn(listing.symbol, venues)}`;
147
+ }
148
+
149
+ /** Fails the command with `notTradedMessage`; returns when the symbol does trade there. */
150
+ export async function failIfNotTraded(
151
+ listing: Pick<ListingArg, "symbol" | "exchange">,
152
+ deps: ListingDeps,
153
+ ctx: Pick<CliCommandContext, "fail">,
154
+ ): Promise<void> {
155
+ const message = await notTradedMessage(listing, deps);
156
+ if (message) ctx.fail(message);
157
+ }
158
+
159
+ /**
160
+ * A data request for the listings a command named. When it throws, or `isMiss`
161
+ * calls what it returned empty, and a listing's exchange is one its symbol does
162
+ * not trade on, the command ends in that message instead of the request's own
163
+ * "unavailable". A request that succeeds costs no extra lookup.
164
+ */
165
+ export async function loadForListing<T>(
166
+ listings: Pick<ListingArg, "symbol" | "exchange"> | readonly Pick<ListingArg, "symbol" | "exchange">[],
167
+ deps: ListingDeps,
168
+ ctx: Pick<CliCommandContext, "fail">,
169
+ load: () => Promise<T>,
170
+ isMiss?: (value: T) => boolean,
171
+ ): Promise<T> {
172
+ const named = ("symbol" in listings ? [listings] : listings).filter((listing) => listing.exchange);
173
+ const checkVenues = () => Promise.all(named.map((listing) => failIfNotTraded(listing, deps, ctx)));
174
+ let value: T;
175
+ try {
176
+ value = await load();
177
+ } catch (error) {
178
+ await checkVenues();
179
+ throw error;
180
+ }
181
+ if (isMiss?.(value)) await checkVenues();
182
+ return value;
183
+ }
184
+
185
+ /** The saved ticker for a listing: under its own key, or a saved symbol whose venue it is. */
186
+ export async function loadSavedListing(store: ListingStore, listing: ListingArg): Promise<TickerRecord | null> {
187
+ if (!listing.exchange) return store.loadTicker(listing.symbol);
188
+ for (const key of new Set([listing.key, publicTickerKey(listing.symbol, listing.exchange), listing.symbol])) {
189
+ const ticker = await store.loadTicker(key);
190
+ if (ticker && (key === listing.key || canonicalExchange(ticker.metadata.exchange) === listing.exchange)) return ticker;
191
+ }
192
+ return null;
193
+ }
194
+
195
+ export interface CliListing extends ListingArg {
196
+ saved: TickerRecord | null;
197
+ /**
198
+ * What data requests take: a named listing goes by its key (SAN:EPA), never
199
+ * the bare symbol's cache; a bare symbol goes on its saved venue, as the
200
+ * command bar opens it.
201
+ */
202
+ request: { symbol: string; exchange: string };
203
+ }
204
+
205
+ export async function resolveCliListing(
206
+ raw: string,
207
+ exchangeOption: string | null | undefined,
208
+ deps: ListingDeps,
209
+ options: { ownExchangeWins?: boolean } = {},
210
+ ): Promise<CliListing> {
211
+ const listing = parseListingArg(raw, exchangeOption, options);
212
+ if (!listing.symbol) throw new ListingArgError("Ticker symbol is required.");
213
+ await checkListingExchange(listing, deps);
214
+ const saved = await loadSavedListing(deps.store, listing);
215
+ return {
216
+ ...listing,
217
+ saved,
218
+ request: listing.exchange
219
+ ? { symbol: listing.key, exchange: listing.exchange }
220
+ : { symbol: listing.symbol, exchange: saved?.metadata.exchange ?? "" },
221
+ };
222
+ }
223
+
224
+ /** `resolveCliListing` for a command: a bad exchange fails the command with its message. */
225
+ export async function requireCliListing(
226
+ raw: string,
227
+ exchangeOption: string | null | undefined,
228
+ deps: ListingDeps,
229
+ ctx: Pick<CliCommandContext, "fail">,
230
+ options: { ownExchangeWins?: boolean } = {},
231
+ ): Promise<CliListing> {
232
+ try {
233
+ return await resolveCliListing(raw, exchangeOption, deps, options);
234
+ } catch (error) {
235
+ if (error instanceof ListingArgError) ctx.fail(error.message, error.details);
236
+ throw error;
237
+ }
238
+ }
239
+
240
+ /**
241
+ * The listing for commands that store things by symbol (notes, alerts). The
242
+ * data sources are only opened to check an exchange the app does not know.
243
+ */
244
+ export async function requireListingArg(
245
+ raw: string,
246
+ exchangeOption: string | null | undefined,
247
+ ctx: Pick<CliCommandContext, "fail" | "initMarketData">,
248
+ ): Promise<ListingArg> {
249
+ try {
250
+ const listing = parseListingArg(raw, exchangeOption);
251
+ if (listing.symbol.endsWith(":") || (listing.exchange && !isKnownExchangeCode(listing.exchange))) {
252
+ await withMarketData(ctx, (market) => checkListingExchange(listing, market));
253
+ }
254
+ return listing;
255
+ } catch (error) {
256
+ if (error instanceof ListingArgError) ctx.fail(error.message, error.details);
257
+ throw error;
258
+ }
259
+ }
260
+
261
+ export interface ListingIdentity {
262
+ symbol: string;
263
+ /** Canonical code of the venue the data is for. */
264
+ exchange: string;
265
+ /** The listing's company, from its own quote. */
266
+ name: string | null;
267
+ }
268
+
269
+ export function listingIdentity(
270
+ listing: CliListing,
271
+ quote?: Pick<Quote, "name" | "listingExchangeName" | "exchangeName"> | null,
272
+ ): ListingIdentity {
273
+ const quoteExchange = canonicalExchange(quote?.listingExchangeName || quote?.exchangeName);
274
+ const exchange = listing.exchange || quoteExchange || canonicalExchange(listing.saved?.metadata.exchange);
275
+ // A quote that prices another venue names another listing's company.
276
+ const quoteName = !quoteExchange || quoteExchange === exchange ? quote?.name?.trim() : undefined;
277
+ return { symbol: listing.symbol, exchange, name: quoteName || listing.saved?.metadata.name?.trim() || null };
278
+ }
279
+
280
+ /** The listing's own quote, for its company name and venue; null when it has none. */
281
+ export async function loadListingQuote(dataProvider: DataProvider, listing: CliListing): Promise<Quote | null> {
282
+ try {
283
+ return await dataProvider.getQuote(listing.request.symbol, listing.request.exchange);
284
+ } catch {
285
+ return null;
286
+ }
287
+ }
288
+
289
+ /** One line above a table naming what it is about: "Sanofi · Euronext Paris (EPA)". */
290
+ export function listingHeading(identity: ListingIdentity): string {
291
+ const venue = identity.exchange ? cliStyles.muted(` · ${exchangeLabel(identity.exchange)}`) : "";
292
+ return `${cliStyles.bold(identity.name || identity.symbol)}${venue}`;
293
+ }
294
+
295
+ /** "Sanofi (EPA)", for sentences. */
296
+ export function listingTitle(identity: ListingIdentity): string {
297
+ const name = identity.name || identity.symbol;
298
+ return identity.exchange ? `${name} (${identity.exchange})` : name;
299
+ }
300
+
301
+ export interface SavedListingName {
302
+ symbol: string;
303
+ /** Canonical code of the venue the row is saved for, or "" when it has none. */
304
+ exchange: string;
305
+ /** SAN:EPA, whichever way the row is stored (SAN, SAN:XNYS). */
306
+ key: string;
307
+ name: string | null;
308
+ /** "SAN:EPA (Sanofi)", for sentences. */
309
+ label: string;
310
+ }
311
+
312
+ /** The listing a saved ticker row is, as a collection command names it after adding or removing it. */
313
+ export function savedListingName(ticker: TickerRecord): SavedListingName {
314
+ const { symbol } = parsePublicTickerKey(ticker.metadata.ticker);
315
+ const exchange = canonicalExchange(ticker.metadata.exchange);
316
+ const key = exchange ? `${symbol}:${exchange}` : symbol;
317
+ // A row saved without a company carries its symbol as the name.
318
+ const typed = ticker.metadata.name?.trim();
319
+ const name = typed && typed !== symbol && typed !== ticker.metadata.ticker ? typed : null;
320
+ return { symbol, exchange, key, name, label: name ? `${key} (${name})` : key };
321
+ }
@@ -15,6 +15,8 @@ export interface ParsedCliArgs {
15
15
  options: CliGlobalOptions;
16
16
  /** `--help` or `-h` appeared before `--`. The flag is removed from args. */
17
17
  help: boolean;
18
+ /** Index in `args` where the arguments after a bare `--` begin; they are never options. */
19
+ literalStart: number;
18
20
  }
19
21
 
20
22
  export function isCliHelpFlag(arg: string): boolean {
@@ -43,10 +45,12 @@ export function parseCliGlobalArgs(rawArgs: string[]): ParsedCliArgs {
43
45
  const options: CliGlobalOptions = { ...DEFAULT_CLI_OPTIONS };
44
46
  const args: string[] = [];
45
47
  let help = false;
48
+ let literalStart: number | null = null;
46
49
 
47
50
  for (let index = 0; index < rawArgs.length; index += 1) {
48
51
  const arg = rawArgs[index]!;
49
52
  if (arg === "--") {
53
+ literalStart = args.length;
50
54
  args.push(...rawArgs.slice(index + 1));
51
55
  break;
52
56
  }
@@ -102,5 +106,5 @@ export function parseCliGlobalArgs(rawArgs: string[]): ParsedCliArgs {
102
106
  args.push(arg);
103
107
  }
104
108
 
105
- return { args, options, help };
109
+ return { args, options, help, literalStart: literalStart ?? args.length };
106
110
  }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * What keeps a pane from showing everything it has: a Pro lock on part of it,
3
+ * or a wall that needs an account. Reports and screenshots name it, so a
4
+ * failure says "locked" instead of a generic incomplete or empty.
5
+ */
6
+ export type PaneAccessGate = "pro" | "sign-in";
7
+
8
+ // A Pro-gated loader reports what is locked in its errors ("Full history requires Gloom Pro").
9
+ const SIGN_IN_ERROR = /\bsign(?:ed)?[ -]?in\b|\bsignup\b|\bemail verification\b|\bverify your email\b/i;
10
+ const PRO_ERROR = /\bGloom (?:Cloud )?Pro\b|\b(?:requires?|needs?) Pro\b|\bPro access\b/;
11
+
12
+ function errorMessages(errors: unknown): string[] {
13
+ return Array.isArray(errors) ? errors.filter((error): error is string => typeof error === "string") : [];
14
+ }
15
+
16
+ /** Why the output cannot be used as it is, as a clause: "some values need Gloom Cloud Pro (locked)". */
17
+ function accessGateReason(gate: PaneAccessGate): string {
18
+ return gate === "pro" ? "some values need Gloom Cloud Pro (locked)" : "it needs a Gloom Cloud sign-in";
19
+ }
20
+
21
+ /** The reason as a sentence, for a screenshot's "Reason" row. */
22
+ export function accessGateSentence(gate: PaneAccessGate): string {
23
+ const reason = accessGateReason(gate);
24
+ return `${reason.charAt(0).toUpperCase()}${reason.slice(1)}.`;
25
+ }
26
+
27
+ /** The word a screenshot's status line uses in place of "empty" for a gated pane. */
28
+ export function accessGateStatus(gate: PaneAccessGate): string {
29
+ return gate === "pro" ? "locked" : "needs sign-in";
30
+ }
31
+
32
+ /**
33
+ * The failure for an incomplete report whose own errors name a gate, with
34
+ * those errors saying which values; null when they name none.
35
+ */
36
+ export function incompleteReportGateMessage(token: string, errors: unknown): string | null {
37
+ const messages = errorMessages(errors);
38
+ const gate = messages.some((message) => SIGN_IN_ERROR.test(message)) ? "sign-in"
39
+ : messages.some((message) => PRO_ERROR.test(message)) ? "pro" : null;
40
+ const detail = messages.map((message) => message.replace(/\.+$/, "")).join(". ");
41
+ return gate ? `${token} is not bot-safe: ${accessGateReason(gate)}. ${detail}.` : null;
42
+ }
@@ -134,6 +134,11 @@ function resolveOptionDef(
134
134
  ));
135
135
  }
136
136
 
137
+ /** Whether the function has an option of its own under this name or an alias. */
138
+ export function capabilityHasOption(capability: PaneFunctionCapability, key: string): boolean {
139
+ return resolveOptionDef(capability, key) !== undefined;
140
+ }
141
+
137
142
  function normalizeEnumValue(option: PaneFunctionOptionDef, rawValue: string): string {
138
143
  const token = optionToken(rawValue);
139
144
  const match = option.values?.find((candidate) => (
@@ -199,6 +199,30 @@ export async function buildPaneCatalogEntries(
199
199
  return entries.sort((left, right) => left.token.localeCompare(right.token));
200
200
  }
201
201
 
202
+ /** The phrase starting a word of the text, so "funding rate" finds "funding rates" but "rate" is not found in "separate". */
203
+ function containsPhrase(text: string, phrase: string): boolean {
204
+ for (let at = text.indexOf(phrase); at >= 0; at = text.indexOf(phrase, at + 1)) {
205
+ if (at === 0 || !/[a-z0-9]/.test(text[at - 1]!)) return true;
206
+ }
207
+ return false;
208
+ }
209
+
210
+ // A multi-word query ranks a function carrying the whole phrase in its name or keywords first, then in its
211
+ // description, then one matching every word somewhere; the rest rank by how many words they match.
212
+ const PHRASE_IN_NAME_BAND = 4000;
213
+ const PHRASE_IN_DESCRIPTION_BAND = 3000;
214
+ const ALL_WORDS_BAND = 2000;
215
+ const PER_MATCHED_WORD = 100;
216
+
217
+ function phraseBand(entry: PaneCatalogEntry, phrase: string): number {
218
+ const lower = (values: Array<string | undefined>) => values
219
+ .filter((value): value is string => !!value).map((value) => value.toLowerCase().replace(/\s+/g, " "));
220
+ const names = lower([entry.token, entry.label, entry.paneName, entry.shortcut, ...entry.aliases, ...entry.keywords, ...entry.capability.aliases]);
221
+ if (names.some((name) => containsPhrase(name, phrase))) return PHRASE_IN_NAME_BAND;
222
+ const descriptions = lower([entry.description, ...entry.capability.intents]);
223
+ return descriptions.some((description) => containsPhrase(description, phrase)) ? PHRASE_IN_DESCRIPTION_BAND : 0;
224
+ }
225
+
202
226
  function paneCatalogSearchScore(entry: PaneCatalogEntry, query: string): number {
203
227
  const terms = query.toLowerCase().split(/\s+/).map((term) => term.trim()).filter(Boolean);
204
228
  if (terms.length === 0) return 1;
@@ -253,7 +277,10 @@ function paneCatalogSearchScore(entry: PaneCatalogEntry, query: string): number
253
277
  if (matchedTerms === 0) return 0;
254
278
  score += Math.round((matchedTerms / terms.length) * 8);
255
279
  if (entry.capability.botSafe) score += 2;
256
- return score;
280
+ // One word has no phrase to prefer: it keeps the plain term scores.
281
+ if (terms.length === 1) return score;
282
+ const band = phraseBand(entry, terms.join(" "));
283
+ return score + matchedTerms * PER_MATCHED_WORD + (band || (matchedTerms === terms.length ? ALL_WORDS_BAND : 0));
257
284
  }
258
285
 
259
286
  export function filterPaneCatalogEntries(entries: PaneCatalogEntry[], query: string): PaneCatalogEntry[] {
@@ -182,5 +182,7 @@ export function collectShotSymbols(resolved: ResolvedPaneFunction, rawArg: strin
182
182
  if (resolved.capability.id === "security-relationship" && symbols.length === 1) {
183
183
  symbols = [...symbols, "SPY"];
184
184
  }
185
- return [...new Set(symbols.map(cleanTickerInput).filter(Boolean))];
185
+ // Entries a ticker list keeps as typed (CORR's GEO:HORMUZ) are not tickers to fetch.
186
+ const keep = resolved.template?.shortcut?.keepArgToken;
187
+ return [...new Set(symbols.filter((symbol) => !keep?.(symbol)).map(cleanTickerInput).filter(Boolean))];
186
188
  }
@@ -1,10 +1,13 @@
1
1
  import type { DesktopPaneShotRenderedRow } from "../desktop-pane-shot";
2
- import { renderSection, renderTable } from "../../utils/cli-output";
2
+ import { cliStyles, renderSection, renderTable } from "../../utils/cli-output";
3
+ import { formatUtcTime } from "../../utils/utc-time";
3
4
  import type { MarketContext } from "../types";
4
5
  import type { PaneFunctionReport } from "./report";
5
6
  import type { ResolvedPaneFunction } from "./resolver";
6
7
  import { collectShotSymbols } from "./data";
7
8
  import { renderDesktopShot, type PaneScreenshotResult } from "./screenshot";
9
+ import { deriveRenderedFreshness, formatFreshnessLine, type ReportFreshness } from "./freshness";
10
+ import { exportTextTable, reportFooterLines, type CliReportTables } from "../report-tables";
8
11
 
9
12
  const DOM_REPORT_WIDTH = 1280;
10
13
  const DOM_REPORT_HEIGHT = 720;
@@ -32,7 +35,21 @@ function domCellKeys(row: DesktopPaneShotRenderedRow): string[] {
32
35
  });
33
36
  }
34
37
 
35
- function renderDomTables(rows: DesktopPaneShotRenderedRow[]): string[] {
38
+ /**
39
+ * A pane may shorten a time to fit ("Wed 11:27", "Oct 2"); the report prints
40
+ * the instant behind it with its date and zone instead.
41
+ */
42
+ function cellText(cell: DesktopPaneShotRenderedRow["cells"][number]): string {
43
+ return cell.instant ? formatUtcTime(cell.instant) || cell.text : cell.text;
44
+ }
45
+
46
+ interface DomTable {
47
+ tableIndex: number;
48
+ columns: Array<{ key: string; header: string }>;
49
+ rows: Array<Map<string, DesktopPaneShotRenderedRow["cells"][number]>>;
50
+ }
51
+
52
+ function domTables(rows: DesktopPaneShotRenderedRow[]): DomTable[] {
36
53
  const byTable = new Map<number, DesktopPaneShotRenderedRow[]>();
37
54
  for (const row of rows) {
38
55
  const tableRows = byTable.get(row.tableIndex) ?? [];
@@ -40,7 +57,7 @@ function renderDomTables(rows: DesktopPaneShotRenderedRow[]): string[] {
40
57
  byTable.set(row.tableIndex, tableRows);
41
58
  }
42
59
 
43
- return [...byTable.entries()].flatMap(([tableIndex, tableRows], index) => {
60
+ return [...byTable.entries()].map(([tableIndex, tableRows]) => {
44
61
  // Captured rows omit blank cells, so a cell's position is not its column.
45
62
  const columns: Array<{ key: string; header: string }> = [];
46
63
  for (const row of tableRows) {
@@ -56,22 +73,54 @@ function renderDomTables(rows: DesktopPaneShotRenderedRow[]): string[] {
56
73
  previous = position;
57
74
  }
58
75
  }
59
- const output = renderTable(
76
+ return {
77
+ tableIndex,
60
78
  columns,
61
- tableRows.map((row) => {
79
+ rows: tableRows.map((row) => {
62
80
  const keys = domCellKeys(row);
63
- const textByKey = new Map(row.cells.map((cell, cellIndex) => [keys[cellIndex]!, cell.text]));
64
- return columns.map((column) => textByKey.get(column.key) ?? "");
81
+ return new Map(row.cells.map((cell, cellIndex) => [keys[cellIndex]!, cell]));
65
82
  }),
66
- );
67
- return [
68
- ...(index > 0 ? [""] : []),
69
- ...(byTable.size > 1 ? [renderSection(`Rendered table ${tableIndex + 1}`)] : []),
70
- output,
71
- ];
83
+ };
72
84
  });
73
85
  }
74
86
 
87
+ function domTableTitle(table: DomTable): string {
88
+ return `Rendered table ${table.tableIndex + 1}`;
89
+ }
90
+
91
+ function renderDomTables(rows: DesktopPaneShotRenderedRow[]): string[] {
92
+ const tables = domTables(rows);
93
+ return tables.flatMap((table, index) => [
94
+ ...(index > 0 ? [""] : []),
95
+ ...(tables.length > 1 ? [renderSection(domTableTitle(table))] : []),
96
+ renderTable(
97
+ table.columns,
98
+ table.rows.map((cells) => table.columns.map((column) => {
99
+ const cell = cells.get(column.key);
100
+ return cell ? cellText(cell) : "";
101
+ })),
102
+ ),
103
+ ]);
104
+ }
105
+
106
+ /** The rendered tables as `--csv` writes them, with the instant behind a shortened time. */
107
+ function domReportTables(
108
+ rows: DesktopPaneShotRenderedRow[],
109
+ title: string,
110
+ freshness: ReportFreshness,
111
+ incomplete: boolean | string,
112
+ ): CliReportTables {
113
+ const tables = domTables(rows);
114
+ return {
115
+ tables: tables.map((table) => exportTextTable(
116
+ tables.length > 1 ? domTableTitle(table) : title,
117
+ table.columns.map((column) => column.header),
118
+ table.rows.map((cells) => table.columns.map((column) => cells.get(column.key))),
119
+ )),
120
+ footer: reportFooterLines({ freshness, incomplete }),
121
+ };
122
+ }
123
+
75
124
  function renderedFailureReason(
76
125
  result: PaneScreenshotResult,
77
126
  rows: DesktopPaneShotRenderedRow[],
@@ -129,7 +178,12 @@ export function buildDomPaneReportFromRender(
129
178
  textLines.push(failureReason ?? "No rendered values were available.");
130
179
  }
131
180
  if (failureReason && rows.length > 0) textLines.push("", failureReason);
181
+ const freshness = deriveRenderedFreshness(resolved.pane.reportFreshness, {
182
+ footerText: result.render.footerText ?? "",
183
+ cellTimes: rows.flatMap((row) => row.cells.flatMap((cell) => cell.instant ?? [])),
184
+ });
132
185
 
186
+ const complete = failureReason === null && !truncated;
133
187
  return {
134
188
  data: {
135
189
  kind: "rendered-view",
@@ -139,7 +193,7 @@ export function buildDomPaneReportFromRender(
139
193
  options: resolved.options,
140
194
  rowCount: rows.length,
141
195
  empty: rows.length === 0,
142
- complete: failureReason === null && !truncated,
196
+ complete,
143
197
  unavailableSymbols,
144
198
  rows,
145
199
  visibleText: result.render.visibleText,
@@ -147,8 +201,15 @@ export function buildDomPaneReportFromRender(
147
201
  truncationReasons,
148
202
  limitation: DOM_LIMITATION,
149
203
  ...(failureReason ? { reason: failureReason } : {}),
204
+ freshness,
150
205
  },
151
206
  text: textLines.join("\n").trimEnd(),
207
+ tables: domReportTables(
208
+ rows,
209
+ resolved.label,
210
+ freshness,
211
+ !complete && (failureReason ?? (truncationReasons.length > 0 ? truncationReasons.join("; ") : true)),
212
+ ),
152
213
  };
153
214
  }
154
215
 
@@ -156,15 +217,22 @@ export function appendDomReportFooter(
156
217
  text: string,
157
218
  elapsedMs: number,
158
219
  truncated: boolean,
220
+ freshness: ReportFreshness,
159
221
  ): string {
160
- const clipping = truncated ? "The rendered view is clipped." : "The rendered view may be clipped.";
161
222
  return [
162
223
  text,
163
224
  "",
164
- `Rendered view: values come from the visible pane. ${clipping} Render time: ${elapsedMs} ms.`,
225
+ domReportNote(elapsedMs, truncated),
226
+ cliStyles.muted(formatFreshnessLine(freshness)),
165
227
  ].join("\n");
166
228
  }
167
229
 
230
+ /** What a rendered-view report says about where its values come from. */
231
+ export function domReportNote(elapsedMs: number, truncated: boolean): string {
232
+ const clipping = truncated ? "The rendered view is clipped." : "The rendered view may be clipped.";
233
+ return `Rendered view: values come from the visible pane. ${clipping} Render time: ${elapsedMs} ms.`;
234
+ }
235
+
168
236
  function failedDomReport(
169
237
  resolved: ResolvedPaneFunction,
170
238
  rawArg: string,
@@ -176,6 +244,7 @@ function failedDomReport(
176
244
  .trim();
177
245
  const reason = `The rendered view could not be read: ${message || "unknown renderer error"}`;
178
246
  const symbols = collectShotSymbols(resolved, rawArg);
247
+ const freshness = deriveRenderedFreshness(resolved.pane.reportFreshness, { footerText: "", cellTimes: [] });
179
248
  return {
180
249
  data: {
181
250
  kind: "rendered-view",
@@ -193,8 +262,10 @@ function failedDomReport(
193
262
  truncationReasons: [],
194
263
  limitation: DOM_LIMITATION,
195
264
  reason,
265
+ freshness,
196
266
  },
197
267
  text: [resolved.label, "", reason].join("\n"),
268
+ tables: { tables: [], footer: reportFooterLines({ freshness, incomplete: reason }) },
198
269
  };
199
270
  }
200
271