gloomberb 0.16.0 → 0.16.2

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 (691) 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 +44 -11
  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 +5 -0
  8. package/src/api-client/market-discovery.ts +10 -0
  9. package/src/api-client/members.ts +26 -0
  10. package/src/api-client/paths.ts +30 -1
  11. package/src/api-client/perps.ts +41 -0
  12. package/src/api-client/request.ts +5 -2
  13. package/src/api-client/types.ts +9 -1
  14. package/src/app/global-shortcuts.ts +14 -6
  15. package/src/app/keybindings/actions.ts +1 -1
  16. package/src/app/runtime/update.ts +38 -2
  17. package/src/app.tsx +10 -6
  18. package/src/brokers/account-cache.ts +24 -0
  19. package/src/cli/commands/command-utils.ts +8 -0
  20. package/src/cli/commands/crypto-hints.ts +75 -0
  21. package/src/cli/commands/market.ts +414 -106
  22. package/src/cli/commands/overview.ts +77 -32
  23. package/src/cli/commands/ticker.ts +101 -43
  24. package/src/cli/desktop-pane-shot.ts +34 -4
  25. package/src/cli/freshness.ts +61 -0
  26. package/src/cli/help.ts +1 -0
  27. package/src/cli/helpers.ts +4 -8
  28. package/src/cli/index.ts +12 -2
  29. package/src/cli/listing-arg.ts +321 -0
  30. package/src/cli/pane-functions/access-gate.ts +42 -0
  31. package/src/cli/pane-functions/catalog.ts +28 -1
  32. package/src/cli/pane-functions/data.ts +3 -1
  33. package/src/cli/pane-functions/dom.ts +20 -2
  34. package/src/cli/pane-functions/freshness.ts +400 -0
  35. package/src/cli/pane-functions/function-help.ts +36 -22
  36. package/src/cli/pane-functions/headless.ts +39 -11
  37. package/src/cli/pane-functions/index.ts +15 -4
  38. package/src/cli/pane-functions/options.ts +3 -0
  39. package/src/cli/pane-functions/report.ts +4 -0
  40. package/src/cli/pane-functions/resolver.ts +35 -7
  41. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  42. package/src/cli/pane-functions/screenshot.ts +7 -3
  43. package/src/cli/result.ts +41 -27
  44. package/src/cli/ticker-resolution.ts +7 -5
  45. package/src/components/chart/composite/composite-chart.tsx +88 -2536
  46. package/src/components/chart/composite/drawing-store.ts +59 -0
  47. package/src/components/chart/composite/legend.tsx +319 -0
  48. package/src/components/chart/composite/panel-bitmap.ts +139 -0
  49. package/src/components/chart/composite/panel-gestures.ts +59 -0
  50. package/src/components/chart/composite/panel-labels.ts +107 -0
  51. package/src/components/chart/composite/panel-surface.tsx +876 -0
  52. package/src/components/chart/composite/tool-catalog.ts +98 -0
  53. package/src/components/chart/composite/toolbar.tsx +186 -0
  54. package/src/components/chart/composite/tools.ts +8 -0
  55. package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
  56. package/src/components/chart/composite/use-composite-viewport.ts +143 -0
  57. package/src/components/command-bar/commands/collection.ts +5 -1
  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/root/command-items.ts +9 -2
  62. package/src/components/command-bar/routes/root/plugin-install.ts +2 -2
  63. package/src/components/command-bar/routes/root/provider-search.ts +19 -5
  64. package/src/components/command-bar/routes/root/runtime.ts +14 -5
  65. package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
  66. package/src/components/command-bar/routes/ticker-search/results.ts +31 -5
  67. package/src/components/command-bar/routes/ticker-search/route.ts +2 -2
  68. package/src/components/command-bar/routing/actions.ts +2 -0
  69. package/src/components/command-bar/selection-runtime.ts +38 -0
  70. package/src/components/command-bar/surface/index.tsx +7 -2
  71. package/src/components/command-bar/workflow/ops.ts +1 -1
  72. package/src/components/command-bar/workflow/tickers.ts +6 -0
  73. package/src/components/data-table/view.tsx +29 -10
  74. package/src/components/feedback-dialog.tsx +2 -1
  75. package/src/components/form-modal/field-row.tsx +2 -2
  76. package/src/components/index.ts +2 -2
  77. package/src/components/layout/detached-pane-shell.tsx +6 -3
  78. package/src/components/layout/floating-pane.tsx +6 -0
  79. package/src/components/layout/header.tsx +24 -7
  80. package/src/components/layout/missing-pane.tsx +2 -2
  81. package/src/components/layout/pane/content.tsx +23 -10
  82. package/src/components/layout/pane/error-boundary.tsx +103 -0
  83. package/src/components/layout/pane/footer/registration.tsx +68 -23
  84. package/src/components/layout/pane/header.tsx +61 -28
  85. package/src/components/layout/pane/index.tsx +6 -0
  86. package/src/components/layout/pane/title.ts +31 -7
  87. package/src/components/layout/shell/drag/index.ts +6 -5
  88. package/src/components/layout/shell/drag/runtime.ts +3 -0
  89. package/src/components/layout/shell/index.tsx +6 -0
  90. package/src/components/layout/shell/menu.ts +2 -1
  91. package/src/components/layout/shell/pane/actions.ts +2 -1
  92. package/src/components/layout/shell/pane/layers.tsx +29 -10
  93. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -3
  94. package/src/components/layout/shell/ticker-link-menu.ts +23 -9
  95. package/src/components/metric-treemap/heat-surface.tsx +745 -0
  96. package/src/components/metric-treemap/heat-tiles.ts +228 -0
  97. package/src/components/metric-treemap/index.tsx +2 -0
  98. package/src/components/metric-treemap/layout.ts +8 -0
  99. package/src/components/metric-treemap/scene.ts +432 -0
  100. package/src/components/onboarding/onboarding-keyboard.ts +311 -0
  101. package/src/components/onboarding/onboarding-wizard.tsx +101 -788
  102. package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
  103. package/src/components/onboarding/use-onboarding-progress.ts +298 -0
  104. package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
  105. package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -0
  106. package/src/components/ticker/list-table-view.tsx +13 -1
  107. package/src/components/toggle-list.tsx +38 -12
  108. package/src/components/ui/country-flag-art.tsx +449 -0
  109. package/src/components/ui/country-flag.tsx +41 -0
  110. package/src/components/ui/data-table/types.ts +13 -0
  111. package/src/components/ui/fields.tsx +8 -0
  112. package/src/components/ui/icon.tsx +2 -0
  113. package/src/components/ui/index.ts +4 -0
  114. package/src/components/ui/multi-select/dialog.tsx +108 -22
  115. package/src/components/ui/range-track.tsx +53 -0
  116. package/src/components/ui/status.tsx +8 -2
  117. package/src/components/ui/tabs.tsx +11 -4
  118. package/src/components/ui/text-prompt-dialog.tsx +4 -2
  119. package/src/core/state/app/types.ts +10 -1
  120. package/src/data/config/store/normalize.ts +17 -1
  121. package/src/i18n/es.ts +24 -4
  122. package/src/i18n/ja.ts +24 -4
  123. package/src/i18n/ko.ts +24 -4
  124. package/src/i18n/zh-cn.ts +24 -4
  125. package/src/i18n/zh-tw.ts +24 -4
  126. package/src/layout/ticker-navigation.ts +28 -2
  127. package/src/market-data/coordinator/chart.ts +1 -1
  128. package/src/market-data/coordinator/quotes.ts +23 -4
  129. package/src/market-data/fx-closes.ts +72 -0
  130. package/src/market-data/market/freshness.ts +78 -6
  131. package/src/market-data/market/session-close-note.ts +57 -0
  132. package/src/market-data/market/status.ts +151 -0
  133. package/src/market-data/published-apac-sessions.ts +66 -0
  134. package/src/market-data/quotes/contributions.ts +8 -0
  135. package/src/market-data/quotes/freshness.ts +36 -0
  136. package/src/market-data/quotes/resolution.ts +24 -8
  137. package/src/market-data/quotes/screener-live-quotes.ts +49 -4
  138. package/src/market-data/quotes/time.ts +16 -0
  139. package/src/plugins/builtin/account-management/pane.tsx +4 -0
  140. package/src/plugins/builtin/alerts/cli.ts +10 -5
  141. package/src/plugins/builtin/alerts/index.tsx +1 -0
  142. package/src/plugins/builtin/analytics/metrics.ts +8 -3
  143. package/src/plugins/builtin/analytics/risk-client.ts +330 -79
  144. package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
  145. package/src/plugins/builtin/analytics/risk-headless.ts +61 -49
  146. package/src/plugins/builtin/analytics/risk-math.ts +33 -13
  147. package/src/plugins/builtin/analytics/risk-model.ts +282 -64
  148. package/src/plugins/builtin/analytics/risk-pane.tsx +62 -30
  149. package/src/plugins/builtin/analytics/risk-test-data.ts +206 -0
  150. package/src/plugins/builtin/attention/headless.ts +6 -4
  151. package/src/plugins/builtin/attention/index.tsx +1 -1
  152. package/src/plugins/builtin/attention/pane.tsx +1 -1
  153. package/src/plugins/builtin/awards/headless.ts +1 -0
  154. package/src/plugins/builtin/awards/pane.tsx +1 -1
  155. package/src/plugins/builtin/backtest/headless.ts +1 -0
  156. package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
  157. package/src/plugins/builtin/buildout/cells.tsx +15 -12
  158. package/src/plugins/builtin/buildout/detail/company.tsx +3 -3
  159. package/src/plugins/builtin/buildout/detail/index.tsx +0 -1
  160. package/src/plugins/builtin/buildout/detail/intel.tsx +6 -6
  161. package/src/plugins/builtin/buildout/detail/site.tsx +4 -7
  162. package/src/plugins/builtin/buildout/detail/ui.tsx +0 -19
  163. package/src/plugins/builtin/buildout/index.tsx +1 -0
  164. package/src/plugins/builtin/catalysts/headless.ts +3 -1
  165. package/src/plugins/builtin/catalysts/index.tsx +2 -2
  166. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  167. package/src/plugins/builtin/cds/headless.ts +2 -0
  168. package/src/plugins/builtin/cds/index.tsx +1 -0
  169. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
  170. package/src/plugins/builtin/chart-composer/headless.ts +38 -3
  171. package/src/plugins/builtin/chart-composer/index.tsx +3 -1
  172. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
  173. package/src/plugins/builtin/chat/channels.ts +19 -3
  174. package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
  175. package/src/plugins/builtin/chat/content/footer.tsx +15 -6
  176. package/src/plugins/builtin/chat/content/index.tsx +120 -21
  177. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
  178. package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
  179. package/src/plugins/builtin/chat/direct-messages.ts +200 -0
  180. package/src/plugins/builtin/chat/index.tsx +1 -0
  181. package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
  182. package/src/plugins/builtin/chat/message/header.tsx +16 -6
  183. package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
  184. package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
  185. package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
  186. package/src/plugins/builtin/chat/message/types.ts +14 -2
  187. package/src/plugins/builtin/chat/profile-popover.ts +18 -13
  188. package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
  189. package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
  190. package/src/plugins/builtin/cloud/plugin.tsx +1 -0
  191. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  192. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  193. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  194. package/src/plugins/builtin/comment-letters/index.tsx +1 -0
  195. package/src/plugins/builtin/company-attention/headless.ts +5 -1
  196. package/src/plugins/builtin/company-attention/pane.tsx +1 -1
  197. package/src/plugins/builtin/company-kpis/headless.ts +1 -0
  198. package/src/plugins/builtin/congress-trades/headless.ts +1 -0
  199. package/src/plugins/builtin/correlation/compute.ts +59 -16
  200. package/src/plugins/builtin/correlation/geo.ts +34 -0
  201. package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
  202. package/src/plugins/builtin/correlation/headless.ts +42 -8
  203. package/src/plugins/builtin/correlation/history.ts +2 -0
  204. package/src/plugins/builtin/correlation/index.tsx +68 -14
  205. package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
  206. package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
  207. package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
  208. package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
  209. package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
  210. package/src/plugins/builtin/correlation/settings.ts +1 -1
  211. package/src/plugins/builtin/cot/headless.ts +6 -3
  212. package/src/plugins/builtin/cot/index.tsx +3 -3
  213. package/src/plugins/builtin/cot/model.ts +36 -3
  214. package/src/plugins/builtin/cpi/headless.ts +4 -0
  215. package/src/plugins/builtin/credit-boards/headless.ts +2 -0
  216. package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
  217. package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
  218. package/src/plugins/builtin/credit-documents/headless.ts +2 -0
  219. package/src/plugins/builtin/crypto-board/headless.ts +3 -0
  220. package/src/plugins/builtin/custom-view/loader.ts +1 -1
  221. package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
  222. package/src/plugins/builtin/debt-maturities/wall-bar.tsx +14 -41
  223. package/src/plugins/builtin/dividend-yield/client.ts +4 -2
  224. package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
  225. package/src/plugins/builtin/doe/headless.ts +7 -0
  226. package/src/plugins/builtin/doe/range-bar.tsx +7 -37
  227. package/src/plugins/builtin/earnings/client.ts +2 -2
  228. package/src/plugins/builtin/earnings/headless.ts +5 -0
  229. package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
  230. package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
  231. package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
  232. package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
  233. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
  234. package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
  235. package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
  236. package/src/plugins/builtin/econ/index.tsx +1 -0
  237. package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
  238. package/src/plugins/builtin/equity-screener/headless.ts +2 -0
  239. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  240. package/src/plugins/builtin/executives/index.tsx +1 -0
  241. package/src/plugins/builtin/exposure/headless.ts +3 -1
  242. package/src/plugins/builtin/fear-greed/headless.ts +2 -0
  243. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  244. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  245. package/src/plugins/builtin/futures-curve/headless.ts +39 -10
  246. package/src/plugins/builtin/futures-curve/index.tsx +3 -3
  247. package/src/plugins/builtin/futures-curve/model.ts +188 -4
  248. package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
  249. package/src/plugins/builtin/fx-matrix/direction.ts +81 -0
  250. package/src/plugins/builtin/fx-matrix/index.tsx +71 -33
  251. package/src/plugins/builtin/fx-matrix/live-legs.ts +17 -0
  252. package/src/plugins/builtin/fx-matrix/pairs.ts +68 -14
  253. package/src/plugins/builtin/fx-matrix/settings.ts +62 -0
  254. package/src/plugins/builtin/gpu/headless.ts +7 -3
  255. package/src/plugins/builtin/gpu/ladder.tsx +26 -30
  256. package/src/plugins/builtin/gpu/model.ts +27 -1
  257. package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
  258. package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
  259. package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
  260. package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
  261. package/src/plugins/builtin/holders/headless.ts +139 -5
  262. package/src/plugins/builtin/holders/index.tsx +10 -3
  263. package/src/plugins/builtin/holders/pane.tsx +20 -3
  264. package/src/plugins/builtin/holders/report-header.ts +95 -0
  265. package/src/plugins/builtin/holders/table-model.ts +20 -5
  266. package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
  267. package/src/plugins/builtin/holders/types.ts +2 -1
  268. package/src/plugins/builtin/insider/headless.ts +2 -0
  269. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
  270. package/src/plugins/builtin/iv-history/headless.ts +4 -1
  271. package/src/plugins/builtin/jobs/headless.ts +1 -0
  272. package/src/plugins/builtin/jobs/index.tsx +1 -0
  273. package/src/plugins/builtin/jobs/share-bars.tsx +5 -28
  274. package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
  275. package/src/plugins/builtin/macro-day/headless.ts +2 -0
  276. package/src/plugins/builtin/market-halts/index.tsx +1 -0
  277. package/src/plugins/builtin/market-heatmap/data.ts +30 -2
  278. package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
  279. package/src/plugins/builtin/market-heatmap/index.tsx +245 -81
  280. package/src/plugins/builtin/market-heatmap/live.ts +88 -0
  281. package/src/plugins/builtin/market-heatmap/model.ts +146 -0
  282. package/src/plugins/builtin/market-heatmap/portfolio.ts +50 -11
  283. package/src/plugins/builtin/market-movers/client.ts +3 -2
  284. package/src/plugins/builtin/market-movers/headless.ts +10 -1
  285. package/src/plugins/builtin/market-movers/screener.ts +18 -5
  286. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  287. package/src/plugins/builtin/members/client.ts +53 -0
  288. package/src/plugins/builtin/members/headless.ts +35 -0
  289. package/src/plugins/builtin/members/index.tsx +20 -0
  290. package/src/plugins/builtin/members/model.ts +68 -0
  291. package/src/plugins/builtin/members/pane.tsx +175 -0
  292. package/src/plugins/builtin/mna/distress/headless.ts +1 -0
  293. package/src/plugins/builtin/mna/headless.ts +1 -0
  294. package/src/plugins/builtin/mna/index.tsx +2 -1
  295. package/src/plugins/builtin/mna/pane.tsx +5 -2
  296. package/src/plugins/builtin/money-markets/headless.ts +1 -0
  297. package/src/plugins/builtin/news/headless.ts +2 -0
  298. package/src/plugins/builtin/news/wire/index.tsx +8 -1
  299. package/src/plugins/builtin/notes/cli.ts +14 -6
  300. package/src/plugins/builtin/notes/index.tsx +1 -0
  301. package/src/plugins/builtin/openfda/index.tsx +1 -0
  302. package/src/plugins/builtin/options/index.tsx +2 -1
  303. package/src/plugins/builtin/options-calculator/headless.ts +2 -0
  304. package/src/plugins/builtin/options-positioning/headless.ts +3 -0
  305. package/src/plugins/builtin/options-scenario/headless.ts +5 -0
  306. package/src/plugins/builtin/pe-band/client.ts +74 -2
  307. package/src/plugins/builtin/pe-band/headless.ts +26 -8
  308. package/src/plugins/builtin/pe-band/model.ts +102 -22
  309. package/src/plugins/builtin/pe-band/pane.tsx +34 -16
  310. package/src/plugins/builtin/pe-band/report-dates.ts +78 -0
  311. package/src/plugins/builtin/perps/client.ts +66 -5
  312. package/src/plugins/builtin/perps/equity-identity.ts +16 -0
  313. package/src/plugins/builtin/perps/equity-row.tsx +6 -4
  314. package/src/plugins/builtin/perps/headless.ts +144 -16
  315. package/src/plugins/builtin/perps/index.tsx +6 -6
  316. package/src/plugins/builtin/perps/model.ts +189 -12
  317. package/src/plugins/builtin/perps/pane.tsx +248 -47
  318. package/src/plugins/builtin/plugin-marketplace/activation.ts +19 -0
  319. package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -2
  320. package/src/plugins/builtin/plugin-marketplace/store.ts +2 -0
  321. package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
  322. package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -0
  323. package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
  324. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
  325. package/src/plugins/builtin/portfolio-list/cli/render.ts +230 -39
  326. package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
  327. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
  328. package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
  329. package/src/plugins/builtin/portfolio-list/headless.ts +98 -16
  330. package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
  331. package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
  332. package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
  333. package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
  334. package/src/plugins/builtin/portfolio-list/pane/index.tsx +47 -13
  335. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +43 -2
  336. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +48 -5
  337. package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
  338. package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -1
  339. package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
  340. package/src/plugins/builtin/power/headless.ts +3 -1
  341. package/src/plugins/builtin/rate-path/headless.ts +2 -0
  342. package/src/plugins/builtin/realized-vol/headless.ts +2 -0
  343. package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
  344. package/src/plugins/builtin/research/analyst-headless.ts +3 -0
  345. package/src/plugins/builtin/research/events-headless.ts +2 -0
  346. package/src/plugins/builtin/research/headless.ts +2 -0
  347. package/src/plugins/builtin/research/index.tsx +1 -0
  348. package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
  349. package/src/plugins/builtin/research/relative-valuation-model.ts +11 -3
  350. package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
  351. package/src/plugins/builtin/research-search/index.tsx +1 -0
  352. package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
  353. package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
  354. package/src/plugins/builtin/risk-factors/headless.ts +2 -0
  355. package/src/plugins/builtin/scanner/flow-history.ts +2 -13
  356. package/src/plugins/builtin/scanner/headless.ts +14 -0
  357. package/src/plugins/builtin/scanner/hilo-bars.tsx +12 -70
  358. package/src/plugins/builtin/scanner/hilo-model.ts +0 -18
  359. package/src/plugins/builtin/seasonality/headless.ts +2 -0
  360. package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
  361. package/src/plugins/builtin/sec/filing-content.ts +42 -17
  362. package/src/plugins/builtin/sec/forms.ts +12 -0
  363. package/src/plugins/builtin/sec/headless.ts +2 -0
  364. package/src/plugins/builtin/sectors/client.ts +1 -0
  365. package/src/plugins/builtin/sectors/headless.ts +9 -1
  366. package/src/plugins/builtin/sectors/move-bar.tsx +10 -32
  367. package/src/plugins/builtin/sectors/sector-model.ts +2 -0
  368. package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
  369. package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
  370. package/src/plugins/builtin/shared/report-freshness.ts +57 -0
  371. package/src/plugins/builtin/shared/research-cells.tsx +4 -9
  372. package/src/plugins/builtin/short-interest/headless.ts +2 -0
  373. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  374. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  375. package/src/plugins/builtin/social-mentions/headless.ts +1 -0
  376. package/src/plugins/builtin/social-mentions/index.tsx +1 -1
  377. package/src/plugins/builtin/supply-chain/headless.ts +7 -1
  378. package/src/plugins/builtin/supply-chain/index.tsx +10 -1
  379. package/src/plugins/builtin/supply-chain/model.ts +27 -2
  380. package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
  381. package/src/plugins/builtin/themes/headless.ts +3 -0
  382. package/src/plugins/builtin/thirteenf/headless.ts +110 -25
  383. package/src/plugins/builtin/thirteenf/index.tsx +2 -1
  384. package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
  385. package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
  386. package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
  387. package/src/plugins/builtin/ticker-detail/overview/components.tsx +5 -60
  388. package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
  389. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +1 -1
  390. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
  391. package/src/plugins/builtin/ticker-detail/pane.tsx +1 -1
  392. package/src/plugins/builtin/ticker-detail/quote-footer.ts +7 -1
  393. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +20 -4
  394. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -2
  395. package/src/plugins/builtin/time-sales/headless.ts +5 -1
  396. package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
  397. package/src/plugins/builtin/vol-surface/index.tsx +1 -1
  398. package/src/plugins/builtin/volatility/headless.ts +6 -1
  399. package/src/plugins/builtin/world-indices/headless.ts +2 -0
  400. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +157 -0
  401. package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
  402. package/src/plugins/builtin/world-venue-map/client.ts +45 -0
  403. package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
  404. package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
  405. package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
  406. package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
  407. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
  408. package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
  409. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +447 -0
  410. package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
  411. package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
  412. package/src/plugins/builtin/world-venue-map/index.ts +67 -4
  413. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
  414. package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
  415. package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
  416. package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
  417. package/src/plugins/builtin/world-venue-map/model.ts +7 -4
  418. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -0
  419. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
  420. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
  421. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
  422. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
  423. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
  424. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
  425. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
  426. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
  429. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
  430. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
  431. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
  432. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
  433. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
  434. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
  435. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
  436. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
  437. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
  438. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
  439. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
  440. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
  441. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
  442. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
  443. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
  444. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
  445. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
  446. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
  447. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
  448. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
  449. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
  450. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
  451. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
  452. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
  453. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
  454. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
  455. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
  456. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
  457. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
  458. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
  459. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
  460. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
  461. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
  462. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
  463. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
  464. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
  465. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
  466. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
  467. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
  468. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
  469. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
  470. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
  471. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
  472. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
  473. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
  474. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
  475. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
  476. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
  477. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
  478. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
  479. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
  480. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
  481. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
  482. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
  483. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
  484. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
  485. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
  486. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
  487. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
  488. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
  489. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
  490. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
  491. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
  492. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
  493. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
  494. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
  495. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
  496. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
  497. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
  498. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
  499. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
  500. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
  501. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
  502. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
  503. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
  504. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
  505. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
  506. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
  507. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
  508. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
  509. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
  510. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
  511. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
  512. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
  513. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
  514. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
  515. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
  516. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
  517. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
  518. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
  519. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
  520. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
  521. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
  522. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
  523. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
  524. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
  525. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
  526. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
  527. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
  528. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
  529. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
  530. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
  531. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
  532. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
  533. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
  534. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
  535. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
  536. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
  537. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
  538. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
  539. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
  540. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
  541. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
  542. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
  543. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
  544. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
  545. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
  546. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
  547. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
  548. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
  549. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
  550. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
  551. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
  552. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
  553. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
  554. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
  555. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
  556. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
  557. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
  558. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
  559. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
  560. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
  561. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
  562. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
  563. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
  564. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
  565. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
  566. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
  567. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
  568. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
  569. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
  570. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
  571. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
  572. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
  573. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
  574. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
  575. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
  576. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
  577. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
  578. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
  579. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
  580. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
  581. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
  582. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
  583. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
  584. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
  585. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
  586. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
  587. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
  588. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
  589. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
  590. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
  591. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
  592. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
  593. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
  594. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
  595. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
  596. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
  597. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
  598. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
  599. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
  600. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
  601. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
  602. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
  603. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
  604. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
  605. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
  606. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
  607. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
  608. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
  609. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
  610. package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
  611. package/src/plugins/builtin/world-venue-map/pane.tsx +28 -43
  612. package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
  613. package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
  614. package/src/plugins/builtin/yield-curve/headless.ts +16 -0
  615. package/src/plugins/catalog-browser.ts +2 -0
  616. package/src/plugins/catalog-manifest.ts +1 -0
  617. package/src/plugins/catalog-ui.ts +3 -1
  618. package/src/plugins/catalog.ts +1 -1
  619. package/src/plugins/host-link.ts +33 -1
  620. package/src/plugins/installer.ts +48 -12
  621. package/src/plugins/loader.ts +30 -3
  622. package/src/plugins/manager-node.ts +15 -5
  623. package/src/plugins/registry/index.ts +1 -1
  624. package/src/plugins/registry/pane-settings.ts +26 -7
  625. package/src/public/__snapshots__/public-api.test.ts.snap +2 -0
  626. package/src/renderers/dom/build-assets.ts +81 -3
  627. package/src/renderers/dom/data-table/row.tsx +52 -16
  628. package/src/renderers/dom/desktop/controls.tsx +7 -3
  629. package/src/renderers/dom/desktop/icons.tsx +1 -0
  630. package/src/renderers/dom/desktop/list-view.tsx +35 -10
  631. package/src/renderers/dom/desktop/popover.tsx +73 -14
  632. package/src/renderers/dom/host/box.tsx +69 -26
  633. package/src/renderers/dom/host/input.tsx +14 -3
  634. package/src/renderers/dom/host/tabs.tsx +37 -1
  635. package/src/renderers/dom/styles.css +41 -7
  636. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +11 -6
  637. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
  638. package/src/renderers/electrobun/bun/desktop/update.ts +181 -87
  639. package/src/renderers/electrobun/bun/index.ts +73 -6
  640. package/src/renderers/electrobun/bun/window/remembered-frame.ts +122 -0
  641. package/src/renderers/electrobun/shared/protocol.ts +3 -0
  642. package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
  643. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +3 -1
  644. package/src/renderers/electrobun/view/main.tsx +7 -1
  645. package/src/renderers/electrobun/view/renderer-window-error.ts +18 -0
  646. package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
  647. package/src/renderers/electrobun/view/update-host.ts +45 -21
  648. package/src/renderers/opentui/host.tsx +5 -0
  649. package/src/sources/gloomberb-cloud/index.ts +25 -4
  650. package/src/sources/gloomberb-cloud/normalizers.ts +36 -5
  651. package/src/sources/provider-router/cached-routes.ts +4 -1
  652. package/src/sources/provider-router/financials.ts +11 -8
  653. package/src/sources/provider-router/history.ts +15 -10
  654. package/src/sources/sec-registrant.ts +75 -0
  655. package/src/state/app/context/index.tsx +24 -8
  656. package/src/state/hooks/quote-streaming.ts +41 -26
  657. package/src/sync/core-contributors.ts +4 -0
  658. package/src/telemetry/benign-window-error.ts +7 -0
  659. package/src/telemetry/crash-reports-dom.ts +2 -0
  660. package/src/telemetry/crash-reports.ts +4 -1
  661. package/src/test-support/cli-context.ts +10 -2
  662. package/src/test-support/daily-nav.ts +25 -0
  663. package/src/theme/heat-colors.ts +357 -2
  664. package/src/tickers/instrument-kind.ts +34 -7
  665. package/src/tickers/search/asset-classes.ts +24 -9
  666. package/src/tickers/search/index.ts +44 -11
  667. package/src/tickers/search/ranking.ts +23 -3
  668. package/src/time-series/resolve.ts +1 -1
  669. package/src/time-series/use-chart-resolution.ts +1 -1
  670. package/src/types/context-menu.ts +6 -0
  671. package/src/types/data-provider.ts +2 -0
  672. package/src/types/financials.ts +5 -0
  673. package/src/types/headless.ts +79 -2
  674. package/src/types/plugin.ts +38 -6
  675. package/src/types/ticker.ts +15 -0
  676. package/src/ui/context-menu.tsx +1 -0
  677. package/src/ui/host.tsx +16 -0
  678. package/src/updater/index.ts +38 -13
  679. package/src/utils/async-deadline.ts +21 -0
  680. package/src/utils/cli-output.ts +5 -1
  681. package/src/utils/crypto-pair.ts +41 -0
  682. package/src/utils/currency-units.ts +14 -0
  683. package/src/utils/depositary-receipt.ts +26 -0
  684. package/src/utils/exchanges.ts +72 -0
  685. package/src/utils/fire-and-forget.ts +24 -0
  686. package/src/utils/format.ts +13 -0
  687. package/src/utils/price-earnings.ts +70 -3
  688. package/src/utils/price-history.ts +58 -13
  689. package/src/utils/rpc-timeout-error.ts +27 -0
  690. package/src/utils/sec.ts +13 -1
  691. package/src/utils/utc-time.ts +79 -0
