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
|
@@ -4,10 +4,14 @@ import {
|
|
|
4
4
|
type AccountProfile,
|
|
5
5
|
type ChatUserSummary,
|
|
6
6
|
} from "../../../api-client";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
import { PROFILE_POPOVER_CLOSE_DELAY_MS } from "./message/profile-popover";
|
|
8
|
+
import type { ChatUserAnchor } from "./message/types";
|
|
9
|
+
|
|
10
|
+
interface ProfilePopoverOptions {
|
|
11
|
+
ownProfile?: boolean;
|
|
12
|
+
/** The name or @mention it opens from; the desktop places the card beside it. */
|
|
13
|
+
anchor?: ChatUserAnchor;
|
|
14
|
+
}
|
|
11
15
|
|
|
12
16
|
function accountProfileToChatUser(profile: AccountProfile): ChatUserSummary {
|
|
13
17
|
return {
|
|
@@ -39,6 +43,7 @@ function isAccountProfileConfigured(profile: AccountProfile): boolean {
|
|
|
39
43
|
|
|
40
44
|
export function useChatProfilePopover(trackOwnProfileUserId?: string) {
|
|
41
45
|
const [profilePopoverUser, setProfilePopoverUser] = useState<ChatUserSummary | null>(null);
|
|
46
|
+
const [profilePopoverAnchor, setProfilePopoverAnchor] = useState<ChatUserAnchor>(null);
|
|
42
47
|
const [ownProfileConfigured, setOwnProfileConfigured] = useState<boolean | null>(null);
|
|
43
48
|
const profilePopoverCloseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
44
49
|
const ownProfileRef = useRef<ChatUserSummary | null>(null);
|
|
@@ -60,6 +65,7 @@ export function useChatProfilePopover(trackOwnProfileUserId?: string) {
|
|
|
60
65
|
pinnedRef.current = false;
|
|
61
66
|
profilePopoverUserIdRef.current = null;
|
|
62
67
|
setProfilePopoverUser(null);
|
|
68
|
+
setProfilePopoverAnchor(null);
|
|
63
69
|
}, [cancelProfilePopoverClose]);
|
|
64
70
|
|
|
65
71
|
const scheduleProfilePopoverClose = useCallback(() => {
|
|
@@ -70,6 +76,7 @@ export function useChatProfilePopover(trackOwnProfileUserId?: string) {
|
|
|
70
76
|
if (pinnedRef.current) return;
|
|
71
77
|
profilePopoverUserIdRef.current = null;
|
|
72
78
|
setProfilePopoverUser(null);
|
|
79
|
+
setProfilePopoverAnchor(null);
|
|
73
80
|
}, PROFILE_POPOVER_CLOSE_DELAY_MS);
|
|
74
81
|
}, [cancelProfilePopoverClose]);
|
|
75
82
|
|
|
@@ -104,32 +111,29 @@ export function useChatProfilePopover(trackOwnProfileUserId?: string) {
|
|
|
104
111
|
|
|
105
112
|
const showProfilePopover = useCallback((
|
|
106
113
|
targetUser: ChatUserSummary,
|
|
107
|
-
options?:
|
|
114
|
+
options?: ProfilePopoverOptions & { pin?: boolean },
|
|
108
115
|
) => {
|
|
109
116
|
const ownProfile = options?.ownProfile === true;
|
|
110
117
|
const cachedUser = ownProfile && ownProfileRef.current?.id === targetUser.id
|
|
111
118
|
? ownProfileRef.current
|
|
112
119
|
: targetUser;
|
|
113
|
-
//
|
|
114
|
-
if (!ownProfile && !hasPublicChatProfileInfo(cachedUser)) {
|
|
115
|
-
closeProfilePopover();
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
120
|
+
// Every name has a card: a private or empty profile gets the name-only one.
|
|
118
121
|
cancelProfilePopoverClose();
|
|
119
122
|
pinnedRef.current = options?.pin === true;
|
|
120
123
|
profilePopoverUserIdRef.current = cachedUser.id;
|
|
121
124
|
setProfilePopoverUser(cachedUser);
|
|
125
|
+
setProfilePopoverAnchor(options?.anchor ?? null);
|
|
122
126
|
if (ownProfile) refreshOwnProfile(targetUser.id);
|
|
123
|
-
}, [cancelProfilePopoverClose,
|
|
127
|
+
}, [cancelProfilePopoverClose, refreshOwnProfile]);
|
|
124
128
|
|
|
125
129
|
/** Pointing at a name previews its card, but never over one a click pinned. */
|
|
126
|
-
const hoverProfilePopover = useCallback((targetUser: ChatUserSummary, options?:
|
|
130
|
+
const hoverProfilePopover = useCallback((targetUser: ChatUserSummary, options?: ProfilePopoverOptions) => {
|
|
127
131
|
if (pinnedRef.current) return;
|
|
128
132
|
showProfilePopover(targetUser, options);
|
|
129
133
|
}, [showProfilePopover]);
|
|
130
134
|
|
|
131
135
|
/** A click on a name pins its card until Esc, a click outside, or a second click. */
|
|
132
|
-
const toggleProfilePopover = useCallback((targetUser: ChatUserSummary, options?:
|
|
136
|
+
const toggleProfilePopover = useCallback((targetUser: ChatUserSummary, options?: ProfilePopoverOptions) => {
|
|
133
137
|
// The desktop card hears the same click first, as a click outside it.
|
|
134
138
|
if (dismissedPinnedUserIdRef.current === targetUser.id) {
|
|
135
139
|
dismissedPinnedUserIdRef.current = null;
|
|
@@ -177,6 +181,7 @@ export function useChatProfilePopover(trackOwnProfileUserId?: string) {
|
|
|
177
181
|
closeProfilePopover,
|
|
178
182
|
dismissProfilePopover,
|
|
179
183
|
ownProfileConfigured,
|
|
184
|
+
profilePopoverAnchor,
|
|
180
185
|
profilePopoverUser,
|
|
181
186
|
hoverProfilePopover,
|
|
182
187
|
scheduleProfilePopoverClose,
|
|
@@ -285,7 +285,8 @@ function defaultHeadlessExecutor(
|
|
|
285
285
|
return {
|
|
286
286
|
result: serializeHeadlessPaneResult(loaded.definition, result),
|
|
287
287
|
rowCount: headlessRowCount(loaded.definition, result),
|
|
288
|
-
|
|
288
|
+
// Ask Gloom reads a caveat as a partial result, so notes join the errors here.
|
|
289
|
+
...(result.errors?.length || result.notes?.length ? { errors: [...(result.errors ?? []), ...(result.notes ?? [])] } : {}),
|
|
289
290
|
};
|
|
290
291
|
};
|
|
291
292
|
}
|
|
@@ -23,6 +23,7 @@ export const teamModule: PluginModule = {
|
|
|
23
23
|
capabilities: [createCloudTeamCapability(), createCloudViewsCapability()],
|
|
24
24
|
panes: [{
|
|
25
25
|
id: TEAM_PANE_ID,
|
|
26
|
+
reportFreshness: { status: "not-a-feed", basis: "account data" },
|
|
26
27
|
name: "Team",
|
|
27
28
|
icon: "T",
|
|
28
29
|
component: TeamPane,
|
|
@@ -12,6 +12,7 @@ import { ThesisTickerTab } from "./ticker-tab";
|
|
|
12
12
|
export const thesisModule: PluginModule = {
|
|
13
13
|
panes: [{
|
|
14
14
|
id: THESIS_PANE_ID,
|
|
15
|
+
reportFreshness: { source: "Your theses", status: "not-a-feed", basis: "your theses" },
|
|
15
16
|
name: "Theses",
|
|
16
17
|
icon: "Θ",
|
|
17
18
|
component: ThesisBoardPane,
|
|
@@ -28,6 +28,7 @@ export function registerTwitterFeedFeature(ctx: GloomPluginContext): void {
|
|
|
28
28
|
|
|
29
29
|
ctx.registerPane({
|
|
30
30
|
id: TWITTER_FEED_PANE_ID,
|
|
31
|
+
reportFreshness: { source: "X posts", status: "not-a-feed", basis: "posts" },
|
|
31
32
|
name: "X Feed",
|
|
32
33
|
icon: "X",
|
|
33
34
|
component: TwitterFeedPane,
|
|
@@ -34,6 +34,7 @@ export const commentLettersPlugin: GloomPlugin = {
|
|
|
34
34
|
panes: [
|
|
35
35
|
{
|
|
36
36
|
id: COMMENT_LETTERS_PANE_ID,
|
|
37
|
+
reportFreshness: { source: "SEC EDGAR", status: "not-a-feed", basis: "comment letters" },
|
|
37
38
|
name: "Comment Letters",
|
|
38
39
|
icon: "L",
|
|
39
40
|
component: CommentLettersPane,
|
|
@@ -7,6 +7,9 @@ import { appsModel, hiringModel, type AttentionKind } from "./model";
|
|
|
7
7
|
export function attentionHeadless(kind: AttentionKind): HeadlessPaneDefinition<"bundle"> {
|
|
8
8
|
return {
|
|
9
9
|
shape: "bundle",
|
|
10
|
+
freshness: kind === "hiring"
|
|
11
|
+
? { source: "Company careers sites", status: "not-a-feed", basis: "observed job postings" }
|
|
12
|
+
: { source: "App Store and Google Play charts", status: "not-a-feed", basis: "observed chart ranks" },
|
|
10
13
|
argument: { kind: "ticker", optional: true, placeholder: "ticker", description: "Company ticker, including exchange for non-US listings. Omit for the global board." },
|
|
11
14
|
options: [
|
|
12
15
|
{ key: "limit", type: "string", defaultValue: "100", description: "Rows per REST page, up to 200 for hiring and 500 for apps." },
|
|
@@ -36,7 +39,8 @@ export function attentionHeadless(kind: AttentionKind): HeadlessPaneDefinition<"
|
|
|
36
39
|
const nextOffset = kind === "hiring" && "total" in data ? offset + data.companies.length < data.total ? offset + data.companies.length : null : (data as AppAttentionPayload).page?.nextOffset ?? null;
|
|
37
40
|
return {
|
|
38
41
|
complete: !model.preview && nextOffset === null,
|
|
39
|
-
errors: [...model.notices, ...(
|
|
42
|
+
errors: [...model.notices, ...(model.preview ? ["Additional rows and history require Gloom Pro."] : [])],
|
|
43
|
+
...(nextOffset !== null ? { notes: [`Additional observations available with --offset ${nextOffset}.`] } : {}),
|
|
40
44
|
sections: Object.entries(model.sections).map(([key, section]) => ({ title: key === "mix" ? kind === "hiring" ? "Role family" : "Countries" : key,
|
|
41
45
|
columns: section.columns.map((column) => ({ key: column.id, header: column.label, align: column.align })),
|
|
42
46
|
rows: section.rows.map((row) => ({ ...row.values, ...(row.url ? { sourceUrl: row.url } : {}), ...(row.details ? { evidence: row.details } : {}) })) })),
|
|
@@ -33,7 +33,7 @@ const LABEL_COLUMNS = new Set(["chart"]);
|
|
|
33
33
|
function Evidence({ row, width, height }: Size & { row: AttentionRow }) {
|
|
34
34
|
const colors = useThemeColors();
|
|
35
35
|
const desktop = !!useUiCapabilities().nativePaneChrome;
|
|
36
|
-
return <ScrollBox width={width} height={desktop ? undefined : height} flexGrow={1} flexBasis={0} contentOptions={{ paddingX: 1 }}>
|
|
36
|
+
return <ScrollBox scrollY width={width} height={desktop ? undefined : height} flexGrow={1} flexBasis={0} contentOptions={{ paddingX: 1 }}>
|
|
37
37
|
{(row.details ?? Object.entries(row.values).map(([label, value]) => ({ label, value: String(value ?? "--") }))).map((entry) => <KeyValueRow key={entry.label} label={entry.label} value={entry.value} labelWidth={22} />)}
|
|
38
38
|
{row.url ? <Box paddingY={1}><Text fg={colors.textMuted}>{row.url}</Text></Box> : null}
|
|
39
39
|
</ScrollBox>;
|
|
@@ -172,7 +172,7 @@ function AttentionView({ kind, symbol, width, height, focused }: Size & { kind:
|
|
|
172
172
|
const numeric = typeof value === "number";
|
|
173
173
|
const decimals = DECIMALS[column.id] ?? 0;
|
|
174
174
|
const text = numeric ? `${SIGNED_COLUMNS.has(column.id) && value > 0 ? "+" : ""}${value.toLocaleString("en-US", { minimumFractionDigits: decimals, maximumFractionDigits: decimals })}` : LABEL_COLUMNS.has(column.id) ? humanLabel(value) : column.id === "title" ? value.trim() : value;
|
|
175
|
-
if (column.id === "share" && numeric && tab === "mix") return { ...shareCell(text, maxShare ? value / maxShare : null, column.width, colors, state.selected
|
|
175
|
+
if (column.id === "share" && numeric && tab === "mix") return { ...shareCell(text, maxShare ? value / maxShare : null, column.width, colors, state.selected), value };
|
|
176
176
|
return { text, value, color: numeric && SIGNED_COLUMNS.has(column.id) ? signedColor(value, colors)
|
|
177
177
|
: column.id === "name" || column.id === "title" ? colors.textBright : column.id === "date" || column.id === "observed" || column.id === "confidence" ? colors.textDim : colors.text };
|
|
178
178
|
}} selectedTextOverridesCellColor showHorizontalScrollbar resetScrollKey={`${kind}:${symbol}:${tab}:${mix}:${country}:${chart}`}
|
|
@@ -4,6 +4,7 @@ import { companyQuery, fetchCompanyData, type CompanyMode } from "./client";
|
|
|
4
4
|
export function companyHeadless(mode: CompanyMode): HeadlessPaneDefinition<"bundle"> {
|
|
5
5
|
return {
|
|
6
6
|
shape: "bundle",
|
|
7
|
+
freshness: { source: "Company filings and calls", status: "not-a-feed", basis: "reported data" },
|
|
7
8
|
argument: { kind: "ticker", description: "Listed company ticker, including exchange-qualified global symbols.", placeholder: "ticker" },
|
|
8
9
|
discovery: { aliases: [mode === "kpis" ? "KPIS" : "GUIDE"], dataRequirements: ["Gloom Cloud company disclosures"],
|
|
9
10
|
limitations: ["Pro dataset with a fixed latest preview on Free", "Coverage follows available company disclosures; missing data is not zero", "Compare matching definition, period, currency, basis and scope", "Fiscal labels without explicit calendar dates are retained without inferred dates"] },
|
|
@@ -104,6 +104,7 @@ export function createCongressHeadless(
|
|
|
104
104
|
): HeadlessPaneDefinition<"rows"> {
|
|
105
105
|
return {
|
|
106
106
|
shape: "rows",
|
|
107
|
+
freshness: { source: "House and Senate disclosures", status: "not-a-feed", basis: "filed reports" },
|
|
107
108
|
argument: {
|
|
108
109
|
kind: "ticker",
|
|
109
110
|
optional: true,
|
|
@@ -8,9 +8,19 @@ export interface CorrelationResult {
|
|
|
8
8
|
|
|
9
9
|
export interface DailyClose {
|
|
10
10
|
dateKey: string;
|
|
11
|
+
/** A closing price, or a map series' value for the day (a transit count). */
|
|
11
12
|
close: number;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* How a series moves between two shared dates. Prices use returns. A map
|
|
17
|
+
* series is a daily count that can be zero (Hormuz logs days with no
|
|
18
|
+
* transits), where a return or log change is undefined, so it uses the
|
|
19
|
+
* change in level. Pearson correlation ignores the unit, so the level change
|
|
20
|
+
* needs no scaling.
|
|
21
|
+
*/
|
|
22
|
+
export type ChangeBasis = "return" | "difference";
|
|
23
|
+
|
|
14
24
|
/** Keep the final valid close for each UTC trading date, in chronological order. */
|
|
15
25
|
export function dailyCloses(points: readonly PricePoint[]): DailyClose[] {
|
|
16
26
|
const byDate = new Map<string, number>();
|
|
@@ -41,11 +51,55 @@ export function alignDailyCloses(left: readonly DailyClose[], right: readonly Da
|
|
|
41
51
|
});
|
|
42
52
|
}
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
54
|
+
/** A map series' daily values, oldest first; zero is a value, unlike a zero close. */
|
|
55
|
+
export function dailyValues(points: readonly { date: Date; value: number | null }[]): DailyClose[] {
|
|
56
|
+
const byDate = new Map<string, number>();
|
|
57
|
+
for (const point of [...points].sort((left, right) => left.date.getTime() - right.date.getTime())) {
|
|
58
|
+
if (point.value === null || !Number.isFinite(point.value) || !Number.isFinite(point.date.getTime())) continue;
|
|
59
|
+
byDate.set(point.date.toISOString().slice(0, 10), point.value);
|
|
60
|
+
}
|
|
61
|
+
return [...byDate].map(([dateKey, close]) => ({ dateKey, close }));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface PairedChange {
|
|
65
|
+
dateKey: string;
|
|
66
|
+
left: number;
|
|
67
|
+
right: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function change(previous: number, current: number, basis: ChangeBasis): number {
|
|
71
|
+
return basis === "difference" ? current - previous : previous > 0 ? (current - previous) / previous : Number.NaN;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Each side's move between consecutive shared dates, dropped for both sides when either is undefined. */
|
|
75
|
+
export function pairedChanges(
|
|
76
|
+
aligned: readonly AlignedDailyClose[],
|
|
77
|
+
leftBasis: ChangeBasis = "return",
|
|
78
|
+
rightBasis: ChangeBasis = "return",
|
|
79
|
+
): PairedChange[] {
|
|
80
|
+
const changes: PairedChange[] = [];
|
|
81
|
+
for (let index = 1; index < aligned.length; index++) {
|
|
82
|
+
const previous = aligned[index - 1]!;
|
|
83
|
+
const current = aligned[index]!;
|
|
84
|
+
const left = change(previous.leftClose, current.leftClose, leftBasis);
|
|
85
|
+
const right = change(previous.rightClose, current.rightClose, rightBasis);
|
|
86
|
+
if (Number.isFinite(left) && Number.isFinite(right)) changes.push({ dateKey: current.dateKey, left, right });
|
|
87
|
+
}
|
|
88
|
+
return changes;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function correlateDailyCloses(
|
|
92
|
+
left: readonly DailyClose[],
|
|
93
|
+
right: readonly DailyClose[],
|
|
94
|
+
minObservations = 5,
|
|
95
|
+
leftBasis: ChangeBasis = "return",
|
|
96
|
+
rightBasis: ChangeBasis = "return",
|
|
97
|
+
): CorrelationResult {
|
|
98
|
+
const changes = pairedChanges(alignDailyCloses(left, right), leftBasis, rightBasis);
|
|
99
|
+
return {
|
|
100
|
+
correlation: pearsonCorrelation(changes.map((point) => point.left), changes.map((point) => point.right), minObservations),
|
|
101
|
+
sampleSize: changes.length,
|
|
102
|
+
};
|
|
49
103
|
}
|
|
50
104
|
|
|
51
105
|
function toDateKey(point: PricePoint): string | null {
|
|
@@ -58,17 +112,6 @@ function comparePricePointsByDate(left: PricePoint, right: PricePoint): number {
|
|
|
58
112
|
return getPricePointTimestamp(left) - getPricePointTimestamp(right);
|
|
59
113
|
}
|
|
60
114
|
|
|
61
|
-
export function computeReturns(closes: number[]): number[] {
|
|
62
|
-
const returns: number[] = [];
|
|
63
|
-
for (let i = 1; i < closes.length; i++) {
|
|
64
|
-
const previous = closes[i - 1]!;
|
|
65
|
-
const current = closes[i]!;
|
|
66
|
-
if (!Number.isFinite(previous) || !Number.isFinite(current) || previous === 0) continue;
|
|
67
|
-
returns.push((current - previous) / previous);
|
|
68
|
-
}
|
|
69
|
-
return returns;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
115
|
export function pearsonCorrelation(x: number[], y: number[], minObservations = 5): number | null {
|
|
73
116
|
const n = Math.min(x.length, y.length);
|
|
74
117
|
if (n < minObservations) return null;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map series (`GEO:HORMUZ`) in CORR, read through the same parser and
|
|
3
|
+
* resolver G uses, so an alias G charts is one CORR correlates.
|
|
4
|
+
*/
|
|
5
|
+
import { loadGeoCatalog, type GeoRequest } from "../../../api-client/geo";
|
|
6
|
+
import type { TimeRange } from "../../../time-series/range";
|
|
7
|
+
import { GEO_SERIES_CAPABILITY_ID, parseSeriesExpression } from "../chart-composer/series-expression";
|
|
8
|
+
import { resolveGeoChartSeries } from "../world-venue-map/geo-series";
|
|
9
|
+
import { dailyValues, type DailyClose } from "./compute";
|
|
10
|
+
import { CORRELATION_HISTORY_RESOLUTION } from "./history";
|
|
11
|
+
|
|
12
|
+
/** The map series a CORR entry names, or null for a ticker. */
|
|
13
|
+
export function geoSeriesToken(entry: string): string | null {
|
|
14
|
+
if (!/^GEO:/i.test(entry.trim())) return null;
|
|
15
|
+
const parsed = parseSeriesExpression(entry);
|
|
16
|
+
return parsed?.kind === "capability" && parsed.capabilityId === GEO_SERIES_CAPABILITY_ID ? parsed.seriesId : null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** A map series' daily values over the range. A server without map series says so instead of "not found". */
|
|
20
|
+
export async function loadGeoCorrelationHistory(
|
|
21
|
+
request: GeoRequest,
|
|
22
|
+
seriesId: string,
|
|
23
|
+
range: TimeRange,
|
|
24
|
+
signal?: AbortSignal,
|
|
25
|
+
): Promise<DailyClose[]> {
|
|
26
|
+
try {
|
|
27
|
+
const series = await resolveGeoChartSeries(request, seriesId, { range, resolution: CORRELATION_HISTORY_RESOLUTION }, signal);
|
|
28
|
+
return dailyValues(series.points);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
signal?.throwIfAborted();
|
|
31
|
+
if (!await loadGeoCatalog(request, { signal })) throw new Error("Map series unavailable.");
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -25,7 +25,10 @@ export const paneSchemas = {
|
|
|
25
25
|
discovery: {
|
|
26
26
|
id: "return-correlation",
|
|
27
27
|
aliases: ["correlation", "return correlation", "correlation matrix", "pearson correlation"],
|
|
28
|
-
limitations: [
|
|
28
|
+
limitations: [
|
|
29
|
+
"Correlation is computed from daily returns with at least five shared observations.",
|
|
30
|
+
"GEO:<series> entries correlate a map series' daily change with the others on shared dates.",
|
|
31
|
+
],
|
|
29
32
|
screenshotReadiness: "partial",
|
|
30
33
|
},
|
|
31
34
|
},
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { HeadlessPaneDefinition } from "../../../types/headless";
|
|
2
2
|
import type { TimeRange } from "../../../time-series/range";
|
|
3
|
-
import { formatNumber } from "../../../utils/format";
|
|
3
|
+
import { formatNumber, formatSignificant } from "../../../utils/format";
|
|
4
|
+
import { mixedSessionCloseNote } from "../../../market-data/market/session-close-note";
|
|
4
5
|
import { resolveHeadlessInstrument, loadHeadlessSymbols } from "../shared/headless-market-data";
|
|
5
|
-
import { buildCorrelationMatrix, buildCorrelationSeries, pairKey } from "./matrix/model";
|
|
6
|
+
import { buildCorrelationMatrix, buildCorrelationSeries, buildGeoCorrelationSeries, pairKey, type CorrelationSeries } from "./matrix/model";
|
|
7
|
+
import { geoSeriesToken, loadGeoCorrelationHistory } from "./geo";
|
|
6
8
|
import { buildRelationshipAnalysis, DEFAULT_RELATIONSHIP_SECOND_SYMBOL } from "./relationship/model";
|
|
7
9
|
import { paneSchemas } from "./headless-schema";
|
|
8
|
-
import { CORRELATION_RETURN_BASIS, loadCorrelationHistory } from "./history";
|
|
10
|
+
import { CORRELATION_RETURN_BASIS, GEO_CORRELATION_CHANGE_BASIS, loadCorrelationHistory } from "./history";
|
|
9
11
|
import type { HeadlessPaneContext } from "../../../types/headless";
|
|
12
|
+
import { newestReportTime } from "../../../utils/utc-time";
|
|
13
|
+
import { DAILY_CLOSES } from "../shared/report-freshness";
|
|
10
14
|
|
|
11
15
|
async function loadHistory(ctx: HeadlessPaneContext, key: string, range: TimeRange) {
|
|
12
16
|
const { symbol, exchange } = await resolveHeadlessInstrument(ctx, key);
|
|
@@ -14,9 +18,32 @@ async function loadHistory(ctx: HeadlessPaneContext, key: string, range: TimeRan
|
|
|
14
18
|
ctx.refresh ? { cacheMode: "refresh" } : undefined);
|
|
15
19
|
}
|
|
16
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Daily closes with the exchange the symbol trades on, which the session note
|
|
23
|
+
* needs. A symbol that is not in the local data names no exchange, so its
|
|
24
|
+
* quote says where it lists; a missing quote only leaves the note out.
|
|
25
|
+
*/
|
|
26
|
+
async function loadListedHistory(ctx: HeadlessPaneContext, key: string, range: TimeRange) {
|
|
27
|
+
const { symbol, exchange } = await resolveHeadlessInstrument(ctx, key);
|
|
28
|
+
const [points, quote] = await Promise.all([
|
|
29
|
+
loadHistory(ctx, key, range),
|
|
30
|
+
exchange ? null : (async () => ctx.marketData.getQuote(symbol, "", ctx.refresh ? { cacheMode: "refresh" } : undefined))().catch(() => null),
|
|
31
|
+
]);
|
|
32
|
+
return { exchange: exchange || quote?.listingExchangeName || quote?.exchangeName || "", points };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A ticker's daily closes, or a map series' daily values read straight from the Cloud client. */
|
|
36
|
+
async function loadCorrelationInput(ctx: HeadlessPaneContext, key: string, range: TimeRange): Promise<CorrelationSeries> {
|
|
37
|
+
const geo = geoSeriesToken(key);
|
|
38
|
+
if (!geo) return buildCorrelationSeries(key, await loadHistory(ctx, key, range));
|
|
39
|
+
const request = <T,>(path: string, init?: RequestInit) => ctx.apiClient.geo<T>(path, { ...init, signal: init?.signal ?? ctx.signal });
|
|
40
|
+
return buildGeoCorrelationSeries(key, await loadGeoCorrelationHistory(request, geo, range, ctx.signal));
|
|
41
|
+
}
|
|
42
|
+
|
|
17
43
|
export const correlationHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
18
44
|
...paneSchemas["correlation-pane"],
|
|
19
45
|
shape: "rows",
|
|
46
|
+
freshness: DAILY_CLOSES,
|
|
20
47
|
describe: ({ symbols, options }) => `Correlation Matrix | Daily returns | ${options.rangePreset ?? "1Y"} | ${symbols.join(", ")}`,
|
|
21
48
|
columns: [
|
|
22
49
|
{ key: "pair", header: "Pair", format: (_value, row) => `${row.left}/${row.right}` },
|
|
@@ -25,8 +52,8 @@ export const correlationHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
|
25
52
|
],
|
|
26
53
|
async load({ symbols, options }, ctx) {
|
|
27
54
|
const range = (options.rangePreset ?? "1Y") as TimeRange;
|
|
28
|
-
const loaded = await loadHeadlessSymbols(symbols, ctx, (symbol) =>
|
|
29
|
-
const bySymbol = new Map(loaded.entries.map(({ symbol, data }) => [symbol,
|
|
55
|
+
const loaded = await loadHeadlessSymbols(symbols, ctx, (symbol) => loadCorrelationInput(ctx, symbol, range));
|
|
56
|
+
const bySymbol = new Map(loaded.entries.map(({ symbol, data }) => [symbol, data]));
|
|
30
57
|
const matrix = buildCorrelationMatrix(symbols, bySymbol);
|
|
31
58
|
const rows = symbols.flatMap((left, index) => symbols.slice(index + 1).map((right) => {
|
|
32
59
|
const result = matrix.results.get(pairKey(left, right));
|
|
@@ -41,6 +68,7 @@ export const correlationHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
|
41
68
|
: row.sampleSize < 5 ? "Insufficient shared return observations" : "Zero return variance",
|
|
42
69
|
}));
|
|
43
70
|
return {
|
|
71
|
+
freshness: { asOf: newestReportTime(symbols.map((symbol) => bySymbol.get(symbol)?.prices.at(-1)?.dateKey)) },
|
|
44
72
|
rows, unavailableSymbols,
|
|
45
73
|
errors: [
|
|
46
74
|
...loaded.errors,
|
|
@@ -50,6 +78,7 @@ export const correlationHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
|
50
78
|
range,
|
|
51
79
|
unavailablePairs,
|
|
52
80
|
returnAlignment: CORRELATION_RETURN_BASIS,
|
|
81
|
+
...(symbols.some((symbol) => geoSeriesToken(symbol)) ? { mapSeriesChange: GEO_CORRELATION_CHANGE_BASIS } : {}),
|
|
53
82
|
availability: symbols.map((symbol) => ({
|
|
54
83
|
symbol, status: bySymbol.get(symbol)?.status ?? "error", observationCount: bySymbol.get(symbol)?.observationCount ?? 0,
|
|
55
84
|
...(bySymbol.get(symbol)?.integrity ? { integrity: bySymbol.get(symbol)!.integrity } : {}),
|
|
@@ -64,14 +93,18 @@ export const correlationHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
|
64
93
|
export const relationshipHeadless: HeadlessPaneDefinition<"series"> = {
|
|
65
94
|
...paneSchemas["relationship-graph-pane"],
|
|
66
95
|
shape: "series",
|
|
96
|
+
freshness: DAILY_CLOSES,
|
|
67
97
|
describe: ({ symbols, options }) => `Relationship Graph | ${symbols[0]}/${symbols[1] ?? DEFAULT_RELATIONSHIP_SECOND_SYMBOL} | ${options.range ?? "1Y"}`,
|
|
68
98
|
async load(args, ctx) {
|
|
69
99
|
const symbols = [args.symbols[0]!, args.symbols[1] ?? DEFAULT_RELATIONSHIP_SECOND_SYMBOL];
|
|
70
100
|
const range = (args.options.range ?? "1Y") as TimeRange;
|
|
71
101
|
const correlationWindow = Number(args.options.correlationWindow ?? 120);
|
|
72
|
-
const loaded = await loadHeadlessSymbols(symbols, ctx, (symbol) =>
|
|
73
|
-
const
|
|
102
|
+
const loaded = await loadHeadlessSymbols(symbols, ctx, (symbol) => loadListedHistory(ctx, symbol, range));
|
|
103
|
+
const listings = new Map(loaded.entries.map(({ symbol, data }) => [symbol, data]));
|
|
104
|
+
const histories = new Map(loaded.entries.map(({ symbol, data }) => [symbol, data.points]));
|
|
74
105
|
const analysis = buildRelationshipAnalysis(histories.get(symbols[0]!) ?? [], histories.get(symbols[1]!) ?? [], correlationWindow);
|
|
106
|
+
const [left, right] = symbols.map((symbol) => ({ symbol, ...listings.get(symbol) }));
|
|
107
|
+
const sessionNote = listings.size === 2 ? mixedSessionCloseNote(left!, right!, analysis.aligned.at(-1)?.dateKey) : null;
|
|
75
108
|
const unavailableSymbols = symbols.filter((symbol) => (histories.get(symbol) ?? []).filter((point) => (
|
|
76
109
|
Number.isFinite(point.close) && point.close > 0 && Number.isFinite(new Date(point.date).getTime())
|
|
77
110
|
)).length < 2);
|
|
@@ -86,7 +119,7 @@ export const relationshipHeadless: HeadlessPaneDefinition<"series"> = {
|
|
|
86
119
|
{ id: "correlation", label: `Rolling correlation (${correlationWindow})`, points: analysis.returns.slice(correlationWindow - 1).map(({ date }) => ({ date: date.toISOString(), value: correlations.get(date.getTime()) ?? null })) },
|
|
87
120
|
],
|
|
88
121
|
stats: [
|
|
89
|
-
{ key: "latestRatio", label: "Latest ratio", value: analysis.latestRatio, formatted:
|
|
122
|
+
{ key: "latestRatio", label: "Latest ratio", value: analysis.latestRatio, formatted: formatSignificant(analysis.latestRatio ?? undefined) },
|
|
90
123
|
{ key: "latestCorrelation", label: `Rolling correlation (${correlationWindow})`, value: analysis.latestCorrelation, formatted: formatNumber(analysis.latestCorrelation ?? undefined, 3) },
|
|
91
124
|
...(["beta", "alpha", "rSquared"] as const).map((key) => ({
|
|
92
125
|
key, label: { beta: "Beta", alpha: "Alpha", rSquared: "R squared" }[key],
|
|
@@ -102,6 +135,7 @@ export const relationshipHeadless: HeadlessPaneDefinition<"series"> = {
|
|
|
102
135
|
metadata: {
|
|
103
136
|
left: symbols[0], right: symbols[1], range, correlationWindow,
|
|
104
137
|
returnAlignment: CORRELATION_RETURN_BASIS,
|
|
138
|
+
...(sessionNote ? { notices: [sessionNote] } : {}),
|
|
105
139
|
firstDate: analysis.aligned.at(0)?.dateKey ?? null,
|
|
106
140
|
lastDate: analysis.aligned.at(-1)?.dateKey ?? null,
|
|
107
141
|
...(analysis.integrity ? { integrity: analysis.integrity } : {}),
|
|
@@ -17,3 +17,5 @@ export async function loadCorrelationHistory(
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const CORRELATION_RETURN_BASIS = "Local-price close-to-close returns between shared UTC dates; cash distributions and FX conversion are excluded, and exchange closing times may differ.";
|
|
20
|
+
|
|
21
|
+
export const GEO_CORRELATION_CHANGE_BASIS = "Map series (GEO:) use the change in daily value between the same shared UTC dates, because counts such as transits can be zero.";
|