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.
- package/README.md +2 -1
- package/package.json +2 -1
- package/src/api-client/beneficial-owners.ts +92 -0
- package/src/api-client/data.ts +26 -8
- package/src/api-client/errors.ts +12 -0
- package/src/api-client/geo.ts +363 -0
- package/src/api-client/index.ts +2 -0
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/paths.ts +30 -1
- package/src/api-client/perps.ts +37 -0
- package/src/api-client/request.ts +5 -2
- package/src/api-client/types.ts +2 -0
- package/src/brokers/account-cache.ts +69 -0
- package/src/cli/command-options.ts +74 -0
- package/src/cli/commands/command-utils.ts +37 -0
- package/src/cli/commands/crypto-hints.ts +75 -0
- package/src/cli/commands/market.ts +560 -136
- package/src/cli/commands/overview.ts +136 -48
- package/src/cli/commands/ticker.ts +220 -67
- package/src/cli/desktop-pane-shot.ts +37 -4
- package/src/cli/freshness.ts +61 -0
- package/src/cli/help.ts +27 -6
- package/src/cli/helpers.ts +4 -8
- package/src/cli/history-rows.ts +187 -15
- package/src/cli/index.ts +23 -8
- package/src/cli/listing-arg.ts +321 -0
- package/src/cli/options.ts +5 -1
- package/src/cli/pane-functions/access-gate.ts +42 -0
- package/src/cli/pane-functions/capabilities.ts +5 -0
- package/src/cli/pane-functions/catalog.ts +28 -1
- package/src/cli/pane-functions/data.ts +3 -1
- package/src/cli/pane-functions/dom.ts +87 -16
- package/src/cli/pane-functions/freshness.ts +400 -0
- package/src/cli/pane-functions/function-help.ts +31 -22
- package/src/cli/pane-functions/headless.ts +201 -41
- package/src/cli/pane-functions/index.ts +24 -6
- package/src/cli/pane-functions/options.ts +3 -0
- package/src/cli/pane-functions/report.ts +12 -1
- package/src/cli/pane-functions/resolver.ts +63 -9
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +11 -3
- package/src/cli/registry.ts +6 -3
- package/src/cli/report-tables.ts +460 -0
- package/src/cli/result.ts +53 -29
- package/src/cli/ticker-resolution.ts +7 -5
- package/src/components/chart/composite/composite-chart.tsx +88 -2536
- package/src/components/chart/composite/drawing-store.ts +59 -0
- package/src/components/chart/composite/legend.tsx +319 -0
- package/src/components/chart/composite/panel-bitmap.ts +139 -0
- package/src/components/chart/composite/panel-gestures.ts +59 -0
- package/src/components/chart/composite/panel-labels.ts +107 -0
- package/src/components/chart/composite/panel-surface.tsx +876 -0
- package/src/components/chart/composite/tool-catalog.ts +98 -0
- package/src/components/chart/composite/toolbar.tsx +186 -0
- package/src/components/chart/composite/tools.ts +8 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
- package/src/components/chart/composite/use-composite-viewport.ts +143 -0
- package/src/components/command-bar/list/model.ts +5 -0
- package/src/components/command-bar/list/view.tsx +16 -3
- package/src/components/command-bar/pane-templates/workflow.ts +1 -0
- package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
- package/src/components/command-bar/workflow/ops.ts +1 -1
- package/src/components/command-bar/workflow/tickers.ts +6 -0
- package/src/components/data-table/export.ts +6 -51
- package/src/components/data-table/view.tsx +32 -11
- package/src/components/feedback-dialog.tsx +2 -1
- package/src/components/form-modal/field-row.tsx +2 -2
- package/src/components/layout/detached-pane-shell.tsx +6 -3
- package/src/components/layout/pane/content.tsx +23 -10
- package/src/components/layout/pane/error-boundary.tsx +103 -0
- package/src/components/layout/pane/footer/registration.tsx +68 -23
- package/src/components/layout/pane/header.tsx +11 -11
- package/src/components/layout/shell/active-drag.ts +67 -35
- package/src/components/layout/shell/cursor-occlusion.ts +6 -5
- package/src/components/layout/shell/drag/index.ts +12 -7
- package/src/components/layout/shell/drag/live.ts +122 -0
- package/src/components/layout/shell/drag/overlays.tsx +179 -35
- package/src/components/layout/shell/drag/runtime.ts +62 -50
- package/src/components/layout/shell/drag/slide.ts +10 -0
- package/src/components/layout/shell/index.tsx +37 -51
- package/src/components/layout/shell/menu.ts +2 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +13 -13
- package/src/components/layout/shell/native/surfaces.ts +30 -14
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +419 -168
- package/src/components/layout/shell/terminal-pointer-runtime.ts +18 -18
- package/src/components/layout/shell/window-mode/overlays.tsx +12 -4
- package/src/components/metric-treemap/heat-surface.tsx +43 -16
- package/src/components/metric-treemap/heat-tiles.ts +18 -0
- package/src/components/metric-treemap/layout.ts +2 -0
- package/src/components/onboarding/onboarding-keyboard.ts +311 -0
- package/src/components/onboarding/onboarding-wizard.tsx +101 -788
- package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
- package/src/components/onboarding/use-onboarding-progress.ts +298 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
- package/src/components/ticker/list-table-view.tsx +13 -1
- package/src/components/ui/fields.tsx +8 -0
- package/src/components/ui/range-track.tsx +10 -3
- package/src/components/ui/status.tsx +8 -2
- package/src/components/ui/tabs.tsx +7 -4
- package/src/components/ui/text-prompt-dialog.tsx +4 -2
- package/src/data/config/store/normalize.ts +17 -1
- package/src/data/json-persistence.ts +17 -3
- package/src/data/json-storage.ts +2 -0
- package/src/data/memory-resource-store.ts +46 -0
- package/src/i18n/es.ts +19 -1
- package/src/i18n/ja.ts +19 -1
- package/src/i18n/ko.ts +19 -1
- package/src/i18n/zh-cn.ts +19 -1
- package/src/i18n/zh-tw.ts +19 -1
- package/src/market-data/coordinator/chart.ts +1 -1
- package/src/market-data/coordinator/quotes.ts +23 -4
- package/src/market-data/fx-closes.ts +72 -0
- package/src/market-data/market/freshness.ts +123 -6
- package/src/market-data/market/session-close-note.ts +57 -0
- package/src/market-data/market/status.ts +151 -0
- package/src/market-data/published-apac-sessions.ts +66 -0
- package/src/market-data/quotes/contributions.ts +2 -0
- package/src/market-data/quotes/freshness.ts +5 -0
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +49 -4
- package/src/plugins/builtin/account-management/pane.tsx +4 -0
- package/src/plugins/builtin/alerts/cli.ts +10 -5
- package/src/plugins/builtin/alerts/index.tsx +1 -0
- package/src/plugins/builtin/analytics/metrics.ts +8 -3
- package/src/plugins/builtin/analytics/pane-model.ts +10 -6
- package/src/plugins/builtin/analytics/risk-client.ts +191 -66
- package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
- package/src/plugins/builtin/analytics/risk-headless.ts +19 -13
- package/src/plugins/builtin/analytics/risk-model.ts +45 -17
- package/src/plugins/builtin/analytics/risk-pane.tsx +1 -0
- package/src/plugins/builtin/analytics/risk-test-data.ts +25 -1
- package/src/plugins/builtin/attention/headless.ts +6 -4
- package/src/plugins/builtin/attention/index.tsx +1 -1
- package/src/plugins/builtin/attention/pane.tsx +2 -2
- package/src/plugins/builtin/awards/headless.ts +1 -0
- package/src/plugins/builtin/awards/pane.tsx +1 -1
- package/src/plugins/builtin/backtest/headless.ts +1 -0
- package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
- package/src/plugins/builtin/buildout/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/detail.tsx +1 -1
- package/src/plugins/builtin/catalysts/headless.ts +3 -1
- package/src/plugins/builtin/cds/headless.ts +2 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
- package/src/plugins/builtin/chart-composer/headless.ts +38 -3
- package/src/plugins/builtin/chart-composer/index.tsx +3 -1
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
- package/src/plugins/builtin/chat/channels.ts +19 -3
- package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
- package/src/plugins/builtin/chat/content/footer.tsx +15 -6
- package/src/plugins/builtin/chat/content/index.tsx +120 -21
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
- package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
- package/src/plugins/builtin/chat/direct-messages.ts +200 -0
- package/src/plugins/builtin/chat/index.tsx +1 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
- package/src/plugins/builtin/chat/message/header.tsx +16 -6
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
- package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
- package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
- package/src/plugins/builtin/chat/message/types.ts +14 -2
- package/src/plugins/builtin/chat/profile-popover.ts +18 -13
- package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
- package/src/plugins/builtin/cloud/plugin.tsx +1 -0
- package/src/plugins/builtin/cloud/team/module.tsx +1 -0
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/comment-letters/index.tsx +1 -0
- package/src/plugins/builtin/company-attention/headless.ts +5 -1
- package/src/plugins/builtin/company-attention/pane.tsx +2 -2
- package/src/plugins/builtin/company-kpis/headless.ts +1 -0
- package/src/plugins/builtin/congress-trades/headless.ts +1 -0
- package/src/plugins/builtin/correlation/compute.ts +59 -16
- package/src/plugins/builtin/correlation/geo.ts +34 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
- package/src/plugins/builtin/correlation/headless.ts +42 -8
- package/src/plugins/builtin/correlation/history.ts +2 -0
- package/src/plugins/builtin/correlation/index.tsx +68 -14
- package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
- package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
- package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
- package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
- package/src/plugins/builtin/correlation/settings.ts +1 -1
- package/src/plugins/builtin/cot/headless.ts +6 -3
- package/src/plugins/builtin/cot/index.tsx +3 -3
- package/src/plugins/builtin/cot/model.ts +36 -3
- package/src/plugins/builtin/cpi/headless.ts +4 -0
- package/src/plugins/builtin/credit-boards/headless.ts +2 -0
- package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
- package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
- package/src/plugins/builtin/credit-documents/headless.ts +2 -0
- package/src/plugins/builtin/crypto-board/headless.ts +3 -0
- package/src/plugins/builtin/custom-view/loader.ts +1 -1
- package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
- package/src/plugins/builtin/doe/headless.ts +7 -0
- package/src/plugins/builtin/doe/range-bar.tsx +7 -37
- package/src/plugins/builtin/earnings/headless.ts +5 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
- package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
- package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
- package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
- package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
- package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
- package/src/plugins/builtin/econ/index.tsx +1 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
- package/src/plugins/builtin/equity-screener/headless.ts +2 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
- package/src/plugins/builtin/executives/index.tsx +1 -0
- package/src/plugins/builtin/exposure/headless.ts +3 -1
- package/src/plugins/builtin/fear-greed/headless.ts +2 -0
- package/src/plugins/builtin/filing-events/index.tsx +1 -0
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +39 -10
- package/src/plugins/builtin/futures-curve/index.tsx +3 -3
- package/src/plugins/builtin/futures-curve/model.ts +188 -4
- package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
- package/src/plugins/builtin/gpu/headless.ts +7 -3
- package/src/plugins/builtin/gpu/ladder.tsx +26 -30
- package/src/plugins/builtin/gpu/model.ts +27 -1
- package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
- package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
- package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
- package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
- package/src/plugins/builtin/holders/client.ts +3 -6
- package/src/plugins/builtin/holders/format.ts +31 -1
- package/src/plugins/builtin/holders/headless.ts +161 -6
- package/src/plugins/builtin/holders/index.tsx +10 -3
- package/src/plugins/builtin/holders/pane.tsx +42 -16
- package/src/plugins/builtin/holders/report-header.ts +136 -0
- package/src/plugins/builtin/holders/table-model.ts +20 -5
- package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
- package/src/plugins/builtin/holders/types.ts +2 -1
- package/src/plugins/builtin/insider/headless.ts +2 -0
- package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
- package/src/plugins/builtin/iv-history/headless.ts +4 -1
- package/src/plugins/builtin/jobs/headless.ts +1 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +12 -6
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +25 -0
- package/src/plugins/builtin/macro-day/headless.ts +2 -0
- package/src/plugins/builtin/market-halts/index.tsx +1 -0
- package/src/plugins/builtin/market-heatmap/data.ts +2 -0
- package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +39 -46
- package/src/plugins/builtin/market-heatmap/model.ts +146 -0
- package/src/plugins/builtin/market-heatmap/portfolio.ts +23 -4
- package/src/plugins/builtin/market-movers/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/members/client.ts +20 -3
- package/src/plugins/builtin/members/headless.ts +5 -3
- package/src/plugins/builtin/members/model.ts +10 -2
- package/src/plugins/builtin/members/pane.tsx +23 -6
- package/src/plugins/builtin/mna/distress/headless.ts +1 -0
- package/src/plugins/builtin/mna/headless.ts +1 -0
- package/src/plugins/builtin/money-markets/headless.ts +1 -0
- package/src/plugins/builtin/news/headless.ts +2 -0
- package/src/plugins/builtin/news/wire/index.tsx +8 -1
- package/src/plugins/builtin/notes/cli.ts +14 -6
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/openfda/index.tsx +1 -0
- package/src/plugins/builtin/options-calculator/headless.ts +2 -0
- package/src/plugins/builtin/options-positioning/headless.ts +3 -0
- package/src/plugins/builtin/options-scenario/headless.ts +5 -0
- package/src/plugins/builtin/pe-band/client.ts +48 -3
- package/src/plugins/builtin/pe-band/headless.ts +25 -7
- package/src/plugins/builtin/pe-band/model.ts +92 -16
- package/src/plugins/builtin/pe-band/pane.tsx +33 -16
- package/src/plugins/builtin/perps/client.ts +50 -3
- package/src/plugins/builtin/perps/headless.ts +144 -16
- package/src/plugins/builtin/perps/index.tsx +6 -6
- package/src/plugins/builtin/perps/model.ts +189 -12
- package/src/plugins/builtin/perps/pane.tsx +249 -48
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +16 -1
- package/src/plugins/builtin/portfolio-list/allocation.ts +248 -0
- package/src/plugins/builtin/portfolio-list/cached-account.ts +42 -0
- package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
- package/src/plugins/builtin/portfolio-list/cli/render.ts +232 -39
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
- package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
- package/src/plugins/builtin/portfolio-list/headless.ts +100 -16
- package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
- package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
- package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +53 -16
- package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +46 -5
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +11 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
- package/src/plugins/builtin/power/headless.ts +3 -1
- package/src/plugins/builtin/rate-path/headless.ts +2 -0
- package/src/plugins/builtin/realized-vol/headless.ts +2 -0
- package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
- package/src/plugins/builtin/research/analyst-headless.ts +3 -0
- package/src/plugins/builtin/research/events-headless.ts +2 -0
- package/src/plugins/builtin/research/headless.ts +2 -0
- package/src/plugins/builtin/research/index.tsx +1 -0
- package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
- package/src/plugins/builtin/research/relative-valuation-model.ts +18 -6
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
- package/src/plugins/builtin/research-search/index.tsx +1 -0
- package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
- package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
- package/src/plugins/builtin/reverse-dcf/model.ts +2 -1
- package/src/plugins/builtin/risk-factors/headless.ts +2 -0
- package/src/plugins/builtin/scanner/flow-history.ts +2 -13
- package/src/plugins/builtin/scanner/headless.ts +14 -0
- package/src/plugins/builtin/seasonality/headless.ts +2 -0
- package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
- package/src/plugins/builtin/sec/filing-content.ts +42 -17
- package/src/plugins/builtin/sec/forms.ts +12 -0
- package/src/plugins/builtin/sec/headless.ts +2 -0
- package/src/plugins/builtin/sectors/client.ts +1 -0
- package/src/plugins/builtin/sectors/headless.ts +9 -1
- package/src/plugins/builtin/sectors/sector-model.ts +2 -0
- package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
- package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
- package/src/plugins/builtin/shared/members-menu.tsx +260 -0
- package/src/plugins/builtin/shared/report-freshness.ts +57 -0
- package/src/plugins/builtin/shared/research-cells.tsx +4 -9
- package/src/plugins/builtin/short-interest/headless.ts +2 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/pane.tsx +1 -1
- package/src/plugins/builtin/social-mentions/headless.ts +1 -0
- package/src/plugins/builtin/social-mentions/pane.tsx +1 -1
- package/src/plugins/builtin/supply-chain/headless.ts +7 -1
- package/src/plugins/builtin/supply-chain/index.tsx +10 -1
- package/src/plugins/builtin/supply-chain/model.ts +27 -2
- package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
- package/src/plugins/builtin/themes/headless.ts +3 -0
- package/src/plugins/builtin/themes/pane.tsx +3 -0
- package/src/plugins/builtin/thirteenf/headless.ts +110 -25
- package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +4 -0
- package/src/plugins/builtin/ticker-detail/financials/model.ts +25 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +27 -5
- package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +17 -5
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +27 -26
- package/src/plugins/builtin/time-sales/headless.ts +5 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
- package/src/plugins/builtin/volatility/headless.ts +6 -1
- package/src/plugins/builtin/world-indices/headless.ts +2 -0
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +159 -0
- package/src/plugins/builtin/world-venue-map/basemap.ts +232 -0
- package/src/plugins/builtin/world-venue-map/client.ts +45 -0
- package/src/plugins/builtin/world-venue-map/country-labels.ts +78 -0
- package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
- package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
- package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
- package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
- package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +448 -0
- package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
- package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
- package/src/plugins/builtin/world-venue-map/index.ts +69 -6
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +565 -0
- package/src/plugins/builtin/world-venue-map/layers.ts +406 -0
- package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +557 -85
- package/src/plugins/builtin/world-venue-map/model.ts +23 -4
- package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +202 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/labels.chunk.ts +244 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
- package/src/plugins/builtin/world-venue-map/pane.tsx +35 -44
- package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
- package/src/plugins/builtin/yield-curve/headless.ts +16 -0
- package/src/plugins/loader.ts +13 -1
- package/src/plugins/registry/pane-settings.ts +1 -0
- package/src/renderers/browser/app-services.ts +3 -1
- package/src/renderers/dom/build-assets.ts +81 -3
- package/src/renderers/dom/data-table/dom.ts +31 -0
- package/src/renderers/dom/data-table/index.tsx +5 -0
- package/src/renderers/dom/data-table/row.tsx +2 -0
- package/src/renderers/dom/desktop/controls.tsx +7 -3
- package/src/renderers/dom/desktop/list-view.tsx +35 -10
- package/src/renderers/dom/desktop/popover.tsx +73 -14
- package/src/renderers/dom/host/box.tsx +113 -17
- package/src/renderers/dom/host/drag-shield.ts +24 -0
- package/src/renderers/dom/host/input.tsx +14 -3
- package/src/renderers/dom/host/live-frame.ts +54 -0
- package/src/renderers/dom/host/mouse.ts +8 -1
- package/src/renderers/dom/host/scroll-box.tsx +6 -5
- package/src/renderers/dom/host/tabs.tsx +3 -2
- package/src/renderers/dom/styles.css +16 -9
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +7 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +2 -0
- package/src/renderers/electrobun/bun/desktop/initialization.ts +13 -0
- package/src/renderers/electrobun/shared/protocol.ts +10 -1
- package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +4 -0
- package/src/renderers/electrobun/view/host/native.ts +0 -10
- package/src/renderers/electrobun/view/host/window-move.ts +28 -0
- package/src/renderers/electrobun/view/remote/persistence.ts +15 -2
- package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
- package/src/renderers/electrobun/view/ui-host.tsx +2 -5
- package/src/renderers/opentui/host.tsx +5 -0
- package/src/renderers/opentui/ui-host.tsx +7 -1
- package/src/sources/gloomberb-cloud/index.ts +25 -4
- package/src/sources/gloomberb-cloud/normalizers.ts +43 -23
- package/src/sources/provider-router/batches.ts +3 -3
- package/src/sources/provider-router/cached-routes.ts +4 -1
- package/src/sources/provider-router/financial-routes.ts +2 -2
- package/src/sources/provider-router/financials.ts +76 -12
- package/src/sources/provider-router/history.ts +15 -10
- package/src/sources/provider-router/primary.ts +2 -2
- package/src/sources/sec-registrant.ts +75 -0
- package/src/state/app/context/index.tsx +24 -8
- package/src/state/hooks/quote-streaming.ts +41 -26
- package/src/state/pane-scroll-registry.tsx +67 -35
- package/src/sync/core-contributors.ts +4 -0
- package/src/telemetry/crash-reports.ts +4 -1
- package/src/test-support/cli-context.ts +10 -2
- package/src/test-support/margin-account.ts +108 -0
- package/src/theme/heat-colors.ts +266 -84
- package/src/time-series/resolution.ts +15 -0
- package/src/time-series/resolve.ts +1 -1
- package/src/time-series/use-chart-resolution.ts +1 -1
- package/src/types/context-menu.ts +6 -0
- package/src/types/data-provider.ts +2 -0
- package/src/types/financials.ts +35 -3
- package/src/types/headless.ts +79 -2
- package/src/types/plugin.ts +20 -1
- package/src/types/ticker.ts +15 -0
- package/src/ui/host.tsx +26 -0
- package/src/ui/index.tsx +8 -3
- package/src/ui/scroll-box-axis.ts +26 -0
- package/src/updater/index.ts +9 -11
- package/src/utils/async-deadline.ts +21 -0
- package/src/utils/cli-output.ts +5 -1
- package/src/utils/crypto-pair.ts +41 -0
- package/src/utils/currency-units.ts +19 -0
- package/src/utils/depositary-receipt.ts +70 -0
- package/src/utils/display-number.ts +63 -0
- package/src/utils/exchanges.ts +72 -0
- package/src/utils/fire-and-forget.ts +24 -0
- package/src/utils/format.ts +13 -0
- package/src/utils/fundamentals.ts +17 -1
- package/src/utils/price-earnings.ts +70 -3
- package/src/utils/price-history-integrity.ts +19 -6
- package/src/utils/price-history.ts +58 -13
- package/src/utils/rpc-timeout-error.ts +27 -0
- package/src/utils/sec.ts +13 -1
- package/src/utils/utc-time.ts +79 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { formatShortDate, parseDisplayDate } from "../../utils/datetime-format";
|
|
2
2
|
import { formatReportedMoney } from "../../utils/reported-money";
|
|
3
|
+
import { fundamentalsCurrency, reportedEnterpriseValue } from "../../utils/fundamentals";
|
|
3
4
|
import { latestFinancialPeriod } from "../../utils/latest-financial-period";
|
|
4
|
-
import { formatPriceEarnings } from "../../utils/price-earnings";
|
|
5
|
+
import { exportedFundamentals, formatPriceEarnings, priceEarningsOnEarnings } from "../../utils/price-earnings";
|
|
5
6
|
import { describeFundamentalMarketCap, selectMarketCapitalization } from "../../utils/market-capitalization";
|
|
6
7
|
import {
|
|
7
8
|
formatCompact,
|
|
@@ -20,7 +21,12 @@ import {
|
|
|
20
21
|
wrapText,
|
|
21
22
|
type CliStatEntry,
|
|
22
23
|
} from "../../utils/cli-output";
|
|
23
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
exchangeShortName,
|
|
26
|
+
getExtendedSessionDisplay,
|
|
27
|
+
getRegularSessionDisplay,
|
|
28
|
+
marketStateLabel,
|
|
29
|
+
} from "../../market-data/market/status";
|
|
24
30
|
import type { AppConfig } from "../../types/config";
|
|
25
31
|
import type { FinancialStatement, TickerFinancials } from "../../types/financials";
|
|
26
32
|
import { computeTickerPriceReturns } from "../../market-data/ticker-price-returns";
|
|
@@ -44,6 +50,13 @@ import {
|
|
|
44
50
|
} from "../helpers";
|
|
45
51
|
import { NotesFiles } from "../../plugins/builtin/notes/files";
|
|
46
52
|
import { isUsEquityTicker } from "../../utils/sec";
|
|
53
|
+
import { canonicalExchange, exchangeLabel, isKnownExchangeCode } from "../../utils/exchanges";
|
|
54
|
+
import { failIfNotTraded, ListingArgError, listingIdentity, resolveCliListing, type CliListing } from "../listing-arg";
|
|
55
|
+
import { sharesOutstandingInReceipts } from "../../utils/depositary-receipt";
|
|
56
|
+
import { cliFreshnessFooter } from "../result";
|
|
57
|
+
import { exportEntriesTable, reportFooterLines, type CliReportTables } from "../report-tables";
|
|
58
|
+
import type { ReportFreshness } from "../pane-functions/freshness";
|
|
59
|
+
import { fundamentalsFreshness, quotesFreshness } from "../freshness";
|
|
47
60
|
|
|
48
61
|
const NEWS_ITEM_LIMIT = 5;
|
|
49
62
|
const SEC_FILING_LIMIT = 5;
|
|
@@ -52,6 +65,8 @@ const MAX_PROSE_WIDTH = 100;
|
|
|
52
65
|
const METADATA_SEPARATOR = " · ";
|
|
53
66
|
|
|
54
67
|
interface TickerCommandDependencies {
|
|
68
|
+
/** `--exchange`: the listing, for a symbol that trades in several places. */
|
|
69
|
+
exchange?: string;
|
|
55
70
|
initMarketData?: () => Promise<MarketContext>;
|
|
56
71
|
fail?: (message: string, details?: string) => never;
|
|
57
72
|
printResult?: CliCommandContext["printResult"];
|
|
@@ -87,10 +102,26 @@ function buildStatementMetrics(statement: FinancialStatement, currency?: string)
|
|
|
87
102
|
["Total Debt", money(statement.totalDebt)],
|
|
88
103
|
["Equity", money(statement.totalEquity)],
|
|
89
104
|
["Diluted EPS", money(statement.eps, true)],
|
|
90
|
-
|
|
105
|
+
// Labelled only when the service says the row counts receipts.
|
|
106
|
+
["Diluted Shares", statement.dilutedShares != null && statement.shareBasis === "depositary_receipt"
|
|
107
|
+
? `${formatCompact(statement.dilutedShares)} (ADR equivalent)`
|
|
108
|
+
: formatCompact(statement.dilutedShares)],
|
|
91
109
|
];
|
|
92
110
|
}
|
|
93
111
|
|
|
112
|
+
/**
|
|
113
|
+
* A receipt's count is its ordinary shares expressed in receipts, as its
|
|
114
|
+
* market cap is; the ordinary count follows when the service gives it.
|
|
115
|
+
*/
|
|
116
|
+
function sharesOutstandingText(fundamentals: TickerFinancials["fundamentals"], inReceipts: boolean): string {
|
|
117
|
+
const shares = fundamentals?.sharesOutstanding;
|
|
118
|
+
if (shares == null || !inReceipts) return formatCompact(shares);
|
|
119
|
+
const ordinary = fundamentals?.shareBasis === "depositary_receipt" ? fundamentals.underlyingOrdinaryShares : undefined;
|
|
120
|
+
return ordinary != null && Number.isFinite(ordinary) && ordinary > 0
|
|
121
|
+
? `${formatCompact(shares)} (ADR equivalent = ${formatCompact(ordinary)} ordinary shares)`
|
|
122
|
+
: `${formatCompact(shares)} (ADR equivalent)`;
|
|
123
|
+
}
|
|
124
|
+
|
|
94
125
|
/** Provider prose is wrapped; `verbatim` keeps the user's own spacing, such as a table in a note. */
|
|
95
126
|
function appendTextSection(lines: string[], title: string, content: string | undefined, verbatim = false) {
|
|
96
127
|
const text = content?.trim();
|
|
@@ -229,72 +260,171 @@ function enterpriseValueCurrency(
|
|
|
229
260
|
|| undefined;
|
|
230
261
|
}
|
|
231
262
|
|
|
263
|
+
/** A fundamentals line: the text the report prints, and for CSV the figure behind it in `unit`. */
|
|
264
|
+
interface FundamentalsMetric {
|
|
265
|
+
label: string;
|
|
266
|
+
text: string;
|
|
267
|
+
value?: number | string | null;
|
|
268
|
+
unit?: string;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
type MetricFigure = Omit<FundamentalsMetric, "label">;
|
|
272
|
+
|
|
273
|
+
/** An amount in the currency the source reported it in; `ccy?` when it named none, as the text says. */
|
|
274
|
+
function reportedMoney(value: number | undefined, currency: string | undefined, perShare = false): MetricFigure {
|
|
275
|
+
return { text: formatReportedMoney(value, currency, perShare), value, unit: currency?.trim() || "ccy?" };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function percentFigure(fraction: number | null | undefined, format: (value: number) => string): MetricFigure {
|
|
279
|
+
return fraction != null ? { text: format(fraction), value: fraction * 100, unit: "%" } : { text: "—" };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function multipleFigure(value: ReturnType<typeof priceEarningsOnEarnings> | number | undefined): MetricFigure {
|
|
283
|
+
const text = formatPriceEarnings(value, 2);
|
|
284
|
+
return { text, value: typeof value === "number" && Number.isFinite(value) && value > 0 ? value : text === "N/M" ? text : null };
|
|
285
|
+
}
|
|
286
|
+
|
|
232
287
|
function fundamentalsMetrics(
|
|
233
288
|
quote: TickerFinancials["quote"],
|
|
234
289
|
fundamentals: TickerFinancials["fundamentals"],
|
|
235
|
-
|
|
290
|
+
profile: TickerFinancials["profile"],
|
|
291
|
+
marketCap: MetricFigure,
|
|
236
292
|
priceReturns: { return1Y?: number | null; return3Y?: number | null },
|
|
237
|
-
|
|
238
|
-
)
|
|
293
|
+
reportingCurrency: string | undefined,
|
|
294
|
+
enterpriseValue = reportedMoney(reportedEnterpriseValue(fundamentals), enterpriseValueCurrency(quote, fundamentals)),
|
|
295
|
+
): FundamentalsMetric[] {
|
|
296
|
+
const signed = (value: number) => colorBySign(formatPercent(value), value);
|
|
297
|
+
const receipt = fundamentals?.sharesOutstanding != null && sharesOutstandingInReceipts(quote, fundamentals, profile?.description);
|
|
239
298
|
return [
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
299
|
+
{ label: "Market Cap", ...marketCap },
|
|
300
|
+
{ label: "Enterprise Value", ...enterpriseValue },
|
|
301
|
+
// A multiple over a loss is N/M, even beside a positive one the source served from an older period.
|
|
302
|
+
{ label: "P/E (TTM)", ...multipleFigure(priceEarningsOnEarnings(fundamentals?.trailingPE, fundamentals?.eps)) },
|
|
303
|
+
{ label: "Forward P/E", ...multipleFigure(priceEarningsOnEarnings(fundamentals?.forwardPE, fundamentals?.forwardEps)) },
|
|
304
|
+
{ label: "PEG", ...multipleFigure(fundamentals?.pegRatio) },
|
|
305
|
+
// The flows and EPS are one trailing-twelve-month block, the same twelve months for each line.
|
|
306
|
+
{ label: "EPS (TTM)", ...reportedMoney(fundamentals?.eps, reportingCurrency, true) },
|
|
307
|
+
{
|
|
308
|
+
label: `Dividend Yield${fundamentals?.dividendYieldBasis ? ` (${fundamentals.dividendYieldBasis})` : ""}`,
|
|
309
|
+
...percentFigure(fundamentals?.dividendYield, formatFractionPercentCell),
|
|
310
|
+
},
|
|
311
|
+
{ label: "Revenue (TTM)", ...reportedMoney(fundamentals?.revenue, reportingCurrency) },
|
|
312
|
+
{ label: "Net Income (TTM)", ...reportedMoney(fundamentals?.netIncome, reportingCurrency) },
|
|
313
|
+
{ label: "Operating Cash Flow (TTM)", ...reportedMoney(fundamentals?.operatingCashFlow, reportingCurrency) },
|
|
314
|
+
{ label: "Free Cash Flow (TTM)", ...reportedMoney(fundamentals?.freeCashFlow, reportingCurrency) },
|
|
251
315
|
// Levels, not changes, so they carry no sign.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
316
|
+
{ label: "Operating Margin", ...percentFigure(fundamentals?.operatingMargin, formatFractionPercentCell) },
|
|
317
|
+
{ label: "Profit Margin", ...percentFigure(fundamentals?.profitMargin, formatFractionPercentCell) },
|
|
318
|
+
{ label: "Revenue Growth", ...percentFigure(fundamentals?.revenueGrowth, signed) },
|
|
319
|
+
{ label: "Last Quarter Growth", ...percentFigure(fundamentals?.lastQuarterGrowth, signed) },
|
|
320
|
+
{ label: "1Y Return", ...percentFigure(priceReturns.return1Y, signed) },
|
|
321
|
+
{ label: "3Y Return", ...percentFigure(priceReturns.return3Y, signed) },
|
|
322
|
+
{
|
|
323
|
+
label: "Shares Outstanding",
|
|
324
|
+
text: sharesOutstandingText(fundamentals, receipt),
|
|
325
|
+
value: fundamentals?.sharesOutstanding,
|
|
326
|
+
...(receipt ? { unit: "ADR equivalent" } : {}),
|
|
327
|
+
},
|
|
259
328
|
];
|
|
260
329
|
}
|
|
261
330
|
|
|
262
|
-
|
|
331
|
+
function metricLines(metrics: readonly FundamentalsMetric[]): Array<[string, string]> {
|
|
332
|
+
return metrics.map((metric) => [metric.label, metric.text]);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const VALUATION_METRICS = new Set(["Market Cap", "Enterprise Value", "P/E (TTM)", "Forward P/E", "PEG", "EPS (TTM)"]);
|
|
336
|
+
|
|
337
|
+
type FundamentalsReportData = TickerFinancials & { symbol: string; exchange?: string };
|
|
338
|
+
|
|
339
|
+
/** The lines `fundamentals` or `valuation` reports, the ones with a value. */
|
|
340
|
+
function fundamentalsReportMetrics(financials: FundamentalsReportData, view: "fundamentals" | "valuation"): FundamentalsMetric[] {
|
|
341
|
+
const quote = financials.quote;
|
|
342
|
+
const fundamentals = financials.fundamentals;
|
|
343
|
+
const capitalization = selectMarketCapitalization(quote, fundamentals);
|
|
344
|
+
const marketCap: MetricFigure = capitalization
|
|
345
|
+
? { text: `${formatCompact(capitalization.value)} ${capitalization.currency}`, value: capitalization.value, unit: capitalization.currency }
|
|
346
|
+
: { text: "—" };
|
|
347
|
+
const metrics = fundamentalsMetrics(quote, fundamentals, financials.profile, marketCap, computeTickerPriceReturns(financials), fundamentalsCurrency(financials));
|
|
348
|
+
return (view === "valuation"
|
|
349
|
+
? metrics.filter(({ label }) => VALUATION_METRICS.has(label) || label.startsWith("Dividend Yield"))
|
|
350
|
+
: metrics).filter((metric) => metric.text !== "—");
|
|
351
|
+
}
|
|
263
352
|
|
|
264
353
|
/** Text for `gloomberb fundamentals` and `gloomberb valuation`: the ticker report's fundamentals without the rest. */
|
|
265
354
|
export function renderFundamentalsReport(
|
|
266
|
-
financials:
|
|
355
|
+
financials: FundamentalsReportData,
|
|
267
356
|
view: "fundamentals" | "valuation",
|
|
268
357
|
): string {
|
|
269
358
|
const quote = financials.quote;
|
|
270
|
-
const fundamentals = financials.fundamentals;
|
|
271
359
|
const profile = financials.profile;
|
|
272
|
-
const capitalization = selectMarketCapitalization(quote, fundamentals);
|
|
273
|
-
const marketCapText = capitalization
|
|
274
|
-
? `${formatCompact(capitalization.value)} ${capitalization.currency}`
|
|
275
|
-
: "—";
|
|
276
|
-
const metrics = fundamentalsMetrics(quote, fundamentals, marketCapText, computeTickerPriceReturns(financials));
|
|
277
360
|
const symbol = quote?.symbol ?? financials.symbol;
|
|
278
361
|
const name = quote?.name && quote.name !== symbol ? ` ${cliStyles.bold(quote.name)}` : "";
|
|
279
362
|
const lines = [`${cliStyles.accent(symbol)}${name}`];
|
|
280
363
|
const profileParts = [
|
|
364
|
+
financials.exchange ? exchangeLabel(financials.exchange) : undefined,
|
|
281
365
|
profile?.sector ? `Sector ${profile.sector}` : undefined,
|
|
282
366
|
profile?.industry ? `Industry ${profile.industry}` : undefined,
|
|
283
367
|
].filter((part): part is string => !!part);
|
|
284
368
|
if (profileParts.length > 0) lines.push(cliStyles.muted(profileParts.join(METADATA_SEPARATOR)));
|
|
285
369
|
|
|
286
|
-
const shown = view === "valuation"
|
|
287
|
-
? metrics.filter(([label]) => VALUATION_METRICS.has(label) || label.startsWith("Dividend Yield"))
|
|
288
|
-
: metrics;
|
|
289
370
|
const before = lines.length;
|
|
290
|
-
appendMetricSection(lines, view === "valuation" ? "Valuation" : "Fundamentals",
|
|
371
|
+
appendMetricSection(lines, view === "valuation" ? "Valuation" : "Fundamentals", metricLines(fundamentalsReportMetrics(financials, view)));
|
|
291
372
|
if (lines.length === before) lines.push("", cliStyles.muted(`No ${view} reported for ${financials.symbol}.`));
|
|
292
373
|
if (view === "fundamentals") appendTextSection(lines, "Description", profile?.description);
|
|
293
374
|
return lines.join("\n");
|
|
294
375
|
}
|
|
295
376
|
|
|
377
|
+
/**
|
|
378
|
+
* `fundamentals` and `valuation` for `--csv` and `--ndjson`: the metrics as
|
|
379
|
+
* `Metric,Value` with each unit in its label, and for `fundamentals` the
|
|
380
|
+
* company profile the text prints around them.
|
|
381
|
+
*/
|
|
382
|
+
export function fundamentalsReportTables(
|
|
383
|
+
financials: FundamentalsReportData,
|
|
384
|
+
view: "fundamentals" | "valuation",
|
|
385
|
+
freshness: ReportFreshness,
|
|
386
|
+
): CliReportTables {
|
|
387
|
+
const metrics = fundamentalsReportMetrics(financials, view);
|
|
388
|
+
const tables = [exportEntriesTable(
|
|
389
|
+
view === "valuation" ? "Valuation" : "Fundamentals",
|
|
390
|
+
metrics.map((metric) => ({ label: metric.label, value: metric.value, formatted: metric.text, unit: metric.unit })),
|
|
391
|
+
)];
|
|
392
|
+
if (view === "fundamentals") {
|
|
393
|
+
const quote = financials.quote;
|
|
394
|
+
const profile = financials.profile;
|
|
395
|
+
tables.push(exportEntriesTable("Profile", [
|
|
396
|
+
{ label: "Symbol", value: quote?.symbol ?? financials.symbol },
|
|
397
|
+
{ label: "Name", value: quote?.name },
|
|
398
|
+
{ label: "Exchange", value: financials.exchange ? exchangeLabel(financials.exchange) : undefined },
|
|
399
|
+
{ label: "Sector", value: profile?.sector },
|
|
400
|
+
{ label: "Industry", value: profile?.industry },
|
|
401
|
+
{ label: "Description", value: profile?.description?.trim() },
|
|
402
|
+
].filter((entry) => typeof entry.value === "string" && entry.value.trim().length > 0)));
|
|
403
|
+
}
|
|
404
|
+
return {
|
|
405
|
+
tables,
|
|
406
|
+
footer: reportFooterLines({
|
|
407
|
+
freshness,
|
|
408
|
+
notes: metrics.length === 0 ? [`No ${view} reported for ${financials.symbol}.`] : [],
|
|
409
|
+
}),
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/** "Euronext Paris (EPA)": the venue the report is for, named in full when the app knows it. */
|
|
414
|
+
function listingVenueLabel(
|
|
415
|
+
listingExchange: string | undefined,
|
|
416
|
+
quote: TickerFinancials["quote"],
|
|
417
|
+
financials: TickerFinancials,
|
|
418
|
+
tickerFile: TickerRecord | null,
|
|
419
|
+
): string {
|
|
420
|
+
const exchangeName = quote?.exchangeName ?? financials.quoteMetadata?.listingExchangeName ?? tickerFile?.metadata.exchange;
|
|
421
|
+
const venue = canonicalExchange(listingExchange || quote?.listingExchangeName || exchangeName);
|
|
422
|
+
return isKnownExchangeCode(venue) ? exchangeLabel(venue) : exchangeShortName(exchangeName, quote?.fullExchangeName);
|
|
423
|
+
}
|
|
424
|
+
|
|
296
425
|
export async function buildTickerReport({
|
|
297
426
|
symbol,
|
|
427
|
+
listingExchange,
|
|
298
428
|
tickerFile,
|
|
299
429
|
financials,
|
|
300
430
|
config,
|
|
@@ -304,6 +434,8 @@ export async function buildTickerReport({
|
|
|
304
434
|
recentSecFilings = [],
|
|
305
435
|
}: {
|
|
306
436
|
symbol: string;
|
|
437
|
+
/** The exchange the command named, as a canonical code. */
|
|
438
|
+
listingExchange?: string;
|
|
307
439
|
tickerFile: TickerRecord | null;
|
|
308
440
|
financials: TickerFinancials;
|
|
309
441
|
config: AppConfig;
|
|
@@ -326,7 +458,7 @@ export async function buildTickerReport({
|
|
|
326
458
|
if (!quote) lines.push(cliStyles.muted("Quote unavailable."));
|
|
327
459
|
|
|
328
460
|
const summaryParts = [
|
|
329
|
-
|
|
461
|
+
listingVenueLabel(listingExchange, quote, financials, tickerFile) || undefined,
|
|
330
462
|
(quote?.currency || financials.quoteMetadata?.currency || tickerFile?.metadata.currency)
|
|
331
463
|
? `Currency ${quote?.currency || financials.quoteMetadata?.currency || tickerFile?.metadata.currency}` : undefined,
|
|
332
464
|
quote?.marketState ? marketStateLabel(quote.marketState) : undefined,
|
|
@@ -370,19 +502,28 @@ export async function buildTickerReport({
|
|
|
370
502
|
: `${formatCompact(capitalization.value)} ${capitalization.currency}`
|
|
371
503
|
: "—";
|
|
372
504
|
// Shown in the same currency as the market cap, so the two can be compared.
|
|
373
|
-
const enterpriseValue = fundamentals
|
|
505
|
+
const enterpriseValue = reportedEnterpriseValue(fundamentals);
|
|
374
506
|
const evCurrency = enterpriseValueCurrency(quote, fundamentals);
|
|
375
507
|
// A minor unit such as GBp stays as reported: the converter would read it as the major currency.
|
|
376
|
-
const convertedEnterpriseValue = enterpriseValue != null &&
|
|
508
|
+
const convertedEnterpriseValue = enterpriseValue != null && evCurrency && /^[A-Z]{3}$/.test(evCurrency)
|
|
377
509
|
? await toBase(enterpriseValue, evCurrency) : Number.NaN;
|
|
378
510
|
const enterpriseValueText = Number.isFinite(convertedEnterpriseValue)
|
|
379
511
|
? `${formatCompact(convertedEnterpriseValue)} ${config.baseCurrency}`
|
|
380
512
|
: formatReportedMoney(enterpriseValue, evCurrency);
|
|
381
513
|
|
|
382
514
|
if (quote) {
|
|
515
|
+
// As the Overview reads it: the regular session, then the extended-hours print against its close.
|
|
516
|
+
const session = getRegularSessionDisplay(quote)!;
|
|
517
|
+
const extended = getExtendedSessionDisplay(quote);
|
|
518
|
+
const extendedRow = (kind: "PRE" | "POST") => extended?.session === kind
|
|
519
|
+
? colorBySign(
|
|
520
|
+
`${formatMarketPriceWithCurrency(extended.price, quote.currency, quoteOptions)} (${formatPercentRaw(extended.changePercent)})`,
|
|
521
|
+
extended.change,
|
|
522
|
+
)
|
|
523
|
+
: "—";
|
|
383
524
|
appendMetricSection(lines, "Quote", [
|
|
384
|
-
["Last", colorBySign(formatMarketPriceWithCurrency(
|
|
385
|
-
["Change", colorBySign(`${formatMarketChangeWithCurrency(
|
|
525
|
+
["Last", colorBySign(formatMarketPriceWithCurrency(session.price, quote.currency, quoteOptions), session.change)],
|
|
526
|
+
["Change", colorBySign(`${formatMarketChangeWithCurrency(session.change, quote.currency, quoteOptions, session.price)} (${formatPercentRaw(session.changePercent)})`, session.change)],
|
|
386
527
|
["Open", quote.open != null ? formatMarketPriceWithCurrency(quote.open, quote.currency, quoteOptions) : "—"],
|
|
387
528
|
["Day Range", quote.low != null || quote.high != null
|
|
388
529
|
? formatPriceRange(quote.low, quote.high, quote.currency, quoteOptions)
|
|
@@ -396,22 +537,12 @@ export async function buildTickerReport({
|
|
|
396
537
|
]);
|
|
397
538
|
|
|
398
539
|
appendMetricSection(lines, "Extended Hours", [
|
|
399
|
-
["Pre-Market",
|
|
400
|
-
|
|
401
|
-
`${formatMarketPriceWithCurrency(quote.preMarketPrice, quote.currency, quoteOptions)} (${formatPercentRaw(quote.preMarketChangePercent)})`,
|
|
402
|
-
quote.preMarketChange ?? 0,
|
|
403
|
-
)
|
|
404
|
-
: "—"],
|
|
405
|
-
["After Hours", quote.postMarketPrice != null
|
|
406
|
-
? colorBySign(
|
|
407
|
-
`${formatMarketPriceWithCurrency(quote.postMarketPrice, quote.currency, quoteOptions)} (${formatPercentRaw(quote.postMarketChangePercent)})`,
|
|
408
|
-
quote.postMarketChange ?? 0,
|
|
409
|
-
)
|
|
410
|
-
: "—"],
|
|
540
|
+
["Pre-Market", extendedRow("PRE")],
|
|
541
|
+
["After Hours", extendedRow("POST")],
|
|
411
542
|
]);
|
|
412
543
|
}
|
|
413
544
|
|
|
414
|
-
appendMetricSection(lines, "Fundamentals", fundamentalsMetrics(quote, fundamentals, marketCapText, priceReturns, enterpriseValueText));
|
|
545
|
+
appendMetricSection(lines, "Fundamentals", metricLines(fundamentalsMetrics(quote, fundamentals, profile, { text: marketCapText }, priceReturns, fundamentalsCurrency(financials), { text: enterpriseValueText })));
|
|
415
546
|
|
|
416
547
|
if (capitalization?.provenance.kind === "fundamentals") {
|
|
417
548
|
lines.push(cliStyles.muted(`Market cap: ${describeFundamentalMarketCap(capitalization.provenance)}.`));
|
|
@@ -469,6 +600,7 @@ export async function buildTickerReport({
|
|
|
469
600
|
|
|
470
601
|
function buildTickerStructuredData({
|
|
471
602
|
symbol,
|
|
603
|
+
listing,
|
|
472
604
|
tickerFile,
|
|
473
605
|
financials,
|
|
474
606
|
config,
|
|
@@ -477,6 +609,7 @@ function buildTickerStructuredData({
|
|
|
477
609
|
recentSecFilings,
|
|
478
610
|
}: {
|
|
479
611
|
symbol: string;
|
|
612
|
+
listing: CliListing;
|
|
480
613
|
tickerFile: TickerRecord | null;
|
|
481
614
|
financials: TickerFinancials;
|
|
482
615
|
config: AppConfig;
|
|
@@ -486,8 +619,10 @@ function buildTickerStructuredData({
|
|
|
486
619
|
}) {
|
|
487
620
|
const quote = financials.quote;
|
|
488
621
|
const priceReturns = computeTickerPriceReturns(financials, tickerFile?.metadata.assetCategory);
|
|
622
|
+
const identity = listingIdentity(listing, quote);
|
|
489
623
|
return {
|
|
490
624
|
symbol,
|
|
625
|
+
listing: { symbol: identity.symbol, exchange: identity.exchange || null, name: identity.name },
|
|
491
626
|
quote: quote ? {
|
|
492
627
|
symbol: quote.symbol,
|
|
493
628
|
instrumentType: quote.instrumentType,
|
|
@@ -518,10 +653,10 @@ function buildTickerStructuredData({
|
|
|
518
653
|
watchlists: formatWatchlistNames(config, tickerFile.metadata.watchlists),
|
|
519
654
|
positions: tickerFile.metadata.positions,
|
|
520
655
|
} : null,
|
|
521
|
-
fundamentals: financials.fundamentals || priceReturns.return1Y != null || priceReturns.return3Y != null ? {
|
|
656
|
+
fundamentals: financials.fundamentals || priceReturns.return1Y != null || priceReturns.return3Y != null ? exportedFundamentals({
|
|
522
657
|
...financials.fundamentals,
|
|
523
658
|
...priceReturns,
|
|
524
|
-
} : undefined,
|
|
659
|
+
}) : undefined,
|
|
525
660
|
profile: financials.profile,
|
|
526
661
|
financialCurrency: financials.financialCurrency ?? null,
|
|
527
662
|
latestAnnual: latestFinancialPeriod(financials.annualStatements, row => row.date) ?? null,
|
|
@@ -551,19 +686,26 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
551
686
|
const initMarketDataFn = dependencies.initMarketData ?? initMarketData;
|
|
552
687
|
const failCommand = dependencies.fail ?? fail;
|
|
553
688
|
await withMarketData(initMarketDataFn, async ({ config, store, dataProvider, dataDir }) => {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
689
|
+
let listing: CliListing;
|
|
690
|
+
try {
|
|
691
|
+
listing = await resolveCliListing(symbol, dependencies.exchange, { store, dataProvider });
|
|
692
|
+
} catch (error) {
|
|
693
|
+
if (error instanceof ListingArgError) failCommand(error.message, error.details);
|
|
694
|
+
throw error;
|
|
695
|
+
}
|
|
696
|
+
// A named listing goes by its key (SAN:EPA); a bare symbol by its saved listing, as before.
|
|
697
|
+
const normalized = listing.key;
|
|
698
|
+
const tickerFile = listing.saved;
|
|
699
|
+
const { symbol: requestSymbol, exchange } = listing.request;
|
|
557
700
|
const toBase = createBaseConverter(dataProvider, config.baseCurrency);
|
|
558
701
|
|
|
559
702
|
let financials: TickerFinancials | null = null;
|
|
560
703
|
try {
|
|
561
|
-
financials = await dataProvider.getTickerFinancials(
|
|
704
|
+
financials = await dataProvider.getTickerFinancials(requestSymbol, exchange);
|
|
562
705
|
} catch (error) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
);
|
|
706
|
+
// A known exchange the symbol is not listed on: say where it is.
|
|
707
|
+
await failIfNotTraded(listing, { store, dataProvider }, { fail: failCommand });
|
|
708
|
+
failCommand(`Failed to fetch data for ${normalized}.`, error instanceof Error ? error.message : String(error));
|
|
567
709
|
}
|
|
568
710
|
|
|
569
711
|
const hasResearchData = financials && (
|
|
@@ -579,25 +721,30 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
579
721
|
|| financials.quarterlyStatements.length > 0
|
|
580
722
|
);
|
|
581
723
|
if (!financials || (!hasResearchData && !tickerFile?.metadata.positions.some((position) => position.shares !== 0))) {
|
|
724
|
+
await failIfNotTraded(listing, { store, dataProvider }, { fail: failCommand });
|
|
582
725
|
failCommand(`No research data available for ${normalized}.`);
|
|
583
726
|
}
|
|
584
727
|
const resolvedFinancials = financials as TickerFinancials;
|
|
585
728
|
const quote = resolvedFinancials.quote;
|
|
586
729
|
|
|
587
730
|
const notesFiles = new NotesFiles(dataDir);
|
|
731
|
+
const listingName = listingIdentity(listing, quote).name;
|
|
588
732
|
const [notesResult, newsResult, secFilingsResult] = await Promise.allSettled([
|
|
589
|
-
notesFiles.load(normalized),
|
|
733
|
+
notesFiles.load(tickerFile?.metadata.ticker ?? normalized),
|
|
590
734
|
dataProvider.getNews({
|
|
591
735
|
feed: "ticker",
|
|
592
736
|
// Still set for news plugins that read the deprecated scope.
|
|
593
737
|
scope: "ticker",
|
|
594
|
-
ticker:
|
|
738
|
+
ticker: requestSymbol,
|
|
595
739
|
exchange: exchange || quote?.exchangeName || "",
|
|
596
740
|
tickerTier: "primary",
|
|
597
741
|
limit: NEWS_ITEM_LIMIT,
|
|
598
742
|
}),
|
|
743
|
+
// Outside the US the lookup checks the SEC registrant against the listing's company,
|
|
744
|
+
// and refuses another company's filings.
|
|
599
745
|
shouldFetchSecFilings(tickerFile, resolvedFinancials) && dataProvider.getSecFilings
|
|
600
|
-
? dataProvider.getSecFilings(
|
|
746
|
+
? dataProvider.getSecFilings(requestSymbol, SEC_FILING_LIMIT, exchange || quote?.exchangeName || "",
|
|
747
|
+
listingName ? { listingName } : undefined)
|
|
601
748
|
: Promise.resolve([]),
|
|
602
749
|
]);
|
|
603
750
|
|
|
@@ -605,11 +752,15 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
605
752
|
const recentNews = newsResult.status === "fulfilled" ? newsResult.value : [];
|
|
606
753
|
const recentSecFilings = secFilingsResult.status === "fulfilled" ? secFilingsResult.value : [];
|
|
607
754
|
|
|
755
|
+
// The quote is the feed in this report; without one, the fundamentals date it.
|
|
756
|
+
const freshness = quote ? quotesFreshness([quote]) : fundamentalsFreshness(resolvedFinancials);
|
|
608
757
|
if (dependencies.printResult) {
|
|
609
758
|
dependencies.printResult({
|
|
759
|
+
freshness,
|
|
610
760
|
warnings: quote ? undefined : ["Quote unavailable."],
|
|
611
761
|
data: buildTickerStructuredData({
|
|
612
762
|
symbol: normalized,
|
|
763
|
+
listing,
|
|
613
764
|
tickerFile,
|
|
614
765
|
financials: resolvedFinancials,
|
|
615
766
|
config,
|
|
@@ -623,6 +774,7 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
623
774
|
|
|
624
775
|
console.log(await buildTickerReport({
|
|
625
776
|
symbol: normalized,
|
|
777
|
+
listingExchange: listing.exchange,
|
|
626
778
|
tickerFile,
|
|
627
779
|
financials: resolvedFinancials,
|
|
628
780
|
config,
|
|
@@ -631,5 +783,6 @@ export async function ticker(symbol: string, dependencies: TickerCommandDependen
|
|
|
631
783
|
recentNews,
|
|
632
784
|
recentSecFilings,
|
|
633
785
|
}));
|
|
786
|
+
if (freshness) console.log(`\n${cliFreshnessFooter(freshness)}`);
|
|
634
787
|
});
|
|
635
788
|
}
|
|
@@ -10,11 +10,13 @@ import type { ManualChartResolution } from "../time-series/resolution";
|
|
|
10
10
|
import type { SnapshotMarketData } from "../market-data/snapshot-provider";
|
|
11
11
|
import type { InstrumentRef } from "../market-data/request-types";
|
|
12
12
|
import type { TickerRecord } from "../types/ticker";
|
|
13
|
+
import type { BrokerAccount } from "../types/trading";
|
|
13
14
|
import type { PaneRuntimeState } from "../core/state/app/state";
|
|
14
15
|
import type { RemoteUiNodeSnapshot } from "../remote/types";
|
|
15
16
|
import type { DatedObservation } from "../plugins/builtin/market-valuation/series";
|
|
16
17
|
import type { DesktopExternalPluginBundle } from "../renderers/electrobun/shared/protocol";
|
|
17
18
|
import type { HttpProxyRequestEnvelope, HttpProxyResponseEnvelope } from "../utils/http-proxy-response";
|
|
19
|
+
import type { PaneAccessGate } from "./pane-functions/access-gate";
|
|
18
20
|
import { readVisibleKeyValues } from "./visible-key-values";
|
|
19
21
|
import { SHOT_API_PROXY_PREFIX, SHOT_HTTP_BRIDGE_PATH, SHOT_MARKET_BRIDGE_PATH } from "./desktop-pane-shot-routes";
|
|
20
22
|
import { SESSION_COOKIE_NAMES } from "../api-client/session-cookie";
|
|
@@ -53,6 +55,8 @@ export interface DesktopPaneShotPayload {
|
|
|
53
55
|
/** Label drawn at the right edge of the pane title bar; null draws nothing. */
|
|
54
56
|
watermark?: string | null;
|
|
55
57
|
tickers: TickerRecord[];
|
|
58
|
+
/** Broker accounts as last synced, by profile, so a broker portfolio shows its equity and cash. */
|
|
59
|
+
brokerAccounts?: Record<string, BrokerAccount[]>;
|
|
56
60
|
financials: Array<[string, TickerFinancials]>;
|
|
57
61
|
instrumentFinancials?: SnapshotMarketData["instrumentFinancials"];
|
|
58
62
|
historyVariants?: SnapshotMarketData["historyVariants"];
|
|
@@ -93,6 +97,8 @@ interface DesktopPaneShotRenderedCell {
|
|
|
93
97
|
columnId?: string;
|
|
94
98
|
columnLabel: string;
|
|
95
99
|
text: string;
|
|
100
|
+
/** The ISO instant behind a cell whose text shortens a time ("Wed 11:27"), from the table cell's export value. */
|
|
101
|
+
instant?: string;
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
export interface DesktopPaneShotRenderedRow {
|
|
@@ -105,6 +111,8 @@ export interface DesktopPaneShotRenderedRow {
|
|
|
105
111
|
|
|
106
112
|
export interface DesktopPaneShotRenderResult {
|
|
107
113
|
visibleText: string;
|
|
114
|
+
/** Text of the pane footers, where a pane says whether its data is live, delayed or stale. */
|
|
115
|
+
footerText?: string;
|
|
108
116
|
visibleKeyValues?: Array<{ label: string; text: string }>;
|
|
109
117
|
rows: DesktopPaneShotRenderedRow[];
|
|
110
118
|
truncated: boolean;
|
|
@@ -114,6 +122,8 @@ export interface DesktopPaneShotRenderResult {
|
|
|
114
122
|
errorStateMarkers: string[];
|
|
115
123
|
emptyStateDetected: boolean;
|
|
116
124
|
emptyStateMarkers: string[];
|
|
125
|
+
/** A wall that needs an account, or a Pro lock on part of the pane. */
|
|
126
|
+
accessGate?: PaneAccessGate | null;
|
|
117
127
|
semanticUi: RemoteUiNodeSnapshot[];
|
|
118
128
|
}
|
|
119
129
|
|
|
@@ -472,14 +482,22 @@ const LOADING_STATE_PATTERNS = [
|
|
|
472
482
|
/\bRendering pane\.{3}/gi,
|
|
473
483
|
];
|
|
474
484
|
|
|
475
|
-
const
|
|
476
|
-
/\b[^.]{1,100} unavailable\./gi,
|
|
477
|
-
/\bFailed to fetch\b/gi,
|
|
478
|
-
/\bCould not load\b/gi,
|
|
485
|
+
const SIGN_IN_WALL_PATTERNS = [
|
|
479
486
|
/\bSign in to\b/gi,
|
|
480
487
|
/\bVerify your email\b/gi,
|
|
481
488
|
/\brequires signup and email verification\b/gi,
|
|
489
|
+
];
|
|
490
|
+
|
|
491
|
+
const PRO_WALL_PATTERNS = [
|
|
482
492
|
/\bpart of Gloom Cloud Pro\b/gi,
|
|
493
|
+
];
|
|
494
|
+
|
|
495
|
+
const ERROR_STATE_PATTERNS = [
|
|
496
|
+
/\b[^.]{1,100} unavailable\./gi,
|
|
497
|
+
/\bFailed to fetch\b/gi,
|
|
498
|
+
/\bCould not load\b/gi,
|
|
499
|
+
...SIGN_IN_WALL_PATTERNS,
|
|
500
|
+
...PRO_WALL_PATTERNS,
|
|
483
501
|
/\bCloud API request failed\b/gi,
|
|
484
502
|
];
|
|
485
503
|
|
|
@@ -569,12 +587,14 @@ async function readRenderedPaneState(session: CdpSession): Promise<DesktopPaneSh
|
|
|
569
587
|
) {
|
|
570
588
|
truncationReasons.add("one or more cells are visibly clipped");
|
|
571
589
|
}
|
|
590
|
+
const instant = cell.getAttribute("data-gloom-cell-instant");
|
|
572
591
|
return {
|
|
573
592
|
...(typeof semanticColumn.id === "string" ? { columnId: semanticColumn.id } : {}),
|
|
574
593
|
columnLabel: typeof semanticColumn.label === "string"
|
|
575
594
|
? semanticColumn.label
|
|
576
595
|
: headers[cellIndex] || (values.length === 1 ? "Row" : String(cellIndex + 1)),
|
|
577
596
|
text,
|
|
597
|
+
...(instant ? { instant } : {}),
|
|
578
598
|
};
|
|
579
599
|
}).filter((cell) => cell.text.length > 0);
|
|
580
600
|
if (cells.length === 0) return;
|
|
@@ -605,6 +625,10 @@ async function readRenderedPaneState(session: CdpSession): Promise<DesktopPaneSh
|
|
|
605
625
|
}
|
|
606
626
|
return {
|
|
607
627
|
visibleText: root.innerText || root.textContent || "",
|
|
628
|
+
footerText: [...root.querySelectorAll('[data-gloom-role="pane-footer"]')]
|
|
629
|
+
.map((footer) => normalize(footer.innerText || footer.textContent))
|
|
630
|
+
.filter(Boolean)
|
|
631
|
+
.join(" "),
|
|
608
632
|
visibleKeyValues: (${readVisibleKeyValues.toString()})(root),
|
|
609
633
|
error: window.__GLOOM_CLI_SHOT_ERROR__ || "",
|
|
610
634
|
loadingStateDetected: root.querySelector('[data-gloom-status="loading"]') !== null,
|
|
@@ -612,6 +636,9 @@ async function readRenderedPaneState(session: CdpSession): Promise<DesktopPaneSh
|
|
|
612
636
|
// An empty sub-section off screen, such as a ticker's news list below
|
|
613
637
|
// the fold, does not make the captured view empty.
|
|
614
638
|
emptyStateDetected: [...root.querySelectorAll('[data-gloom-status="empty"]')].some(isVisible),
|
|
639
|
+
// The shared sign-in wall and the Pro lock prompt every gated pane draws.
|
|
640
|
+
accessGate: [...root.querySelectorAll('[data-gloom-ui="sign-in-wall"]')].some(isVisible) ? "sign-in"
|
|
641
|
+
: [...root.querySelectorAll('[data-gloom-ui="pro-lock"]')].some(isVisible) ? "pro" : "",
|
|
615
642
|
rows,
|
|
616
643
|
truncated: truncationReasons.size > 0,
|
|
617
644
|
truncationReasons: [...truncationReasons],
|
|
@@ -623,11 +650,13 @@ async function readRenderedPaneState(session: CdpSession): Promise<DesktopPaneSh
|
|
|
623
650
|
result?: {
|
|
624
651
|
value?: {
|
|
625
652
|
visibleText?: string;
|
|
653
|
+
footerText?: string;
|
|
626
654
|
visibleKeyValues?: Array<{ label: string; text: string }>;
|
|
627
655
|
error?: string;
|
|
628
656
|
loadingStateDetected?: boolean;
|
|
629
657
|
errorStateDetected?: boolean;
|
|
630
658
|
emptyStateDetected?: boolean;
|
|
659
|
+
accessGate?: string;
|
|
631
660
|
rows?: DesktopPaneShotRenderedRow[];
|
|
632
661
|
truncated?: boolean;
|
|
633
662
|
truncationReasons?: string[];
|
|
@@ -641,6 +670,8 @@ async function readRenderedPaneState(session: CdpSession): Promise<DesktopPaneSh
|
|
|
641
670
|
const loadingStateMarkers = stateMarkers(visibleText, LOADING_STATE_PATTERNS);
|
|
642
671
|
const errorStateMarkers = stateMarkers(visibleText, ERROR_STATE_PATTERNS);
|
|
643
672
|
const emptyStateMarkers = stateMarkers(visibleText, EMPTY_STATE_PATTERNS);
|
|
673
|
+
const accessGate: PaneAccessGate | null = value?.accessGate === "sign-in" || stateMarkers(visibleText, SIGN_IN_WALL_PATTERNS).length > 0 ? "sign-in"
|
|
674
|
+
: value?.accessGate === "pro" || stateMarkers(visibleText, PRO_WALL_PATTERNS).length > 0 ? "pro" : null;
|
|
644
675
|
const rows = Array.isArray(value?.rows) ? value.rows : [];
|
|
645
676
|
const textShowsEllipsis = rows.some((row) => row.cells.some((cell) => /\u2026|\.\.\./.test(cell.text)));
|
|
646
677
|
const truncationReasons = Array.isArray(value?.truncationReasons)
|
|
@@ -651,6 +682,7 @@ async function readRenderedPaneState(session: CdpSession): Promise<DesktopPaneSh
|
|
|
651
682
|
}
|
|
652
683
|
return {
|
|
653
684
|
visibleText,
|
|
685
|
+
footerText: typeof value?.footerText === "string" ? value.footerText : "",
|
|
654
686
|
visibleKeyValues: Array.isArray(value?.visibleKeyValues) ? value.visibleKeyValues : [],
|
|
655
687
|
rows,
|
|
656
688
|
truncated: value?.truncated === true || textShowsEllipsis,
|
|
@@ -660,6 +692,7 @@ async function readRenderedPaneState(session: CdpSession): Promise<DesktopPaneSh
|
|
|
660
692
|
errorStateMarkers,
|
|
661
693
|
emptyStateDetected: value?.emptyStateDetected === true || emptyStateMarkers.length > 0,
|
|
662
694
|
emptyStateMarkers,
|
|
695
|
+
accessGate,
|
|
663
696
|
semanticUi: Array.isArray(value?.semanticUi) ? value.semanticUi : [],
|
|
664
697
|
};
|
|
665
698
|
}
|