package/src/i18n/ko.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  * Keep finance terminology precise and translations concise for dense layouts.
4
4
  */
5
5
  export const ko: Record<string, string> = {
6
+ "NAV · as of {date}": "NAV · {date} 기준",
6
7
  // ── Common UI ────────────────────────────────────────────────
7
8
  "Back": "뒤로",
8
9
  "Done": "완료",
@@ -376,7 +377,6 @@ export const ko: Record<string, string> = {
376
377
  "Price trigger alerts with notifications": "알림이 있는 목표가 알림",
377
378
  "Create a price alert from a symbol, condition, and target price": "종목코드, 조건 및 목표가로 가격 알림 생성",
378
379
  "Public market heatmap for the largest US stocks and ETFs.": "미국 대형주 및 ETF 시장 히트맵.",
379
- "Largest US stocks and ETFs, sized by market cap or assets and colored by daily move.": "미국 대형주와 ETF를 시가총액·자산 규모 및 일일 변동률로 표시.",
380
380
  "Top gainers, losers, most active, and trending tickers": "상승률·하락률·거래량 상위 및 인기 종목",
381
381
  "Top gainers, losers, most active, and trending tickers.": "상승률·하락률·거래량 상위 및 인기 종목.",
382
382
  "S&P 500 sector and industry performance via ETF proxies": "ETF 기준 S&P 500 섹터 및 산업 성과",
@@ -523,7 +523,7 @@ export const ko: Record<string, string> = {
523
523
  "Quit the terminal app.": "터미널 앱을 종료합니다.",
524
524
  "Copy the active terminal selection.": "활성 터미널 선택을 복사합니다.",
525
525
  "Paste clipboard text into the active input.": "클립보드 텍스트를 활성 입력에 붙여넣습니다.",
526
- "Install an available app update when one is shown.": "사용 가능한 앱 업데이트가 표시되면 설치하세요.",
526
+ "Restart into a downloaded app update, or retry one that failed.": "다운로드한 업데이트로 다시 시작하거나, 실패한 업데이트를 다시 시도합니다.",
527
527
  "Close the focused pane, docked or floating.": "도킹 또는 플로팅된 포커스 패널을 닫습니다.",
528
528
  "Close all floating panes.": "모든 플로팅 패널을 닫습니다.",
529
529
  "Edit settings for the focused pane.": "포커스 패널 설정을 편집합니다.",
@@ -835,7 +835,22 @@ export const ko: Record<string, string> = {
835
835
  "Recent users": "최근 사용자",
836
836
  "No recent users": "최근 사용자 없음",
837
837
  "Enter at least one @username.": "@username을 하나 이상 입력하세요.",
838
- "Could not start conversation.": "대화를 시작할 수 없습니다.",
838
+ "@{username} only takes DMs from people they have written to first.": "@{username}님은 먼저 메시지를 보낸 상대의 DM만 받습니다.",
839
+ "@{username} does not take DMs.": "@{username}님은 DM을 받지 않습니다.",
840
+ "@{username} was not found.": "@{username}님을 찾을 수 없습니다.",
841
+ "{usernames} were not found.": "{usernames}님을 찾을 수 없습니다.",
842
+ "One of those users was not found.": "찾을 수 없는 사용자가 있습니다.",
843
+ "Someone in that group only takes DMs from people they have written to first.": "이 그룹에 먼저 메시지를 보낸 상대의 DM만 받는 사람이 있습니다.",
844
+ "Could not start the conversation (error {status}).": "대화를 시작할 수 없습니다 (오류 {status}).",
845
+ "Could not start the conversation. Check your connection and try again.": "대화를 시작할 수 없습니다. 연결을 확인하고 다시 시도하세요.",
846
+ "no DMs": "DM 불가",
847
+ "Only takes DMs from people they have written to first.": "먼저 메시지를 보낸 상대의 DM만 받습니다.",
848
+ "Does not take DMs.": "DM을 받지 않습니다.",
849
+ "Message @{username}": "@{username}님에게 메시지",
850
+ "Open DM with @{username}": "@{username}님과의 DM 열기",
851
+ "Message": "메시지",
852
+ "Open DM": "DM 열기",
853
+ "Show Profile": "프로필 보기",
839
854
  "Starting": "시작 중",
840
855
  "Start": "시작",
841
856
 
@@ -955,7 +970,9 @@ export const ko: Record<string, string> = {
955
970
 
956
971
  // ── Main dashboard ──────────────────────────────────────────
957
972
  "Installing update...": "업데이트 설치 중...",
958
- "Update installed, restart to apply": "업데이트 설치 완료. 적용하려면 다시 시작하세요",
973
+ "Update ready, restart to apply": "업데이트 준비 완료. 적용하려면 다시 시작하세요",
974
+ "Update ready": "업데이트 준비 완료",
975
+ "Restart": "다시 시작",
959
976
  "Checking for updates...": "업데이트 확인 중...",
960
977
  "Downloading v{version}: {percent}%": "v{version} 다운로드 중: {percent}%",
961
978
  "Update failed: {error}": "업데이트 실패: {error}",
@@ -970,6 +987,9 @@ export const ko: Record<string, string> = {
970
987
  "Minimize": "최소화",
971
988
  "Maximize": "최대화",
972
989
  "Pane unavailable.": "패널을 사용할 수 없습니다.",
990
+ "{title} stopped working.": "{title}이(가) 작동을 멈췄습니다.",
991
+ "Reload pane": "패널 다시 불러오기",
992
+ "Close pane": "패널 닫기",
973
993
  "Cash & Margin": "현금·증거금",
974
994
  "No non-zero cash balances.": "표시할 현금 잔액이 없습니다.",
975
995
  "adding...": "추가 중...",
package/src/i18n/zh-cn.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  * fixed-width terminal layouts stay readable.
6
6
  */
7
7
  export const zhCN: Record<string, string> = {
8
+ "NAV · as of {date}": "NAV · 截至{date}",
8
9
  // ── Common UI ────────────────────────────────────────────────
9
10
  "Back": "返回",
10
11
  "Done": "完成",
@@ -378,7 +379,6 @@ export const zhCN: Record<string, string> = {
378
379
  "Price trigger alerts with notifications": "带通知的价格触发提醒",
379
380
  "Create a price alert from a symbol, condition, and target price": "用代码、条件和目标价创建价格提醒",
380
381
  "Public market heatmap for the largest US stocks and ETFs.": "美股大盘股与 ETF 的市场热力图。",
381
- "Largest US stocks and ETFs, sized by market cap or assets and colored by daily move.": "按市值/规模定大小、按日涨跌着色的美股与 ETF。",
382
382
  "Top gainers, losers, most active, and trending tickers": "涨幅榜、跌幅榜、成交活跃与热门股票",
383
383
  "Top gainers, losers, most active, and trending tickers.": "涨幅榜、跌幅榜、成交活跃与热门股票。",
384
384
  "S&P 500 sector and industry performance via ETF proxies": "以 ETF 代理呈现的标普 500 板块与行业表现",
@@ -525,7 +525,7 @@ export const zhCN: Record<string, string> = {
525
525
  "Quit the terminal app.": "退出终端应用。",
526
526
  "Copy the active terminal selection.": "复制当前终端选中内容。",
527
527
  "Paste clipboard text into the active input.": "把剪贴板文本粘贴到当前输入框。",
528
- "Install an available app update when one is shown.": "有可用更新提示时安装更新。",
528
+ "Restart into a downloaded app update, or retry one that failed.": "使用已下载的更新重启,或重试失败的更新。",
529
529
  "Close the focused pane, docked or floating.": "关闭聚焦面板(停靠或浮动)。",
530
530
  "Close all floating panes.": "关闭所有浮动面板。",
531
531
  "Edit settings for the focused pane.": "编辑聚焦面板的设置。",
@@ -837,7 +837,22 @@ export const zhCN: Record<string, string> = {
837
837
  "Recent users": "最近联系人",
838
838
  "No recent users": "没有最近联系人",
839
839
  "Enter at least one @username.": "至少输入一个 @用户名。",
840
- "Could not start conversation.": "无法开始会话。",
840
+ "@{username} only takes DMs from people they have written to first.": "@{username} 只接收自己先联系过的人的私信。",
841
+ "@{username} does not take DMs.": "@{username} 不接收私信。",
842
+ "@{username} was not found.": "找不到 @{username}。",
843
+ "{usernames} were not found.": "找不到 {usernames}。",
844
+ "One of those users was not found.": "其中有用户不存在。",
845
+ "Someone in that group only takes DMs from people they have written to first.": "该群组中有人只接收自己先联系过的人的私信。",
846
+ "Could not start the conversation (error {status}).": "无法开始会话(错误 {status})。",
847
+ "Could not start the conversation. Check your connection and try again.": "无法开始会话。请检查网络连接后重试。",
848
+ "no DMs": "不收私信",
849
+ "Only takes DMs from people they have written to first.": "只接收自己先联系过的人的私信。",
850
+ "Does not take DMs.": "不接收私信。",
851
+ "Message @{username}": "私信 @{username}",
852
+ "Open DM with @{username}": "打开与 @{username} 的私信",
853
+ "Message": "发私信",
854
+ "Open DM": "打开私信",
855
+ "Show Profile": "查看资料",
841
856
  "Starting": "正在开始",
842
857
  "Start": "开始",
843
858
 
@@ -957,7 +972,9 @@ export const zhCN: Record<string, string> = {
957
972
 
958
973
  // ── Main dashboard ──────────────────────────────────────────
959
974
  "Installing update...": "正在安装更新...",
960
- "Update installed, restart to apply": "更新已安装,重启后生效",
975
+ "Update ready, restart to apply": "更新已就绪,重启后生效",
976
+ "Update ready": "更新已就绪",
977
+ "Restart": "重启",
961
978
  "Checking for updates...": "正在检查更新...",
962
979
  "Downloading v{version}: {percent}%": "正在下载 v{version}:{percent}%",
963
980
  "Update failed: {error}": "更新失败:{error}",
@@ -972,6 +989,9 @@ export const zhCN: Record<string, string> = {
972
989
  "Minimize": "最小化",
973
990
  "Maximize": "最大化",
974
991
  "Pane unavailable.": "面板不可用。",
992
+ "{title} stopped working.": "{title} 已停止工作。",
993
+ "Reload pane": "重新加载面板",
994
+ "Close pane": "关闭面板",
975
995
  "Cash & Margin": "现金与保证金",
976
996
  "No non-zero cash balances.": "没有非零现金余额。",
977
997
  "adding...": "添加中...",
package/src/i18n/zh-tw.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  * fixed-width terminal layouts stay readable.
6
6
  */
7
7
  export const zhTW: Record<string, string> = {
8
+ "NAV · as of {date}": "NAV · 截至{date}",
8
9
  // ── Common UI ────────────────────────────────────────────────
9
10
  "Back": "返回",
10
11
  "Done": "完成",
@@ -378,7 +379,6 @@ export const zhTW: Record<string, string> = {
378
379
  "Price trigger alerts with notifications": "透過通知的價格觸發提醒",
379
380
  "Create a price alert from a symbol, condition, and target price": "用代號、條件和目標價建立價格提醒",
380
381
  "Public market heatmap for the largest US stocks and ETFs.": "美股大盤股與 ETF 的市場熱力圖。",
381
- "Largest US stocks and ETFs, sized by market cap or assets and colored by daily move.": "按市值/規模定大小、按日漲跌著色的美股與 ETF。",
382
382
  "Top gainers, losers, most active, and trending tickers": "漲幅榜、跌幅榜、成交活躍與熱門股票",
383
383
  "Top gainers, losers, most active, and trending tickers.": "漲幅榜、跌幅榜、成交活躍與熱門股票。",
384
384
  "S&P 500 sector and industry performance via ETF proxies": "以 ETF 代表 S&P 500 類股與產業表現",
@@ -525,7 +525,7 @@ export const zhTW: Record<string, string> = {
525
525
  "Quit the terminal app.": "結束終端機應用程式。",
526
526
  "Copy the active terminal selection.": "複製目前終端機選取內容。",
527
527
  "Paste clipboard text into the active input.": "將剪貼簿文字貼到目前的輸入欄位。",
528
- "Install an available app update when one is shown.": "有可用更新提示時安裝更新。",
528
+ "Restart into a downloaded app update, or retry one that failed.": "使用已下載的更新重新啟動,或重試失敗的更新。",
529
529
  "Close the focused pane, docked or floating.": "關閉聚焦面板(停靠或浮動)。",
530
530
  "Close all floating panes.": "關閉所有浮動面板。",
531
531
  "Edit settings for the focused pane.": "編輯聚焦面板的設定。",
@@ -837,7 +837,22 @@ export const zhTW: Record<string, string> = {
837
837
  "Recent users": "最近聯絡人",
838
838
  "No recent users": "沒有最近聯絡人",
839
839
  "Enter at least one @username.": "至少輸入一個 @username。",
840
- "Could not start conversation.": "無法開始對話。",
840
+ "@{username} only takes DMs from people they have written to first.": "@{username} 只接收自己先聯絡過的人的私訊。",
841
+ "@{username} does not take DMs.": "@{username} 不接收私訊。",
842
+ "@{username} was not found.": "找不到 @{username}。",
843
+ "{usernames} were not found.": "找不到 {usernames}。",
844
+ "One of those users was not found.": "其中有使用者不存在。",
845
+ "Someone in that group only takes DMs from people they have written to first.": "該群組中有人只接收自己先聯絡過的人的私訊。",
846
+ "Could not start the conversation (error {status}).": "無法開始對話(錯誤 {status})。",
847
+ "Could not start the conversation. Check your connection and try again.": "無法開始對話。請檢查網路連線後再試一次。",
848
+ "no DMs": "不收私訊",
849
+ "Only takes DMs from people they have written to first.": "只接收自己先聯絡過的人的私訊。",
850
+ "Does not take DMs.": "不接收私訊。",
851
+ "Message @{username}": "私訊 @{username}",
852
+ "Open DM with @{username}": "開啟與 @{username} 的私訊",
853
+ "Message": "傳私訊",
854
+ "Open DM": "開啟私訊",
855
+ "Show Profile": "查看個人資料",
841
856
  "Starting": "正在開始",
842
857
  "Start": "開始",
843
858
 
@@ -957,7 +972,9 @@ export const zhTW: Record<string, string> = {
957
972
 
958
973
  // ── Main dashboard ──────────────────────────────────────────
959
974
  "Installing update...": "正在安裝更新...",
960
- "Update installed, restart to apply": "更新已安裝,重新啟動後生效",
975
+ "Update ready, restart to apply": "更新已就緒,重新啟動後生效",
976
+ "Update ready": "更新已就緒",
977
+ "Restart": "重新啟動",
961
978
  "Checking for updates...": "正在檢查更新...",
962
979
  "Downloading v{version}: {percent}%": "正在下載 v{version}:{percent}%",
963
980
  "Update failed: {error}": "更新失敗:{error}",
@@ -972,6 +989,9 @@ export const zhTW: Record<string, string> = {
972
989
  "Minimize": "最小化",
973
990
  "Maximize": "最大化",
974
991
  "Pane unavailable.": "面板不可用。",
992
+ "{title} stopped working.": "{title} 已停止運作。",
993
+ "Reload pane": "重新載入面板",
994
+ "Close pane": "關閉面板",
975
995
  "Cash & Margin": "現金與保證金",
976
996
  "No non-zero cash balances.": "沒有非零的現金餘額。",
977
997
  "adding...": "新增中...",
@@ -22,8 +22,8 @@ export function listVisibleTickerSourcePanes(
22
22
  }
23
23
 
24
24
  /**
25
- * Whether the pane menu may link this pane to a ticker source (`PaneDef.tickerFollower`). A source
26
- * never follows: its own cursor symbol would win over the binding.
25
+ * Whether the pane menu may link this pane to another pane's ticker (`PaneDef.tickerFollower`).
26
+ * A source never follows: its own cursor symbol would win over the binding.
27
27
  */
28
28
  export function canFollowTickerSource(
29
29
  instance: PaneInstanceConfig,
@@ -34,6 +34,32 @@ export function canFollowTickerSource(
34
34
  return typeof def.tickerFollower === "function" ? def.tickerFollower(instance) : def.tickerFollower === true;
35
35
  }
36
36
 
37
+ /**
38
+ * A single-ticker pane other panes can follow. Lists and scanners stay sources; Ticker Research
39
+ * follows the same rule as any pane flagged `tickerFollower`.
40
+ */
41
+ export function isTickerLinkPeer(
42
+ instance: PaneInstanceConfig,
43
+ panes: ReadonlyMap<string, PaneDef>,
44
+ ): boolean {
45
+ return instance.paneId === TICKER_RESEARCH_PANE_ID || canFollowTickerSource(instance, panes);
46
+ }
47
+
48
+ /** True when `fromInstanceId`'s follow chain reaches `targetInstanceId`. */
49
+ export function followBindingReaches(
50
+ layout: LayoutConfig,
51
+ fromInstanceId: string,
52
+ targetInstanceId: string,
53
+ seen = new Set<string>(),
54
+ ): boolean {
55
+ if (seen.has(fromInstanceId)) return false;
56
+ seen.add(fromInstanceId);
57
+ const instance = findPaneInstance(layout, fromInstanceId);
58
+ if (instance?.binding?.kind !== "follow") return false;
59
+ const next = instance.binding.sourceInstanceId;
60
+ return next === targetInstanceId || followBindingReaches(layout, next, targetInstanceId, seen);
61
+ }
62
+
37
63
  /** The visible Ticker Research pane that follows `sourceInstanceId`, if any. */
38
64
  export function findTickerResearchFollower(
39
65
  layout: LayoutConfig,
@@ -57,7 +57,7 @@ export function normalizeFreshChartData(
57
57
  interval: interval ?? undefined }) ?? undefined;
58
58
  if (
59
59
  isIntradayChartRequest(request, history)
60
- && isPriceHistoryStaleForCurrentWindow(normalized, Date.now(), { exchange: target.exchange,
60
+ && isPriceHistoryStaleForCurrentWindow(normalized, Date.now(), { symbol: target.symbol, exchange: target.exchange,
61
61
  intervalMs: interval ? priceHistoryIntervalMs(interval) : undefined, session })
62
62
  ) {
63
63
  return [];
@@ -113,13 +113,24 @@ export async function loadQuoteEntry({
113
113
  const attempts = [createAttempt(source, startedAt, "success")];
114
114
  return quoteStore.update(key, (current) => readyQuoteEntry(current, resolvedQuote, source, attempts, { keepNewerHeldQuote: true }));
115
115
  } catch (error) {
116
- const classified = classifyError(error);
117
- const attempt = createAttempt(dataProvider.id, startedAt, EXPECTED_EMPTY.test(classified.message) ? "empty" : "fatal_error", classified.reasonCode, classified.message);
118
- return quoteStore.update(key, (current) => errorEntry(current, attempt));
116
+ return storeQuoteFailure(quoteStore, key, dataProvider.id, startedAt, error);
119
117
  }
120
118
  });
121
119
  }
122
120
 
121
+ function storeQuoteFailure(
122
+ quoteStore: QueryStore<Quote>,
123
+ key: string,
124
+ providerId: string,
125
+ startedAt: number,
126
+ error: unknown,
127
+ ): QueryEntry<Quote> {
128
+ const classified = classifyError(error);
129
+ const status = EXPECTED_EMPTY.test(classified.message) ? "empty" : "fatal_error";
130
+ const attempt = createAttempt(providerId, startedAt, status, classified.reasonCode, classified.message);
131
+ return quoteStore.update(key, (current) => errorEntry(current, attempt));
132
+ }
133
+
123
134
  interface LoadQuoteBatchEntriesOptions {
124
135
  dataProvider: DataProvider;
125
136
  instruments: InstrumentRef[];
@@ -152,14 +163,22 @@ export async function loadQuoteBatchEntries({
152
163
  }
153
164
 
154
165
  if (misses.length > 0 && dataProvider.getQuotesBatch) {
166
+ const startedAt = Date.now();
155
167
  const batchResults = await dataProvider.getQuotesBatch(
156
168
  misses.map((instrument) => quoteTargetFromInstrument(instrument)),
157
169
  { forceRefresh: options.forceRefresh },
158
170
  );
159
171
  batchResults.forEach((item, index) => {
160
172
  const instrument = misses[index];
161
- if (!instrument || !item.quote) return;
173
+ if (!instrument) return;
162
174
  const key = buildQuoteKey(instrument);
175
+ if (!item.quote) {
176
+ // The batch already asked for this one, one by one where the batch
177
+ // answer fell short, and says why it failed. Asking again here would
178
+ // only send the same request a second time.
179
+ if (item.error != null) results.set(key, storeQuoteFailure(quoteStore, key, dataProvider.id, startedAt, item.error));
180
+ return;
181
+ }
163
182
  const quote = resolveQuote?.(instrument, item.quote) ?? item.quote;
164
183
  const source = quote.providerId ?? dataProvider.id;
165
184
  const attempts = [createAttempt(source, Date.now(), "success")];
@@ -0,0 +1,72 @@
1
+ import type { CloudMarketResponse, CloudPricePointPayload } from "../api-client/types";
2
+ import type { FxLeg } from "./coordinator/fx-legs";
3
+
4
+ /** USD per unit of one currency at each completed daily FX close, by date. */
5
+ export interface FxCloses {
6
+ currency: string;
7
+ closes: ReadonlyMap<string, number>;
8
+ first: string;
9
+ asOf: string;
10
+ }
11
+
12
+ /** Why a daily FX history cannot be used: no usable closes, or none in the last week. */
13
+ export class FxHistoryError extends Error {
14
+ constructor(readonly problem: "unavailable" | "stale") {
15
+ super(problem === "stale" ? "Daily FX history is stale" : "Daily FX history unavailable");
16
+ this.name = "FxHistoryError";
17
+ }
18
+ }
19
+
20
+ const DAY_MS = 86_400_000;
21
+ /** A pair's latest completed close older than this is stale; a weekend and a holiday fit well inside it. */
22
+ const FX_MAX_AGE_DAYS = 7;
23
+
24
+ const isDay = (value: string) => /^\d{4}-\d{2}-\d{2}$/.test(value) && Number.isFinite(Date.parse(value))
25
+ && new Date(value).toISOString().slice(0, 10) === value;
26
+
27
+ /**
28
+ * Completed daily closes of the pair as USD per unit, today's still-trading
29
+ * bar left out. A malformed row, two different closes on one date, or more
30
+ * rows than asked for rejects the whole history rather than a part of it.
31
+ */
32
+ export function dailyFxCloses(
33
+ response: CloudMarketResponse<CloudPricePointPayload[]>,
34
+ leg: FxLeg,
35
+ now = new Date(),
36
+ maxRows = 1500,
37
+ ): FxCloses {
38
+ if (response.status !== "success" || !Array.isArray(response.data) || response.data.length < 2) throw new FxHistoryError("unavailable");
39
+ if (response.stale || response.providerMeta?.stale) throw new FxHistoryError("stale");
40
+ if (response.data.length > maxRows) throw new FxHistoryError("unavailable");
41
+ const today = now.toISOString().slice(0, 10);
42
+ const closes = new Map<string, number>();
43
+ for (const row of response.data) {
44
+ if (!row || typeof row.date !== "string" || !Number.isFinite(Date.parse(row.date)) || !isDay(row.date.slice(0, 10))
45
+ || !Number.isFinite(row.close) || row.close <= 0) throw new FxHistoryError("unavailable");
46
+ const date = new Date(row.date).toISOString().slice(0, 10);
47
+ if (date >= today) continue;
48
+ const rate = leg.invert ? 1 / row.close : row.close;
49
+ const previous = closes.get(date);
50
+ if (previous != null && previous !== rate) throw new FxHistoryError("unavailable");
51
+ closes.set(date, rate);
52
+ }
53
+ const dates = [...closes.keys()].sort();
54
+ const asOf = dates.at(-1);
55
+ if (!asOf || Date.parse(today) - Date.parse(asOf) > FX_MAX_AGE_DAYS * DAY_MS) throw new FxHistoryError("stale");
56
+ return { currency: leg.currency, closes, first: dates[0]!, asOf };
57
+ }
58
+
59
+ /**
60
+ * The last completed close on or before `date` (YYYY-MM-DD), looking back at
61
+ * most a week so a weekend or holiday finds the close before it but a gap in
62
+ * the history is not bridged.
63
+ */
64
+ export function fxCloseOnOrBefore(fx: FxCloses, date: string): { date: string; rate: number } | null {
65
+ const end = Date.parse(`${(date < fx.asOf ? date : fx.asOf)}T00:00:00Z`);
66
+ for (let back = 0; back <= FX_MAX_AGE_DAYS; back++) {
67
+ const day = new Date(end - back * DAY_MS).toISOString().slice(0, 10);
68
+ const rate = fx.closes.get(day);
69
+ if (rate != null) return { date: day, rate };
70
+ }
71
+ return null;
72
+ }
@@ -1,5 +1,6 @@
1
1
  import type { MarketState } from "../../types/financials";
2
2
  import { canonicalExchange, EXCHANGE_TIME_ZONES, isUsListingExchange } from "../../utils/exchanges";
3
+ import { hasPublishedApacCalendar, isPublishedApacClosure } from "../published-apac-sessions";
3
4
  import { hasPublishedCnCalendar, isPublishedCnClosure } from "../published-cn-sessions";
4
5
  import { hasPublishedJpxCalendar, isPublishedJpxClosure } from "../published-jpx-sessions";
5
6
  import { hasPublishedNseCalendar, isPublishedNseClosure } from "../published-nse-sessions";
@@ -11,6 +12,9 @@ const ALWAYS_OPEN_EXCHANGES = new Set(["CCC"]);
11
12
  const MS_PER_DAY = 24 * 60 * 60 * 1000;
12
13
  const OVERNIGHT_CLOSE_MAX_AGE_MS = 20 * 60 * 60 * 1000;
13
14
  const ALWAYS_OPEN_MAX_AGE_MS = 2 * 60 * 60 * 1000;
15
+ // Spring Festival can put the previous session twelve calendar days back
16
+ // (TWSE, February 2026).
17
+ const SESSION_LOOKBACK_DAYS = 14;
14
18
  const REGULAR_OPEN_MINUTES: Record<string, number> = {
15
19
  NASDAQ: 9 * 60 + 30,
16
20
  NYSE: 9 * 60 + 30,
@@ -72,6 +76,28 @@ const REGULAR_CLOSE_MINUTES: Record<string, number> = {
72
76
  NZX: 17 * 60, SSE: 15 * 60 + 30, SZSE: 15 * 60 + 30,
73
77
  BMV: 15 * 60 + 10, B3: 18 * 60 + 30, BYMA: 17 * 60 + 10, JSE: 17 * 60 + 15, TASE: 17 * 60 + 40,
74
78
  };
79
+ // Venues that pause at midday, as local minutes [start, end), with a zone for
80
+ // those the session tables above do not cover. Jakarta pauses longer on Fridays.
81
+ const MIDDAY_BREAKS: Record<string, {
82
+ timeZone?: string;
83
+ weekdays: readonly [number, number];
84
+ friday?: readonly [number, number];
85
+ }> = {
86
+ HKEX: { weekdays: [12 * 60, 13 * 60] },
87
+ SGX: { weekdays: [12 * 60, 13 * 60] },
88
+ SSE: { weekdays: [11 * 60 + 30, 13 * 60] },
89
+ SZSE: { weekdays: [11 * 60 + 30, 13 * 60] },
90
+ JPX: { weekdays: [11 * 60 + 30, 12 * 60 + 30] },
91
+ BURSAMY: { timeZone: "Asia/Kuala_Lumpur", weekdays: [12 * 60 + 30, 14 * 60 + 30] },
92
+ JAKARTA: { timeZone: "Asia/Jakarta", weekdays: [12 * 60, 13 * 60 + 30], friday: [11 * 60 + 30, 14 * 60] },
93
+ };
94
+ // A morning print this close to the break is its last one, and afternoon
95
+ // prints are due this long after the feed's lag has passed the reopening.
96
+ const MIDDAY_BREAK_MARGIN_MS = 5 * 60_000;
97
+ // How far the delayed feed runs behind each venue's trades.
98
+ const DELAYED_FEED_LAG_MS = 15 * 60_000;
99
+ const SLOWER_DELAYED_FEED_LAG_MS = 20 * 60_000;
100
+ const SLOWER_DELAYED_FEEDS = new Set(["ASX", "KRX", "KOSDAQ", "TWSE", "TPEX", "SGX", "NZX"]);
75
101
  const exchangeLocalTimeFormatters = new Map<string, Intl.DateTimeFormat>();
76
102
  const usSessionFormatter = new Intl.DateTimeFormat("en-US", {
77
103
  timeZone: "America/New_York",
@@ -159,6 +185,7 @@ function isPublishedClosure(exchange: string, date: string): boolean {
159
185
  if (exchange === "JPX") return isPublishedJpxClosure(date);
160
186
  if (exchange === "NSE" || exchange === "BSE") return isPublishedNseClosure(date);
161
187
  if (exchange === "SSE" || exchange === "SZSE") return isPublishedCnClosure(date);
188
+ if (isPublishedApacClosure(exchange, date)) return true;
162
189
  return getPublishedUsEquityCalendarDay(exchange, date) === "closed";
163
190
  }
164
191
 
@@ -207,9 +234,7 @@ export function latestRegularSessionClose(
207
234
  if (!timeZone || ALWAYS_OPEN_EXCHANGES.has(canonical) || !Number.isFinite(time)) return null;
208
235
  const { year, month, day } = zonedDateTimeParts(time, timeZone);
209
236
  const today = Date.UTC(year, month - 1, day) / MS_PER_DAY;
210
- // Spring Festival can put the previous session eleven calendar days back.
211
- const lookback = (canonical === "SSE" || canonical === "SZSE") && hasPublishedCnCalendar(year) ? 14 : 10;
212
- for (let offset = 0; offset <= lookback; offset++) {
237
+ for (let offset = 0; offset <= SESSION_LOOKBACK_DAYS; offset++) {
213
238
  const date = new Date((today - offset) * MS_PER_DAY).toISOString().slice(0, 10);
214
239
  const published = getPublishedUsEquitySession(canonical, date);
215
240
  let close: number | null = null;
@@ -225,6 +250,20 @@ export function latestRegularSessionClose(
225
250
  return null;
226
251
  }
227
252
 
253
+ /**
254
+ * The UTC minute of the day the venue's regular session closed, for the latest
255
+ * session at or before `time` (20:00 UTC is 1200 while New York is on daylight
256
+ * time). Null for round-the-clock venues and for venues whose close hour is
257
+ * not listed, which `latestRegularSessionClose` would take to close at local
258
+ * midnight.
259
+ */
260
+ export function regularSessionCloseUtcMinute(exchange: string | undefined, time: number): number | null {
261
+ const canonical = canonicalExchange(exchange);
262
+ if (REGULAR_CLOSE_MINUTES[canonical] === undefined) return null;
263
+ const close = latestRegularSessionClose(canonical, time);
264
+ return close ? Math.floor(close.close / 60_000) % 1440 : null;
265
+ }
266
+
228
267
  /**
229
268
  * The open of the regular session `time` falls in, or of the latest one
230
269
  * before it: the published calendar for US venues, otherwise the venue's
@@ -238,8 +277,7 @@ export function latestRegularSessionOpen(exchange: string | undefined, time: num
238
277
  const minutes = REGULAR_OPEN_MINUTES[canonical];
239
278
  const { year, month, day } = zonedDateTimeParts(time, timeZone);
240
279
  const today = Date.UTC(year, month - 1, day) / MS_PER_DAY;
241
- const lookback = (canonical === "SSE" || canonical === "SZSE") && hasPublishedCnCalendar(year) ? 14 : 10;
242
- for (let offset = 0; offset <= lookback; offset++) {
280
+ for (let offset = 0; offset <= SESSION_LOOKBACK_DAYS; offset++) {
243
281
  const date = new Date((today - offset) * MS_PER_DAY).toISOString().slice(0, 10);
244
282
  const published = getPublishedUsEquitySession(canonical, date);
245
283
  let open: number | null = null;
@@ -270,7 +308,8 @@ export function isRegularSessionTime(exchange: string | undefined, time: number)
270
308
 
271
309
  /**
272
310
  * True when the venue's full-day closures for the year of `date` are
273
- * published: US venues, JPX, NSE, BSE, SSE and SZSE. Elsewhere a local holiday reads as a weekday.
311
+ * published: US venues, JPX, NSE, BSE, SSE, SZSE, KRX, KOSDAQ, TWSE, TPEX,
312
+ * HKEX, SGX and ASX. Elsewhere a local holiday reads as a weekday.
274
313
  */
275
314
  export function hasPublishedSessionCalendar(exchange: string | undefined, date: string): boolean {
276
315
  const canonical = canonicalExchange(exchange);
@@ -278,9 +317,42 @@ export function hasPublishedSessionCalendar(exchange: string | undefined, date:
278
317
  if (canonical === "JPX") return hasPublishedJpxCalendar(year);
279
318
  if (canonical === "NSE" || canonical === "BSE") return hasPublishedNseCalendar(year);
280
319
  if (canonical === "SSE" || canonical === "SZSE") return hasPublishedCnCalendar(year);
320
+ if (hasPublishedApacCalendar(canonical, year)) return true;
281
321
  return !!getPublishedUsEquityCalendarYears(canonical)?.includes(year);
282
322
  }
283
323
 
324
+ /** How far the delayed feed runs behind the venue's trades. */
325
+ export function delayedFeedLagMs(exchange: string | undefined): number {
326
+ return SLOWER_DELAYED_FEEDS.has(canonicalExchange(exchange)) ? SLOWER_DELAYED_FEED_LAG_MS : DELAYED_FEED_LAG_MS;
327
+ }
328
+
329
+ /**
330
+ * Whether a print is still the current price because the venue is paused at
331
+ * midday: `now` falls in the break, or within the feed's lag plus five
332
+ * minutes after it, and the print is the morning's last, no earlier than five
333
+ * minutes before the break started. An earlier morning print means the feed
334
+ * stopped before the break.
335
+ */
336
+ export function isMiddayBreakPrint(
337
+ timestampMs: number,
338
+ exchange: string | undefined,
339
+ now: number,
340
+ feedLagMs: number,
341
+ ): boolean {
342
+ const canonical = canonicalExchange(exchange);
343
+ const pause = MIDDAY_BREAKS[canonical];
344
+ const timeZone = pause?.timeZone ?? EXCHANGE_TIME_ZONES[canonical];
345
+ if (!pause || !timeZone || !Number.isFinite(timestampMs) || !Number.isFinite(now) || timestampMs > now) return false;
346
+ const { year, month, day } = zonedDateTimeParts(now, timeZone);
347
+ const weekday = new Date(Date.UTC(year, month - 1, day)).getUTCDay();
348
+ if (weekday === 0 || weekday === 6) return false;
349
+ const [start, end] = weekday === 5 && pause.friday ? pause.friday : pause.weekdays;
350
+ const at = (minutes: number) => zonedWallClockToUtcMs(timeZone, year, month, day, Math.floor(minutes / 60), minutes % 60, 0);
351
+ const breakStart = at(start);
352
+ return now >= breakStart && now <= at(end) + feedLagMs + MIDDAY_BREAK_MARGIN_MS
353
+ && timestampMs >= breakStart - MIDDAY_BREAK_MARGIN_MS;
354
+ }
355
+
284
356
  function usSessionState(timestampMs: number): UsSessionState {
285
357
  const minute = Math.floor(timestampMs / 60_000);
286
358
  return perMinute(usSessionCache, minute, () => formatUsSessionState(minute * 60_000));
@@ -0,0 +1,57 @@
1
+ import { canonicalExchange } from "../../utils/exchanges";
2
+ import { futuresListingVenue } from "../../utils/futures-generic";
3
+ import { regularSessionCloseUtcMinute } from "./freshness";
4
+
5
+ interface SessionLeg {
6
+ symbol: string;
7
+ /** The listing's exchange; without one the close is unknown and no note is made. */
8
+ exchange?: string;
9
+ /** What the reader typed, when it differs from the symbol. */
10
+ label?: string;
11
+ }
12
+
13
+ const MINUTES_PER_DAY = 1440;
14
+ /** Crypto and FX carry no regular session. */
15
+ const ALWAYS_OPEN_EXCHANGES = new Set(["CCC", "CCY"]);
16
+
17
+ const clock = (minute: number) => `${String(Math.floor(minute / 60) % 24).padStart(2, "0")}:${String(minute % 60).padStart(2, "0")}`;
18
+
19
+ function offsetText(minutes: number): string {
20
+ const hours = Math.floor(minutes / 60);
21
+ const rest = minutes % 60;
22
+ return [hours ? `${hours} h` : "", rest ? `${rest} min` : ""].filter(Boolean).join(" ");
23
+ }
24
+
25
+ /**
26
+ * Where a daily bar of the listing falls on its date. A venue with a listed
27
+ * regular close closes at that UTC time. Crypto, FX and futures carry a bar
28
+ * dated 00:00 UTC, which closes when the next UTC day starts. A venue with
29
+ * neither is unknown.
30
+ */
31
+ function dailyBarClose(leg: SessionLeg, time: number): { minute: number; text: string } | null {
32
+ const label = leg.label ?? leg.symbol;
33
+ const minute = regularSessionCloseUtcMinute(leg.exchange, time);
34
+ if (minute !== null) return { minute, text: `${label} closes ${clock(minute)} UTC` };
35
+ const exchange = canonicalExchange(leg.exchange);
36
+ return exchange && (ALWAYS_OPEN_EXCHANGES.has(exchange) || futuresListingVenue(leg.symbol, exchange))
37
+ ? { minute: MINUTES_PER_DAY, text: `${label} bar is ${clock(0)} UTC` }
38
+ : null;
39
+ }
40
+
41
+ /**
42
+ * One line for a daily pair whose two sides close at different times, such as
43
+ * a US equity against crypto, or null when they close together (two US
44
+ * equities) or a close is not known. Daily closes pair by UTC date, so a
45
+ * reader of a correlation or ratio should know the two prices are not taken
46
+ * at the same moment. `dateKey` is the date the pair is read on, which
47
+ * settles daylight time.
48
+ */
49
+ export function mixedSessionCloseNote(left: SessionLeg, right: SessionLeg, dateKey?: string | null): string | null {
50
+ const parsed = dateKey ? Date.parse(`${dateKey}T23:59:59Z`) : Number.NaN;
51
+ const time = Number.isFinite(parsed) ? parsed : Date.now();
52
+ const a = dailyBarClose(left, time);
53
+ const b = dailyBarClose(right, time);
54
+ if (!a || !b) return null;
55
+ const offset = Math.abs(a.minute - b.minute);
56
+ return offset === 0 ? null : `${a.text}; ${b.text} (${offsetText(offset)} offset). Daily pairs are matched by date.`;
57
+ }