gloomberb 0.16.4 → 0.16.6
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 +14 -91
- package/package.json +5 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
- package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
- package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/central-bank-rates.ts +6 -1
- package/src/api-client/chat.ts +26 -0
- package/src/api-client/credit-boards.ts +2 -0
- package/src/api-client/data.ts +73 -3
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/europe-energy.ts +106 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +13 -1
- package/src/api-client/market-discovery.ts +13 -1
- package/src/api-client/normalizers.ts +32 -0
- package/src/api-client/paths.ts +7 -0
- package/src/api-client/perps.ts +8 -0
- package/src/api-client/request.ts +9 -2
- package/src/api-client/research-activity.ts +15 -10
- package/src/api-client/socket.ts +29 -0
- package/src/api-client/themes.ts +22 -1
- package/src/api-client/types.ts +78 -2
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +50 -2
- package/src/app/keybindings/actions.ts +12 -1
- package/src/app/pane-runtime/plugin-bindings.ts +2 -2
- package/src/app/pane-runtime/ticker-open-runtime.ts +16 -6
- package/src/app/runtime/desktop-deeplink.ts +10 -5
- package/src/app/runtime/startup.ts +1 -1
- package/src/app.tsx +6 -0
- package/src/architecture/core-builtin-allowlist.json +8 -26
- package/src/ask-gloom/pane-context.ts +114 -0
- package/src/ask-gloom/pane-request.ts +70 -0
- package/src/ask-gloom/pane-text.ts +201 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
- package/src/capabilities/chart-series.ts +19 -2
- package/src/capabilities/factories.ts +1 -0
- package/src/cli/central-bank-events.ts +23 -0
- package/src/cli/command-options.ts +17 -5
- package/src/cli/commands/crypto-hints.ts +35 -2
- package/src/cli/commands/fred-series.ts +146 -0
- package/src/cli/commands/market.ts +501 -115
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-leaps.ts +5 -2
- package/src/cli/commands/overview.ts +132 -26
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +317 -13
- package/src/cli/commands/system.ts +55 -8
- package/src/cli/commands/ticker.ts +155 -18
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +76 -7
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +7 -5
- package/src/cli/exit-codes.ts +8 -0
- package/src/cli/export-source.ts +58 -0
- package/src/cli/freshness.ts +18 -7
- package/src/cli/glossary.ts +483 -0
- package/src/cli/help.ts +10 -0
- package/src/cli/helpers.ts +2 -5
- package/src/cli/history-rows.ts +118 -7
- package/src/cli/index-roots.ts +7 -0
- package/src/cli/index.ts +29 -9
- package/src/cli/known-gaps.ts +84 -0
- package/src/cli/listing-arg.ts +551 -97
- package/src/cli/not-a-ticker.ts +24 -9
- package/src/cli/pane-functions/access-gate.ts +13 -2
- package/src/cli/pane-functions/capabilities.ts +4 -3
- package/src/cli/pane-functions/catalog.ts +214 -40
- package/src/cli/pane-functions/data.ts +42 -8
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +37 -8
- package/src/cli/pane-functions/freshness.ts +393 -49
- package/src/cli/pane-functions/function-help.ts +31 -15
- package/src/cli/pane-functions/headless.ts +98 -30
- package/src/cli/pane-functions/index.ts +101 -19
- package/src/cli/pane-functions/market-session.ts +22 -8
- package/src/cli/pane-functions/options.ts +71 -22
- package/src/cli/pane-functions/report-notices.ts +25 -7
- package/src/cli/pane-functions/report.ts +15 -8
- package/src/cli/pane-functions/resolver.ts +74 -19
- package/src/cli/pane-functions/screenshot.ts +250 -27
- package/src/cli/perpetual-contract.ts +60 -0
- package/src/cli/registry.ts +3 -1
- package/src/cli/report-tables.ts +26 -7
- package/src/cli/result.ts +45 -11
- package/src/cli/series-search.ts +111 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +27 -0
- package/src/cli/symbol-list.ts +154 -0
- package/src/cli/symbol-rows.ts +154 -0
- package/src/cli/ticker-resolution.ts +311 -27
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +14 -3
- package/src/components/chart/composite/composite-chart.tsx +71 -11
- package/src/components/chart/composite/crosshair-readout.tsx +150 -0
- package/src/components/chart/composite/downsample.ts +1 -1
- package/src/components/chart/composite/format.ts +29 -0
- package/src/components/chart/composite/interactions.ts +9 -2
- package/src/components/chart/composite/legend.tsx +100 -33
- package/src/components/chart/composite/panel-bitmap.ts +70 -35
- package/src/components/chart/composite/panel-labels.ts +18 -17
- package/src/components/chart/composite/panel-series.ts +1 -0
- package/src/components/chart/composite/panel-surface.tsx +46 -21
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +50 -8
- package/src/components/chart/composite/scene.ts +2 -1
- package/src/components/chart/composite/time-scale.ts +26 -9
- package/src/components/chart/composite/types.ts +18 -0
- package/src/components/chart/composite/use-composite-viewport.ts +30 -2
- package/src/components/chart/native/raster/crosshair.ts +8 -3
- package/src/components/chart/native/raster/primitives.ts +85 -21
- package/src/components/chart/native/surface/manager.ts +33 -8
- package/src/components/chart/surface3d/chart.tsx +1 -1
- package/src/components/command-bar/action-runtime.ts +1 -1
- package/src/components/command-bar/commands/collection-list.ts +210 -0
- package/src/components/command-bar/commands/collection.ts +40 -1
- package/src/components/command-bar/commands/direct/index.ts +4 -0
- package/src/components/command-bar/commands/registry.ts +8 -0
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/routing/actions.ts +1 -1
- package/src/components/command-bar/workflow/tickers.ts +42 -17
- package/src/components/layout/detached-pane-shell.tsx +68 -39
- package/src/components/layout/floating-pane.tsx +10 -1
- package/src/components/layout/header.tsx +25 -5
- package/src/components/layout/missing-pane.tsx +3 -3
- package/src/components/layout/pane/capture-stamp.ts +41 -0
- package/src/components/layout/pane/capture-status.ts +12 -0
- package/src/components/layout/pane/content.tsx +7 -13
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/keyboard.ts +3 -0
- package/src/components/layout/pane/footer/model.ts +41 -1
- package/src/components/layout/pane/header.tsx +50 -1
- package/src/components/layout/pane/index.tsx +21 -3
- package/src/components/layout/pane/sidebar.tsx +88 -21
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/cursor-occlusion.ts +2 -1
- package/src/components/layout/shell/drag/index.ts +39 -9
- package/src/components/layout/shell/drag/live.ts +61 -51
- package/src/components/layout/shell/drag/runtime.ts +54 -12
- package/src/components/layout/shell/index.tsx +84 -65
- package/src/components/layout/shell/menu.ts +14 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +32 -10
- package/src/components/layout/shell/pane/ask.ts +131 -0
- package/src/components/layout/shell/pane/capture.ts +162 -0
- package/src/components/layout/shell/pane/layers.tsx +218 -50
- package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
- package/src/components/layout/shell/shortcuts.ts +21 -4
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/markdown-text.tsx +62 -20
- package/src/components/metric-treemap/heat-surface.tsx +8 -1
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +2 -2
- package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/reader/article-reader.tsx +642 -0
- package/src/components/reader/article-text.ts +527 -0
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +43 -2
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +7 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +18 -6
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +12 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +6 -1
- package/src/components/ui/query-bar.tsx +10 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/normalize.ts +7 -2
- package/src/data/config/store/portfolio-as-of-column.ts +57 -0
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7555 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +65 -5
- package/src/i18n/ja.ts +65 -5
- package/src/i18n/ko.ts +65 -5
- package/src/i18n/zh-cn.ts +65 -5
- package/src/i18n/zh-tw.ts +65 -5
- package/src/layout/desks.ts +1 -1
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/index.ts +1 -0
- package/src/layout-marketplace/gallery.tsx +1 -1
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +84 -20
- package/src/market-data/market/session-close-note.ts +3 -2
- package/src/market-data/market/status.ts +19 -23
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +5 -0
- package/src/market-data/quotes/metadata.ts +19 -24
- package/src/market-data/quotes/resolution.ts +5 -0
- package/src/market-data/quotes/screener-live-quotes.ts +5 -4
- package/src/market-data/result-types.ts +2 -0
- package/src/notifications/app-notifier.ts +17 -1
- package/src/notifications/notification-log.ts +180 -0
- package/src/plugins/auto-update-node.ts +2 -2
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/model.ts +1 -56
- package/src/plugins/builtin/account-management/pane.tsx +6 -4
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/catalysts.ts +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/focus.ts +27 -0
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +47 -11
- package/src/plugins/builtin/alerts/pane.tsx +27 -1
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +8 -3
- package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +35 -5
- package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
- package/src/plugins/builtin/attention/headless.ts +1 -1
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/headless.ts +88 -18
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/model.ts +41 -1
- package/src/plugins/builtin/awards/pane.tsx +22 -13
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/headless.ts +2 -2
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/index.tsx +1 -0
- package/src/plugins/builtin/catalysts/headless.ts +1 -1
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +49 -12
- package/src/plugins/builtin/cds/headless.ts +119 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +214 -32
- package/src/plugins/builtin/cds/pane.tsx +58 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
- package/src/plugins/builtin/central-bank-rates/index.tsx +3 -1
- package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
- package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
- package/src/plugins/builtin/central-bank-rates/series.ts +36 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless-schema.ts +1 -1
- package/src/plugins/builtin/chart-composer/headless.ts +70 -5
- package/src/plugins/builtin/chart-composer/index.tsx +15 -3
- package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
- package/src/plugins/builtin/chat/content/composer.tsx +5 -1
- package/src/plugins/builtin/chat/content/footer.tsx +12 -0
- package/src/plugins/builtin/chat/content/index.tsx +89 -5
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
- package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
- package/src/plugins/builtin/chat/content/scroll.ts +127 -27
- package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
- package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
- package/src/plugins/builtin/chat/content/types.ts +1 -0
- package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
- package/src/plugins/builtin/chat/controller/index.ts +123 -1
- package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
- package/src/plugins/builtin/chat/controller/messages.ts +7 -2
- package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
- package/src/plugins/builtin/chat/controller/send.ts +61 -1
- package/src/plugins/builtin/chat/controller/state.ts +8 -0
- package/src/plugins/builtin/chat/ghost-user.ts +20 -0
- package/src/plugins/builtin/chat/index.tsx +23 -5
- package/src/plugins/builtin/chat/layout.ts +78 -5
- package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
- package/src/plugins/builtin/chat/message/header.tsx +16 -4
- package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
- package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
- package/src/plugins/builtin/chat/message/render-state.ts +18 -2
- package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
- package/src/plugins/builtin/chat/message/types.ts +12 -0
- package/src/plugins/builtin/chat/reactions.ts +197 -0
- package/src/plugins/builtin/chat/share/flow.tsx +87 -0
- package/src/plugins/builtin/chat/share/targets.ts +27 -0
- package/src/plugins/builtin/chat/status-widget.tsx +6 -3
- package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
- package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
- package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
- package/src/plugins/builtin/cloud/askg/model.ts +27 -8
- package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
- package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
- package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
- package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
- package/src/plugins/builtin/cloud/plugin.tsx +19 -2
- package/src/plugins/builtin/cloud/team/model.ts +5 -0
- package/src/plugins/builtin/cloud/team/module.tsx +1 -0
- package/src/plugins/builtin/cloud/team/store.ts +8 -3
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +21 -7
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/headless.ts +97 -10
- package/src/plugins/builtin/company-kpis/model.ts +24 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +17 -16
- package/src/plugins/builtin/composite-plugins.ts +19 -13
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +1 -1
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/cpi/headless.ts +3 -3
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
- package/src/plugins/builtin/credit-boards/client.ts +6 -2
- package/src/plugins/builtin/credit-boards/headless.ts +108 -31
- package/src/plugins/builtin/credit-boards/index.tsx +2 -0
- package/src/plugins/builtin/credit-boards/model.ts +11 -1
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-conditions/client.ts +12 -9
- package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
- package/src/plugins/builtin/credit-conditions/index.tsx +18 -9
- package/src/plugins/builtin/credit-conditions/model.ts +19 -11
- package/src/plugins/builtin/credit-conditions/series.ts +16 -0
- package/src/plugins/builtin/credit-documents/headless.ts +33 -3
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/client.ts +3 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/dividend-yield/types.ts +2 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/headless.ts +12 -8
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/earnings/index.tsx +9 -0
- package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
- package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
- package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
- package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +2 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/equity-screener/headless.ts +3 -3
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
- package/src/plugins/builtin/exposure/drivers.ts +13 -0
- package/src/plugins/builtin/exposure/headless.ts +205 -13
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/index.tsx +1 -0
- package/src/plugins/builtin/exposure/model.ts +23 -3
- package/src/plugins/builtin/exposure/pane.tsx +14 -12
- package/src/plugins/builtin/fear-greed/index.tsx +18 -10
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +71 -10
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/client.ts +63 -0
- package/src/plugins/builtin/fx-matrix/export.ts +2 -1
- package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
- package/src/plugins/builtin/fx-matrix/index.tsx +4 -4
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +58 -27
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +101 -16
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/function-index.ts +2 -0
- package/src/plugins/builtin/help/index.tsx +31 -9
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +36 -133
- package/src/plugins/builtin/holders/pane.tsx +11 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +26 -9
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
- package/src/plugins/builtin/iv-history/client.ts +20 -6
- package/src/plugins/builtin/iv-history/format.ts +9 -0
- package/src/plugins/builtin/iv-history/headless.ts +56 -21
- package/src/plugins/builtin/iv-history/index.tsx +2 -0
- package/src/plugins/builtin/iv-history/model.ts +143 -8
- package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +26 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/macro-day/client.ts +44 -3
- package/src/plugins/builtin/macro-day/headless.ts +13 -10
- package/src/plugins/builtin/macro-day/model.ts +56 -10
- package/src/plugins/builtin/macro-day/pane.tsx +30 -20
- package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
- package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
- package/src/plugins/builtin/market-heatmap/model.ts +19 -11
- package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/index.tsx +3 -2
- package/src/plugins/builtin/market-movers/model.ts +30 -0
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +8 -3
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +6 -8
- package/src/plugins/builtin/mna/distress/headless.ts +4 -4
- package/src/plugins/builtin/mna/headless.ts +18 -6
- package/src/plugins/builtin/money-markets/headless.ts +5 -4
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/news/index.tsx +0 -2
- package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
- package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/notes/index.tsx +1 -0
- package/src/plugins/builtin/options/index.tsx +3 -0
- package/src/plugins/builtin/options/view.tsx +1 -1
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +4 -3
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +2 -1
- package/src/plugins/builtin/options-scenario/headless.ts +1 -0
- package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
- package/src/plugins/builtin/perps/client.ts +90 -16
- package/src/plugins/builtin/perps/equity-row.tsx +52 -17
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +47 -32
- package/src/plugins/builtin/perps/index.tsx +23 -4
- package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
- package/src/plugins/builtin/perps/model.ts +20 -5
- package/src/plugins/builtin/perps/open-market.ts +15 -0
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
- package/src/plugins/builtin/plugin-module.ts +3 -0
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
- package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +161 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
- package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
- package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +52 -9
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
- package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
- package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +9 -4
- package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +63 -10
- package/src/plugins/builtin/power/headless.ts +77 -9
- package/src/plugins/builtin/power/index.tsx +28 -3
- package/src/plugins/builtin/power/model.ts +73 -2
- package/src/plugins/builtin/power/pane.tsx +37 -9
- package/src/plugins/builtin/power/prices-client.ts +139 -0
- package/src/plugins/builtin/power/prices-headless.ts +137 -0
- package/src/plugins/builtin/power/prices-model.ts +103 -0
- package/src/plugins/builtin/power/prices.tsx +179 -0
- package/src/plugins/builtin/rate-path/headless.ts +46 -18
- package/src/plugins/builtin/realized-vol/headless.ts +5 -0
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/research/index.tsx +2 -0
- package/src/plugins/builtin/research-search/article.ts +65 -0
- package/src/plugins/builtin/research-search/document-view.tsx +33 -215
- package/src/plugins/builtin/research-search/model.ts +0 -9
- package/src/plugins/builtin/research-search/pane.tsx +41 -30
- package/src/plugins/builtin/research-search/snippet.ts +0 -29
- package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/sec/headless.ts +25 -3
- package/src/plugins/builtin/sec/index.tsx +2 -1
- package/src/plugins/builtin/series-inventory.ts +93 -0
- package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +30 -12
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/free-preview.ts +47 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +12 -1
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/volatility/options.ts +4 -1
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +2 -0
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +2 -1
- package/src/plugins/builtin/short-volume/index.tsx +2 -0
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/headless.ts +1 -1
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/headless.ts +43 -11
- package/src/plugins/builtin/supply-chain/model.ts +13 -0
- package/src/plugins/builtin/supply-chain/pane.tsx +8 -6
- package/src/plugins/builtin/themes/headless.ts +74 -10
- package/src/plugins/builtin/themes/model.ts +71 -4
- package/src/plugins/builtin/themes/pane.tsx +22 -5
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +114 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
- package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +49 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +2 -1
- package/src/plugins/builtin/time-sales/index.tsx +2 -1
- package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
- package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
- package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
- package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
- package/src/plugins/builtin/vol-surface/headless.ts +51 -17
- package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
- package/src/plugins/builtin/vol-surface/model.ts +39 -6
- package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
- package/src/plugins/builtin/vol-surface/stored.ts +63 -3
- package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
- package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
- package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
- package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +2 -1
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +144 -13
- package/src/plugins/builtin/world-venue-map/model.ts +56 -19
- package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +4 -2
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/installer.ts +2 -2
- package/src/plugins/loader.ts +15 -0
- package/src/plugins/manager-node.ts +1 -1
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +6 -6
- package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
- package/src/plugins/registry/host-actions.ts +11 -0
- package/src/plugins/registry/index.ts +89 -4
- package/src/portfolio/collection-name.ts +31 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/portfolio/valuation-basis.ts +79 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/react/input.ts +33 -1
- package/src/react/key-repeat.ts +86 -0
- package/src/remote/app-host.tsx +20 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +144 -7
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +65 -2
- package/src/remote/types.ts +30 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +4 -3
- package/src/renderers/browser/research-entry.ts +4 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +30 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +16 -0
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
- package/src/renderers/dom/host/box.tsx +8 -0
- package/src/renderers/dom/host/chart-surface.tsx +33 -2
- package/src/renderers/dom/host/live-frame.ts +6 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/scroll-box.tsx +32 -0
- package/src/renderers/dom/host/size-observer.ts +41 -0
- package/src/renderers/dom/host/sticky-scroll.ts +128 -0
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/surface-3d.tsx +19 -7
- package/src/renderers/dom/host/surface-fit.ts +406 -0
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +1 -0
- package/src/renderers/dom/styles.css +102 -5
- package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
- package/src/renderers/electrobun/bun/index.ts +3 -2
- package/src/renderers/electrobun/shared/protocol.ts +1 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +5 -3
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
- package/src/renderers/opentui/chart-surface.tsx +1 -0
- package/src/renderers/opentui/frame-capture.ts +33 -0
- package/src/renderers/opentui/host.tsx +10 -13
- package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
- package/src/renderers/opentui/pane-image/glyphs.json +1 -0
- package/src/renderers/opentui/pane-image/index.ts +107 -0
- package/src/renderers/opentui/pane-image/raster.ts +428 -0
- package/src/renderers/opentui/start.tsx +3 -3
- package/src/renderers/opentui/test-utils.tsx +3 -0
- package/src/renderers/opentui/ui-host.tsx +29 -1
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +108 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +153 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/chat.ts +34 -0
- package/src/shares/dialog.tsx +295 -0
- package/src/shares/flow.tsx +56 -0
- package/src/shares/live.ts +14 -22
- package/src/shares/pane-image.ts +152 -0
- package/src/shares/personal-pane.ts +64 -0
- package/src/shares/portable-layout.ts +4 -2
- package/src/shares/prepare.ts +20 -0
- package/src/sources/gloomberb-cloud/index.ts +109 -10
- package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
- package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
- package/src/sources/history-result.ts +1 -0
- package/src/sources/history-retention.ts +11 -0
- package/src/sources/listing-symbols.ts +4 -1
- package/src/sources/listing-target.ts +4 -0
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +1 -1
- package/src/sources/provider-router/financial-routes.ts +1 -0
- package/src/sources/provider-router/financials.ts +13 -0
- package/src/sources/provider-router/history.ts +43 -25
- package/src/sources/provider-router/index.ts +14 -0
- package/src/sources/provider-router/search.ts +1 -0
- package/src/state/hooks/inline-tickers.ts +49 -11
- package/src/sync/core-contributors.ts +1 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/theme-context.tsx +15 -1
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +34 -1
- package/src/tickers/listing-name.ts +34 -0
- package/src/tickers/listing-venues.ts +132 -0
- package/src/tickers/open-target.ts +13 -4
- package/src/tickers/perpetual-listing.ts +151 -0
- package/src/tickers/prediction-listing.ts +26 -0
- package/src/tickers/search/index.ts +72 -11
- package/src/tickers/search/ranking.ts +98 -20
- package/src/tickers/search/types.ts +7 -1
- package/src/tickers/ticker-changes.ts +213 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/economic.ts +2 -6
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/ice-credit.ts +39 -0
- package/src/time-series/resolve.ts +211 -29
- package/src/time-series/studies.ts +1 -0
- package/src/time-series/types.ts +12 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +10 -2
- package/src/types/data-provider.ts +11 -0
- package/src/types/financials.ts +62 -1
- package/src/types/headless.ts +113 -0
- package/src/types/instrument.ts +4 -0
- package/src/types/plugin.ts +52 -2
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker-changes.ts +26 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/context-menu.tsx +13 -1
- package/src/ui/host.tsx +57 -3
- package/src/ui/live-resize.ts +91 -0
- package/src/ui/live-stretch.ts +153 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/sticky-scroll.ts +7 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/central-banks.ts +76 -0
- package/src/utils/cli-output.ts +131 -15
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/currency-units.ts +11 -0
- package/src/utils/datetime-format.ts +27 -6
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +439 -52
- package/src/utils/double-escape-close.ts +15 -1
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +143 -1
- package/src/utils/format.ts +35 -5
- package/src/utils/forward-dividend.ts +14 -0
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +15 -5
- package/src/utils/fx-status.ts +6 -1
- package/src/utils/inline-content-tokenizer.ts +22 -3
- package/src/utils/market-capitalization.ts +8 -0
- package/src/utils/one-shot.ts +73 -0
- package/src/utils/options.ts +37 -8
- package/src/utils/price-history.ts +99 -42
- package/src/utils/sec-eps-basis.ts +24 -11
- package/src/utils/sec.ts +61 -7
- package/src/utils/utc-time.ts +63 -4
- package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
- /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
- /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
|
@@ -18,6 +18,7 @@ import type { TickerRecord } from "../../../../types/ticker";
|
|
|
18
18
|
import { addTickerToPortfolio, addTickerToWatchlist } from "../mutations";
|
|
19
19
|
import { captureAttentionAction } from "../../../../telemetry/attention-counts";
|
|
20
20
|
import { publicTickerKey } from "../../../../utils/exchanges";
|
|
21
|
+
import { tickerChangeLine } from "../../../../tickers/ticker-changes";
|
|
21
22
|
import {
|
|
22
23
|
IDLE_VALIDATION,
|
|
23
24
|
isPlausibleTickerQuery,
|
|
@@ -30,6 +31,8 @@ import {
|
|
|
30
31
|
} from "./resolution";
|
|
31
32
|
|
|
32
33
|
const QUICK_ADD_DEBOUNCE_MS = 300;
|
|
34
|
+
/** The pane key that opens the add row, as its footer hint shows it. */
|
|
35
|
+
export const QUICK_ADD_KEY = "a";
|
|
33
36
|
|
|
34
37
|
export type { QuickAddCollectionKind } from "./resolution";
|
|
35
38
|
|
|
@@ -80,15 +83,20 @@ function QuickAddPreview({
|
|
|
80
83
|
const exchange = exchangeLabelFromValidation(validation);
|
|
81
84
|
const showSymbol = normalizeQuickAddQuery(validation.symbol) !== validation.query;
|
|
82
85
|
const symbolPrefix = showSymbol ? `${validation.symbol} ` : "";
|
|
86
|
+
// A symbol whose company moved on says where it went before it is added, ahead of the
|
|
87
|
+
// name of what lists there now; the add notice prints the whole line.
|
|
88
|
+
const change = validation.change?.kind === "moved" ? validation.change : null;
|
|
89
|
+
const moved = change?.listed ? `${change.issuer ?? `the former ${change.symbol}`} trades as ${change.tradesAs}` : change?.note;
|
|
83
90
|
|
|
84
91
|
return (
|
|
85
92
|
<Box flexDirection="row" overflow="hidden">
|
|
86
|
-
<Text fg={colors.textDim}>{`${symbolPrefix}${priceText} `}</Text>
|
|
87
|
-
<Text fg={changeValue == null ? colors.textDim : priceColor(changeValue)}>
|
|
93
|
+
<Text fg={colors.textDim} flexShrink={0}>{`${symbolPrefix}${priceText} `}</Text>
|
|
94
|
+
<Text fg={changeValue == null ? colors.textDim : priceColor(changeValue)} flexShrink={0}>
|
|
88
95
|
{formatPercentRaw(changeValue)}
|
|
89
96
|
</Text>
|
|
90
|
-
{
|
|
91
|
-
{
|
|
97
|
+
{moved ? <Text fg={colors.warning} flexShrink={0}>{` ${moved}`}</Text> : null}
|
|
98
|
+
{name && (!change || change.listed) ? <Text fg={colors.textMuted}>{` ${name}`}</Text> : null}
|
|
99
|
+
{exchange && !change ? <Text fg={colors.textDim}>{` ${exchange}`}</Text> : null}
|
|
92
100
|
</Box>
|
|
93
101
|
);
|
|
94
102
|
}
|
|
@@ -101,6 +109,7 @@ export function QuickAddTickerInput({
|
|
|
101
109
|
width,
|
|
102
110
|
onAdded,
|
|
103
111
|
onFocusChange,
|
|
112
|
+
focusRequest = 0,
|
|
104
113
|
}: {
|
|
105
114
|
collectionId: string;
|
|
106
115
|
collectionKind: QuickAddCollectionKind;
|
|
@@ -109,6 +118,12 @@ export function QuickAddTickerInput({
|
|
|
109
118
|
width: number;
|
|
110
119
|
onAdded: (symbol: string) => void;
|
|
111
120
|
onFocusChange?: (focused: boolean) => void;
|
|
121
|
+
/**
|
|
122
|
+
* Bumped by a control outside the row, such as the empty table's
|
|
123
|
+
* "+ ticker" button, to open it. A click there focuses the pane in the same
|
|
124
|
+
* press, so the row opens once the pane is focused.
|
|
125
|
+
*/
|
|
126
|
+
focusRequest?: number;
|
|
112
127
|
}) {
|
|
113
128
|
const dispatch = useAppDispatch();
|
|
114
129
|
const { notify } = usePluginAppActions();
|
|
@@ -132,6 +147,13 @@ export function QuickAddTickerInput({
|
|
|
132
147
|
setInputFocused(false);
|
|
133
148
|
}, []);
|
|
134
149
|
|
|
150
|
+
const handledFocusRequestRef = useRef(focusRequest);
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
if (focusRequest === handledFocusRequestRef.current || !focused) return;
|
|
153
|
+
handledFocusRequestRef.current = focusRequest;
|
|
154
|
+
focusInput();
|
|
155
|
+
}, [focusInput, focusRequest, focused]);
|
|
156
|
+
|
|
135
157
|
const resetInput = useCallback(() => {
|
|
136
158
|
setInputValue("");
|
|
137
159
|
setValidation(IDLE_VALIDATION);
|
|
@@ -295,13 +317,13 @@ export function QuickAddTickerInput({
|
|
|
295
317
|
}
|
|
296
318
|
|
|
297
319
|
onAdded(result.ticker.metadata.ticker);
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
symbol: result.ticker.metadata.ticker,
|
|
302
|
-
collection: collectionName,
|
|
303
|
-
}),
|
|
320
|
+
const added = tf("Added {symbol} to {collection}.", {
|
|
321
|
+
symbol: result.ticker.metadata.ticker,
|
|
322
|
+
collection: collectionName,
|
|
304
323
|
});
|
|
324
|
+
// As `watchlist add` prints it: FB now lists another security, Meta trades as META.
|
|
325
|
+
const change = tickerChangeLine(currentValidation.change);
|
|
326
|
+
notify({ type: "success", body: change ? `${added} ${change}.` : added });
|
|
305
327
|
resetInput();
|
|
306
328
|
queueMicrotask(() => inputRef.current?.focus?.());
|
|
307
329
|
} catch {
|
|
@@ -350,7 +372,7 @@ export function QuickAddTickerInput({
|
|
|
350
372
|
|
|
351
373
|
// The row shows only its placeholder, so the footer says which key reaches it.
|
|
352
374
|
usePaneFooter("portfolio-list:quick-add", () => ({
|
|
353
|
-
hints: inputFocused ? [] : [{ id: "add", key:
|
|
375
|
+
hints: inputFocused ? [] : [{ id: "add", key: QUICK_ADD_KEY, label: "dd", onPress: focusInput }],
|
|
354
376
|
}), [focusInput, inputFocused]);
|
|
355
377
|
|
|
356
378
|
return (
|
|
@@ -8,6 +8,14 @@ import {
|
|
|
8
8
|
import type { Quote } from "../../../../types/financials";
|
|
9
9
|
import type { TickerRecord } from "../../../../types/ticker";
|
|
10
10
|
import { canonicalExchange, parsePublicTickerKey, publicTickerKey } from "../../../../utils/exchanges";
|
|
11
|
+
import {
|
|
12
|
+
describeTickerChange,
|
|
13
|
+
isUsSymbolVenue,
|
|
14
|
+
quotedListing,
|
|
15
|
+
startTickerChangeLookup,
|
|
16
|
+
tickerChangeLine,
|
|
17
|
+
type TickerChange,
|
|
18
|
+
} from "../../../../tickers/ticker-changes";
|
|
11
19
|
|
|
12
20
|
const QUICK_ADD_MAX_QUERY_LENGTH = 32;
|
|
13
21
|
const QUICK_ADD_SYMBOL_RE = /^[A-Z0-9][A-Z0-9.\-\s]*$/;
|
|
@@ -20,6 +28,8 @@ interface ResolvedQuickAdd {
|
|
|
20
28
|
resolved: ResolvedTickerSearch;
|
|
21
29
|
ticker: TickerRecord | null;
|
|
22
30
|
quote: Quote | null;
|
|
31
|
+
/** The symbol changed (FB became META), as `watchlist add` says it. */
|
|
32
|
+
change: TickerChange | null;
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
export type QuickAddValidation =
|
|
@@ -135,6 +145,8 @@ export async function resolveQuickAddValidation({
|
|
|
135
145
|
if (!registry) {
|
|
136
146
|
return { status: "error", query, message: "Ticker lookup unavailable" };
|
|
137
147
|
}
|
|
148
|
+
// Beside the search, so a symbol that changed (FB is now META) costs no wait.
|
|
149
|
+
const changes = startTickerChangeLookup(registry.marketData, query);
|
|
138
150
|
|
|
139
151
|
try {
|
|
140
152
|
const resolved = await resolveTickerSearch({
|
|
@@ -144,7 +156,8 @@ export async function resolveQuickAddValidation({
|
|
|
144
156
|
dataProvider: registry.marketData,
|
|
145
157
|
});
|
|
146
158
|
if (!resolved) {
|
|
147
|
-
|
|
159
|
+
const change = describeTickerChange(query, await changes.settle(), null);
|
|
160
|
+
return { status: "missing", query, message: tickerChangeLine(change) ?? "No exact ticker match" };
|
|
148
161
|
}
|
|
149
162
|
|
|
150
163
|
const symbol = resolved.symbol;
|
|
@@ -163,6 +176,12 @@ export async function resolveQuickAddValidation({
|
|
|
163
176
|
}
|
|
164
177
|
}
|
|
165
178
|
|
|
179
|
+
// A listing abroad is not the US symbol the changes are of.
|
|
180
|
+
const venue = resolved.kind === "provider" && resolved.result.exchange === "SMART"
|
|
181
|
+
? resolved.result.primaryExchange
|
|
182
|
+
: exchangeFromResolved(resolved);
|
|
183
|
+
const payload = isUsSymbolVenue(venue) ? await changes.settle() : null;
|
|
184
|
+
const name = ticker?.metadata.name || (resolved.kind === "provider" ? resolved.result.name : "");
|
|
166
185
|
return {
|
|
167
186
|
status: tickerBelongsToCollection(ticker, collectionKind, collectionId) ? "duplicate" : "ready",
|
|
168
187
|
query,
|
|
@@ -170,6 +189,7 @@ export async function resolveQuickAddValidation({
|
|
|
170
189
|
resolved,
|
|
171
190
|
ticker,
|
|
172
191
|
quote,
|
|
192
|
+
change: describeTickerChange(query, payload, quote ? quotedListing(quote) : { name }),
|
|
173
193
|
};
|
|
174
194
|
} catch (error) {
|
|
175
195
|
if (error instanceof AmbiguousTickerError && !(error instanceof AmbiguousContractError)) {
|
|
@@ -13,6 +13,8 @@ export interface PortfolioPaneSettings {
|
|
|
13
13
|
viewMode: PortfolioViewMode;
|
|
14
14
|
hideHeader: boolean;
|
|
15
15
|
hideCash: boolean;
|
|
16
|
+
/** Value a portfolio at the regular close rather than the latest print (`fn PF --close`). */
|
|
17
|
+
valueAtClose: boolean;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export interface CollectionEntry {
|
|
@@ -47,6 +49,9 @@ const PORTFOLIO_COLUMN_DEFS: ColumnConfig[] = [
|
|
|
47
49
|
{ id: "rating", label: "RATING", width: 7, align: "right", format: "number" },
|
|
48
50
|
{ id: "ex_div", label: "EX-DIV", width: 7, align: "right" },
|
|
49
51
|
{ id: "next_earn", label: "ERN", width: 7, align: "right" },
|
|
52
|
+
// The stock's perpetual: its premium to the stock's last price and its funding per eight hours.
|
|
53
|
+
{ id: "perp_premium", label: "PERP%", width: 7, align: "right", format: "percent" },
|
|
54
|
+
{ id: "perp_funding", label: "FUND 8H", width: 8, align: "right", format: "percent" },
|
|
50
55
|
{ id: "side", label: "SIDE", width: 5, align: "left" },
|
|
51
56
|
{ id: "shares", label: "SHARES", width: 9, align: "right", format: "number" },
|
|
52
57
|
{ id: "avg_cost", label: "AVG COST", width: 10, align: "right", format: "currency" },
|
|
@@ -64,6 +69,8 @@ const PORTFOLIO_COLUMN_DEFS: ColumnConfig[] = [
|
|
|
64
69
|
{ id: "mark_delta", label: "MARK%", width: 8, align: "right", format: "percent" },
|
|
65
70
|
{ id: "acq_date", label: "ACQ", width: 7, align: "right" },
|
|
66
71
|
{ id: "held", label: "HELD", width: 6, align: "right" },
|
|
72
|
+
// When the price a row is valued at is from: its print, or the regular close.
|
|
73
|
+
{ id: "as_of", label: "AS OF UTC", width: 10, align: "right" },
|
|
67
74
|
];
|
|
68
75
|
|
|
69
76
|
const PORTFOLIO_COLUMNS_BY_ID = new Map(PORTFOLIO_COLUMN_DEFS.map((column) => [column.id, column]));
|
|
@@ -171,6 +178,9 @@ function withTargetColumns(columnIds: string[]): string[] {
|
|
|
171
178
|
function describeColumnOption(column: ColumnConfig): string {
|
|
172
179
|
if (column.id === PRICE_SPARKLINE_COLUMN_ID) return "One-month price sparkline.";
|
|
173
180
|
if (TARGET_COLUMN_IDS.has(column.id)) return "Shown by default once the portfolio has target weights.";
|
|
181
|
+
if (column.id === "perp_premium") return "Premium of the stock's perpetual to its last price.";
|
|
182
|
+
if (column.id === "perp_funding") return "Funding of the stock's perpetual, per 8 hours.";
|
|
183
|
+
if (column.id === "as_of") return "When each row's price is from: its last print, or the regular close.";
|
|
174
184
|
return PORTFOLIO_ONLY_COLUMN_IDS.has(column.id)
|
|
175
185
|
? "Visible only when this pane is showing a portfolio."
|
|
176
186
|
: "Visible for watchlists and portfolios.";
|
|
@@ -191,6 +201,7 @@ export function getPortfolioPaneSettings(settings: Record<string, unknown> | und
|
|
|
191
201
|
viewMode: isPortfolioViewMode(settings?.viewMode) ? settings.viewMode : "table",
|
|
192
202
|
hideHeader: settings?.hideHeader === true,
|
|
193
203
|
hideCash: settings?.hideCash === true,
|
|
204
|
+
valueAtClose: settings?.valueAtClose === true,
|
|
194
205
|
};
|
|
195
206
|
}
|
|
196
207
|
|
|
@@ -306,6 +317,12 @@ export function buildPortfolioPaneSettingsDef(
|
|
|
306
317
|
type: "select",
|
|
307
318
|
options: VIEW_MODE_OPTIONS,
|
|
308
319
|
});
|
|
320
|
+
fields.push({
|
|
321
|
+
key: "valueAtClose",
|
|
322
|
+
label: "Value at Regular Close",
|
|
323
|
+
description: "Price holdings at the regular close instead of the latest print, which includes extended hours.",
|
|
324
|
+
type: "toggle",
|
|
325
|
+
});
|
|
309
326
|
}
|
|
310
327
|
|
|
311
328
|
if (settings.collectionScope === "custom") {
|
|
@@ -22,6 +22,13 @@ import { formatAllocationDrift, formatAllocationWeight, type PortfolioCashLine }
|
|
|
22
22
|
import { getMostRecentQuoteUpdate } from "../../../../market-data/quotes/time";
|
|
23
23
|
import { fxStatusLabel, type FxRateStatus } from "../../../../utils/fx-status";
|
|
24
24
|
import { t } from "../../../../i18n";
|
|
25
|
+
import type { PortfolioValuationBasis } from "../../../../portfolio/valuation-basis";
|
|
26
|
+
|
|
27
|
+
/** What the value beside it is priced at, short enough that the header row keeps it with the value. */
|
|
28
|
+
const PRICED_AT_TEXT: Record<PortfolioValuationBasis, string> = {
|
|
29
|
+
"latest-print": "(latest print)",
|
|
30
|
+
"regular-close": "(regular close)",
|
|
31
|
+
};
|
|
25
32
|
|
|
26
33
|
export interface PortfolioSummarySegment {
|
|
27
34
|
id: string;
|
|
@@ -225,8 +232,11 @@ export function buildPortfolioSummarySegments({
|
|
|
225
232
|
baseCurrency = "USD",
|
|
226
233
|
manualCash = null,
|
|
227
234
|
brokerPortfolio = false,
|
|
235
|
+
valuationBasis,
|
|
228
236
|
}: {
|
|
229
237
|
totals: PortfolioSummaryTotals;
|
|
238
|
+
/** What the values are priced at, said beside the value; left out when absent. */
|
|
239
|
+
valuationBasis?: PortfolioValuationBasis;
|
|
230
240
|
accountState: PortfolioSummaryAccountState | null;
|
|
231
241
|
isPortfolioTab?: boolean;
|
|
232
242
|
/** Synced from a broker, so it is worth its account's equity even while the account is missing. */
|
|
@@ -285,9 +295,11 @@ export function buildPortfolioSummarySegments({
|
|
|
285
295
|
]));
|
|
286
296
|
}
|
|
287
297
|
|
|
298
|
+
// Which price the value uses goes with it, so a narrow row never shows one without the other.
|
|
288
299
|
candidates.push(createSummarySegment("val", [
|
|
289
300
|
{ text: broker || totals.hasShorts ? "Gross" : "Val", tone: "label" },
|
|
290
301
|
{ text: money(totalMarketValue), tone: "value", bold: true },
|
|
302
|
+
...(valuationBasis ? [{ text: PRICED_AT_TEXT[valuationBasis], tone: "muted" as const }] : []),
|
|
291
303
|
]));
|
|
292
304
|
|
|
293
305
|
if (totals.hasShorts && totals.netMktValue != null) {
|
|
@@ -7,14 +7,14 @@ import { isQuoteStaleForCurrentSession } from "../../../../market-data/quotes/fr
|
|
|
7
7
|
import { headlineQuoteDisplay } from "../column-values";
|
|
8
8
|
import { isManualPortfolio } from "../mutations";
|
|
9
9
|
import type { AllocationHolding } from "../allocation";
|
|
10
|
+
import { getPortfolioValuationDisplay, type PortfolioValuationBasis } from "../../../../portfolio/valuation-basis";
|
|
10
11
|
import {
|
|
11
12
|
getPortfolioPositionMetrics,
|
|
12
|
-
getPortfolioQuoteDisplay,
|
|
13
13
|
resolvePortfolioMarketValue,
|
|
14
14
|
resolvePortfolioPositionPnl,
|
|
15
15
|
portfolioPnlPercent,
|
|
16
16
|
type PortfolioPositionPnl,
|
|
17
|
-
} from "
|
|
17
|
+
} from "../../../../portfolio/position-metrics";
|
|
18
18
|
|
|
19
19
|
/** A position lot valued from a current quote, in the totals currency. */
|
|
20
20
|
interface PricedPortfolioLot {
|
|
@@ -90,7 +90,11 @@ export function formatPortfolioAmount(
|
|
|
90
90
|
return `${sign}${getCurrencySymbol(currency)}${text.slice(sign.length)}`;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* Totals over the collection, every amount converted into `totalsCurrency`,
|
|
95
|
+
* valued at `valuationBasis`: the latest print unless given, or the regular
|
|
96
|
+
* close, whose day is that session's move.
|
|
97
|
+
*/
|
|
94
98
|
export function calculatePortfolioSummaryTotals(
|
|
95
99
|
tickers: TickerRecord[],
|
|
96
100
|
financialsMap: Map<string, TickerFinancials>,
|
|
@@ -98,6 +102,7 @@ export function calculatePortfolioSummaryTotals(
|
|
|
98
102
|
exchangeRates: Map<string, number>,
|
|
99
103
|
isPortfolio: boolean,
|
|
100
104
|
collectionId: string | null,
|
|
105
|
+
valuationBasis: PortfolioValuationBasis = "latest-print",
|
|
101
106
|
): PortfolioSummaryTotals {
|
|
102
107
|
let totalMktValue = 0;
|
|
103
108
|
let netMktValue = 0;
|
|
@@ -144,7 +149,7 @@ export function calculatePortfolioSummaryTotals(
|
|
|
144
149
|
const positionMetrics = getPortfolioPositionMetrics(ticker, collectionId ?? undefined, quoteCurrency, {
|
|
145
150
|
currency: totalsCurrency, convert: toBase,
|
|
146
151
|
}, quote);
|
|
147
|
-
activeQuote =
|
|
152
|
+
activeQuote = getPortfolioValuationDisplay(positionMetrics, quote, valuationBasis);
|
|
148
153
|
const { totalPriceUnits, grossPriceUnits, totalCost } = positionMetrics;
|
|
149
154
|
if (positionMetrics.positionCount === 0) {
|
|
150
155
|
// Not held, so a missing rate is no gap in the totals: it only leaves the trade in units out.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useCallback, useMemo, useRef } from "react";
|
|
2
|
+
import { QUICK_ADD_KEY } from "./quick-add";
|
|
2
3
|
import {
|
|
3
4
|
TickerListTableView,
|
|
4
5
|
type DataTableKeyEvent,
|
|
@@ -8,18 +9,29 @@ import { useDataTableSortMenu } from "../../../components/data-table/sort-menu";
|
|
|
8
9
|
import { followLiveSparklinePrice } from "../../../components/price-sparkline/model";
|
|
9
10
|
import { PRICE_SPARKLINE_COLUMN_ID } from "../../../components/price-sparkline/view";
|
|
10
11
|
import type { QuoteFlashDirection } from "../../../components/quote-flash";
|
|
12
|
+
import type { TickerTableCell } from "../../../components/ticker/list-table-view";
|
|
11
13
|
import { createRowValueCache } from "../../../components/ui/row-value-cache";
|
|
12
14
|
import type { ColumnConfig } from "../../../types/config";
|
|
13
15
|
import type { PricePoint, TickerFinancials } from "../../../types/financials";
|
|
14
16
|
import type { TickerRecord } from "../../../types/ticker";
|
|
15
17
|
import { objectVersion } from "../../../utils/object-version";
|
|
16
|
-
import { columnContextVersion } from "./cell-version";
|
|
18
|
+
import { columnContextVersion, PERPETUAL_COLUMN_IDS } from "./cell-version";
|
|
17
19
|
import { getColumnValue, type ColumnContext } from "./metrics";
|
|
18
|
-
import {
|
|
20
|
+
import { tickerDisplayName } from "./column-values";
|
|
21
|
+
import { displayWidth } from "../../../utils/format";
|
|
22
|
+
import { portfolioPnlLabel } from "../../../portfolio/position-metrics";
|
|
19
23
|
import { PORTFOLIO_ROW_MENU_KEYS } from "./row-actions";
|
|
20
24
|
|
|
21
25
|
export type { QuoteFlashDirection };
|
|
22
26
|
|
|
27
|
+
/** The market-state dot and the space after it, before each symbol in the Ticker column. */
|
|
28
|
+
const TICKER_DOT_WIDTH = 2;
|
|
29
|
+
/**
|
|
30
|
+
* The widest the Ticker column grows for its symbols: a perpetual as its venue writes it (`xyz:BRENTOIL`) and an
|
|
31
|
+
* option as its terms (`NVDA C $1250 Dec'26`) fit, so only a list holding options is given the width.
|
|
32
|
+
*/
|
|
33
|
+
const MAX_TICKER_COLUMN_WIDTH = 22;
|
|
34
|
+
|
|
23
35
|
/** A cell recomputes only when its row's records or a context input it reads change. */
|
|
24
36
|
function buildCellVersion(
|
|
25
37
|
column: ColumnConfig,
|
|
@@ -98,6 +110,8 @@ export function PortfolioTickerTable({
|
|
|
98
110
|
visibleRangeBuffer,
|
|
99
111
|
resetScrollKey,
|
|
100
112
|
onRowActivate,
|
|
113
|
+
onAddTicker,
|
|
114
|
+
onOpenPerpetual,
|
|
101
115
|
rootHeight,
|
|
102
116
|
}: {
|
|
103
117
|
columns: ColumnConfig[];
|
|
@@ -117,18 +131,26 @@ export function PortfolioTickerTable({
|
|
|
117
131
|
visibleRangeBuffer?: number;
|
|
118
132
|
resetScrollKey?: unknown;
|
|
119
133
|
onRowActivate?: (ticker: TickerRecord) => void;
|
|
134
|
+
/** Opens the add row; the empty table offers it as a button. */
|
|
135
|
+
onAddTicker?: () => void;
|
|
136
|
+
/** Opens PERP on a row's stock perpetual: its PERP% and FUND 8H cells link to it. */
|
|
137
|
+
onOpenPerpetual?: (marketId: string) => void;
|
|
120
138
|
rootHeight?: number;
|
|
121
139
|
}) {
|
|
122
|
-
const cellCacheRef = useRef(createRowValueCache<string, ReturnType<typeof getColumnValue
|
|
140
|
+
const cellCacheRef = useRef(createRowValueCache<string, ReturnType<typeof getColumnValue> & TickerTableCell>(5000));
|
|
141
|
+
const openPerpetualRef = useRef(onOpenPerpetual);
|
|
142
|
+
openPerpetualRef.current = onOpenPerpetual;
|
|
123
143
|
const sparklineVisible = columns.some((column) => column.id === PRICE_SPARKLINE_COLUMN_ID);
|
|
124
144
|
const tableFinancialsMap = useLiveSparklineFinancials(financialsMap, sortedTickers, sparklineVisible);
|
|
125
145
|
const resolveCell = useCallback(
|
|
126
146
|
(column: ColumnConfig, ticker: TickerRecord, financials: TickerFinancials | undefined) => {
|
|
127
147
|
const key = `${ticker.metadata.ticker}:${column.id}`;
|
|
128
148
|
const version = buildCellVersion(column, ticker, financials, columnContext);
|
|
129
|
-
return cellCacheRef.current.get(key, version, () =>
|
|
130
|
-
getColumnValue(column, ticker, financials, columnContext)
|
|
131
|
-
|
|
149
|
+
return cellCacheRef.current.get(key, version, () => {
|
|
150
|
+
const cell = getColumnValue(column, ticker, financials, columnContext);
|
|
151
|
+
const marketId = PERPETUAL_COLUMN_IDS.has(column.id) ? columnContext.perpetuals?.get(ticker.metadata.ticker)?.marketId : undefined;
|
|
152
|
+
return marketId ? { ...cell, onPress: () => openPerpetualRef.current?.(marketId) } : cell;
|
|
153
|
+
});
|
|
132
154
|
},
|
|
133
155
|
[columnContext],
|
|
134
156
|
);
|
|
@@ -139,11 +161,17 @@ export function PortfolioTickerTable({
|
|
|
139
161
|
const hasNonShareQuantity = useMemo(() => sortedTickers.some(ticker => ticker.metadata.positions.some(position =>
|
|
140
162
|
(!columnContext.activeTab || position.portfolio === columnContext.activeTab) && position.shares !== 0 && (position.priceBasis === "percent-of-par" || ticker.metadata.assetCategory?.toUpperCase() === "BOND"))),
|
|
141
163
|
[columnContext.activeTab, sortedTickers]);
|
|
164
|
+
// The Ticker column grows to its longest symbol, so ETH-USD shows whole beside its market-state dot.
|
|
165
|
+
const tickerWidth = useMemo(() => Math.min(MAX_TICKER_COLUMN_WIDTH, sortedTickers.reduce(
|
|
166
|
+
(widest, ticker) => Math.max(widest, TICKER_DOT_WIDTH + displayWidth(tickerDisplayName(ticker))),
|
|
167
|
+
0,
|
|
168
|
+
)), [sortedTickers]);
|
|
142
169
|
const displayColumns = useMemo(() => columns.map((column) => column.id === "shares" && hasNonShareQuantity ? { ...column, label: "QTY" }
|
|
170
|
+
: column.id === "ticker" && tickerWidth > column.width ? { ...column, width: tickerWidth }
|
|
143
171
|
: pnlLabel !== "P&L" && (column.id === "pnl" || column.id === "pnl_pct") ? {
|
|
144
172
|
...column,
|
|
145
173
|
label: column.id === "pnl_pct" ? pnlLabel.replace("P&L", "%") : pnlLabel,
|
|
146
|
-
} : column), [columns, hasNonShareQuantity, pnlLabel]);
|
|
174
|
+
} : column), [columns, hasNonShareQuantity, pnlLabel, tickerWidth]);
|
|
147
175
|
// The table offers "Sort by…" while it has a sort column. A watchlist starts
|
|
148
176
|
// unsorted and a third header click turns sorting off, so the unsorted state
|
|
149
177
|
// needs its own entry until TickerListTableView takes `sortable`.
|
|
@@ -175,6 +203,8 @@ export function PortfolioTickerTable({
|
|
|
175
203
|
resetScrollKey={resetScrollKey}
|
|
176
204
|
onRowActivate={onRowActivate}
|
|
177
205
|
rowMenuAccelerators={PORTFOLIO_ROW_MENU_KEYS}
|
|
206
|
+
onAddTicker={onAddTicker}
|
|
207
|
+
addTickerShortcut={onAddTicker ? QUICK_ADD_KEY : undefined}
|
|
178
208
|
rootHeight={rootHeight}
|
|
179
209
|
/>
|
|
180
210
|
);
|
|
@@ -2,6 +2,8 @@ import { apiClient } from "../../../api-client";
|
|
|
2
2
|
import type { PowerBoard, PowerDetail, PowerFilter, PowerHistory, PowerProject } from "../../../api-client/power";
|
|
3
3
|
import { createPluginCache } from "../../../data/plugin-cache";
|
|
4
4
|
import { loadCloudResource, unavailableOnServer } from "../shared/cloud-resource";
|
|
5
|
+
import { powerTickerScopes, type PowerTab, type PowerTickerScope } from "./model";
|
|
6
|
+
import { powerQuery } from "./query";
|
|
5
7
|
|
|
6
8
|
const cacheOptions = { source: "gloom-cloud", schemaVersion: 1, policy: { staleMs: 60 * 60_000, expireMs: 30 * 86_400_000 } };
|
|
7
9
|
export const powerBoardCache = createPluginCache<PowerBoard>({ ...cacheOptions, kind: "power-board" });
|
|
@@ -88,6 +90,20 @@ export async function fetchAllPowerHistory(filter: PowerFilter, client: Pick<Pow
|
|
|
88
90
|
}
|
|
89
91
|
return { ...first, points, hasMore: false, nextOffset: null };
|
|
90
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* How many records name a ticker on each other tab, for a tab that has none:
|
|
95
|
+
* one single-row page per scope, read for its total, which a free preview
|
|
96
|
+
* reports in full. A scope that fails to answer has no total rather than
|
|
97
|
+
* failing the tab it explains.
|
|
98
|
+
*/
|
|
99
|
+
export async function fetchPowerTickerScopes(symbol: string, tab: PowerTab, context: string,
|
|
100
|
+
client: Pick<PowerApi, "getCloudPowerBoard"> = apiClient, signal?: AbortSignal): Promise<PowerTickerScope[]> {
|
|
101
|
+
return Promise.all(powerTickerScopes(tab, context).map((scope) => {
|
|
102
|
+
const count = () => fetchPowerBoard({ ...powerQuery({ tab: scope.tab, context: scope.context }, symbol), limit: 1 }, client, signal).then((board) => board.total);
|
|
103
|
+
// One retry: a count is cheap, and the first of several at once is the one most often refused.
|
|
104
|
+
return count().catch(() => count()).then((total) => ({ ...scope, total }), () => ({ ...scope, total: null }));
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
91
107
|
const key = (query: unknown, scope: string) => `${scope}:${JSON.stringify(query)}`;
|
|
92
108
|
export const loadPowerBoard = (filter: PowerFilter, scope: string, force = false, signal?: AbortSignal) =>
|
|
93
109
|
loadCloudResource(powerBoardCache, key(filter, scope), () => fetchPowerBoard(filter, apiClient, signal), { force, validate: validatePowerBoard });
|
|
@@ -1,56 +1,109 @@
|
|
|
1
|
+
import type { CarbonBoard, CarbonHistory, EuropePowerBoard, EuropePowerHistory } from "../../../api-client/europe-energy";
|
|
1
2
|
import type { PowerBoard, PowerHistory } from "../../../api-client/power";
|
|
2
3
|
import type { PaneScreenshotEvidenceHook } from "../../../cli/pane-functions/screenshot-evidence";
|
|
3
4
|
import { useRemoteUiNode } from "../../../remote/semantic-tree";
|
|
4
5
|
import { isRecord } from "../../../utils/guards";
|
|
5
|
-
import { fetchPowerBoard, fetchAllPowerHistory, validatePowerBoard, validatePowerHistory } from "./client";
|
|
6
|
+
import { fetchPowerBoard, fetchAllPowerHistory, fetchPowerTickerScopes, validatePowerBoard, validatePowerHistory } from "./client";
|
|
6
7
|
import { otherRows, powerTab, projectRows } from "./model";
|
|
8
|
+
import { fetchCarbonHistory, fetchCarbonPrice, fetchPowerPriceHistory, fetchPowerPrices, validateCarbonPrice, validatePowerPrices } from "./prices-client";
|
|
9
|
+
import { DEFAULT_PRICE_MARKET, isCarbonQuery, powerPriceMarket } from "./prices-model";
|
|
7
10
|
import { powerQuery } from "./query";
|
|
8
11
|
interface PowerEvidence {
|
|
9
12
|
kind: "power";
|
|
10
13
|
version: 1;
|
|
11
14
|
complete: boolean;
|
|
12
15
|
plottedValueCount: number;
|
|
13
|
-
board
|
|
16
|
+
/** The grid board, on every tab but Prices. */
|
|
17
|
+
board: PowerBoard | null;
|
|
14
18
|
history: PowerHistory | null;
|
|
19
|
+
/** The day-ahead board and the EUA board, on the Prices tab. */
|
|
20
|
+
prices?: EuropePowerBoard | null;
|
|
21
|
+
carbon?: CarbonBoard | null;
|
|
15
22
|
tab: string;
|
|
16
23
|
rowIds: string[];
|
|
17
24
|
}
|
|
25
|
+
/** What the Prices tab draws, frozen by `shot` so the capture and its check read the same days. */
|
|
26
|
+
export interface PowerPricesSnapshot {
|
|
27
|
+
board: EuropePowerBoard;
|
|
28
|
+
/** The charted history: the selected market's, or the carbon allowance's for EPWR EUA. */
|
|
29
|
+
history: EuropePowerHistory | CarbonHistory | null;
|
|
30
|
+
/** Null when the server has no EUA price yet; the tab then shows the board alone. */
|
|
31
|
+
carbon: CarbonBoard | null;
|
|
32
|
+
}
|
|
18
33
|
export function usePowerEvidence(board: PowerBoard | undefined, history: PowerHistory | undefined, tab: string, rowIds: string[], loading: boolean) {
|
|
19
34
|
useRemoteUiNode({ role: "chart-data", label: "Rendered power and grid observations", getMetadata: () => ({
|
|
20
35
|
kind: "power", version: 1, complete: !!board && !loading, ready: !!board && !loading,
|
|
21
36
|
plottedValueCount: rowIds.length, board, history: history ?? null, tab, rowIds,
|
|
22
37
|
}) });
|
|
23
38
|
}
|
|
39
|
+
export function usePowerPricesEvidence(prices: EuropePowerBoard | null, carbon: CarbonBoard | null, rowIds: string[], loading: boolean) {
|
|
40
|
+
useRemoteUiNode({ role: "chart-data", label: "Rendered day-ahead power and carbon prices", getMetadata: () => ({
|
|
41
|
+
kind: "power", version: 1, complete: !!prices && !loading, ready: !!prices && !loading,
|
|
42
|
+
plottedValueCount: rowIds.length, board: null, history: null, prices, carbon, tab: "prices", rowIds,
|
|
43
|
+
}) });
|
|
44
|
+
}
|
|
45
|
+
const instanceSettings = (payload: Parameters<PaneScreenshotEvidenceHook["mismatches"]>[1]["payload"]) =>
|
|
46
|
+
payload.config.layout.instances.find((entry) => entry.instanceId === payload.paneId)?.settings;
|
|
24
47
|
export const powerScreenshotEvidence: PaneScreenshotEvidenceHook<PowerEvidence> = {
|
|
25
48
|
paneId: "power", kind: "power", label: "power and grid",
|
|
26
49
|
async prepare({ resolved, settings }) {
|
|
27
50
|
const tab = powerTab(settings.tab ?? resolved.options.tab);
|
|
51
|
+
if (tab === "prices") {
|
|
52
|
+
const board = await fetchPowerPrices();
|
|
53
|
+
// The carbon figures are captured when the server has them, and left out when it does not.
|
|
54
|
+
const carbon = await fetchCarbonPrice().catch(() => null);
|
|
55
|
+
const arg = resolved.createOptions?.arg;
|
|
56
|
+
const market = powerPriceMarket(arg)?.code ?? DEFAULT_PRICE_MARKET;
|
|
57
|
+
const history = isCarbonQuery(arg) && carbon?.row.date ? await fetchCarbonHistory()
|
|
58
|
+
: board.rows.some((row) => row.code === market && row.date) ? await fetchPowerPriceHistory(market) : null;
|
|
59
|
+
return { settings: { powerPricesSnapshot: { board, history, carbon } satisfies PowerPricesSnapshot }, financials: [] };
|
|
60
|
+
}
|
|
28
61
|
const symbol = resolved.createOptions?.symbol ?? resolved.createOptions?.arg;
|
|
29
62
|
const filter = powerQuery({ ...settings, ...resolved.options, tab }, symbol);
|
|
30
63
|
const board = await fetchPowerBoard({ ...filter, limit: 100 });
|
|
31
64
|
const history = tab === "history" ? await fetchAllPowerHistory(filter) : undefined;
|
|
32
|
-
|
|
65
|
+
// A ticker with nothing on this tab: the counts that say where its records are, captured with the rest.
|
|
66
|
+
const empty = !!symbol && tab !== "coverage" && !(tab === "history" ? history?.points.length : tab === "outcomes" ? board.rates.length
|
|
67
|
+
: tab === "utilities" ? board.exposure.length : board.projects.length);
|
|
68
|
+
const tickerScopes = empty && symbol ? await fetchPowerTickerScopes(symbol, tab, String(settings.context ?? resolved.options.context ?? "capacity")) : undefined;
|
|
69
|
+
return { settings: { powerSnapshot: { board, ...(history ? { history } : {}), ...(tickerScopes ? { tickerScopes } : {}) } }, financials: [] };
|
|
33
70
|
},
|
|
34
71
|
read(value) {
|
|
35
|
-
if (!isRecord(value) || value.kind !== "power" || value.version !== 1 || value.complete !== true
|
|
72
|
+
if (!isRecord(value) || value.kind !== "power" || value.version !== 1 || value.complete !== true
|
|
36
73
|
|| !Array.isArray(value.rowIds) || !value.rowIds.every((id) => typeof id === "string") || value.plottedValueCount !== value.rowIds.length) return null;
|
|
37
74
|
try {
|
|
75
|
+
const tab = powerTab(value.tab);
|
|
76
|
+
if (tab === "prices") {
|
|
77
|
+
if (!isRecord(value.prices)) return null;
|
|
78
|
+
const prices = validatePowerPrices(value.prices as unknown as EuropePowerBoard);
|
|
79
|
+
if (value.carbon != null) validateCarbonPrice(value.carbon as unknown as CarbonBoard);
|
|
80
|
+
if (value.rowIds.some((id) => !prices.rows.some((row) => row.code === id))) return null;
|
|
81
|
+
return value as unknown as PowerEvidence;
|
|
82
|
+
}
|
|
83
|
+
if (!isRecord(value.board)) return null;
|
|
38
84
|
const board = validatePowerBoard(value.board as unknown as PowerBoard);
|
|
39
85
|
const history = value.history ? validatePowerHistory(value.history as PowerHistory) : null;
|
|
40
|
-
const tab = powerTab(value.tab);
|
|
41
86
|
const rows = ["queue", "loads", "capacity"].includes(tab) ? projectRows(board.projects) : otherRows(tab, board, history?.points ?? []);
|
|
42
87
|
if (value.rowIds.some((id) => !rows.some((r) => r.id === id))) return null;
|
|
43
88
|
return value as unknown as PowerEvidence;
|
|
44
89
|
} catch { return null; }
|
|
45
90
|
},
|
|
46
91
|
mismatches(evidence, { resolved, payload }) {
|
|
47
|
-
const
|
|
92
|
+
const settings = instanceSettings(payload);
|
|
48
93
|
const errors: string[] = [];
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
94
|
+
if (evidence.tab === "prices") {
|
|
95
|
+
const snapshot = settings?.powerPricesSnapshot;
|
|
96
|
+
if (!isRecord(snapshot) || JSON.stringify(snapshot.board) !== JSON.stringify(evidence.prices)
|
|
97
|
+
|| JSON.stringify(snapshot.carbon ?? null) !== JSON.stringify(evidence.carbon ?? null)) errors.push("Power prices differ from the captured data.");
|
|
98
|
+
} else {
|
|
99
|
+
const snapshot = settings?.powerSnapshot;
|
|
100
|
+
if (!isRecord(snapshot) || JSON.stringify(snapshot.board) !== JSON.stringify(evidence.board)
|
|
101
|
+
|| JSON.stringify(snapshot.history ?? null) !== JSON.stringify(evidence.history)) errors.push("Power observations differ from the captured data.");
|
|
102
|
+
}
|
|
103
|
+
// EPWR opens the Prices tab by its settings; POWER by --tab.
|
|
104
|
+
if (evidence.tab !== powerTab(resolved.options.tab ?? settings?.tab)) errors.push("Power tab does not match the requested view.");
|
|
52
105
|
return errors;
|
|
53
106
|
},
|
|
54
|
-
unavailable(evidence) { return evidence?.complete ? [] : ["power observations"]; },
|
|
107
|
+
unavailable(evidence) { return evidence?.complete ? [] : [evidence?.tab === "prices" ? "power prices" : "power observations"]; },
|
|
55
108
|
symbols() { return []; },
|
|
56
109
|
};
|