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
|
@@ -32,6 +32,8 @@ export function projectSectorRows(
|
|
|
32
32
|
loading: false,
|
|
33
33
|
quoteUnavailable: !byEtf.get(definition.etf) || byEtf.get(definition.etf)?.quoteUnavailable === true,
|
|
34
34
|
quoteSessionDate: byEtf.get(definition.etf)?.quoteSessionDate ?? null,
|
|
35
|
+
quoteUpdatedAt: byEtf.get(definition.etf)?.quoteUpdatedAt ?? null,
|
|
36
|
+
quoteDataSource: byEtf.get(definition.etf)?.quoteDataSource,
|
|
35
37
|
quoteIssue: byEtf.get(definition.etf)?.quoteIssue ?? null,
|
|
36
38
|
lastReportedPrice: byEtf.get(definition.etf)?.lastReportedPrice ?? null,
|
|
37
39
|
returnIntegrity: byEtf.get(definition.etf)?.returnIntegrity ?? {},
|
|
@@ -58,6 +60,8 @@ export function createSectorsHeadless(
|
|
|
58
60
|
): HeadlessPaneDefinition<"rows"> {
|
|
59
61
|
return {
|
|
60
62
|
shape: "rows",
|
|
63
|
+
// Dated by each ETF's quote; the shared session date is the returns' end, not an observation.
|
|
64
|
+
freshness: { observedKey: "quoteUpdatedAt" },
|
|
61
65
|
argument: { kind: "none" },
|
|
62
66
|
options: [{
|
|
63
67
|
key: "collection",
|
|
@@ -81,7 +85,11 @@ export function createSectorsHeadless(
|
|
|
81
85
|
return {
|
|
82
86
|
unavailableSymbols: unavailableSymbols.length > 0 ? unavailableSymbols : undefined,
|
|
83
87
|
errors: rows.flatMap((row) => sectorRowIssues(row).map((issue) => `${row.etf}: ${issue}.`)),
|
|
84
|
-
|
|
88
|
+
// The quote behind each row says whether it is real-time or delayed, and how current it is.
|
|
89
|
+
rows: rows.map(({ quoteDataSource, ...row }) => ({
|
|
90
|
+
...row,
|
|
91
|
+
...(quoteDataSource === "live" || quoteDataSource === "delayed" ? { dataSource: quoteDataSource } : {}),
|
|
92
|
+
})),
|
|
85
93
|
metadata: {
|
|
86
94
|
collection: collectionId,
|
|
87
95
|
available: outcomes.filter((outcome) => outcome.row).length,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RatioBar } from "../../../components/ui/ratio-bar";
|
|
2
|
+
import { Text } from "../../../ui";
|
|
2
3
|
import { colors } from "../../../theme/colors";
|
|
3
4
|
import { moveBarRatio } from "./sector-model";
|
|
4
5
|
|
|
@@ -7,37 +8,14 @@ export interface SectorMoveBarProps {
|
|
|
7
8
|
width: number;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
/**
|
|
11
|
-
* The session move as a length, not as a number that is already in the 1D
|
|
12
|
-
* column. Desktop draws a real element; the terminal falls back to block cells,
|
|
13
|
-
* so box-drawing characters never reach the browser renderer.
|
|
14
|
-
*/
|
|
11
|
+
/** The session move as a length, not as a number that is already in the 1D column. */
|
|
15
12
|
export function SectorMoveBar({ changePercent, width }: SectorMoveBarProps) {
|
|
16
|
-
const isDesktopWeb = useUiCapabilities().nativePaneChrome === true;
|
|
17
13
|
if (changePercent == null || width <= 0) return <Text fg={colors.textDim}>{""}</Text>;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
<Box
|
|
26
|
-
backgroundColor={color}
|
|
27
|
-
style={{
|
|
28
|
-
width: `${(ratio * 100).toFixed(2)}%`,
|
|
29
|
-
height: "9px",
|
|
30
|
-
borderRadius: "2px",
|
|
31
|
-
minWidth: ratio > 0 ? "2px" : "0",
|
|
32
|
-
}}
|
|
33
|
-
/>
|
|
34
|
-
</Box>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const cells = ratio * width;
|
|
39
|
-
const full = Math.floor(cells);
|
|
40
|
-
const half = cells - full >= 0.5;
|
|
41
|
-
const bar = `${"█".repeat(full)}${half ? "▌" : ""}`;
|
|
42
|
-
return <Text fg={color}>{bar}</Text>;
|
|
14
|
+
return (
|
|
15
|
+
<RatioBar
|
|
16
|
+
ratio={moveBarRatio(changePercent)}
|
|
17
|
+
width={width}
|
|
18
|
+
color={changePercent >= 0 ? colors.positive : colors.negative}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
43
21
|
}
|
|
@@ -25,6 +25,8 @@ export interface SectorRow extends SectorDef {
|
|
|
25
25
|
lastReportedPrice?: number | null;
|
|
26
26
|
/** When the snapshot quote behind `price` was stamped; a live quote must be at least as new. */
|
|
27
27
|
quoteUpdatedAt?: number | null;
|
|
28
|
+
/** Whether that quote is real-time or delayed, for the report's freshness line. */
|
|
29
|
+
quoteDataSource?: Quote["dataSource"];
|
|
28
30
|
returnIntegrity?: Partial<Record<SectorReturnRange, PriceHistoryIntegrity>>;
|
|
29
31
|
returnAsOfDate?: string | null;
|
|
30
32
|
return1MStartDate?: string | null;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The coin a USD crypto pair names: BTC-USD gives BTC. CME lists bitcoin and
|
|
3
|
+
* ether futures, but BTC and ETH are also US equity tickers (Grayscale's mini
|
|
4
|
+
* trusts), so a futures function that falls back to the ticker under the
|
|
5
|
+
* cursor reads a bare symbol as the equity and only a pair as the coin.
|
|
6
|
+
*/
|
|
7
|
+
export function cryptoPairCoin(ticker: string): string | null {
|
|
8
|
+
return /^([A-Z0-9]{2,10})-USD$/.exec(ticker.trim().toUpperCase())?.[1] ?? null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** `BTC=F`: the spelling of a futures contract, which no equity shares. */
|
|
12
|
+
export function isFuturesSymbol(ticker: string): boolean {
|
|
13
|
+
return ticker.trim().toUpperCase().endsWith("=F");
|
|
14
|
+
}
|
|
@@ -20,7 +20,7 @@ export function Blurred({ children }: { children: ReactNode }) {
|
|
|
20
20
|
export function UpgradeLabel({ text, onPress, role }: { text: string; onPress: () => void; role?: string }) {
|
|
21
21
|
const colors = useThemeColors();
|
|
22
22
|
return (
|
|
23
|
-
<Box flexDirection="row" gap={1} onMouseDown={onPress} data-gloom-role={role}>
|
|
23
|
+
<Box flexDirection="row" gap={1} onMouseDown={onPress} data-gloom-role={role} data-gloom-ui="pro-lock">
|
|
24
24
|
<Icon name="lock" size={11} color={colors.textBright} />
|
|
25
25
|
<Text fg={colors.textBright}>{text}</Text>
|
|
26
26
|
</Box>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { HeadlessPaneFreshness } from "../../../types/headless";
|
|
2
|
+
import type { Quote } from "../../../types/financials";
|
|
3
|
+
import { isQuoteStaleForCurrentSession } from "../../../market-data/quotes/freshness";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Freshness declarations shared by built-in reports. Each `fn` report ends
|
|
7
|
+
* with the source, as-of and status line these feed; see
|
|
8
|
+
* docs/usage.md#how-current-a-report-is.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Analyses over end-of-day history: not a feed, but stale once the closes stop arriving. */
|
|
12
|
+
export const DAILY_CLOSES: HeadlessPaneFreshness = { status: "not-a-feed", basis: "daily closes", cadence: "daily" };
|
|
13
|
+
|
|
14
|
+
const DAY_MINUTES = 24 * 60;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Price bars: a history, not a feed, stale once the bars stop arriving for
|
|
18
|
+
* their size. Intraday and daily bars follow the US trading sessions; a
|
|
19
|
+
* weekly or monthly bar is dated by the start of its period.
|
|
20
|
+
*/
|
|
21
|
+
export function barHistoryFreshness(resolution: string | null | undefined): HeadlessPaneFreshness {
|
|
22
|
+
if (resolution === "1wk") return { status: "not-a-feed", basis: "weekly bars", maxAgeMinutes: 14 * DAY_MINUTES };
|
|
23
|
+
if (resolution === "1mo") return { status: "not-a-feed", basis: "monthly bars", maxAgeMinutes: 45 * DAY_MINUTES };
|
|
24
|
+
if (resolution === "1d") return DAILY_CLOSES;
|
|
25
|
+
return { status: "not-a-feed", basis: "intraday bars", cadence: "daily" };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The bar size of a dated history, read from the gap between its last two bars. */
|
|
29
|
+
export function barResolutionFromDates(dates: readonly (string | number | Date)[]): "1d" | "1wk" | "1mo" {
|
|
30
|
+
const times = dates.slice(-2).map((date) => new Date(date).getTime());
|
|
31
|
+
const gapDays = times.length === 2 && times.every(Number.isFinite) ? (times[1]! - times[0]!) / 86_400_000 : 1;
|
|
32
|
+
return gapDays >= 25 ? "1mo" : gapDays >= 6 ? "1wk" : "1d";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Company filings read from EDGAR. Old filings are not stale; there is no schedule to miss. */
|
|
36
|
+
export const SEC_FILINGS: HeadlessPaneFreshness = { source: "SEC EDGAR", status: "not-a-feed", basis: "filed data", oldest: null };
|
|
37
|
+
|
|
38
|
+
/** Places and listings that change only when someone edits them: venues, ports, pipelines. */
|
|
39
|
+
export const REFERENCE_DATA: HeadlessPaneFreshness = { status: "not-a-feed", basis: "reference data", oldest: null };
|
|
40
|
+
|
|
41
|
+
/** Company fundamentals, estimates and calendars: reported figures, not a feed. */
|
|
42
|
+
export const REPORTED_DATA: HeadlessPaneFreshness = { status: "not-a-feed", basis: "reported data" };
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The standard freshness fields of one quote, spread into a report row so the
|
|
46
|
+
* report can say whether that row is live, delayed or stale for its session.
|
|
47
|
+
*/
|
|
48
|
+
export function quoteFreshnessFields(
|
|
49
|
+
quote: Quote | null | undefined,
|
|
50
|
+
now = Date.now(),
|
|
51
|
+
): { dataSource?: "live" | "delayed"; stale?: boolean } {
|
|
52
|
+
if (!quote) return {};
|
|
53
|
+
return {
|
|
54
|
+
...(quote.dataSource === "live" || quote.dataSource === "delayed" ? { dataSource: quote.dataSource } : {}),
|
|
55
|
+
stale: isQuoteStaleForCurrentSession(quote, now),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DataTableCell, DataTableColumn } from "../../../components";
|
|
2
|
+
import { RatioBar } from "../../../components/ui/ratio-bar";
|
|
2
3
|
import { SplitBar } from "../../../components/ui/split-bar";
|
|
3
4
|
import { blendHex } from "../../../theme/colors";
|
|
4
5
|
import type { ThemeColors } from "../../../theme/colors";
|
|
@@ -39,21 +40,15 @@ export function listingCell(key: string | null | undefined, colors: ThemeColors,
|
|
|
39
40
|
* so the eye compares lengths down the column. The bar gives way first in a
|
|
40
41
|
* narrow column; the number never does.
|
|
41
42
|
*/
|
|
42
|
-
export function shareCell(text: string, ratio: number | null, width: number, colors: ThemeColors, selected: boolean,
|
|
43
|
+
export function shareCell(text: string, ratio: number | null, width: number, colors: ThemeColors, selected: boolean,
|
|
43
44
|
color = blendHex(colors.bg, colors.borderFocused, 0.6)): DataTableCell {
|
|
44
45
|
const textCells = displayWidth(text);
|
|
45
46
|
const barCells = width - textCells - 1;
|
|
46
47
|
if (ratio == null || !(ratio > 0) || barCells < 4) return { text, color: selected ? colors.selectedText : colors.text };
|
|
47
|
-
|
|
48
|
-
const ink = selected ? colors.selectedText : color;
|
|
49
|
-
// The desktop draws the bar on a faint track; terminal cells draw the length alone, at half-cell steps,
|
|
48
|
+
// The desktop draws the bar on a faint track; terminal cells draw the length alone,
|
|
50
49
|
// since a track of block cells would join the rows above and below into one wall.
|
|
51
|
-
const units = Math.max(1, Math.round(fill * barCells * 2));
|
|
52
50
|
return { text, content: <Box flexDirection="row" height={1} width={width} overflow="hidden" alignItems="center">
|
|
53
|
-
<
|
|
54
|
-
{desktop ? <SplitBar width={barCells} parts={[{ id: "share", value: fill, color: ink }, { id: "rest", value: 1 - fill, color: blendHex(colors.bg, color, 0.2) }]} />
|
|
55
|
-
: <Text fg={ink}>{`${"█".repeat(Math.floor(units / 2))}${units % 2 ? "▌" : ""}`}</Text>}
|
|
56
|
-
</Box>
|
|
51
|
+
<RatioBar ratio={ratio} width={barCells} color={selected ? colors.selectedText : color} track />
|
|
57
52
|
<Box flexGrow={1} justifyContent="flex-end"><Text fg={selected ? colors.selectedText : colors.text}>{` ${text}`}</Text></Box>
|
|
58
53
|
</Box> };
|
|
59
54
|
}
|
|
@@ -58,6 +58,8 @@ export function createShortInterestHeadless(
|
|
|
58
58
|
): HeadlessPaneDefinition<"rows"> {
|
|
59
59
|
return {
|
|
60
60
|
shape: "rows",
|
|
61
|
+
// Settled twice a month and published about a week later; a month without one has missed it.
|
|
62
|
+
freshness: { source: "FINRA", status: "not-a-feed", basis: "twice-monthly settlement", observedKey: "settlementDate", oldest: null, maxAgeMinutes: 30 * 24 * 60 },
|
|
61
63
|
argument: {
|
|
62
64
|
kind: "ticker",
|
|
63
65
|
placeholder: "ticker",
|
|
@@ -10,6 +10,7 @@ const signedPercent = (value: unknown) =>
|
|
|
10
10
|
|
|
11
11
|
export const shortWatchHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
12
12
|
shape: "rows",
|
|
13
|
+
freshness: { source: "FINRA", status: "not-a-feed", basis: "twice-monthly settlement", observedKey: "settlementDate", maxAgeMinutes: 30 * 24 * 60 },
|
|
13
14
|
argument: { kind: "symbol-list", maximum: SHORT_WATCH_LIMIT, description: "US tickers; the pane defaults to your portfolios and watchlists." },
|
|
14
15
|
options: [],
|
|
15
16
|
describe: "Short squeeze watch",
|
|
@@ -4,6 +4,7 @@ import { volumePercent, volumePointStatus, volumeQuantity } from "./model";
|
|
|
4
4
|
|
|
5
5
|
export const shortVolumeHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
6
6
|
shape: "bundle", argument: { kind: "ticker", description: "US equity ticker.", placeholder: "ticker" },
|
|
7
|
+
freshness: { source: "FINRA", status: "not-a-feed", basis: "daily short volume", cadence: "daily", observedKey: "date", oldest: null },
|
|
7
8
|
discovery: { aliases: ["SIV"], dataRequirements: ["Gloom Cloud FINRA daily short volume"],
|
|
8
9
|
limitations: ["Regular-session off-exchange volume, not short interest", "Short volume includes exempt volume", "One-year history depends on source discovery and ingestion"] },
|
|
9
10
|
options: [
|
|
@@ -5,6 +5,7 @@ import { socialCount, socialDayRows, socialRatio, socialStance, topPostCell } fr
|
|
|
5
5
|
|
|
6
6
|
export const socialMentionsHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
7
7
|
shape: "bundle", argument: { kind: "ticker", description: "Ticker with a searchable cashtag (up to six letters and digits).", placeholder: "ticker" },
|
|
8
|
+
freshness: { source: "X posts", status: "not-a-feed", basis: "daily post counts" },
|
|
8
9
|
discovery: { aliases: ["BUZZ"], dataRequirements: ["Gloom Cloud X mention history"],
|
|
9
10
|
limitations: ["Daily $cashtag posts on X in UTC days, spam included", "Top posts and stance cover days that were looked up", "Views exist from 2022-12-22"] },
|
|
10
11
|
options: [
|
|
@@ -10,7 +10,7 @@ const socialMentionsSettings = [
|
|
|
10
10
|
];
|
|
11
11
|
export const socialMentionsModule: PluginModule = {
|
|
12
12
|
panes: [{ id: "social-mentions", name: "Social Mentions", icon: "B", component: SocialMentionsPane,
|
|
13
|
-
defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 96, height: 30 },
|
|
13
|
+
defaultPosition: "right", tickerFollower: true, defaultMode: "floating", defaultFloatingSize: { width: 96, height: 30 },
|
|
14
14
|
tableExport: true, headless: socialMentionsHeadless, settings: { title: "Social Mentions", fields: socialMentionsSettings } }],
|
|
15
15
|
paneTemplates: [{ ...createTickerSurfacePaneTemplate({ id: "social-mentions-pane", paneId: "social-mentions", label: "Social Mentions",
|
|
16
16
|
description: "Daily posts on X naming the ticker's cashtag, the day's top posts and their stance.",
|
|
@@ -4,6 +4,7 @@ import { fetchSupplyChain } from "./client";
|
|
|
4
4
|
import { evidenceLabel, isUnconfirmed, matchesSupplyOptions, supplyOptions, trustTier } from "./trust";
|
|
5
5
|
import { fetchSupplyGraph, graphOptions } from "./graph-client";
|
|
6
6
|
import { exposureLabel, pathLabel } from "./graph-model";
|
|
7
|
+
import { supplyRoleCounts } from "./model";
|
|
7
8
|
|
|
8
9
|
const pathColumns = [
|
|
9
10
|
{ key: "route", header: "Route" }, { key: "hops", header: "Hops" },
|
|
@@ -54,6 +55,7 @@ function graphReport(data: GraphPayload, target: string): HeadlessBundleResult {
|
|
|
54
55
|
|
|
55
56
|
export const supplyChainHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
56
57
|
shape: "bundle",
|
|
58
|
+
freshness: { source: "Company filings, calls and news", status: "not-a-feed", basis: "disclosed relationships" },
|
|
57
59
|
argument: { kind: "ticker", description: "Company ticker, exchange-qualified ticker, or id:<entity-id>.", placeholder: "ticker" },
|
|
58
60
|
discovery: { aliases: ["SPLC", "SUPPLY"], dataRequirements: ["Gloom Cloud relationship evidence (Pro with free preview)"],
|
|
59
61
|
limitations: ["Filings, company announcements, earnings calls and news where evidence is available globally", "Japan filings await an API key and Taiwan report ingestion is disabled", "English glosses are machine translations, separate from original evidence", "Absence is not proof of no relationship",
|
|
@@ -87,6 +89,9 @@ export const supplyChainHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
87
89
|
}
|
|
88
90
|
const options = supplyOptions(args.options.tiers);
|
|
89
91
|
const data = await fetchSupplyChain(args.symbols[0]!, ctx.apiClient, options);
|
|
92
|
+
// The pane's figures, per tab: Table shows one direction, Flow both.
|
|
93
|
+
const figures = (key: "counterparties" | "locked") => Object.fromEntries(([["says", ["says"]], ["names", ["names"]], ["flow", ["says", "names"]]] as const)
|
|
94
|
+
.map(([scope, views]) => [scope, Object.fromEntries(supplyRoleCounts(data, views, options).filter((entry) => entry[key] > 0).map((entry) => [entry.role, entry[key]]))]));
|
|
90
95
|
return { complete: !data.truncated, errors: data.truncated ? ["Additional relationships need Gloom Pro"] : [],
|
|
91
96
|
sections: (["says", "names"] as const).flatMap((view) => [false, true].map((leads) => ({ title: `${view === "says" ? `${data.symbol} says` : `Names ${data.symbol}`}${leads ? " | Unconfirmed" : ""}`,
|
|
92
97
|
rows: data[view].filter((row) => matchesSupplyOptions(row, options) && isUnconfirmed(row) === leads).map((row) => ({ counterparty: row.counterparty.name, ticker: row.counterparty.ticker, aggregate: row.counterparty.aggregate, role: row.role, direction: row.direction,
|
|
@@ -100,6 +105,7 @@ export const supplyChainHeadless: HeadlessPaneDefinition<"bundle"> = {
|
|
|
100
105
|
quote: row.quote, quoteLanguage: row.quoteLanguage, quoteGloss: row.quoteGloss ?? null, quoteGlossKind: row.quoteGloss ? "machine_translation" : null,
|
|
101
106
|
quoteMatchMode: row.quoteMatchMode, sourceUrl: row.filingUrl, filingUrl: row.filingUrl, sectionRef: row.sectionRef ?? null, sourceAttribution: row.sourceAttribution ?? null,
|
|
102
107
|
evidence: row.evidence ?? [] })) })).filter((section) => section.rows.length > 0)),
|
|
103
|
-
metadata: { symbol: data.symbol, asOf: data.asOf,
|
|
108
|
+
metadata: { symbol: data.symbol, asOf: data.asOf, counterparties: figures("counterparties"), locked: figures("locked"),
|
|
109
|
+
counts: data.counts, tierCounts: data.tierCounts, tiers: options.tiers, disclaimer: data.disclaimer } };
|
|
104
110
|
},
|
|
105
111
|
};
|
|
@@ -5,6 +5,11 @@ import { supplyChainCache } from "./client";
|
|
|
5
5
|
import { supplyChainHeadless } from "./headless";
|
|
6
6
|
import { SupplyChainPane } from "./pane";
|
|
7
7
|
|
|
8
|
+
/** What another pane can open SPLC on: a Graph or Path view, its target and its query, as `graphOptions` reads them. */
|
|
9
|
+
const OPENING_SETTINGS = ["tab", "to", "depth", "direction", "roles", "tiers"];
|
|
10
|
+
const openingSettings = (values: Record<string, string> = {}) =>
|
|
11
|
+
Object.fromEntries(OPENING_SETTINGS.flatMap((key) => values[key] ? [[key, values[key]]] : []));
|
|
12
|
+
|
|
8
13
|
export const supplyChainModule: PluginModule = {
|
|
9
14
|
setup(ctx) { supplyChainCache.attach(ctx.persistence); graphCache.attach(ctx.persistence); },
|
|
10
15
|
dispose() { supplyChainCache.reset(); graphCache.reset(); },
|
|
@@ -13,5 +18,9 @@ export const supplyChainModule: PluginModule = {
|
|
|
13
18
|
tickerFollower: true, tableExport: true, headless: supplyChainHeadless }],
|
|
14
19
|
paneTemplates: [{ ...createTickerSurfacePaneTemplate({ id: "supply-chain-pane", paneId: "supply-chain", label: "Supply Chain",
|
|
15
20
|
description: "Pro global supply chain evidence from filings, company announcements, calls and news, with trust tiers, original quotes, native units, four-hop graphs, ranked paths and a free preview.",
|
|
16
|
-
keywords: ["supply", "supply chain", "suppliers", "customers", "concentration", "filings", "earnings calls", "news", "evidence", "global", "Korea", "Japan", "Taiwan", "graph", "paths", "Pro"], shortcut: "SPLC", shortcutAliases: ["SUPPLY"]
|
|
21
|
+
keywords: ["supply", "supply chain", "suppliers", "customers", "concentration", "filings", "earnings calls", "news", "evidence", "global", "Korea", "Japan", "Taiwan", "graph", "paths", "Pro"], shortcut: "SPLC", shortcutAliases: ["SUPPLY"],
|
|
22
|
+
settings: (_symbol, _context, options) => openingSettings(options?.values),
|
|
23
|
+
// A route opened from another pane gets a pane of its own, so the company's SPLC keeps its view.
|
|
24
|
+
viewKey: (_symbol, _context, options) => options?.values?.to ? `${options.values.tab ?? "graph"}:${options.values.to}` : undefined,
|
|
25
|
+
}), headless: supplyChainHeadless }],
|
|
17
26
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { SupplyRole, SupplyRow } from "../../../api-client/supply-chain";
|
|
1
|
+
import type { SupplyChainPayload, SupplyOptions, SupplyRole, SupplyRow } from "../../../api-client/supply-chain";
|
|
2
2
|
import { SERIES_COLORS } from "../../../time-series/resolve";
|
|
3
3
|
import { revenueAmount } from "../revenue-breakdown/model";
|
|
4
|
-
import { activeRelationship, corroborationLabel, evidenceDate, evidenceLabel, isUnconfirmed, trustTier } from "./trust";
|
|
4
|
+
import { activeRelationship, corroborationLabel, evidenceDate, evidenceLabel, isUnconfirmed, matchesSupplyOptions, trustTier } from "./trust";
|
|
5
5
|
|
|
6
6
|
/** One colour per role from the shared series palette, the same in the table, the flow and the evidence. */
|
|
7
7
|
export const ROLE_COLORS: Record<SupplyRole, string> = {
|
|
@@ -64,6 +64,31 @@ export function counterpartyName(row: SupplyRow): string {
|
|
|
64
64
|
return member ? `${member.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s*\(undisclosed\)/gi, "")} (undisclosed)` : name;
|
|
65
65
|
}
|
|
66
66
|
export const roleLabel = (role: SupplyRole) => role[0]!.toUpperCase() + role.slice(1);
|
|
67
|
+
|
|
68
|
+
const SUPPLY_ROLE_ORDER: readonly SupplyRole[] = ["customer", "supplier", "partner", "competitor", "investee"];
|
|
69
|
+
export interface SupplyRoleCount { role: SupplyRole; counterparties: number; locked: number }
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The one count behind the figures over the table, the flow and the headless
|
|
73
|
+
* report: per role, the companies the reader can see, each counted once
|
|
74
|
+
* however many disclosures name it (the flow draws one card per counterparty
|
|
75
|
+
* and role). Unconfirmed leads, inactive links and cohort groups are not
|
|
76
|
+
* counterparties. The server's counts are disclosures, not companies, so what
|
|
77
|
+
* a free preview withholds is reported apart as locked disclosures rather
|
|
78
|
+
* than added to the companies.
|
|
79
|
+
*/
|
|
80
|
+
export function supplyRoleCounts(data: Pick<SupplyChainPayload, "says" | "names" | "counts">, views: readonly ("says" | "names")[], options: Required<SupplyOptions>): SupplyRoleCount[] {
|
|
81
|
+
return SUPPLY_ROLE_ORDER.map((role) => {
|
|
82
|
+
const companies = new Set<string>();
|
|
83
|
+
let locked = 0;
|
|
84
|
+
for (const view of views) {
|
|
85
|
+
const rows = data[view].filter((row) => row.role === role);
|
|
86
|
+
for (const row of rows) if (!row.counterparty.aggregate && !isUnconfirmed(row) && matchesSupplyOptions(row, options)) companies.add(row.counterparty.id);
|
|
87
|
+
locked += Math.max(0, data.counts[view][role] - rows.length);
|
|
88
|
+
}
|
|
89
|
+
return { role, counterparties: companies.size, locked };
|
|
90
|
+
}).filter((entry) => entry.counterparties > 0 || entry.locked > 0);
|
|
91
|
+
}
|
|
67
92
|
export const percentage = (row: SupplyRow) => row.pctOfRevenue === null || trustTier(row) !== 1 || isUnconfirmed(row) || !activeRelationship(row) ? "--" : `${Number(row.pctOfRevenue.toFixed(2))}% ${row.pctScope ? "scoped " : ""}${row.pctBasis ?? ""}`;
|
|
68
93
|
export const dollars = (row: SupplyRow) => row.usd === null ? "--" : `${row.usdBasis === "derived" ? "≈ " : ""}$${revenueAmount(row.usd)} ${row.usdBasis}`;
|
|
69
94
|
const scaleLabel = (scale: number) => scale === 1 ? "" : scale === 1_000 ? " thousand" : scale === 1_000_000 ? " million" : scale === 1_000_000_000 ? " billion" : ` ×${scale.toLocaleString("en-US")}`;
|
|
@@ -27,27 +27,46 @@ import { SupplyFlow } from "./flow";
|
|
|
27
27
|
import { SupplyGraphPane } from "./graph-pane";
|
|
28
28
|
import {
|
|
29
29
|
cellText, counterpartyKind, counterpartyKindLabel, counterpartyLabel, counterpartyName, disclosedValue, nativeValue, percentage, ROLE_COLORS, roleLabel,
|
|
30
|
-
shareParts, sortRows, type SupplySort,
|
|
30
|
+
shareParts, sortRows, supplyRoleCounts, type SupplySort,
|
|
31
31
|
} from "./model";
|
|
32
32
|
import { RowEvidence } from "./row-evidence";
|
|
33
33
|
import { evidenceDate, evidenceLabel, isUnconfirmed, matchesSupplyOptions, supplyOptions, TIER_OPTIONS } from "./trust";
|
|
34
34
|
|
|
35
35
|
type Item = { kind: "edge"; row: SupplyRow } | { kind: "locked"; id: string };
|
|
36
36
|
const itemId = (item: Item) => item.kind === "edge" ? item.row.id : item.id;
|
|
37
|
-
const ROLE_ORDER: SupplyRole[] = ["customer", "supplier", "partner", "competitor", "investee"];
|
|
38
37
|
const ROLE_PLURALS: Record<SupplyRole, string> = { customer: "Customers", supplier: "Suppliers", partner: "Partners", competitor: "Competitors", investee: "Investees" };
|
|
39
|
-
|
|
38
|
+
/** A share figure is at most five cells (`99.9%`, `100%`), right-aligned so the bars line up. */
|
|
39
|
+
const SHARE_FIGURE_CELLS = 5;
|
|
40
|
+
/** Bar, gap and figure: below this a share cell shows the figure alone. */
|
|
41
|
+
const SHARE_BAR_MIN_CELLS = 3 + 1 + SHARE_FIGURE_CELLS;
|
|
40
42
|
|
|
41
43
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* row
|
|
44
|
+
* Cells of a share column's bar: as long as the column allows after the figure
|
|
45
|
+
* and the longest basis that fits, between 3 and 8 cells, and the same on every
|
|
46
|
+
* row so the bars and figures line up. Zero leaves the figure alone.
|
|
45
47
|
*/
|
|
46
|
-
function
|
|
48
|
+
function shareBarCells(width: number, bases: readonly number[]): number {
|
|
49
|
+
if (width < SHARE_BAR_MIN_CELLS) return 0;
|
|
50
|
+
// Room for the longest basis that can show at all; a longer one gives way, not every bar.
|
|
51
|
+
const basis = longestBasis(bases, width);
|
|
52
|
+
return Math.min(width >= 36 ? 8 : 5, Math.max(3, width - SHARE_FIGURE_CELLS - 2 - basis));
|
|
53
|
+
}
|
|
54
|
+
const longestBasis = (bases: readonly number[], width: number) => Math.max(0, ...bases.filter((cells) => SHARE_BAR_MIN_CELLS + 1 + cells <= width));
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Columns that fit the pane, giving up the least first: the share bar shortens
|
|
58
|
+
* to keep the whole basis, the name shortens to 18 cells, the ticker folds into
|
|
59
|
+
* the name and the period is left to the evidence view; then the share drops
|
|
60
|
+
* its basis and its bar, and the name shortens further. Only a pane narrower
|
|
61
|
+
* than that scrolls sideways, so the pane edge never cuts a share in half.
|
|
62
|
+
* Value shows only when some row discloses a value, retaining its original
|
|
63
|
+
* currency and units.
|
|
64
|
+
*/
|
|
65
|
+
function tableColumns(width: number, desktop: boolean, locked: boolean, valueWidth: number | null, bases: readonly number[]): DataTableColumn[] {
|
|
47
66
|
const wide = width >= 150, medium = width >= 110;
|
|
48
67
|
const name: DataTableColumn = { id: "name", label: "Counterparty", width: Math.max(locked && !desktop ? 34 : 0, wide ? 30 : medium ? 26 : 20), flexGrow: 1, align: "left" };
|
|
49
68
|
const share: DataTableColumn = { id: "pct", label: "Share", width: wide ? 34 : medium ? 30 : 26, align: "left" };
|
|
50
|
-
|
|
69
|
+
let columns: DataTableColumn[] = [
|
|
51
70
|
name,
|
|
52
71
|
{ id: "evidence", label: "Evidence", width: 12, align: "left" },
|
|
53
72
|
...(medium ? [{ id: "ticker", label: "Ticker", width: 8, align: "left" as const }] : []),
|
|
@@ -61,40 +80,57 @@ function tableColumns(width: number, desktop: boolean, locked: boolean, valueWid
|
|
|
61
80
|
{ id: "corroboration", label: "Origins", width: 8, align: "right" as const },
|
|
62
81
|
] : []),
|
|
63
82
|
];
|
|
64
|
-
|
|
83
|
+
const preferred = { share: share.width, name: name.width };
|
|
65
84
|
// The table ignores its last trailing gutter when deciding whether it fits.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
85
|
+
const overflow = () => getTableWidth(columns) - width - 1;
|
|
86
|
+
// Native units keep their column before the share keeps its bar or basis.
|
|
87
|
+
const shareFloor = valueWidth !== null ? SHARE_BAR_MIN_CELLS + 1 : SHARE_BAR_MIN_CELLS + 1 + longestBasis(bases, preferred.share);
|
|
88
|
+
const fit = (shareMin: number, nameMin = 18) => {
|
|
89
|
+
share.width = preferred.share; name.width = preferred.name;
|
|
90
|
+
share.width = Math.max(shareMin, share.width - Math.max(0, overflow()));
|
|
91
|
+
name.width = Math.max(nameMin, name.width - Math.max(0, overflow()));
|
|
92
|
+
};
|
|
93
|
+
fit(shareFloor);
|
|
94
|
+
for (const id of ["ticker", "fy"]) {
|
|
95
|
+
if (overflow() <= 0) break;
|
|
96
|
+
if (!columns.some((column) => column.id === id)) continue;
|
|
97
|
+
columns = columns.filter((column) => column.id !== id);
|
|
98
|
+
fit(shareFloor);
|
|
69
99
|
}
|
|
100
|
+
// The narrowest panes keep the figure alone, then a shorter name, before anything scrolls.
|
|
101
|
+
if (overflow() > 0) fit(SHARE_BAR_MIN_CELLS);
|
|
102
|
+
if (overflow() > 0) fit(SHARE_FIGURE_CELLS + 2, 12);
|
|
70
103
|
return columns;
|
|
71
104
|
}
|
|
72
105
|
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Company, then the counterparties per role on this tab, with how many
|
|
108
|
+
* disclosures a free preview locks: the strip that heads the table and the flow.
|
|
109
|
+
*/
|
|
110
|
+
function supplyFigures(data: SupplyChainPayload, views: readonly ("says" | "names")[], options: Required<SupplyOptions>): StatItem[] {
|
|
76
111
|
return [
|
|
77
112
|
...(data.entity ? [{ id: "company", label: "Company", value: data.entity.name }] : []),
|
|
78
|
-
...
|
|
79
|
-
|
|
80
|
-
const count = data.truncated && !flow && !options.includeLeads ? views.reduce((total, view) => total + data.counts[view][role], 0) : visible;
|
|
81
|
-
return count ? [{ id: role, label: ROLE_PLURALS[role], value: String(count), color: ROLE_COLORS[role],
|
|
82
|
-
detail: visible < count ? `${visible} shown` : undefined }] : [];
|
|
83
|
-
}),
|
|
113
|
+
...supplyRoleCounts(data, views, options).map(({ role, counterparties, locked }) => ({ id: role, label: ROLE_PLURALS[role], value: String(counterparties),
|
|
114
|
+
color: ROLE_COLORS[role], detail: locked ? `+${locked} locked` : undefined })),
|
|
84
115
|
];
|
|
85
116
|
}
|
|
86
117
|
|
|
87
|
-
/**
|
|
88
|
-
|
|
118
|
+
/**
|
|
119
|
+
* The share as a bar on a 0 to 100% scale, the figure, and what it is a share
|
|
120
|
+
* of. The basis shows whole or not at all: a column too narrow for it keeps
|
|
121
|
+
* the bar and figure, and the evidence view says the rest.
|
|
122
|
+
*/
|
|
123
|
+
function ShareCell({ row, focusId, width, bases, selected }: { row: SupplyRow; focusId?: string; width: number; bases: readonly number[]; selected: boolean }) {
|
|
89
124
|
const colors = useThemeColors();
|
|
90
125
|
const share = shareParts(row, focusId);
|
|
91
126
|
if (!share) return <Text fg={colors.textMuted}>{""}</Text>;
|
|
92
|
-
|
|
93
|
-
|
|
127
|
+
const bar = shareBarCells(width, bases);
|
|
128
|
+
if (!bar) return <Text fg={selected ? colors.selectedText : colors.textBright} attributes={TextAttributes.BOLD}>{share.value}</Text>;
|
|
129
|
+
const basis = bar + SHARE_FIGURE_CELLS + 2 + displayWidth(share.basis) <= width;
|
|
94
130
|
return <Box flexDirection="row" width={width} height={1} gap={1} overflow="hidden">
|
|
95
|
-
<RatioBar ratio={row.pctOfRevenue! / 100} width={
|
|
96
|
-
<Text fg={selected ? colors.selectedText : colors.textBright} attributes={TextAttributes.BOLD}>{share.value.padStart(
|
|
97
|
-
<Text fg={selected ? colors.selectedText : colors.textDim}>{
|
|
131
|
+
<RatioBar ratio={row.pctOfRevenue! / 100} width={bar} color={ROLE_COLORS[row.role]} track />
|
|
132
|
+
<Text fg={selected ? colors.selectedText : colors.textBright} attributes={TextAttributes.BOLD}>{share.value.padStart(SHARE_FIGURE_CELLS)}</Text>
|
|
133
|
+
{basis ? <Text fg={selected ? colors.selectedText : colors.textDim}>{share.basis}</Text> : null}
|
|
98
134
|
</Box>;
|
|
99
135
|
}
|
|
100
136
|
|
|
@@ -180,7 +216,8 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
180
216
|
const focusId = data?.entity?.id;
|
|
181
217
|
const values = rows.filter((row) => nativeValue(row) !== null || row.usd !== null);
|
|
182
218
|
const valueWidth = values.length ? Math.min(28, Math.max(...values.map((row) => displayWidth(disclosedValue(row).replace(/ (disclosed|derived)$/, ""))))) : null;
|
|
183
|
-
const
|
|
219
|
+
const bases = rows.flatMap((row) => { const share = shareParts(row, focusId); return share ? [displayWidth(share.basis)] : []; });
|
|
220
|
+
const columns = tableColumns(width, desktop, locked > 0, valueWidth, bases);
|
|
184
221
|
const renderCell = (entry: SectionedRow<Item>, column: DataTableColumn, _index: number, state: { selected: boolean }): DataTableCell => {
|
|
185
222
|
if (!isSectionedItemRow(entry)) return { text: "" };
|
|
186
223
|
const item = entry.item;
|
|
@@ -222,7 +259,7 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
222
259
|
<Text fg={ink ?? ROLE_COLORS[row.role]}>{` ${roleLabel(row.role)}`}</Text>
|
|
223
260
|
</Box> };
|
|
224
261
|
case "pct": return { text: percentage(row) === "--" ? "" : `${shareParts(row, focusId)?.value ?? ""} ${shareParts(row, focusId)?.basis ?? ""}`.trim(), value: row.pctOfRevenue,
|
|
225
|
-
content: <ShareCell row={row} focusId={focusId} width={column.width} selected={state.selected} /> };
|
|
262
|
+
content: <ShareCell row={row} focusId={focusId} width={column.width} bases={bases} selected={state.selected} /> };
|
|
226
263
|
case "usd": return nativeValue(row) === null && row.usd === null ? { text: "", value: null }
|
|
227
264
|
: { text: disclosedValue(row).replace(/ (disclosed|derived)$/, ""), value: row.nativeAmount != null ? row.nativeAmount * (row.nativeScale ?? 1) : row.usd, color: colors.text };
|
|
228
265
|
case "fy": return { text: row.period, color: colors.textDim };
|
|
@@ -233,7 +270,7 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
233
270
|
if (graphTab) return <Box width={width} height={height} flexDirection="column">{strip}<SupplyGraphPane symbol={symbol} tab={savedTab as "graph" | "path"} width={width} height={Math.max(3, height - tabRows)} focused={focused} /></Box>;
|
|
234
271
|
if (!data && isCloudSessionRequired(resource.error)) return <SignInWall placement="supply-chain-signin" action="view supply chain disclosures" needsVerification={session.needsVerification} />;
|
|
235
272
|
const bodyHeight = Math.max(3, height - tabRows);
|
|
236
|
-
const figures = data ? supplyFigures(data, tab === "flow" ? ["says", "names"] : [view], options
|
|
273
|
+
const figures = data ? supplyFigures(data, tab === "flow" ? ["says", "names"] : [view], options) : [];
|
|
237
274
|
const tierFilter = { id: "tiers", label: "Evidence", kind: "multi" as const, emptyLabel: "Primary", values: options.tiers, options: TIER_OPTIONS, onChange: (value: string[]) => { setTiers(supplyOptions(value).tiers); setSelected(null); setOpen(null); } };
|
|
238
275
|
const header = <Box flexDirection="column" flexShrink={0}>
|
|
239
276
|
<QueryBar width={width} filters={[{ id: "direction", label: "Direction", inline: true, value: view,
|
|
@@ -263,7 +300,9 @@ function SupplyView({ symbol, width, height, focused }: Pick<PaneProps, "width"
|
|
|
263
300
|
</Box> : <DataTableView<SectionedRow<Item>> columns={columns}
|
|
264
301
|
items={items} focused={focused && !openRow} rootWidth={width} rootHeight={bodyHeight} rootBefore={header}
|
|
265
302
|
selection={{ kind: "id", selectedId: selected?.id ?? null, getId: (entry) => entry.key, onChange: (id) => setSelected(id) }} getItemKey={(entry) => entry.key}
|
|
266
|
-
isNavigable={isSectionedItemRow}
|
|
303
|
+
isNavigable={isSectionedItemRow}
|
|
304
|
+
// The placeholders stand for every locked disclosure; the header counts those, as the figures do.
|
|
305
|
+
renderSectionHeader={(entry) => entry.kind === "section" && entry.label === "Pro" ? { text: `Pro (${locked})` } : renderSectionedRowHeader(entry)}
|
|
267
306
|
onActivate={(entry) => { if (isSectionedItemRow(entry)) entry.item.kind === "edge" ? navigate(entry.item.row) : openUpgrade(); }}
|
|
268
307
|
renderCell={renderCell} sortColumnId={sort.column} sortDirection={sort.direction}
|
|
269
308
|
onHeaderClick={(column) => setSort((old) => ({ column, direction: old.column === column && old.direction === "desc" ? "asc" : "desc" }))}
|
|
@@ -6,6 +6,9 @@ import { aggregateText, DEFAULT_SORT, matchTheme, memberPrice, percent, PERIOD_L
|
|
|
6
6
|
const periods: HeadlessPaneColumn[] = THEME_PERIODS.map((key) => ({ key, header: PERIOD_LABELS[key], align: "right", format: (value) => percent(value as number | null) }));
|
|
7
7
|
export const themesHeadless: HeadlessPaneDefinition<"rows"> = {
|
|
8
8
|
shape: "rows",
|
|
9
|
+
// The pane's stored snapshot: 15-minute delayed prices, refreshed every 15 minutes. As in the pane,
|
|
10
|
+
// the payload's stale flags are historical; a snapshot over 30 minutes old is what reads stale.
|
|
11
|
+
freshness: { status: "delayed", delayMinutes: 15, maxAgeMinutes: 30, ignoreStaleFlags: true },
|
|
9
12
|
argument: { kind: "free-text", optional: true, placeholder: "theme", description: "Theme name or keyword, such as nuclear; omit for all themes." },
|
|
10
13
|
options: [],
|
|
11
14
|
discovery: { aliases: ["THEM"], dataRequirements: ["Gloom Cloud stored equity snapshot"],
|