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
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HeadlessBundleResult,
|
|
3
|
+
HeadlessFreshnessStatus,
|
|
4
|
+
HeadlessPaneDefinition,
|
|
5
|
+
HeadlessPaneFreshness,
|
|
6
|
+
HeadlessPaneResult,
|
|
7
|
+
HeadlessPaneRow,
|
|
8
|
+
HeadlessSeriesResult,
|
|
9
|
+
HeadlessSnapshotResult,
|
|
10
|
+
} from "../../types/plugin";
|
|
11
|
+
import { formatUtcTime, parseReportTime, type ReportTime } from "../../utils/utc-time";
|
|
12
|
+
import { isRecord } from "../../utils/guards";
|
|
13
|
+
import { latestRegularSessionClose } from "../../market-data/market/freshness";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The four states of docs/usage.md#how-current-a-report-is, plus `unreported`
|
|
17
|
+
* for a report that cannot tell: a rendered view whose footer names no state,
|
|
18
|
+
* or a plugin that declares nothing and carries no feed signal.
|
|
19
|
+
*/
|
|
20
|
+
type ReportFreshnessStatus = HeadlessFreshnessStatus | "unreported";
|
|
21
|
+
|
|
22
|
+
/** What every `fn` report cites about its data, in its JSON and its last text line. */
|
|
23
|
+
export interface ReportFreshness {
|
|
24
|
+
source: string;
|
|
25
|
+
/** Newest observation: an ISO instant in UTC, or an ISO date. Null when nothing in the data is dated. */
|
|
26
|
+
asOf: string | null;
|
|
27
|
+
/** Oldest observation, when it is more than a day older than `asOf`. */
|
|
28
|
+
oldest?: string;
|
|
29
|
+
status: ReportFreshnessStatus;
|
|
30
|
+
delayMinutes?: number;
|
|
31
|
+
/** How old the stale data is: the newest observation, or the oldest stale row when only some are. */
|
|
32
|
+
ageMinutes?: number;
|
|
33
|
+
/** When only some rows are stale: how many, of the rows that say whether they are... */
|
|
34
|
+
staleCount?: number;
|
|
35
|
+
observationCount?: number;
|
|
36
|
+
/** ...and what the rest are. */
|
|
37
|
+
feed?: "live" | "delayed";
|
|
38
|
+
basis?: string;
|
|
39
|
+
/** When this report was built. */
|
|
40
|
+
retrievedAt: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const DEFAULT_REPORT_SOURCE = "Gloom Cloud";
|
|
44
|
+
|
|
45
|
+
/** Top-level row and metadata keys that say when a value was observed. */
|
|
46
|
+
const OBSERVATION_KEYS = [
|
|
47
|
+
"asOf", "asOfDate", "observedAt", "quoteTime",
|
|
48
|
+
"quoteAsOf", "priceAsOf", "sourceAsOf", "lastTradeTime", "timestamp",
|
|
49
|
+
];
|
|
50
|
+
// Updates can be refresh stamps; use them only when there is no explicit observation.
|
|
51
|
+
const UPDATE_KEYS = ["lastUpdated", "updatedAt"];
|
|
52
|
+
// A stamp a little ahead of this clock is skew; further ahead it is a schedule, not an observation.
|
|
53
|
+
const FUTURE_TOLERANCE_MS = 10 * 60_000;
|
|
54
|
+
const OLDEST_GAP_MS = 24 * 60 * 60_000;
|
|
55
|
+
// A scheduled release can slip by hours; a day past it, the data has missed it.
|
|
56
|
+
const RELEASE_GRACE_MS = 24 * 60 * 60_000;
|
|
57
|
+
|
|
58
|
+
interface FeedSignals {
|
|
59
|
+
live: boolean;
|
|
60
|
+
delayed: boolean;
|
|
61
|
+
delayMinutes?: number;
|
|
62
|
+
/** A record-wide stale flag (metadata), read only when no row says whether it is stale. */
|
|
63
|
+
stale: boolean;
|
|
64
|
+
/** Rows and series that carry a `stale` flag, and the times of those that are stale. */
|
|
65
|
+
flagged: number;
|
|
66
|
+
staleTimes: Array<ReportTime | null>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface Observations {
|
|
70
|
+
/** One time per row, item or series: what `oldest` compares. */
|
|
71
|
+
units: ReportTime[];
|
|
72
|
+
/** Metadata and snapshot stamps: candidates for `asOf` only. */
|
|
73
|
+
extra: ReportTime[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function emptySignals(): FeedSignals {
|
|
77
|
+
return { live: false, delayed: false, stale: false, flagged: 0, staleTimes: [] };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function readFeedSignals(record: Record<string, unknown>, signals: FeedSignals): void {
|
|
81
|
+
if (record.dataSource === "live") signals.live = true;
|
|
82
|
+
if (record.dataSource === "delayed") signals.delayed = true;
|
|
83
|
+
const delay = record.delayMinutes;
|
|
84
|
+
if (typeof delay === "number" && Number.isFinite(delay) && delay > 0) {
|
|
85
|
+
signals.delayed = true;
|
|
86
|
+
signals.delayMinutes = Math.max(signals.delayMinutes ?? 0, delay);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** A row's or series' own stale flag; worst of across them, counted so a partly stale board says how much. */
|
|
91
|
+
function readUnitStale(record: Record<string, unknown>, time: ReportTime | null, signals: FeedSignals): void {
|
|
92
|
+
if (typeof record.stale !== "boolean") return;
|
|
93
|
+
signals.flagged += 1;
|
|
94
|
+
if (record.stale) signals.staleTimes.push(time);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function observedTime(record: Record<string, unknown>, now: number, keys: readonly string[] = OBSERVATION_KEYS): ReportTime | null {
|
|
98
|
+
let newest: ReportTime | null = null;
|
|
99
|
+
for (const key of keys) {
|
|
100
|
+
const time = parseReportTime(record[key]);
|
|
101
|
+
if (time && time.time <= now + FUTURE_TOLERANCE_MS && (!newest || time.time > newest.time)) newest = time;
|
|
102
|
+
}
|
|
103
|
+
return newest;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function resultRecords(definition: Pick<HeadlessPaneDefinition, "shape">, result: HeadlessPaneResult): HeadlessPaneRow[] {
|
|
107
|
+
switch (definition.shape) {
|
|
108
|
+
case "rows":
|
|
109
|
+
return (result as { rows: HeadlessPaneRow[] }).rows;
|
|
110
|
+
case "bundle":
|
|
111
|
+
return (result as HeadlessBundleResult).sections.flatMap((section) => (
|
|
112
|
+
"rows" in section && section.rows ? section.rows : []
|
|
113
|
+
));
|
|
114
|
+
case "snapshot":
|
|
115
|
+
return (result as HeadlessSnapshotResult).items;
|
|
116
|
+
case "series":
|
|
117
|
+
return [];
|
|
118
|
+
default: {
|
|
119
|
+
const _exhaustive: never = definition.shape;
|
|
120
|
+
return _exhaustive;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function seriesNewestTime(series: HeadlessSeriesResult["series"][number], now: number): ReportTime | null {
|
|
126
|
+
for (let index = series.points.length - 1; index >= 0; index -= 1) {
|
|
127
|
+
const point = series.points[index]!;
|
|
128
|
+
if (point.value == null && point.close == null) continue;
|
|
129
|
+
const time = parseReportTime(point.date);
|
|
130
|
+
if (time && time.time <= now + FUTURE_TOLERANCE_MS) return time;
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function collect(
|
|
136
|
+
definition: Pick<HeadlessPaneDefinition, "shape">,
|
|
137
|
+
result: HeadlessPaneResult,
|
|
138
|
+
now: number,
|
|
139
|
+
{ observedKey, ignoreStaleFlags }: Pick<HeadlessPaneFreshness, "observedKey" | "ignoreStaleFlags">,
|
|
140
|
+
): { signals: FeedSignals; observations: Observations } {
|
|
141
|
+
const signals = emptySignals();
|
|
142
|
+
const observations: Observations = { units: [], extra: [] };
|
|
143
|
+
const rowKeys = observedKey ? [observedKey] : OBSERVATION_KEYS;
|
|
144
|
+
for (const row of resultRecords(definition, result)) {
|
|
145
|
+
if (!isRecord(row)) continue;
|
|
146
|
+
readFeedSignals(row, signals);
|
|
147
|
+
const time = observedTime(row, now, rowKeys)
|
|
148
|
+
?? (observedKey ? null : observedTime(row, now, UPDATE_KEYS));
|
|
149
|
+
if (!ignoreStaleFlags) readUnitStale(row, time, signals);
|
|
150
|
+
if (time) observations.units.push(time);
|
|
151
|
+
}
|
|
152
|
+
if (definition.shape === "series") {
|
|
153
|
+
for (const series of (result as HeadlessSeriesResult).series) {
|
|
154
|
+
const record = series as unknown as Record<string, unknown>;
|
|
155
|
+
readFeedSignals(record, signals);
|
|
156
|
+
const time = seriesNewestTime(series, now);
|
|
157
|
+
if (!ignoreStaleFlags) readUnitStale(record, time, signals);
|
|
158
|
+
if (time) observations.units.push(time);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (isRecord(result.metadata)) {
|
|
162
|
+
readFeedSignals(result.metadata, signals);
|
|
163
|
+
if (result.metadata.stale === true && !ignoreStaleFlags) signals.stale = true;
|
|
164
|
+
// An explicit summary as-of can be a real observation (CRYP's newest quote).
|
|
165
|
+
// A summary update stamp must not supersede dated rows.
|
|
166
|
+
const time = observedKey ? null : observedTime(result.metadata, now)
|
|
167
|
+
?? (observations.units.length ? null : observedTime(result.metadata, now, UPDATE_KEYS));
|
|
168
|
+
if (time) observations.extra.push(time);
|
|
169
|
+
}
|
|
170
|
+
if (definition.shape === "snapshot" && !observedKey) {
|
|
171
|
+
const time = parseReportTime((result as HeadlessSnapshotResult).asOf);
|
|
172
|
+
if (time && time.time <= now + FUTURE_TOLERANCE_MS) observations.extra.push(time);
|
|
173
|
+
}
|
|
174
|
+
return { signals, observations };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function isoTime(time: ReportTime): string {
|
|
178
|
+
return time.dateOnly ? new Date(time.time).toISOString().slice(0, 10) : new Date(time.time).toISOString();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function newest(times: ReportTime[]): ReportTime | null {
|
|
182
|
+
return times.reduce<ReportTime | null>((best, time) => (!best || time.time > best.time ? time : best), null);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function oldest(times: ReportTime[]): ReportTime | null {
|
|
186
|
+
return times.reduce<ReportTime | null>((best, time) => (!best || time.time < best.time ? time : best), null);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** The declaration with the result's own fields winning over the definition's. */
|
|
190
|
+
function mergeDeclarations(...declarations: Array<HeadlessPaneFreshness | undefined>): HeadlessPaneFreshness {
|
|
191
|
+
const merged: HeadlessPaneFreshness = {};
|
|
192
|
+
for (const declaration of declarations) {
|
|
193
|
+
if (!declaration) continue;
|
|
194
|
+
for (const [key, value] of Object.entries(declaration)) {
|
|
195
|
+
if (value !== undefined) (merged as Record<string, unknown>)[key] = value;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return merged;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const FEED_RANK: Record<"live" | "delayed" | "stale", number> = { live: 0, delayed: 1, stale: 2 };
|
|
202
|
+
|
|
203
|
+
function worstFeedStatus(statuses: Array<"live" | "delayed" | "stale">): "live" | "delayed" | "stale" | null {
|
|
204
|
+
return statuses.reduce<"live" | "delayed" | "stale" | null>((worst, status) => (
|
|
205
|
+
!worst || FEED_RANK[status] > FEED_RANK[worst] ? status : worst
|
|
206
|
+
), null);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** Completed US sessions after the day of `newest`, counted back from `now`, up to `limit`. */
|
|
210
|
+
function sessionsAfter(newest: ReportTime, now: number, limit: number): number {
|
|
211
|
+
const newestDate = new Date(newest.time).toISOString().slice(0, 10);
|
|
212
|
+
let count = 0;
|
|
213
|
+
let cursor = now;
|
|
214
|
+
while (count < limit) {
|
|
215
|
+
const close = latestRegularSessionClose("NYSE", cursor);
|
|
216
|
+
if (!close || close.date <= newestDate) break;
|
|
217
|
+
count += 1;
|
|
218
|
+
cursor = close.close - 1;
|
|
219
|
+
}
|
|
220
|
+
return count;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** What the data's declared schedule says about its age, whatever kind of data it is. */
|
|
224
|
+
function overdue(declared: HeadlessPaneFreshness, asOf: ReportTime | null, now: number): boolean {
|
|
225
|
+
const nextExpected = declared.nextExpectedAt != null ? parseReportTime(declared.nextExpectedAt) : null;
|
|
226
|
+
if (nextExpected != null && now > nextExpected.time + RELEASE_GRACE_MS) return true;
|
|
227
|
+
if (!asOf) return false;
|
|
228
|
+
if (declared.maxAgeMinutes != null && now - asOf.time > declared.maxAgeMinutes * 60_000) return true;
|
|
229
|
+
return declared.cadence === "daily" && sessionsAfter(asOf, now, 2) > 1;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
interface FreshnessInputs {
|
|
233
|
+
declared: HeadlessPaneFreshness;
|
|
234
|
+
signals: FeedSignals;
|
|
235
|
+
observations: Observations;
|
|
236
|
+
now: number;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function resolveFreshness({ declared, signals, observations, now }: FreshnessInputs): ReportFreshness {
|
|
240
|
+
const declaredAsOf = observedTime({ asOf: declared.asOf }, now, ["asOf"]);
|
|
241
|
+
const asOf = declaredAsOf ?? newest([...observations.units, ...observations.extra]);
|
|
242
|
+
// A loader that dates its data itself also says how old the oldest part is, or nothing;
|
|
243
|
+
// `oldest: null` says the rows are a history, whose first entry is not stale data.
|
|
244
|
+
const oldestTime = declared.oldest != null ? parseReportTime(declared.oldest)
|
|
245
|
+
: declaredAsOf || declared.oldest === null ? null : oldest(observations.units);
|
|
246
|
+
const late = overdue(declared, asOf, now);
|
|
247
|
+
|
|
248
|
+
let status: ReportFreshnessStatus;
|
|
249
|
+
let delayMinutes: number | undefined;
|
|
250
|
+
let staleAt: ReportTime | null = null;
|
|
251
|
+
let partial: { staleCount: number; observationCount: number; feed?: "live" | "delayed" } | null = null;
|
|
252
|
+
if (declared.status === "not-a-feed") {
|
|
253
|
+
// Age alone does not make filed or published data stale. Honor explicit flags,
|
|
254
|
+
// with row-level flags outranking the metadata summary, or a missed schedule.
|
|
255
|
+
const staleRows = signals.staleTimes.length;
|
|
256
|
+
if (late || (signals.flagged > 0 ? staleRows === signals.flagged : signals.stale)) {
|
|
257
|
+
status = "stale";
|
|
258
|
+
staleAt = asOf;
|
|
259
|
+
} else if (staleRows > 0) {
|
|
260
|
+
status = "stale";
|
|
261
|
+
partial = { staleCount: staleRows, observationCount: signals.flagged };
|
|
262
|
+
staleAt = oldest(signals.staleTimes.filter((time): time is ReportTime => time != null));
|
|
263
|
+
} else {
|
|
264
|
+
status = "not-a-feed";
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
const feed = worstFeedStatus([
|
|
268
|
+
...(declared.status ? [declared.status] : []),
|
|
269
|
+
...(signals.live ? ["live" as const] : []),
|
|
270
|
+
...(signals.delayed ? ["delayed" as const] : []),
|
|
271
|
+
]);
|
|
272
|
+
const staleRows = signals.staleTimes.length;
|
|
273
|
+
// Rows that say whether they are stale outrank a summary flag beside them.
|
|
274
|
+
const allStale = feed === "stale" || late
|
|
275
|
+
|| (signals.flagged > 0 ? staleRows === signals.flagged : signals.stale);
|
|
276
|
+
if (allStale) {
|
|
277
|
+
status = "stale";
|
|
278
|
+
staleAt = asOf;
|
|
279
|
+
} else if (staleRows > 0) {
|
|
280
|
+
status = "stale";
|
|
281
|
+
partial = {
|
|
282
|
+
staleCount: staleRows,
|
|
283
|
+
observationCount: signals.flagged,
|
|
284
|
+
...(feed === "live" || feed === "delayed" ? { feed } : {}),
|
|
285
|
+
};
|
|
286
|
+
staleAt = oldest(signals.staleTimes.filter((time): time is ReportTime => time != null));
|
|
287
|
+
} else {
|
|
288
|
+
status = feed ?? "unreported";
|
|
289
|
+
}
|
|
290
|
+
// A partly stale board still says how far its fresh rows are held back.
|
|
291
|
+
if (status === "delayed" || partial?.feed === "delayed") delayMinutes = declared.delayMinutes ?? signals.delayMinutes;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
source: declared.source?.trim() || DEFAULT_REPORT_SOURCE,
|
|
296
|
+
asOf: asOf ? isoTime(asOf) : null,
|
|
297
|
+
...(asOf && oldestTime && asOf.time - oldestTime.time > OLDEST_GAP_MS ? { oldest: isoTime(oldestTime) } : {}),
|
|
298
|
+
status,
|
|
299
|
+
...(delayMinutes != null && delayMinutes > 0 ? { delayMinutes } : {}),
|
|
300
|
+
...(status === "stale" && staleAt ? { ageMinutes: Math.max(0, Math.floor((now - staleAt.time) / 60_000)) } : {}),
|
|
301
|
+
...(partial ?? {}),
|
|
302
|
+
...(status === "not-a-feed" && declared.basis ? { basis: declared.basis } : {}),
|
|
303
|
+
retrievedAt: new Date(now).toISOString(),
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Source, as-of and status for a headless report: what the loader declared
|
|
309
|
+
* (the result's `freshness` over the definition's), the rest read from the
|
|
310
|
+
* standard signals in the result. Never live unless the data says so.
|
|
311
|
+
*/
|
|
312
|
+
export function deriveHeadlessFreshness(
|
|
313
|
+
definition: Pick<HeadlessPaneDefinition, "shape" | "freshness">,
|
|
314
|
+
result: HeadlessPaneResult,
|
|
315
|
+
now = Date.now(),
|
|
316
|
+
): ReportFreshness {
|
|
317
|
+
const declared = mergeDeclarations(definition.freshness, result.freshness);
|
|
318
|
+
const { signals, observations } = collect(definition, result, now, declared);
|
|
319
|
+
return resolveFreshness({ declared, signals, observations, now });
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* A rendered view has no structured data: the source is the pane's
|
|
324
|
+
* declaration, the times are the cells that carry an instant, and the state
|
|
325
|
+
* is what the pane's own footer says, or not reported.
|
|
326
|
+
*/
|
|
327
|
+
export function deriveRenderedFreshness(
|
|
328
|
+
declared: HeadlessPaneFreshness | undefined,
|
|
329
|
+
input: { footerText: string; cellTimes: unknown[] },
|
|
330
|
+
now = Date.now(),
|
|
331
|
+
): ReportFreshness {
|
|
332
|
+
const signals = emptySignals();
|
|
333
|
+
const footer = input.footerText;
|
|
334
|
+
const delayed = /\b(\d+)\s*(?:m|min|minutes?)\s+delayed\b/i.exec(footer);
|
|
335
|
+
if (delayed) {
|
|
336
|
+
signals.delayed = true;
|
|
337
|
+
signals.delayMinutes = Number(delayed[1]);
|
|
338
|
+
} else if (/\bdelayed\b/i.test(footer)) {
|
|
339
|
+
signals.delayed = true;
|
|
340
|
+
}
|
|
341
|
+
if (/\bstale\b/i.test(footer)) signals.stale = true;
|
|
342
|
+
if (/\breal-time\b/i.test(footer)) signals.live = true;
|
|
343
|
+
const units = input.cellTimes
|
|
344
|
+
.map((value) => parseReportTime(value))
|
|
345
|
+
.filter((time): time is ReportTime => time != null && time.time <= now + FUTURE_TOLERANCE_MS);
|
|
346
|
+
return resolveFreshness({
|
|
347
|
+
declared: mergeDeclarations(declared),
|
|
348
|
+
signals,
|
|
349
|
+
// Rendered rows are often a history (a news list, a filing feed), so only the newest is cited.
|
|
350
|
+
observations: { units: [], extra: units },
|
|
351
|
+
now,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function ageText(minutes: number): string {
|
|
356
|
+
if (minutes < 120) return `${minutes} min`;
|
|
357
|
+
const hours = Math.floor(minutes / 60);
|
|
358
|
+
if (hours < 48) return `${hours} hours`;
|
|
359
|
+
return `${Math.floor(hours / 24)} days`;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function delayedText(minutes: number | undefined): string {
|
|
363
|
+
return minutes ? `Delayed ${minutes} min` : "Delayed";
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function statusText(freshness: ReportFreshness): string {
|
|
367
|
+
switch (freshness.status) {
|
|
368
|
+
case "live":
|
|
369
|
+
return "Live";
|
|
370
|
+
case "delayed":
|
|
371
|
+
return delayedText(freshness.delayMinutes);
|
|
372
|
+
case "stale": {
|
|
373
|
+
if (freshness.staleCount != null && freshness.observationCount != null) {
|
|
374
|
+
const rest = freshness.feed === "live" ? "Live" : freshness.feed === "delayed" ? delayedText(freshness.delayMinutes) : null;
|
|
375
|
+
return `${rest ? `${rest}, ` : ""}${freshness.staleCount} of ${freshness.observationCount} stale`;
|
|
376
|
+
}
|
|
377
|
+
return freshness.ageMinutes != null ? `Stale (${ageText(freshness.ageMinutes)} old)` : "Stale";
|
|
378
|
+
}
|
|
379
|
+
case "not-a-feed":
|
|
380
|
+
return freshness.basis ? `Not a live feed (${freshness.basis})` : "Not a live feed";
|
|
381
|
+
case "unreported":
|
|
382
|
+
return "Status not reported";
|
|
383
|
+
default: {
|
|
384
|
+
const _exhaustive: never = freshness.status;
|
|
385
|
+
return _exhaustive;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* The one line every `fn` text report ends with:
|
|
392
|
+
* `Source: Gloom Cloud | As of 2026-10-09 00:08 UTC | Delayed 10 min`.
|
|
393
|
+
* Without a dated observation it says when the report was retrieved instead.
|
|
394
|
+
*/
|
|
395
|
+
export function formatFreshnessLine(freshness: ReportFreshness): string {
|
|
396
|
+
const time = freshness.asOf
|
|
397
|
+
? `As of ${formatUtcTime(freshness.asOf)}${freshness.oldest ? ` (oldest ${freshness.oldest.slice(0, 10)})` : ""}`
|
|
398
|
+
: `Retrieved ${formatUtcTime(freshness.retrievedAt)}`;
|
|
399
|
+
return [`Source: ${freshness.source}`, time, statusText(freshness)].join(" | ");
|
|
400
|
+
}
|
|
@@ -81,6 +81,8 @@ const SEARCH = key("/", "search");
|
|
|
81
81
|
const OPEN_SOURCE = key("o", "pen source");
|
|
82
82
|
const POP_OUT = key("p", "op out");
|
|
83
83
|
const STEP = key("←/→", " step");
|
|
84
|
+
/** THEM and MEMB members: open them in RRG, CORR, SIW or RIPL, or save them as a watchlist. */
|
|
85
|
+
const MEMBERS_MENU = key(".", " open members in, save as watchlist");
|
|
84
86
|
const CHART_KEYS = [key("s", "eries"), key("i", "ndicators"), key("t", "imeframe"), key("f", "ormulas")];
|
|
85
87
|
|
|
86
88
|
export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
@@ -114,8 +116,8 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
114
116
|
bloomberg: ["GIP"],
|
|
115
117
|
},
|
|
116
118
|
G: {
|
|
117
|
-
summary: "Chart any series together: prices, statement lines, valuation multiples, FRED series, indicators and formulas. Series read SYMBOL:field or
|
|
118
|
-
usage: ["G", "G NVDA:revenue, NVDA:net_income"],
|
|
119
|
+
summary: "Chart any series together: prices, statement lines, valuation multiples, FRED series, map series such as chokepoint transits, indicators and formulas. Series read SYMBOL:field, FRED:series or GEO:series.",
|
|
120
|
+
usage: ["G", "G NVDA:revenue, NVDA:net_income", "G XOM, GEO:HORMUZ"],
|
|
119
121
|
keys: CHART_KEYS,
|
|
120
122
|
data: { free: "Prices 15 minutes delayed, other series as published", pro: "Prices real-time for US listings, other series as published" },
|
|
121
123
|
bloomberg: ["G"],
|
|
@@ -292,9 +294,9 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
292
294
|
bloomberg: ["SEAS"],
|
|
293
295
|
},
|
|
294
296
|
RIPL: {
|
|
295
|
-
summary: "Which of my holdings are tied to a company that reports soon? Customers your holdings name in their filings, and suppliers whose filings name your holdings, with the disclosed revenue share, by report date.",
|
|
297
|
+
summary: "Which of my holdings are tied to a company that reports soon? Customers your holdings name in their filings, and suppliers whose filings name your holdings, with the disclosed revenue share, by report date. With Pro, the 2 hops tab adds a supplier's supplier or a customer's customer, the company in between and each hop's share.",
|
|
296
298
|
usage: ["RIPL", "RIPL CRUS QRVO"],
|
|
297
|
-
keys: [key("Enter", " supply chain"), key("e", "arnings")],
|
|
299
|
+
keys: [TABS, key("Enter", " supply chain, the route on 2 hops"), key("e", "arnings")],
|
|
298
300
|
data: ON_RELEASE,
|
|
299
301
|
bloomberg: [],
|
|
300
302
|
},
|
|
@@ -663,14 +665,14 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
663
665
|
MEMB: {
|
|
664
666
|
summary: "ETF holdings with weights, shares, member returns, daily contributions and index changes. SPX and SPY use IVV holdings.",
|
|
665
667
|
usage: ["MEMB", "MEMB SPY", "MEMB IWM"],
|
|
666
|
-
keys: [TABS, OPEN],
|
|
668
|
+
keys: [TABS, OPEN, MEMBERS_MENU],
|
|
667
669
|
data: same("Dated fund holdings and partial delayed member returns. Nasdaq-100 is not covered."),
|
|
668
670
|
bloomberg: ["MEMB", "MRR", "IMOV"],
|
|
669
671
|
},
|
|
670
672
|
THEM: {
|
|
671
673
|
summary: "Curated thematic baskets with equal-weight returns and breadth. Open a theme to see its members, leaders and laggards. The Themes tab of BI.",
|
|
672
674
|
usage: ["THEM", "THEM nuclear"],
|
|
673
|
-
keys: [TABS, OPEN, key("Esc", "back")],
|
|
675
|
+
keys: [TABS, OPEN, key("Esc", "back"), MEMBERS_MENU],
|
|
674
676
|
data: same("Updated every 15 minutes"),
|
|
675
677
|
bloomberg: ["IMAP", "custom baskets"],
|
|
676
678
|
},
|
|
@@ -696,10 +698,10 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
696
698
|
bloomberg: ["FXC"],
|
|
697
699
|
},
|
|
698
700
|
PERP: {
|
|
699
|
-
summary: "Perpetual funding, open interest and premiums across crypto and stock, index, commodity and FX contracts
|
|
701
|
+
summary: "Perpetual funding, open interest and premiums across venues, for crypto and stock, index, commodity and FX contracts: a board, rankings, one asset across venues, and a market's History and Evidence.",
|
|
700
702
|
usage: ["PERP", "PERP BTC", "PERP TSLA"],
|
|
701
|
-
keys: [TABS,
|
|
702
|
-
data: { free: "
|
|
703
|
+
keys: [TABS, OPEN, SEARCH, key("e", "vidence"), key("a", "lert")],
|
|
704
|
+
data: { free: "A fixed preview and any one market's latest values", pro: "Every market, full rankings and stored history; source timestamps retained" },
|
|
703
705
|
bloomberg: [],
|
|
704
706
|
},
|
|
705
707
|
CRYP: {
|
|
@@ -717,8 +719,8 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
717
719
|
bloomberg: ["GLCO"],
|
|
718
720
|
},
|
|
719
721
|
CTM: {
|
|
720
|
-
summary: "A futures root's listed contracts as a curve against a week and a month ago, with roll yield, contango or backwardation, and each contract's price, open interest and volume.",
|
|
721
|
-
usage: ["CTM GC"],
|
|
722
|
+
summary: "A futures root's listed contracts as a curve against a week and a month ago, with roll yield, contango or backwardation, and each contract's price, open interest and volume. Takes a FUT root, VX or a CME crypto root (BTC, ETH, SOL, XRP), which also shows each contract's premium to spot and annualised basis against the USD pair quote.",
|
|
723
|
+
usage: ["CTM GC", "CTM BTC"],
|
|
722
724
|
keys: [key("d", "ate"), key("c", "urrent"), STEP],
|
|
723
725
|
data: same("Delayed, usually 10 minutes; VIX at settlement"),
|
|
724
726
|
bloomberg: ["CTM", "CT"],
|
|
@@ -731,8 +733,8 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
731
733
|
bloomberg: [],
|
|
732
734
|
},
|
|
733
735
|
COT: {
|
|
734
|
-
summary: "CFTC Commitments of Traders: net positioning by trader class, the weekly change, and one- and three-year percentiles. Pass a root like CL
|
|
735
|
-
usage: ["COT", "COT CL"],
|
|
736
|
+
summary: "CFTC Commitments of Traders: net positioning by trader class, the weekly change, and one- and three-year percentiles. Pass a root like CL or BTC (also ETH, MBT, MET, SOL, XRP) for one market, charted under its front-month price where there is one.",
|
|
737
|
+
usage: ["COT", "COT CL", "COT BTC"],
|
|
736
738
|
keys: [key("c", "lass"), key("s", "cope"), SEARCH],
|
|
737
739
|
data: same("Weekly: Tuesday positions, out on Friday"),
|
|
738
740
|
bloomberg: ["COT"],
|
|
@@ -809,10 +811,17 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
809
811
|
bloomberg: ["IPO"],
|
|
810
812
|
},
|
|
811
813
|
MAP: {
|
|
812
|
-
summary: "Trading venues around the world with open or closed status, local time and time to the next session change.",
|
|
813
|
-
usage: ["MAP"],
|
|
814
|
-
keys: [SEARCH, key("
|
|
815
|
-
data: same("
|
|
814
|
+
summary: "Trading venues around the world with open or closed status, local time and time to the next session change. Layers add ships, chokepoints, ports, pipelines, fields, LNG terminals and airports to the same map, each with a table of what is in view and the companies it links to.",
|
|
815
|
+
usage: ["MAP", "MAP ships", "MAP energy", "MAP air", "MAP ports"],
|
|
816
|
+
keys: [SEARCH, OPEN, key("d", "es"), key("+", " zoom in")],
|
|
817
|
+
data: same("Venues live from exchange calendars; ships live, chokepoints and ports daily, the rest reference data"),
|
|
818
|
+
bloomberg: [],
|
|
819
|
+
},
|
|
820
|
+
CHOKE: {
|
|
821
|
+
summary: "Daily vessel transits through the main shipping chokepoints charted together, or one of them by name, as series you can mix with anything else in G.",
|
|
822
|
+
usage: ["CHOKE", "CHOKE SUEZ"],
|
|
823
|
+
keys: CHART_KEYS,
|
|
824
|
+
data: same("Daily"),
|
|
816
825
|
bloomberg: [],
|
|
817
826
|
},
|
|
818
827
|
|
|
@@ -953,10 +962,10 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
953
962
|
bloomberg: [],
|
|
954
963
|
},
|
|
955
964
|
HDS: {
|
|
956
|
-
summary: "Institutional holders as a table (value, shares, change, percent held) or as an ownership treemap.",
|
|
957
|
-
usage: ["HDS NVDA"],
|
|
958
|
-
keys: [TABS, key("o", "pen 13F")],
|
|
959
|
-
data: same("
|
|
965
|
+
summary: "Institutional holders as a table (value, shares, change, percent held) or as an ownership treemap, and the 13D/G tab: 13D and 13G beneficial owners over 5%, activists and passive stakes, with percent of class, its change and each filer's 13F move.",
|
|
966
|
+
usage: ["HDS NVDA", "HDS CAR"],
|
|
967
|
+
keys: [TABS, OPEN, key("o", "pen 13F or filing")],
|
|
968
|
+
data: same("13F quarterly as filed; 13D and 13G as filed"),
|
|
960
969
|
bloomberg: ["HDS"],
|
|
961
970
|
},
|
|
962
971
|
"13F": {
|
|
@@ -983,7 +992,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
983
992
|
|
|
984
993
|
// Run a workspace
|
|
985
994
|
PF: {
|
|
986
|
-
summary: "Your portfolio or watchlist with live quotes, P&L, weights and sparklines.
|
|
995
|
+
summary: "Your portfolio or watchlist with live quotes, market value, P&L, weights of the total with cash, and sparklines. With target weights set, each holding adds its target, drift and the trade that rebalances it; broker-synced and manual positions sit in the same table.",
|
|
987
996
|
usage: ["PF"],
|
|
988
997
|
keys: [key("a", "dd"), OPEN, key("s", " grid")],
|
|
989
998
|
data: QUOTES,
|