gloomberb 0.16.0 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +44 -11
- package/src/api-client/errors.ts +12 -0
- package/src/api-client/geo.ts +363 -0
- package/src/api-client/index.ts +5 -0
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/members.ts +26 -0
- package/src/api-client/paths.ts +30 -1
- package/src/api-client/perps.ts +41 -0
- package/src/api-client/request.ts +5 -2
- package/src/api-client/types.ts +9 -1
- package/src/app/global-shortcuts.ts +14 -6
- package/src/app/keybindings/actions.ts +1 -1
- package/src/app/runtime/update.ts +38 -2
- package/src/app.tsx +10 -6
- package/src/brokers/account-cache.ts +24 -0
- package/src/cli/commands/command-utils.ts +8 -0
- package/src/cli/commands/crypto-hints.ts +75 -0
- package/src/cli/commands/market.ts +414 -106
- package/src/cli/commands/overview.ts +77 -32
- package/src/cli/commands/ticker.ts +101 -43
- package/src/cli/desktop-pane-shot.ts +34 -4
- package/src/cli/freshness.ts +61 -0
- package/src/cli/help.ts +1 -0
- package/src/cli/helpers.ts +4 -8
- package/src/cli/index.ts +12 -2
- package/src/cli/listing-arg.ts +321 -0
- package/src/cli/pane-functions/access-gate.ts +42 -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 +20 -2
- package/src/cli/pane-functions/freshness.ts +400 -0
- package/src/cli/pane-functions/function-help.ts +36 -22
- package/src/cli/pane-functions/headless.ts +39 -11
- package/src/cli/pane-functions/index.ts +15 -4
- package/src/cli/pane-functions/options.ts +3 -0
- package/src/cli/pane-functions/report.ts +4 -0
- package/src/cli/pane-functions/resolver.ts +35 -7
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +7 -3
- package/src/cli/result.ts +41 -27
- 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/commands/collection.ts +5 -1
- 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/root/command-items.ts +9 -2
- package/src/components/command-bar/routes/root/plugin-install.ts +2 -2
- package/src/components/command-bar/routes/root/provider-search.ts +19 -5
- package/src/components/command-bar/routes/root/runtime.ts +14 -5
- package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
- package/src/components/command-bar/routes/ticker-search/results.ts +31 -5
- package/src/components/command-bar/routes/ticker-search/route.ts +2 -2
- package/src/components/command-bar/routing/actions.ts +2 -0
- package/src/components/command-bar/selection-runtime.ts +38 -0
- package/src/components/command-bar/surface/index.tsx +7 -2
- 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/view.tsx +29 -10
- package/src/components/feedback-dialog.tsx +2 -1
- package/src/components/form-modal/field-row.tsx +2 -2
- package/src/components/index.ts +2 -2
- package/src/components/layout/detached-pane-shell.tsx +6 -3
- package/src/components/layout/floating-pane.tsx +6 -0
- package/src/components/layout/header.tsx +24 -7
- package/src/components/layout/missing-pane.tsx +2 -2
- 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 +61 -28
- package/src/components/layout/pane/index.tsx +6 -0
- package/src/components/layout/pane/title.ts +31 -7
- package/src/components/layout/shell/drag/index.ts +6 -5
- package/src/components/layout/shell/drag/runtime.ts +3 -0
- package/src/components/layout/shell/index.tsx +6 -0
- package/src/components/layout/shell/menu.ts +2 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +29 -10
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -3
- package/src/components/layout/shell/ticker-link-menu.ts +23 -9
- package/src/components/metric-treemap/heat-surface.tsx +745 -0
- package/src/components/metric-treemap/heat-tiles.ts +228 -0
- package/src/components/metric-treemap/index.tsx +2 -0
- package/src/components/metric-treemap/layout.ts +8 -0
- package/src/components/metric-treemap/scene.ts +432 -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/pane-settings-dialog/field-dialogs.tsx +1 -0
- package/src/components/ticker/list-table-view.tsx +13 -1
- package/src/components/toggle-list.tsx +38 -12
- package/src/components/ui/country-flag-art.tsx +449 -0
- package/src/components/ui/country-flag.tsx +41 -0
- package/src/components/ui/data-table/types.ts +13 -0
- package/src/components/ui/fields.tsx +8 -0
- package/src/components/ui/icon.tsx +2 -0
- package/src/components/ui/index.ts +4 -0
- package/src/components/ui/multi-select/dialog.tsx +108 -22
- package/src/components/ui/range-track.tsx +53 -0
- package/src/components/ui/status.tsx +8 -2
- package/src/components/ui/tabs.tsx +11 -4
- package/src/components/ui/text-prompt-dialog.tsx +4 -2
- package/src/core/state/app/types.ts +10 -1
- package/src/data/config/store/normalize.ts +17 -1
- package/src/i18n/es.ts +24 -4
- package/src/i18n/ja.ts +24 -4
- package/src/i18n/ko.ts +24 -4
- package/src/i18n/zh-cn.ts +24 -4
- package/src/i18n/zh-tw.ts +24 -4
- package/src/layout/ticker-navigation.ts +28 -2
- 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 +78 -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 +8 -0
- package/src/market-data/quotes/freshness.ts +36 -0
- package/src/market-data/quotes/resolution.ts +24 -8
- package/src/market-data/quotes/screener-live-quotes.ts +49 -4
- package/src/market-data/quotes/time.ts +16 -0
- 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/risk-client.ts +330 -79
- package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
- package/src/plugins/builtin/analytics/risk-headless.ts +61 -49
- package/src/plugins/builtin/analytics/risk-math.ts +33 -13
- package/src/plugins/builtin/analytics/risk-model.ts +282 -64
- package/src/plugins/builtin/analytics/risk-pane.tsx +62 -30
- package/src/plugins/builtin/analytics/risk-test-data.ts +206 -0
- 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 +1 -1
- 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/cells.tsx +15 -12
- package/src/plugins/builtin/buildout/detail/company.tsx +3 -3
- package/src/plugins/builtin/buildout/detail/index.tsx +0 -1
- package/src/plugins/builtin/buildout/detail/intel.tsx +6 -6
- package/src/plugins/builtin/buildout/detail/site.tsx +4 -7
- package/src/plugins/builtin/buildout/detail/ui.tsx +0 -19
- package/src/plugins/builtin/buildout/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/headless.ts +3 -1
- package/src/plugins/builtin/catalysts/index.tsx +2 -2
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/headless.ts +2 -0
- package/src/plugins/builtin/cds/index.tsx +1 -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 +1 -1
- 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/debt-maturities/wall-bar.tsx +14 -41
- package/src/plugins/builtin/dividend-yield/client.ts +4 -2
- 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/client.ts +2 -2
- package/src/plugins/builtin/earnings/headless.ts +5 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
- package/src/plugins/builtin/earnings-calls/index.tsx +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/fx-matrix/direction.ts +81 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +71 -33
- package/src/plugins/builtin/fx-matrix/live-legs.ts +17 -0
- package/src/plugins/builtin/fx-matrix/pairs.ts +68 -14
- package/src/plugins/builtin/fx-matrix/settings.ts +62 -0
- 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/headless.ts +139 -5
- package/src/plugins/builtin/holders/index.tsx +10 -3
- package/src/plugins/builtin/holders/pane.tsx +20 -3
- package/src/plugins/builtin/holders/report-header.ts +95 -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/jobs/index.tsx +1 -0
- package/src/plugins/builtin/jobs/share-bars.tsx +5 -28
- package/src/plugins/builtin/kelly-sizer/index.tsx +1 -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 +30 -2
- package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +245 -81
- package/src/plugins/builtin/market-heatmap/live.ts +88 -0
- package/src/plugins/builtin/market-heatmap/model.ts +146 -0
- package/src/plugins/builtin/market-heatmap/portfolio.ts +50 -11
- package/src/plugins/builtin/market-movers/client.ts +3 -2
- package/src/plugins/builtin/market-movers/headless.ts +10 -1
- package/src/plugins/builtin/market-movers/screener.ts +18 -5
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/members/client.ts +53 -0
- package/src/plugins/builtin/members/headless.ts +35 -0
- package/src/plugins/builtin/members/index.tsx +20 -0
- package/src/plugins/builtin/members/model.ts +68 -0
- package/src/plugins/builtin/members/pane.tsx +175 -0
- package/src/plugins/builtin/mna/distress/headless.ts +1 -0
- package/src/plugins/builtin/mna/headless.ts +1 -0
- package/src/plugins/builtin/mna/index.tsx +2 -1
- package/src/plugins/builtin/mna/pane.tsx +5 -2
- 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/index.tsx +2 -1
- 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 +74 -2
- package/src/plugins/builtin/pe-band/headless.ts +26 -8
- package/src/plugins/builtin/pe-band/model.ts +102 -22
- package/src/plugins/builtin/pe-band/pane.tsx +34 -16
- package/src/plugins/builtin/pe-band/report-dates.ts +78 -0
- package/src/plugins/builtin/perps/client.ts +66 -5
- package/src/plugins/builtin/perps/equity-identity.ts +16 -0
- package/src/plugins/builtin/perps/equity-row.tsx +6 -4
- 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 +248 -47
- package/src/plugins/builtin/plugin-marketplace/activation.ts +19 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -2
- package/src/plugins/builtin/plugin-marketplace/store.ts +2 -0
- package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
- package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -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 +230 -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 +98 -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 +47 -13
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +43 -2
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +48 -5
- package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -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 +11 -3
- 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/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/scanner/hilo-bars.tsx +12 -70
- package/src/plugins/builtin/scanner/hilo-model.ts +0 -18
- 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/move-bar.tsx +10 -32
- 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/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/social-mentions/headless.ts +1 -0
- package/src/plugins/builtin/social-mentions/index.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/thirteenf/headless.ts +110 -25
- package/src/plugins/builtin/thirteenf/index.tsx +2 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
- package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +5 -60
- package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
- package/src/plugins/builtin/ticker-detail/pane.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +7 -1
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +20 -4
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -2
- package/src/plugins/builtin/time-sales/headless.ts +5 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
- package/src/plugins/builtin/vol-surface/index.tsx +1 -1
- 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 +157 -0
- package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
- package/src/plugins/builtin/world-venue-map/client.ts +45 -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 +447 -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 +67 -4
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
- package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
- package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
- package/src/plugins/builtin/world-venue-map/model.ts +7 -4
- package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -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 +28 -43
- 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/catalog-browser.ts +2 -0
- package/src/plugins/catalog-manifest.ts +1 -0
- package/src/plugins/catalog-ui.ts +3 -1
- package/src/plugins/catalog.ts +1 -1
- package/src/plugins/host-link.ts +33 -1
- package/src/plugins/installer.ts +48 -12
- package/src/plugins/loader.ts +30 -3
- package/src/plugins/manager-node.ts +15 -5
- package/src/plugins/registry/index.ts +1 -1
- package/src/plugins/registry/pane-settings.ts +26 -7
- package/src/public/__snapshots__/public-api.test.ts.snap +2 -0
- package/src/renderers/dom/build-assets.ts +81 -3
- package/src/renderers/dom/data-table/row.tsx +52 -16
- package/src/renderers/dom/desktop/controls.tsx +7 -3
- package/src/renderers/dom/desktop/icons.tsx +1 -0
- 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 +69 -26
- package/src/renderers/dom/host/input.tsx +14 -3
- package/src/renderers/dom/host/tabs.tsx +37 -1
- package/src/renderers/dom/styles.css +41 -7
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +11 -6
- package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +181 -87
- package/src/renderers/electrobun/bun/index.ts +73 -6
- package/src/renderers/electrobun/bun/window/remembered-frame.ts +122 -0
- package/src/renderers/electrobun/shared/protocol.ts +3 -0
- package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +3 -1
- package/src/renderers/electrobun/view/main.tsx +7 -1
- package/src/renderers/electrobun/view/renderer-window-error.ts +18 -0
- package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
- package/src/renderers/electrobun/view/update-host.ts +45 -21
- package/src/renderers/opentui/host.tsx +5 -0
- package/src/sources/gloomberb-cloud/index.ts +25 -4
- package/src/sources/gloomberb-cloud/normalizers.ts +36 -5
- package/src/sources/provider-router/cached-routes.ts +4 -1
- package/src/sources/provider-router/financials.ts +11 -8
- package/src/sources/provider-router/history.ts +15 -10
- 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/sync/core-contributors.ts +4 -0
- package/src/telemetry/benign-window-error.ts +7 -0
- package/src/telemetry/crash-reports-dom.ts +2 -0
- package/src/telemetry/crash-reports.ts +4 -1
- package/src/test-support/cli-context.ts +10 -2
- package/src/test-support/daily-nav.ts +25 -0
- package/src/theme/heat-colors.ts +357 -2
- package/src/tickers/instrument-kind.ts +34 -7
- package/src/tickers/search/asset-classes.ts +24 -9
- package/src/tickers/search/index.ts +44 -11
- package/src/tickers/search/ranking.ts +23 -3
- 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 +5 -0
- package/src/types/headless.ts +79 -2
- package/src/types/plugin.ts +38 -6
- package/src/types/ticker.ts +15 -0
- package/src/ui/context-menu.tsx +1 -0
- package/src/ui/host.tsx +16 -0
- package/src/updater/index.ts +38 -13
- 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 +14 -0
- package/src/utils/depositary-receipt.ts +26 -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/price-earnings.ts +70 -3
- 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
|
@@ -199,6 +199,30 @@ export async function buildPaneCatalogEntries(
|
|
|
199
199
|
return entries.sort((left, right) => left.token.localeCompare(right.token));
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
/** The phrase starting a word of the text, so "funding rate" finds "funding rates" but "rate" is not found in "separate". */
|
|
203
|
+
function containsPhrase(text: string, phrase: string): boolean {
|
|
204
|
+
for (let at = text.indexOf(phrase); at >= 0; at = text.indexOf(phrase, at + 1)) {
|
|
205
|
+
if (at === 0 || !/[a-z0-9]/.test(text[at - 1]!)) return true;
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// A multi-word query ranks a function carrying the whole phrase in its name or keywords first, then in its
|
|
211
|
+
// description, then one matching every word somewhere; the rest rank by how many words they match.
|
|
212
|
+
const PHRASE_IN_NAME_BAND = 4000;
|
|
213
|
+
const PHRASE_IN_DESCRIPTION_BAND = 3000;
|
|
214
|
+
const ALL_WORDS_BAND = 2000;
|
|
215
|
+
const PER_MATCHED_WORD = 100;
|
|
216
|
+
|
|
217
|
+
function phraseBand(entry: PaneCatalogEntry, phrase: string): number {
|
|
218
|
+
const lower = (values: Array<string | undefined>) => values
|
|
219
|
+
.filter((value): value is string => !!value).map((value) => value.toLowerCase().replace(/\s+/g, " "));
|
|
220
|
+
const names = lower([entry.token, entry.label, entry.paneName, entry.shortcut, ...entry.aliases, ...entry.keywords, ...entry.capability.aliases]);
|
|
221
|
+
if (names.some((name) => containsPhrase(name, phrase))) return PHRASE_IN_NAME_BAND;
|
|
222
|
+
const descriptions = lower([entry.description, ...entry.capability.intents]);
|
|
223
|
+
return descriptions.some((description) => containsPhrase(description, phrase)) ? PHRASE_IN_DESCRIPTION_BAND : 0;
|
|
224
|
+
}
|
|
225
|
+
|
|
202
226
|
function paneCatalogSearchScore(entry: PaneCatalogEntry, query: string): number {
|
|
203
227
|
const terms = query.toLowerCase().split(/\s+/).map((term) => term.trim()).filter(Boolean);
|
|
204
228
|
if (terms.length === 0) return 1;
|
|
@@ -253,7 +277,10 @@ function paneCatalogSearchScore(entry: PaneCatalogEntry, query: string): number
|
|
|
253
277
|
if (matchedTerms === 0) return 0;
|
|
254
278
|
score += Math.round((matchedTerms / terms.length) * 8);
|
|
255
279
|
if (entry.capability.botSafe) score += 2;
|
|
256
|
-
|
|
280
|
+
// One word has no phrase to prefer: it keeps the plain term scores.
|
|
281
|
+
if (terms.length === 1) return score;
|
|
282
|
+
const band = phraseBand(entry, terms.join(" "));
|
|
283
|
+
return score + matchedTerms * PER_MATCHED_WORD + (band || (matchedTerms === terms.length ? ALL_WORDS_BAND : 0));
|
|
257
284
|
}
|
|
258
285
|
|
|
259
286
|
export function filterPaneCatalogEntries(entries: PaneCatalogEntry[], query: string): PaneCatalogEntry[] {
|
|
@@ -182,5 +182,7 @@ export function collectShotSymbols(resolved: ResolvedPaneFunction, rawArg: strin
|
|
|
182
182
|
if (resolved.capability.id === "security-relationship" && symbols.length === 1) {
|
|
183
183
|
symbols = [...symbols, "SPY"];
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
// Entries a ticker list keeps as typed (CORR's GEO:HORMUZ) are not tickers to fetch.
|
|
186
|
+
const keep = resolved.template?.shortcut?.keepArgToken;
|
|
187
|
+
return [...new Set(symbols.filter((symbol) => !keep?.(symbol)).map(cleanTickerInput).filter(Boolean))];
|
|
186
188
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { DesktopPaneShotRenderedRow } from "../desktop-pane-shot";
|
|
2
|
-
import { renderSection, renderTable } from "../../utils/cli-output";
|
|
2
|
+
import { cliStyles, renderSection, renderTable } from "../../utils/cli-output";
|
|
3
|
+
import { formatUtcTime } from "../../utils/utc-time";
|
|
3
4
|
import type { MarketContext } from "../types";
|
|
4
5
|
import type { PaneFunctionReport } from "./report";
|
|
5
6
|
import type { ResolvedPaneFunction } from "./resolver";
|
|
6
7
|
import { collectShotSymbols } from "./data";
|
|
7
8
|
import { renderDesktopShot, type PaneScreenshotResult } from "./screenshot";
|
|
9
|
+
import { deriveRenderedFreshness, formatFreshnessLine, type ReportFreshness } from "./freshness";
|
|
8
10
|
|
|
9
11
|
const DOM_REPORT_WIDTH = 1280;
|
|
10
12
|
const DOM_REPORT_HEIGHT = 720;
|
|
@@ -32,6 +34,14 @@ function domCellKeys(row: DesktopPaneShotRenderedRow): string[] {
|
|
|
32
34
|
});
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
/**
|
|
38
|
+
* A pane may shorten a time to fit ("Wed 11:27", "Oct 2"); the report prints
|
|
39
|
+
* the instant behind it with its date and zone instead.
|
|
40
|
+
*/
|
|
41
|
+
function cellText(cell: DesktopPaneShotRenderedRow["cells"][number]): string {
|
|
42
|
+
return cell.instant ? formatUtcTime(cell.instant) || cell.text : cell.text;
|
|
43
|
+
}
|
|
44
|
+
|
|
35
45
|
function renderDomTables(rows: DesktopPaneShotRenderedRow[]): string[] {
|
|
36
46
|
const byTable = new Map<number, DesktopPaneShotRenderedRow[]>();
|
|
37
47
|
for (const row of rows) {
|
|
@@ -60,7 +70,7 @@ function renderDomTables(rows: DesktopPaneShotRenderedRow[]): string[] {
|
|
|
60
70
|
columns,
|
|
61
71
|
tableRows.map((row) => {
|
|
62
72
|
const keys = domCellKeys(row);
|
|
63
|
-
const textByKey = new Map(row.cells.map((cell, cellIndex) => [keys[cellIndex]!, cell
|
|
73
|
+
const textByKey = new Map(row.cells.map((cell, cellIndex) => [keys[cellIndex]!, cellText(cell)]));
|
|
64
74
|
return columns.map((column) => textByKey.get(column.key) ?? "");
|
|
65
75
|
}),
|
|
66
76
|
);
|
|
@@ -129,6 +139,10 @@ export function buildDomPaneReportFromRender(
|
|
|
129
139
|
textLines.push(failureReason ?? "No rendered values were available.");
|
|
130
140
|
}
|
|
131
141
|
if (failureReason && rows.length > 0) textLines.push("", failureReason);
|
|
142
|
+
const freshness = deriveRenderedFreshness(resolved.pane.reportFreshness, {
|
|
143
|
+
footerText: result.render.footerText ?? "",
|
|
144
|
+
cellTimes: rows.flatMap((row) => row.cells.flatMap((cell) => cell.instant ?? [])),
|
|
145
|
+
});
|
|
132
146
|
|
|
133
147
|
return {
|
|
134
148
|
data: {
|
|
@@ -147,6 +161,7 @@ export function buildDomPaneReportFromRender(
|
|
|
147
161
|
truncationReasons,
|
|
148
162
|
limitation: DOM_LIMITATION,
|
|
149
163
|
...(failureReason ? { reason: failureReason } : {}),
|
|
164
|
+
freshness,
|
|
150
165
|
},
|
|
151
166
|
text: textLines.join("\n").trimEnd(),
|
|
152
167
|
};
|
|
@@ -156,12 +171,14 @@ export function appendDomReportFooter(
|
|
|
156
171
|
text: string,
|
|
157
172
|
elapsedMs: number,
|
|
158
173
|
truncated: boolean,
|
|
174
|
+
freshness: ReportFreshness,
|
|
159
175
|
): string {
|
|
160
176
|
const clipping = truncated ? "The rendered view is clipped." : "The rendered view may be clipped.";
|
|
161
177
|
return [
|
|
162
178
|
text,
|
|
163
179
|
"",
|
|
164
180
|
`Rendered view: values come from the visible pane. ${clipping} Render time: ${elapsedMs} ms.`,
|
|
181
|
+
cliStyles.muted(formatFreshnessLine(freshness)),
|
|
165
182
|
].join("\n");
|
|
166
183
|
}
|
|
167
184
|
|
|
@@ -193,6 +210,7 @@ function failedDomReport(
|
|
|
193
210
|
truncationReasons: [],
|
|
194
211
|
limitation: DOM_LIMITATION,
|
|
195
212
|
reason,
|
|
213
|
+
freshness: deriveRenderedFreshness(resolved.pane.reportFreshness, { footerText: "", cellTimes: [] }),
|
|
196
214
|
},
|
|
197
215
|
text: [resolved.label, "", reason].join("\n"),
|
|
198
216
|
};
|
|
@@ -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
|
+
}
|
|
@@ -114,8 +114,8 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
114
114
|
bloomberg: ["GIP"],
|
|
115
115
|
},
|
|
116
116
|
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"],
|
|
117
|
+
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.",
|
|
118
|
+
usage: ["G", "G NVDA:revenue, NVDA:net_income", "G XOM, GEO:HORMUZ"],
|
|
119
119
|
keys: CHART_KEYS,
|
|
120
120
|
data: { free: "Prices 15 minutes delayed, other series as published", pro: "Prices real-time for US listings, other series as published" },
|
|
121
121
|
bloomberg: ["G"],
|
|
@@ -292,9 +292,9 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
292
292
|
bloomberg: ["SEAS"],
|
|
293
293
|
},
|
|
294
294
|
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.",
|
|
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. 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
296
|
usage: ["RIPL", "RIPL CRUS QRVO"],
|
|
297
|
-
keys: [key("Enter", " supply chain"), key("e", "arnings")],
|
|
297
|
+
keys: [TABS, key("Enter", " supply chain, the route on 2 hops"), key("e", "arnings")],
|
|
298
298
|
data: ON_RELEASE,
|
|
299
299
|
bloomberg: [],
|
|
300
300
|
},
|
|
@@ -660,6 +660,13 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
660
660
|
data: QUOTES,
|
|
661
661
|
bloomberg: ["IMAP"],
|
|
662
662
|
},
|
|
663
|
+
MEMB: {
|
|
664
|
+
summary: "ETF holdings with weights, shares, member returns, daily contributions and index changes. SPX and SPY use IVV holdings.",
|
|
665
|
+
usage: ["MEMB", "MEMB SPY", "MEMB IWM"],
|
|
666
|
+
keys: [TABS, OPEN],
|
|
667
|
+
data: same("Dated fund holdings and partial delayed member returns. Nasdaq-100 is not covered."),
|
|
668
|
+
bloomberg: ["MEMB", "MRR", "IMOV"],
|
|
669
|
+
},
|
|
663
670
|
THEM: {
|
|
664
671
|
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.",
|
|
665
672
|
usage: ["THEM", "THEM nuclear"],
|
|
@@ -675,24 +682,24 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
675
682
|
bloomberg: ["RRG"],
|
|
676
683
|
},
|
|
677
684
|
HM: {
|
|
678
|
-
summary: "The largest US stocks and ETFs as a treemap sized by market cap or assets and colored by the day's move.",
|
|
685
|
+
summary: "The largest US stocks and ETFs as a treemap sized by the square root of market cap or assets, or by plain market cap in its settings, and colored by the day's move.",
|
|
679
686
|
usage: ["HM"],
|
|
680
687
|
keys: [OPEN],
|
|
681
688
|
data: QUOTES,
|
|
682
689
|
bloomberg: ["IMAP"],
|
|
683
690
|
},
|
|
684
691
|
FXC: {
|
|
685
|
-
summary: "A cross-rate matrix for the major currencies.",
|
|
692
|
+
summary: "A cross-rate matrix for the major currencies, or for any of 45 chosen in its settings.",
|
|
686
693
|
usage: ["FXC"],
|
|
687
694
|
keys: [],
|
|
688
695
|
data: FX,
|
|
689
696
|
bloomberg: ["FXC"],
|
|
690
697
|
},
|
|
691
698
|
PERP: {
|
|
692
|
-
summary: "Perpetual funding, open interest and premiums across crypto and stock, index, commodity and FX contracts
|
|
699
|
+
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.",
|
|
693
700
|
usage: ["PERP", "PERP BTC", "PERP TSLA"],
|
|
694
|
-
keys: [TABS,
|
|
695
|
-
data: { free: "
|
|
701
|
+
keys: [TABS, OPEN, SEARCH, key("e", "vidence"), key("a", "lert")],
|
|
702
|
+
data: { free: "A fixed preview and any one market's latest values", pro: "Every market, full rankings and stored history; source timestamps retained" },
|
|
696
703
|
bloomberg: [],
|
|
697
704
|
},
|
|
698
705
|
CRYP: {
|
|
@@ -710,8 +717,8 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
710
717
|
bloomberg: ["GLCO"],
|
|
711
718
|
},
|
|
712
719
|
CTM: {
|
|
713
|
-
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.",
|
|
714
|
-
usage: ["CTM GC"],
|
|
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. 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.",
|
|
721
|
+
usage: ["CTM GC", "CTM BTC"],
|
|
715
722
|
keys: [key("d", "ate"), key("c", "urrent"), STEP],
|
|
716
723
|
data: same("Delayed, usually 10 minutes; VIX at settlement"),
|
|
717
724
|
bloomberg: ["CTM", "CT"],
|
|
@@ -724,8 +731,8 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
724
731
|
bloomberg: [],
|
|
725
732
|
},
|
|
726
733
|
COT: {
|
|
727
|
-
summary: "CFTC Commitments of Traders: net positioning by trader class, the weekly change, and one- and three-year percentiles. Pass a root like CL
|
|
728
|
-
usage: ["COT", "COT CL"],
|
|
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 or BTC (also ETH, MBT, MET, SOL, XRP) for one market, charted under its front-month price where there is one.",
|
|
735
|
+
usage: ["COT", "COT CL", "COT BTC"],
|
|
729
736
|
keys: [key("c", "lass"), key("s", "cope"), SEARCH],
|
|
730
737
|
data: same("Weekly: Tuesday positions, out on Friday"),
|
|
731
738
|
bloomberg: ["COT"],
|
|
@@ -802,10 +809,17 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
802
809
|
bloomberg: ["IPO"],
|
|
803
810
|
},
|
|
804
811
|
MAP: {
|
|
805
|
-
summary: "Trading venues around the world with open or closed status, local time and time to the next session change.",
|
|
806
|
-
usage: ["MAP"],
|
|
807
|
-
keys: [SEARCH, key("
|
|
808
|
-
data: same("
|
|
812
|
+
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.",
|
|
813
|
+
usage: ["MAP", "MAP ships", "MAP energy", "MAP air", "MAP ports"],
|
|
814
|
+
keys: [SEARCH, OPEN, key("d", "es"), key("+", " zoom in")],
|
|
815
|
+
data: same("Venues live from exchange calendars; ships live, chokepoints and ports daily, the rest reference data"),
|
|
816
|
+
bloomberg: [],
|
|
817
|
+
},
|
|
818
|
+
CHOKE: {
|
|
819
|
+
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.",
|
|
820
|
+
usage: ["CHOKE", "CHOKE SUEZ"],
|
|
821
|
+
keys: CHART_KEYS,
|
|
822
|
+
data: same("Daily"),
|
|
809
823
|
bloomberg: [],
|
|
810
824
|
},
|
|
811
825
|
|
|
@@ -946,10 +960,10 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
946
960
|
bloomberg: [],
|
|
947
961
|
},
|
|
948
962
|
HDS: {
|
|
949
|
-
summary: "Institutional holders as a table (value, shares, change, percent held) or as an ownership treemap.",
|
|
950
|
-
usage: ["HDS NVDA"],
|
|
951
|
-
keys: [TABS, key("o", "pen 13F")],
|
|
952
|
-
data: same("
|
|
963
|
+
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.",
|
|
964
|
+
usage: ["HDS NVDA", "HDS CAR"],
|
|
965
|
+
keys: [TABS, OPEN, key("o", "pen 13F or filing")],
|
|
966
|
+
data: same("13F quarterly as filed; 13D and 13G as filed"),
|
|
953
967
|
bloomberg: ["HDS"],
|
|
954
968
|
},
|
|
955
969
|
"13F": {
|
|
@@ -976,7 +990,7 @@ export const FUNCTION_HELP: Readonly<Record<string, FunctionHelp>> = {
|
|
|
976
990
|
|
|
977
991
|
// Run a workspace
|
|
978
992
|
PF: {
|
|
979
|
-
summary: "Your portfolio or watchlist with live quotes, P&L, weights and sparklines.
|
|
993
|
+
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.",
|
|
980
994
|
usage: ["PF"],
|
|
981
995
|
keys: [key("a", "dd"), OPEN, key("s", " grid")],
|
|
982
996
|
data: QUOTES,
|