@gloom-sh/terminal 0.18.5 → 0.19.1
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/patches/electrobun@1.18.1.patch +163 -8
- package/src/api-client/app-attention.ts +3 -0
- package/src/api-client/beneficial-owners.ts +3 -0
- package/src/api-client/company-kpis.ts +3 -0
- package/src/api-client/cot.ts +6 -2
- package/src/api-client/credit-documents.ts +6 -0
- package/src/api-client/data.ts +19 -7
- package/src/api-client/equity-screener.ts +24 -0
- package/src/api-client/fund-facts.ts +45 -4
- package/src/api-client/hiring.ts +3 -0
- package/src/api-client/index.ts +15 -0
- package/src/api-client/ipo.ts +24 -1
- package/src/api-client/market-discovery.ts +10 -0
- package/src/api-client/market-movers.ts +7 -0
- package/src/api-client/members.ts +1 -1
- package/src/api-client/mna.ts +3 -0
- package/src/api-client/paths.ts +9 -1
- package/src/api-client/perps.ts +43 -0
- package/src/api-client/research-activity.ts +3 -2
- package/src/api-client/roadmap.ts +85 -0
- package/src/api-client/types.ts +82 -2
- package/src/app/pane-runtime/plugin-bindings.ts +9 -5
- package/src/app/runtime/broker-import.ts +0 -2
- package/src/app/runtime/plugin-bindings.ts +73 -56
- package/src/architecture/core-builtin-allowlist.json +2 -2
- package/src/architecture/pane-tabs-allowlist.json +3 -0
- package/src/architecture/ttl-caches-allowlist.json +19 -0
- package/src/brokers/sync-broker-instance.ts +2 -8
- package/src/capabilities/chart-series.ts +1 -1
- package/src/cli/commands/crypto-hints.ts +40 -24
- package/src/cli/commands/market.ts +107 -38
- package/src/cli/commands/news-search.ts +22 -0
- package/src/cli/commands/options-chain.ts +48 -7
- package/src/cli/commands/options-leaps.ts +9 -3
- package/src/cli/commands/overview.ts +147 -32
- package/src/cli/commands/search.ts +21 -1
- package/src/cli/commands/themes.ts +11 -2
- package/src/cli/commands/ticker.ts +87 -36
- package/src/cli/company-name-hint.ts +41 -0
- package/src/cli/earnings-calendar.ts +1 -1
- package/src/cli/errors.ts +25 -2
- package/src/cli/glossary.ts +31 -2
- package/src/cli/history-rows.ts +57 -9
- package/src/cli/index-roots.ts +0 -7
- package/src/cli/index.ts +2 -0
- package/src/cli/listing-arg.ts +235 -60
- package/src/cli/output-file.ts +68 -0
- package/src/cli/pane-functions/capabilities.ts +4 -0
- package/src/cli/pane-functions/catalog.ts +80 -7
- package/src/cli/pane-functions/discovery.ts +21 -1
- package/src/cli/pane-functions/dom.ts +13 -3
- package/src/cli/pane-functions/freshness.ts +93 -4
- package/src/cli/pane-functions/function-help.ts +20 -10
- package/src/cli/pane-functions/headless.ts +17 -7
- package/src/cli/pane-functions/index.ts +54 -16
- package/src/cli/pane-functions/market-session.ts +66 -4
- package/src/cli/pane-functions/options.ts +19 -1
- package/src/cli/pane-functions/resolver.ts +19 -8
- package/src/cli/pane-functions/screenshot-assessment.ts +6 -4
- package/src/cli/pane-functions/screenshot-types.ts +5 -0
- package/src/cli/quote-answer.ts +22 -11
- package/src/cli/saved-copy-persistence.ts +88 -0
- package/src/cli/ticker-resolution.ts +3 -2
- package/src/components/chart/composite/composite-chart.tsx +4 -0
- package/src/components/chart/composite/interactions.ts +6 -0
- package/src/components/chart/composite/legend.tsx +45 -7
- package/src/components/chart/composite/panel-gestures.ts +33 -0
- package/src/components/chart/composite/panel-surface.tsx +52 -3
- package/src/components/chart/composite/rasterizer.ts +24 -13
- package/src/components/chart/composite/scene.ts +39 -4
- package/src/components/chart/composite/series-cues.ts +14 -0
- package/src/components/chart/composite/text-renderer.ts +9 -2
- package/src/components/chart/composite/tool-catalog.ts +36 -0
- package/src/components/chart/composite/tools.ts +203 -44
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +11 -4
- package/src/components/command-bar/assist/inventory.ts +2 -1
- package/src/components/command-bar/commands/direct/index.ts +28 -13
- package/src/components/command-bar/list/model.ts +5 -0
- package/src/components/command-bar/pane-templates/items.ts +3 -2
- package/src/components/command-bar/routes/root/runtime.ts +6 -7
- package/src/components/command-bar/selection-runtime.ts +52 -3
- package/src/components/command-bar/surface/index.tsx +2 -0
- package/src/components/command-bar/workflow/collection-actions.ts +3 -3
- package/src/components/layout/pane/capture-stamp.ts +2 -2
- package/src/components/layout/pane/footer/index.tsx +22 -6
- package/src/components/layout/pane/footer/model.ts +83 -15
- package/src/components/layout/pane/status-footer.ts +35 -2
- package/src/components/layout/status-widget-space.ts +9 -0
- package/src/components/onboarding/onboarding-wizard.tsx +4 -1
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +12 -7
- package/src/components/onboarding/wizard-broker-sync.ts +0 -1
- package/src/components/onboarding/wizard-positions.ts +3 -3
- package/src/components/ticker/list-table-view.tsx +8 -21
- package/src/components/ui/choice-dialog.tsx +23 -18
- package/src/components/ui/choice-groups.ts +18 -0
- package/src/components/ui/data-table/opentui/index.tsx +9 -7
- package/src/components/ui/data-table/opentui/model.ts +26 -1
- package/src/components/ui/data-table/types.ts +2 -0
- package/src/components/ui/display.tsx +18 -3
- package/src/components/ui/icon.tsx +4 -1
- package/src/components/ui/list-view.tsx +8 -4
- package/src/components/ui/query-bar-keys.tsx +2 -0
- package/src/components/ui/query-bar.tsx +1 -0
- package/src/components/ui/select-button.tsx +5 -1
- package/src/components/ui/select-field.tsx +1 -0
- package/src/components/ui/table-layout.ts +8 -5
- package/src/core/app-runtime.ts +2 -0
- package/src/core/app-services.ts +2 -2
- package/src/data/config/chart-settings.ts +1 -1
- package/src/data/json-ticker-repository.ts +17 -8
- package/src/data/plugin-cache.ts +5 -3
- package/src/data/saved-copies.ts +8 -0
- package/src/data/ticker-repository.ts +16 -9
- package/src/data/ticker-writes.ts +81 -0
- package/src/data/ttl-cache.ts +165 -0
- package/src/docs/snapshot.json +103 -142
- package/src/i18n/es.ts +20 -6
- package/src/i18n/ja.ts +20 -6
- package/src/i18n/ko.ts +20 -6
- package/src/i18n/zh-cn.ts +20 -6
- package/src/i18n/zh-tw.ts +20 -6
- package/src/market-data/depositary-pair.ts +27 -3
- package/src/market-data/fund-facts.ts +50 -0
- package/src/market-data/market/change-basis.ts +16 -3
- package/src/market-data/market/format.ts +25 -0
- package/src/market-data/market/freshness.ts +2 -1
- package/src/market-data/options-alternatives.ts +81 -4
- package/src/market-data/quotes/metadata.ts +7 -0
- package/src/news/aggregator.ts +119 -9
- package/src/news/cloud-session.ts +21 -0
- package/src/news/hooks.ts +1 -0
- package/src/news/news-model.ts +1 -0
- package/src/news/types.ts +17 -0
- package/src/plugins/builtin/alerts/alert-engine.ts +20 -1
- package/src/plugins/builtin/alerts/alert-log.ts +33 -0
- package/src/plugins/builtin/alerts/calendar-events.ts +10 -4
- package/src/plugins/builtin/alerts/cli-forms.ts +216 -0
- package/src/plugins/builtin/alerts/cli.ts +362 -80
- package/src/plugins/builtin/alerts/command.ts +25 -1
- package/src/plugins/builtin/alerts/event-rows.ts +24 -3
- package/src/plugins/builtin/alerts/events-pane.tsx +34 -10
- package/src/plugins/builtin/alerts/fired-log.ts +73 -9
- package/src/plugins/builtin/alerts/format.ts +75 -5
- package/src/plugins/builtin/alerts/headless.ts +34 -12
- package/src/plugins/builtin/alerts/history-rows.ts +3 -2
- package/src/plugins/builtin/alerts/history.ts +1 -1
- package/src/plugins/builtin/alerts/index.tsx +79 -16
- package/src/plugins/builtin/alerts/metric-command.ts +77 -4
- package/src/plugins/builtin/alerts/metric-data.ts +54 -13
- package/src/plugins/builtin/alerts/metric-model.ts +163 -14
- package/src/plugins/builtin/alerts/metric-parity-fixture.json +1 -1
- package/src/plugins/builtin/alerts/pane.tsx +61 -23
- package/src/plugins/builtin/alerts/quotes.ts +6 -0
- package/src/plugins/builtin/alerts/storage.ts +12 -8
- package/src/plugins/builtin/alerts/types.ts +4 -0
- package/src/plugins/builtin/analytics/index.tsx +2 -1
- package/src/plugins/builtin/analytics/risk-client.ts +16 -5
- package/src/plugins/builtin/analytics/risk-fx.ts +70 -15
- package/src/plugins/builtin/analytics/risk-headless.ts +27 -0
- package/src/plugins/builtin/analytics/risk-model.ts +55 -9
- package/src/plugins/builtin/analytics/risk-pane.tsx +8 -2
- package/src/plugins/builtin/attention/index.tsx +2 -1
- package/src/plugins/builtin/attention/listing.ts +14 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/buildout/cells.tsx +12 -4
- package/src/plugins/builtin/buildout/format.ts +38 -0
- package/src/plugins/builtin/buildout/model/normalizers.ts +36 -1
- package/src/plugins/builtin/buildout/pane/index.tsx +4 -1
- package/src/plugins/builtin/buildout/table-model.ts +23 -2
- package/src/plugins/builtin/builtin-plugin-meta.ts +6 -2
- package/src/plugins/builtin/cds/client.ts +142 -30
- package/src/plugins/builtin/cds/headless.ts +35 -8
- package/src/plugins/builtin/cds/model.ts +145 -18
- package/src/plugins/builtin/cds/pane.tsx +16 -5
- package/src/plugins/builtin/changelog/index.tsx +9 -6
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +3 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +4 -0
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +7 -0
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -2
- package/src/plugins/builtin/chart-composer/follow-binding.ts +14 -2
- package/src/plugins/builtin/chart-composer/headless-schema.ts +7 -1
- package/src/plugins/builtin/chart-composer/headless.ts +6 -1
- package/src/plugins/builtin/chart-composer/index.tsx +5 -6
- package/src/plugins/builtin/chart-composer/pane.tsx +37 -8
- package/src/plugins/builtin/chart-composer/settings.ts +27 -0
- package/src/plugins/builtin/chat/content/command-suggestions.ts +1 -0
- package/src/plugins/builtin/chat/controller/index.ts +5 -1
- package/src/plugins/builtin/chat/controller/notifications.ts +33 -3
- package/src/plugins/builtin/chat/controller/state.ts +25 -2
- package/src/plugins/builtin/chat/controller/unread-people.ts +89 -23
- package/src/plugins/builtin/chat/controller/utils.ts +7 -2
- package/src/plugins/builtin/chat/pane-links/commands.ts +7 -1
- package/src/plugins/builtin/chat/status-preview.ts +79 -0
- package/src/plugins/builtin/chat/status-widget.tsx +147 -10
- package/src/plugins/builtin/chat/unread-badge.ts +51 -10
- package/src/plugins/builtin/clinical-trials/client.ts +49 -4
- package/src/plugins/builtin/clinical-trials/model.ts +86 -31
- package/src/plugins/builtin/clinical-trials/pane.tsx +61 -49
- package/src/plugins/builtin/clinical-trials/sponsor-listing.ts +90 -0
- package/src/plugins/builtin/clinical-trials/sponsor-tickers.ts +95 -15
- package/src/plugins/builtin/clinical-trials/trial-pages.ts +50 -0
- package/src/plugins/builtin/cloud/askg/manifest.ts +2 -0
- package/src/plugins/builtin/company-attention/building.tsx +5 -1
- package/src/plugins/builtin/company-attention/client.ts +8 -9
- package/src/plugins/builtin/company-attention/evidence.ts +4 -1
- package/src/plugins/builtin/company-attention/headless.ts +2 -1
- package/src/plugins/builtin/company-attention/moves.tsx +5 -1
- package/src/plugins/builtin/company-attention/pane.tsx +12 -2
- package/src/plugins/builtin/company-attention/signals.tsx +5 -1
- package/src/plugins/builtin/company-kpis/headless.ts +8 -3
- package/src/plugins/builtin/company-kpis/model.ts +73 -5
- package/src/plugins/builtin/company-kpis/pane.tsx +15 -7
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/correlation/headless.ts +13 -5
- package/src/plugins/builtin/correlation/history.ts +22 -0
- package/src/plugins/builtin/cot/client.ts +22 -18
- package/src/plugins/builtin/cot/headless.ts +15 -10
- package/src/plugins/builtin/cot/model.ts +14 -1
- package/src/plugins/builtin/cot/pane.tsx +22 -14
- package/src/plugins/builtin/credit-boards/client.ts +6 -10
- package/src/plugins/builtin/credit-conditions/headless.ts +8 -2
- package/src/plugins/builtin/credit-conditions/index.tsx +5 -1
- package/src/plugins/builtin/credit-conditions/model.ts +4 -0
- package/src/plugins/builtin/credit-conditions/series.ts +3 -1
- package/src/plugins/builtin/credit-documents/detail.tsx +2 -2
- package/src/plugins/builtin/credit-documents/export.ts +173 -0
- package/src/plugins/builtin/credit-documents/headless.ts +10 -10
- package/src/plugins/builtin/credit-documents/model.ts +104 -14
- package/src/plugins/builtin/credit-documents/pane.tsx +12 -5
- package/src/plugins/builtin/custom-view/sources.ts +2 -0
- package/src/plugins/builtin/dividend-yield/client.ts +131 -23
- package/src/plugins/builtin/dividend-yield/headless.ts +44 -16
- package/src/plugins/builtin/dividend-yield/model.ts +8 -5
- package/src/plugins/builtin/dividend-yield/pane.tsx +38 -13
- package/src/plugins/builtin/dividend-yield/ranking.ts +37 -14
- package/src/plugins/builtin/dividend-yield/types.ts +20 -2
- package/src/plugins/builtin/dividend-yield/view.ts +30 -2
- package/src/plugins/builtin/docs/targets.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +3 -2
- package/src/plugins/builtin/doe/pane.tsx +13 -3
- package/src/plugins/builtin/earnings/board-model.ts +16 -15
- package/src/plugins/builtin/earnings/board.tsx +62 -71
- package/src/plugins/builtin/earnings/headless.ts +40 -4
- package/src/plugins/builtin/earnings/scope.ts +31 -43
- package/src/plugins/builtin/earnings-calls/calendar.tsx +2 -2
- package/src/plugins/builtin/earnings-calls/data.ts +18 -6
- package/src/plugins/builtin/earnings-calls/format.ts +31 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +20 -5
- package/src/plugins/builtin/earnings-calls/model.ts +6 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +12 -4
- package/src/plugins/builtin/econ/calendar-model.ts +48 -1
- package/src/plugins/builtin/econ/calendar-source.ts +4 -2
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/figures.ts +48 -0
- package/src/plugins/builtin/econ/index.tsx +14 -5
- package/src/plugins/builtin/econ/print-watch.ts +3 -1
- package/src/plugins/builtin/econ/types.ts +2 -0
- package/src/plugins/builtin/econ-statistics/client.ts +11 -0
- package/src/plugins/builtin/econ-statistics/defs.ts +6 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +16 -6
- package/src/plugins/builtin/econ-statistics/pane.tsx +8 -4
- package/src/plugins/builtin/econ-statistics/stats.ts +39 -9
- package/src/plugins/builtin/equity-screener/categories.ts +179 -0
- package/src/plugins/builtin/equity-screener/client.ts +4 -2
- package/src/plugins/builtin/equity-screener/headless.ts +144 -13
- package/src/plugins/builtin/equity-screener/ideas.ts +49 -0
- package/src/plugins/builtin/equity-screener/model.ts +99 -10
- package/src/plugins/builtin/equity-screener/pane.tsx +68 -13
- package/src/plugins/builtin/fixed-income/pane.tsx +2 -1
- package/src/plugins/builtin/futures/use-board-terms.ts +42 -28
- package/src/plugins/builtin/futures/use-front-returns.ts +45 -28
- package/src/plugins/builtin/fx-matrix/client.ts +6 -3
- package/src/plugins/builtin/fx-matrix/headless.ts +1 -1
- package/src/plugins/builtin/fx-matrix/index.tsx +4 -2
- package/src/plugins/builtin/fx-matrix/live-legs.ts +42 -3
- package/src/plugins/builtin/gpu/headless.ts +8 -2
- package/src/plugins/builtin/help/function-index.ts +4 -1
- package/src/plugins/builtin/help/index.tsx +62 -59
- package/src/plugins/builtin/help/shortcut-model.ts +1 -1
- package/src/plugins/builtin/help/shortcut-table.tsx +5 -6
- package/src/plugins/builtin/help/table-cells.tsx +13 -2
- package/src/plugins/builtin/holders/beneficial-client.ts +5 -1
- package/src/plugins/builtin/holders/beneficial-view.tsx +3 -0
- package/src/plugins/builtin/holders/fund-holders.ts +51 -0
- package/src/plugins/builtin/holders/headless.ts +22 -3
- package/src/plugins/builtin/holders/pane.tsx +3 -0
- package/src/plugins/builtin/holders/report-rows.ts +4 -1
- package/src/plugins/builtin/insider/headless.ts +2 -2
- package/src/plugins/builtin/ipo-calendar/client.ts +18 -2
- package/src/plugins/builtin/ipo-calendar/headless.ts +75 -11
- package/src/plugins/builtin/ipo-calendar/listing-ipo.ts +160 -0
- package/src/plugins/builtin/ipo-calendar/model.ts +98 -2
- package/src/plugins/builtin/iv-history/client.ts +52 -11
- package/src/plugins/builtin/iv-history/format.ts +36 -23
- package/src/plugins/builtin/iv-history/headless.ts +33 -18
- package/src/plugins/builtin/iv-history/index.tsx +2 -2
- package/src/plugins/builtin/iv-history/model.ts +163 -27
- package/src/plugins/builtin/iv-history/pane.tsx +10 -6
- package/src/plugins/builtin/iv-history/screen-pane.tsx +22 -15
- package/src/plugins/builtin/iv-history/universe.ts +5 -1
- package/src/plugins/builtin/jobs/client.ts +25 -29
- package/src/plugins/builtin/kelly-sizer/model.ts +12 -8
- package/src/plugins/builtin/kelly-sizer/pane.tsx +9 -9
- package/src/plugins/builtin/kelly-sizer/sections.tsx +19 -10
- package/src/plugins/builtin/kelly-sizer/types.ts +10 -4
- package/src/plugins/builtin/macro-day/headless.ts +12 -5
- package/src/plugins/builtin/macro-day/index.tsx +1 -1
- package/src/plugins/builtin/macro-day/model.ts +39 -5
- package/src/plugins/builtin/macro-day/pane.tsx +27 -19
- package/src/plugins/builtin/macro-day/release-table.ts +2 -2
- package/src/plugins/builtin/market-heatmap/data.ts +8 -33
- package/src/plugins/builtin/market-movers/client.ts +27 -7
- package/src/plugins/builtin/market-movers/headless.ts +34 -12
- package/src/plugins/builtin/market-movers/index.tsx +26 -14
- package/src/plugins/builtin/market-movers/min-float.ts +74 -0
- package/src/plugins/builtin/market-movers/model.ts +4 -1
- package/src/plugins/builtin/market-movers/screener.ts +22 -4
- package/src/plugins/builtin/market-movers/session-body.tsx +13 -8
- package/src/plugins/builtin/market-movers/session-table.ts +4 -3
- package/src/plugins/builtin/market-movers/table.ts +17 -5
- package/src/plugins/builtin/members/breadth-pane.tsx +2 -1
- package/src/plugins/builtin/mna/headless.ts +2 -0
- package/src/plugins/builtin/mna/pane.tsx +3 -1
- package/src/plugins/builtin/news/headless.ts +3 -1
- package/src/plugins/builtin/news/index.tsx +4 -0
- package/src/plugins/builtin/news/wire/categories.ts +19 -3
- package/src/plugins/builtin/news/wire/industry-pane.tsx +1 -0
- package/src/plugins/builtin/news/wire/news/footer.ts +31 -5
- package/src/plugins/builtin/news/wire/news/preset-pane.tsx +6 -1
- package/src/plugins/builtin/news/wire/news/table.tsx +2 -2
- package/src/plugins/builtin/openfda/client.ts +14 -2
- package/src/plugins/builtin/openfda/index.tsx +3 -2
- package/src/plugins/builtin/openfda/model.ts +9 -0
- package/src/plugins/builtin/openfda/pane.tsx +42 -6
- package/src/plugins/builtin/options/analytics.ts +29 -5
- package/src/plugins/builtin/options/enrichment.ts +17 -5
- package/src/plugins/builtin/options/table.ts +5 -2
- package/src/plugins/builtin/options/types.ts +2 -0
- package/src/plugins/builtin/options/view.tsx +17 -4
- package/src/plugins/builtin/options-positioning/client.ts +11 -0
- package/src/plugins/builtin/options-positioning/headless.ts +21 -8
- package/src/plugins/builtin/options-positioning/index.tsx +1 -1
- package/src/plugins/builtin/options-positioning/model.ts +78 -9
- package/src/plugins/builtin/options-positioning/pane.tsx +21 -6
- package/src/plugins/builtin/options-scenario/client.ts +116 -47
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +142 -10
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +206 -55
- package/src/plugins/builtin/options-scenario/csp-screen.ts +63 -23
- package/src/plugins/builtin/options-scenario/csp.ts +8 -2
- package/src/plugins/builtin/options-scenario/index.tsx +9 -7
- package/src/plugins/builtin/options-scenario/strategy-screen.ts +532 -0
- package/src/plugins/builtin/pe-band/model.ts +12 -49
- package/src/plugins/builtin/perps/cascade-tabs.tsx +161 -0
- package/src/plugins/builtin/perps/cascade.ts +236 -0
- package/src/plugins/builtin/perps/client.ts +56 -2
- package/src/plugins/builtin/perps/headless.ts +65 -9
- package/src/plugins/builtin/perps/index.tsx +7 -5
- package/src/plugins/builtin/perps/model.ts +18 -4
- package/src/plugins/builtin/perps/pane.tsx +19 -22
- package/src/plugins/builtin/perps/status-line.ts +25 -0
- package/src/plugins/builtin/plugin-module.ts +5 -1
- package/src/plugins/builtin/portfolio-list/cached-account.ts +3 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +2 -8
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +4 -4
- package/src/plugins/builtin/portfolio-list/cli/render.ts +7 -5
- package/src/plugins/builtin/portfolio-list/pane/futures-front.ts +40 -0
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -7
- package/src/plugins/builtin/portfolio-list/pane/streaming.ts +5 -2
- package/src/plugins/builtin/portfolio-list/pane/supplemental.ts +3 -2
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +0 -14
- package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +5 -2
- package/src/plugins/builtin/portfolio-list/table.tsx +15 -9
- package/src/plugins/builtin/primary-dealers/client.ts +13 -38
- package/src/plugins/builtin/realized-vol/client.ts +13 -5
- package/src/plugins/builtin/realized-vol/evidence.ts +29 -4
- package/src/plugins/builtin/realized-vol/headless.ts +8 -4
- package/src/plugins/builtin/realized-vol/index.tsx +2 -2
- package/src/plugins/builtin/realized-vol/model.ts +37 -6
- package/src/plugins/builtin/realized-vol/pane.tsx +11 -9
- package/src/plugins/builtin/relative-rotation/client.ts +18 -4
- package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
- package/src/plugins/builtin/relative-rotation/index.tsx +2 -1
- package/src/plugins/builtin/relative-rotation/model.ts +16 -40
- package/src/plugins/builtin/relative-rotation/pane.tsx +3 -2
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +3 -2
- package/src/plugins/builtin/research/event-model.ts +40 -12
- package/src/plugins/builtin/research/headless.ts +1 -1
- package/src/plugins/builtin/research/index.tsx +7 -3
- package/src/plugins/builtin/research/relative-valuation-headless.ts +13 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +31 -3
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +59 -20
- package/src/plugins/builtin/research/relative-valuation-peers.ts +217 -20
- package/src/plugins/builtin/research/relative-valuation-settings.ts +44 -0
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -3
- package/src/plugins/builtin/reverse-dcf/model.ts +61 -6
- package/src/plugins/builtin/reverse-dcf/pane.tsx +7 -4
- package/src/plugins/builtin/risk-factors/data.ts +4 -2
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/roadmap/index.tsx +28 -0
- package/src/plugins/builtin/roadmap/model.ts +67 -0
- package/src/plugins/builtin/roadmap/pane.tsx +244 -0
- package/src/plugins/builtin/scanner/flow-model.ts +50 -4
- package/src/plugins/builtin/scanner/flow-pane.tsx +367 -65
- package/src/plugins/builtin/scanner/flow-session.ts +146 -0
- package/src/plugins/builtin/scanner/headless.ts +204 -35
- package/src/plugins/builtin/scanner/index.ts +16 -5
- package/src/plugins/builtin/scanner/live-headless.ts +48 -5
- package/src/plugins/builtin/scanner/live-model.ts +11 -0
- package/src/plugins/builtin/scanner/live-pane.tsx +3 -3
- package/src/plugins/builtin/scanner/lock-note.ts +3 -2
- package/src/plugins/builtin/seasonality/headless.ts +10 -1
- package/src/plugins/builtin/sec/fund-facts-view.tsx +5 -2
- package/src/plugins/builtin/sec/fund-facts.ts +116 -34
- package/src/plugins/builtin/sec/headless.ts +4 -2
- package/src/plugins/builtin/sec/index.tsx +3 -0
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/cloud-resource.ts +16 -7
- package/src/plugins/builtin/shared/cloud-upgrade.ts +4 -3
- package/src/plugins/builtin/shared/earnings-calendar.ts +6 -2
- package/src/plugins/builtin/shared/earnings-report.ts +2 -2
- package/src/plugins/builtin/shared/headless-market-data.ts +2 -2
- package/src/plugins/builtin/shared/job-posting.ts +1 -0
- package/src/plugins/builtin/shared/members-menu.tsx +3 -2
- package/src/plugins/builtin/shared/pro-lock-note.ts +12 -12
- package/src/plugins/builtin/shared/report-freshness.ts +11 -2
- package/src/plugins/builtin/shared/research-cells.tsx +1 -1
- package/src/plugins/builtin/shared/series-cache.ts +4 -4
- package/src/plugins/builtin/shared/ticker-choice.tsx +2 -1
- package/src/plugins/builtin/shared/ticker-company.ts +77 -0
- package/src/plugins/builtin/shared/use-quote-board.ts +2 -1
- package/src/plugins/builtin/shared/volatility/live-session.ts +34 -8
- package/src/plugins/builtin/shared/volatility/pricing.ts +19 -0
- package/src/plugins/builtin/shared/wall-view-lifecycle.ts +3 -1
- package/src/plugins/builtin/themes/model.ts +16 -7
- package/src/plugins/builtin/themes/pane.tsx +5 -5
- package/src/plugins/builtin/thirteenf/api.ts +12 -1
- package/src/plugins/builtin/thirteenf/data.ts +7 -7
- package/src/plugins/builtin/thirteenf/headless.ts +31 -4
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +43 -18
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +3 -2
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +62 -0
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +83 -46
- package/src/plugins/builtin/ticker-detail/headless.ts +31 -16
- package/src/plugins/builtin/ticker-detail/overview/model.ts +11 -3
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/pane.tsx +14 -8
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/settings.ts +1 -0
- package/src/plugins/builtin/time-sales/pane.tsx +31 -19
- package/src/plugins/builtin/treasury-auctions/headless.ts +21 -12
- package/src/plugins/builtin/treasury-auctions/pane.tsx +9 -3
- package/src/plugins/builtin/treasury-daily/client.ts +41 -5
- package/src/plugins/builtin/treasury-daily/headless.ts +2 -2
- package/src/plugins/builtin/treasury-daily/index.tsx +1 -1
- package/src/plugins/builtin/treasury-daily/model.ts +50 -3
- package/src/plugins/builtin/treasury-daily/pane.tsx +81 -2
- package/src/plugins/builtin/vol-surface/client.ts +3 -13
- package/src/plugins/builtin/vol-surface/headless.ts +3 -3
- package/src/plugins/builtin/vol-surface/index.tsx +1 -1
- package/src/plugins/builtin/vol-surface/pane.tsx +7 -5
- package/src/plugins/builtin/volatility/index.tsx +2 -2
- package/src/plugins/builtin/volatility/pane.tsx +7 -4
- package/src/plugins/builtin/world-venue-map/headless.ts +3 -3
- package/src/plugins/builtin/yield-curve/client.ts +61 -1
- package/src/plugins/builtin/yield-curve/headless.ts +9 -6
- package/src/plugins/builtin/yield-curve/index.tsx +34 -10
- package/src/plugins/builtin/yield-curve/swaps.tsx +9 -5
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/catalog-manifest.ts +2 -1
- package/src/plugins/host-link.ts +1 -1
- package/src/plugins/marketplace/model.ts +18 -5
- package/src/portfolio/column-values.ts +11 -7
- package/src/portfolio/futures-positions.ts +6 -3
- package/src/portfolio/position-quantity.ts +15 -9
- package/src/remote/resources.ts +2 -1
- package/src/renderers/dom/data-table/row.tsx +26 -0
- package/src/renderers/dom/desktop/icons.tsx +7 -0
- package/src/renderers/dom/desktop/list-view.tsx +13 -10
- package/src/renderers/dom/desktop/query-bar.tsx +4 -2
- package/src/renderers/dom/desktop/select-field.tsx +4 -2
- package/src/renderers/dom/host/chart-surface.tsx +21 -0
- package/src/renderers/electrobun/bun/desktop/app-name.ts +3 -3
- package/src/renderers/electrobun/bun/desktop/backend.ts +21 -10
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +15 -0
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -0
- package/src/renderers/electrobun/bun/desktop/installer-folder.ts +731 -0
- package/src/renderers/electrobun/bun/desktop/relaunch.ts +102 -10
- package/src/renderers/electrobun/bun/desktop/update.ts +115 -14
- package/src/renderers/electrobun/bun/desktop/view-ids.ts +52 -0
- package/src/renderers/electrobun/bun/desktop/windows-script.ts +92 -0
- package/src/renderers/electrobun/bun/index.ts +26 -2
- package/src/renderers/electrobun/bun/window/create.ts +43 -4
- package/src/renderers/electrobun/bun/window/events.ts +20 -0
- package/src/renderers/electrobun/bun/window/windows-custom-chrome.ts +9 -2
- package/src/renderers/electrobun/bun/window/windows-native.ts +78 -0
- package/src/renderers/electrobun/bun/window/windows-quit.ts +57 -0
- package/src/renderers/electrobun/shared/app-name.ts +13 -0
- package/src/renderers/electrobun/shared/protocol.ts +12 -0
- package/src/renderers/electrobun/view/backend-rpc.ts +6 -0
- package/src/renderers/electrobun/view/main.tsx +24 -1
- package/src/renderers/electrobun/view/news-source.ts +5 -1
- package/src/renderers/electrobun/view/remote/ticker-repository.ts +14 -7
- package/src/renderers/electrobun/view/ui-host.tsx +8 -0
- package/src/renderers/electrobun/view/view-ids.ts +85 -0
- package/src/renderers/opentui/start.tsx +5 -0
- package/src/series/registry.ts +1 -0
- package/src/series/types.ts +6 -0
- package/src/series/validate.ts +1 -0
- package/src/sources/gloomberb-cloud/fred-series.ts +3 -1
- package/src/sources/gloomberb-cloud/index.ts +43 -8
- package/src/sources/gloomberb-cloud/news.ts +47 -7
- package/src/sources/provider-router/financials.ts +15 -3
- package/src/sources/provider-router/index.ts +8 -5
- package/src/state/ticker-cleanup.ts +50 -0
- package/src/sync/controller.ts +4 -3
- package/src/sync/core-contributors.ts +90 -31
- package/src/telemetry/stall-reports-dom.ts +38 -0
- package/src/telemetry/stall-reports-node.ts +75 -0
- package/src/telemetry/stall-reports.ts +214 -0
- package/src/test-support/preload.ts +14 -0
- package/src/theme/themes.ts +10 -0
- package/src/tickers/company-name-listing.ts +53 -13
- package/src/tickers/company-name.ts +50 -4
- package/src/tickers/index-roots.ts +7 -0
- package/src/tickers/listing-fate.ts +2 -2
- package/src/tickers/listing-venues.ts +15 -3
- package/src/tickers/search/index.ts +6 -2
- package/src/tickers/search/ranking.ts +5 -1
- package/src/tickers/search/upsert.ts +13 -0
- package/src/tickers/terminal-codes.ts +19 -0
- package/src/tickers/ticker-changes.ts +8 -4
- package/src/time-series/alignment.ts +1 -1
- package/src/time-series/economic.ts +18 -4
- package/src/time-series/field-catalog.ts +1 -1
- package/src/time-series/filed-trailing-eps.ts +197 -0
- package/src/time-series/fundamentals.ts +44 -1
- package/src/time-series/ice-credit.ts +3 -0
- package/src/time-series/price-comparison.ts +30 -2
- package/src/time-series/resolve-context.ts +3 -1
- package/src/time-series/resolve.ts +56 -4
- package/src/time-series/session-bar.ts +11 -0
- package/src/time-series/spec.ts +3 -2
- package/src/time-series/studies.ts +8 -2
- package/src/time-series/total-return.ts +160 -0
- package/src/time-series/transforms.ts +2 -3
- package/src/time-series/types.ts +22 -1
- package/src/types/company-from.ts +40 -0
- package/src/types/data-provider.ts +7 -0
- package/src/types/financials.ts +59 -1
- package/src/types/headless.ts +27 -3
- package/src/types/news-source.ts +1 -0
- package/src/types/plugin.ts +9 -0
- package/src/ui/host.tsx +3 -0
- package/src/updater/failure.ts +4 -1
- package/src/utils/cli-output.ts +42 -1
- package/src/utils/crypto-pair.ts +165 -7
- package/src/utils/declared-dividends.ts +1 -1
- package/src/utils/forward-dividend.ts +2 -0
- package/src/utils/fundamentals.ts +60 -8
- package/src/utils/fx-market-hours.ts +26 -3
- package/src/utils/main-thread-stall.ts +35 -2
- package/src/utils/market-capitalization.ts +24 -1
- package/src/utils/price-history.ts +7 -1
- package/src/utils/shell-word.ts +8 -0
- package/src/utils/trailing-dividend.ts +53 -4
- package/src/version.ts +2 -2
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +0 -17
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
2
|
import { formatActionChords, hasKeybindingCaptureRequest, subscribeKeybindingCapture, useKeybindings } from "../../../app/keybindings";
|
|
3
|
-
import { Notice,
|
|
3
|
+
import { Notice, usePaneFooter, usePaneMenuItems, usePaneTabs, type PaneHint, type TableSection } from "../../../components";
|
|
4
4
|
import { t, tf } from "../../../i18n";
|
|
5
5
|
import { colors } from "../../../theme/colors";
|
|
6
6
|
import type { PaneProps } from "../../../types/plugin";
|
|
@@ -18,6 +18,7 @@ import { FunctionsTable } from "./functions-table";
|
|
|
18
18
|
import { KeybindingsEditor } from "./keybindings-editor";
|
|
19
19
|
import { ShortcutTable, type ShortcutTableEntry } from "./shortcut-table";
|
|
20
20
|
import { resolveCommandShortcuts, resolveWindowTemplates } from "./shortcut-model";
|
|
21
|
+
import { badgeColumnWidth } from "./table-cells";
|
|
21
22
|
|
|
22
23
|
const HELP_TABS = [
|
|
23
24
|
{ label: "Basics", value: "basics" },
|
|
@@ -47,6 +48,9 @@ const TRY_THESE = [
|
|
|
47
48
|
{ query: "EE TSLA", description: "What analysts expect from Tesla" },
|
|
48
49
|
] as const;
|
|
49
50
|
|
|
51
|
+
/** The most of a table its key column takes, however many chips a row carries. */
|
|
52
|
+
const KEY_COLUMN_MAX_SHARE = 0.4;
|
|
53
|
+
|
|
50
54
|
function HelpPane({ focused, width, height }: PaneProps) {
|
|
51
55
|
const registry = getSharedRegistry();
|
|
52
56
|
const { openCommandBar, showPane, createPaneFromTemplate } = usePluginAppActions();
|
|
@@ -83,7 +87,7 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
83
87
|
// The UPGRADE line says how long the trial is; the length comes from /pricing.
|
|
84
88
|
const [pricing, setPricing] = useState<CloudPricing | null>(null);
|
|
85
89
|
useEffect(() => {
|
|
86
|
-
if (activeTabId !== "
|
|
90
|
+
if (activeTabId !== "reference" || pricing) return;
|
|
87
91
|
let live = true;
|
|
88
92
|
void apiClient.getCloudPricing()
|
|
89
93
|
.then((next) => {
|
|
@@ -131,10 +135,11 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
131
135
|
// Each tab's actions. `l` moves between tabs, so layout actions take `a`.
|
|
132
136
|
const tabHints = useMemo<PaneHint[]>(() => {
|
|
133
137
|
if (activeTabId === "basics") {
|
|
134
|
-
return [
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
return [{ id: "docs", key: "d", label: "ocs", title: "Open Docs", onPress: openDocs }];
|
|
139
|
+
}
|
|
140
|
+
// The layout rows are here, so their action is.
|
|
141
|
+
if (activeTabId === "reference") {
|
|
142
|
+
return [{ id: "layout-actions", key: "a", label: " layout actions", title: "Layout Actions", onPress: openLayoutActions }];
|
|
138
143
|
}
|
|
139
144
|
if (activeTabId === "functions") {
|
|
140
145
|
return [{ id: "plugins", key: "p", label: "lugins", title: "Manage Plugins", onPress: openPluginManager }];
|
|
@@ -192,32 +197,31 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
192
197
|
].filter((item) => hasCode(item.badges[0]!)),
|
|
193
198
|
}], [hasCode]);
|
|
194
199
|
|
|
195
|
-
const commandBarSections = useMemo<Array<TableSection<ShortcutTableEntry>>>(() => [{
|
|
196
|
-
label: "Command Bar",
|
|
197
|
-
items: [
|
|
198
|
-
...(commandBarBadges.length > 0
|
|
199
|
-
? [entry("open", commandBarBadges, "Open command mode for actions, pane commands, and typed prefixes.")]
|
|
200
|
-
: []),
|
|
201
|
-
...(tickerSearchBadges.length > 0
|
|
202
|
-
? [entry("ticker-search", tickerSearchBadges, "Open ticker search directly.")]
|
|
203
|
-
: []),
|
|
204
|
-
entry("des", ["DES", "<ticker>"], "Open security details for a specific ticker."),
|
|
205
|
-
entry("help-card", ["HELP", "<function>"], "Open a function's help card: what it shows, its keys, how fresh its data is. HELP HELP reaches support."),
|
|
206
|
-
entry("docs", ["DOCS", "<function>"], "Read the docs and Academy lessons in the app. The ? on a pane opens its entry."),
|
|
207
|
-
entry("upgrade", ["UPGRADE"], tf("Go Pro for real-time data at gloom.sh/cloud, free for {days} days.", { days: trialDays })),
|
|
208
|
-
entry("mcp", ["MCP"], "Connect Claude Code, Codex, Cursor or any MCP client to Gloom's research tools."),
|
|
209
|
-
entry("move", ["Up/Down", "Ctrl+P/N"], "Move through command bar results."),
|
|
210
|
-
entry("page", ["PageUp/PageDown", "Ctrl+Home/End"], "Jump a page, or to the first or last result."),
|
|
211
|
-
entry("run", ["Enter", "Shift+Enter"], "Run the selected result or its secondary action."),
|
|
212
|
-
entry("accept-arg", ["Tab"], "Accept a suggested command argument when one is available."),
|
|
213
|
-
entry("close", ["Esc", ...tickerSearchBadges.filter((badge) => badge === "`" || badge.includes("+"))], "Close the command bar."),
|
|
214
|
-
entry("clear", ["Ctrl+U"], "Clear command text."),
|
|
215
|
-
entry("delete-word", ["Ctrl+W"], "Delete the previous word in command text."),
|
|
216
|
-
entry("back", ["Backspace"], "Go back from a nested command screen when the query is empty."),
|
|
217
|
-
],
|
|
218
|
-
}], [commandBarBadges, tickerSearchBadges, trialDays]);
|
|
219
|
-
|
|
220
200
|
const referenceSections = useMemo<Array<TableSection<ShortcutTableEntry>>>(() => [
|
|
201
|
+
{
|
|
202
|
+
label: "Command Bar",
|
|
203
|
+
items: [
|
|
204
|
+
...(commandBarBadges.length > 0
|
|
205
|
+
? [entry("cmd-open", commandBarBadges, "Open command mode for actions, pane commands, and typed prefixes.")]
|
|
206
|
+
: []),
|
|
207
|
+
...(tickerSearchBadges.length > 0
|
|
208
|
+
? [entry("cmd-ticker-search", tickerSearchBadges, "Open ticker search directly.")]
|
|
209
|
+
: []),
|
|
210
|
+
entry("cmd-des", ["DES", "<ticker>"], "Open security details for a specific ticker."),
|
|
211
|
+
entry("cmd-help-card", ["HELP", "<function>"], "Open a function's help card: what it shows, its keys, how fresh its data is. HELP HELP reaches support."),
|
|
212
|
+
entry("cmd-docs", ["DOCS", "<function>"], "Read the docs and Academy lessons in the app. The ? on a pane opens its entry."),
|
|
213
|
+
entry("cmd-upgrade", ["UPGRADE"], tf("Go Pro for real-time data at gloom.sh/cloud, free for {days} days.", { days: trialDays })),
|
|
214
|
+
entry("cmd-mcp", ["MCP"], "Connect Claude Code, Codex, Cursor or any MCP client to Gloom's research tools."),
|
|
215
|
+
entry("cmd-move", ["Up/Down", "Ctrl+P/N"], "Move through command bar results."),
|
|
216
|
+
entry("cmd-page", ["PageUp/PageDown", "Ctrl+Home/End"], "Jump a page, or to the first or last result."),
|
|
217
|
+
entry("cmd-run", ["Enter", "Shift+Enter"], "Run the selected result or its secondary action."),
|
|
218
|
+
entry("cmd-accept-arg", ["Tab"], "Accept a suggested command argument when one is available."),
|
|
219
|
+
entry("cmd-close", ["Esc", ...tickerSearchBadges.filter((badge) => badge === "`" || badge.includes("+"))], "Close the command bar."),
|
|
220
|
+
entry("cmd-clear", ["Ctrl+U"], "Clear command text."),
|
|
221
|
+
entry("cmd-delete-word", ["Ctrl+W"], "Delete the previous word in command text."),
|
|
222
|
+
entry("cmd-back", ["Backspace"], "Go back from a nested command screen when the query is empty."),
|
|
223
|
+
],
|
|
224
|
+
},
|
|
221
225
|
{
|
|
222
226
|
label: "Navigation",
|
|
223
227
|
items: [
|
|
@@ -235,7 +239,8 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
235
239
|
entry("search", ["/"], "Search in the focused pane."),
|
|
236
240
|
entry("sidebar", ["<", ">"], "Narrow or widen the list beside the content, as in MAP and ASKG."),
|
|
237
241
|
entry("warnings", ["!"], "Open the focused pane's data warnings."),
|
|
238
|
-
entry("notification",
|
|
242
|
+
entry("notification", actionBadges("notification-action"), "Run the newest notification."),
|
|
243
|
+
entry("notification-dismiss", actionBadges("notification-dismiss"), "Dismiss the newest notification."),
|
|
239
244
|
],
|
|
240
245
|
},
|
|
241
246
|
{
|
|
@@ -264,6 +269,7 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
264
269
|
entry("zoom-tool", ["Shift+Z", "Shift+Drag"], "Pick the zoom tool, then drag a time range."),
|
|
265
270
|
entry("ruler", ["Shift+M", "Alt+Drag"], "Pick the ruler, then drag to measure a move."),
|
|
266
271
|
entry("draw", ["Shift+D", "Shift+P"], "Draw a trend line or a freehand shape."),
|
|
272
|
+
entry("shapes", ["Shift+J", "Shift+B", "Shift+F"], "Draw a horizontal ray, a rectangle or a Fib retracement."),
|
|
267
273
|
entry("place", ["Enter", "Arrows"], "With a tool picked, Enter starts it at the cursor, the arrows move its end, and Enter finishes it."),
|
|
268
274
|
entry("drawings", ["[", "]"], "With a drawing tool picked, pick a drawing."),
|
|
269
275
|
entry("colour", ["c", "Backspace"], "Cycle the drawing colour, or delete the picked drawing (the last one while a drawing tool is picked)."),
|
|
@@ -302,6 +308,14 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
302
308
|
entry("close-pane", ["Esc", "Esc"], "Close the focused pane when nothing is being dragged."),
|
|
303
309
|
],
|
|
304
310
|
},
|
|
311
|
+
{
|
|
312
|
+
// Docked panes keep the saved layout and floating ones follow the pointer; the keyboard's way is Window Mode below.
|
|
313
|
+
label: "Layout",
|
|
314
|
+
items: [
|
|
315
|
+
entry("layout-drag", ["Drag"], "Floating panes can be dragged by the title bar and resized from the lower-right corner."),
|
|
316
|
+
{ ...entry("layout-actions", ["LMA"], "Use Layout Actions for split, move, duplicate, close all floating panes, undo, redo, and layout presets."), run: openLayoutActions },
|
|
317
|
+
],
|
|
318
|
+
},
|
|
305
319
|
{
|
|
306
320
|
label: "Window Mode",
|
|
307
321
|
items: [
|
|
@@ -319,7 +333,14 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
319
333
|
entry("commit", ["Enter", "Esc"], "Commit pending changes or exit window mode."),
|
|
320
334
|
],
|
|
321
335
|
},
|
|
322
|
-
], [askBadges, copyBadges, functionHelpBadges, pasteBadges, windowMoveBadges, windowResizeBadges]);
|
|
336
|
+
], [askBadges, commandBarBadges, copyBadges, functionHelpBadges, openLayoutActions, pasteBadges, tickerSearchBadges, trialDays, windowMoveBadges, windowResizeBadges]);
|
|
337
|
+
|
|
338
|
+
// One key column for every key table in Help, wide enough for the longest group of chips, so the descriptions
|
|
339
|
+
// line up from table to table. A narrow pane caps it, and a row past the cap shows the chips that fit whole.
|
|
340
|
+
const keyColumnWidth = useMemo(() => badgeColumnWidth(
|
|
341
|
+
[...trySections, ...startSections, ...referenceSections].flatMap((section) => section.items.map((item) => item.badges)),
|
|
342
|
+
{ min: 8, max: Math.max(8, Math.floor(width * KEY_COLUMN_MAX_SHARE)) },
|
|
343
|
+
), [referenceSections, startSections, trySections, width]);
|
|
323
344
|
|
|
324
345
|
const renderContent = () => {
|
|
325
346
|
switch (activeTabId) {
|
|
@@ -338,38 +359,19 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
338
359
|
<>
|
|
339
360
|
{trySections.length > 0 && (
|
|
340
361
|
<Box marginBottom={1}>
|
|
341
|
-
<ShortcutTable sections={trySections} width={bodyWidth} keyLabel="TYPE" descriptionLabel="OPENS" />
|
|
362
|
+
<ShortcutTable sections={trySections} width={bodyWidth} keyWidth={keyColumnWidth} keyLabel="TYPE" descriptionLabel="OPENS" />
|
|
342
363
|
</Box>
|
|
343
364
|
)}
|
|
344
365
|
|
|
345
|
-
<
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
{commandBarBadges[0]
|
|
351
|
-
? tf("Not sure of a code? Click the search bar at the top, or press {key}, and type what you want in plain words, like \"top news\". The Functions tab lists everything.", { key: commandBarBadges[0] })
|
|
352
|
-
: t("Not sure of a code? Click the search bar at the top and type what you want in plain words, like \"top news\". The Functions tab lists everything.")}
|
|
353
|
-
</Text>
|
|
354
|
-
</Box>
|
|
355
|
-
</Box>
|
|
366
|
+
<Text fg={colors.textDim} wrapText>
|
|
367
|
+
{commandBarBadges[0]
|
|
368
|
+
? tf("Not sure of a code? Click the search bar at the top, or press {key}, and type what you want in plain words, like \"top news\". The Functions tab lists everything.", { key: commandBarBadges[0] })
|
|
369
|
+
: t("Not sure of a code? Click the search bar at the top and type what you want in plain words, like \"top news\". The Functions tab lists everything.")}
|
|
370
|
+
</Text>
|
|
356
371
|
|
|
357
372
|
<Box marginTop={1}>
|
|
358
|
-
<ShortcutTable sections={startSections} width={bodyWidth} />
|
|
373
|
+
<ShortcutTable sections={startSections} width={bodyWidth} keyWidth={keyColumnWidth} />
|
|
359
374
|
</Box>
|
|
360
|
-
|
|
361
|
-
<Box marginTop={1}>
|
|
362
|
-
<ShortcutTable sections={commandBarSections} width={bodyWidth} />
|
|
363
|
-
</Box>
|
|
364
|
-
|
|
365
|
-
<Section title="Layout Basics">
|
|
366
|
-
<Text fg={colors.text}>{t("Docked panes stay in the saved layout.")}</Text>
|
|
367
|
-
<Text fg={colors.text} wrapText>{t("Floating panes can be dragged by the title bar and resized from the lower-right corner.")}</Text>
|
|
368
|
-
{windowMoveBadges[0] && windowResizeBadges[0] && (
|
|
369
|
-
<Text fg={colors.text} wrapText>{tf("From the keyboard, {move} moves the focused window and {resize} resizes it.", { move: windowMoveBadges[0], resize: windowResizeBadges[0] })}</Text>
|
|
370
|
-
)}
|
|
371
|
-
<Text fg={colors.text} wrapText>{t("Use Layout Actions for split, move, duplicate, close all floating panes, undo, redo, and layout presets.")}</Text>
|
|
372
|
-
</Section>
|
|
373
375
|
</>
|
|
374
376
|
);
|
|
375
377
|
}
|
|
@@ -395,6 +397,7 @@ function HelpPane({ focused, width, height }: PaneProps) {
|
|
|
395
397
|
<ShortcutTable
|
|
396
398
|
sections={referenceSections}
|
|
397
399
|
width={width}
|
|
400
|
+
keyWidth={keyColumnWidth}
|
|
398
401
|
height={contentHeight}
|
|
399
402
|
after={(
|
|
400
403
|
<Box paddingX={1} flexShrink={0}>
|
|
@@ -18,7 +18,7 @@ export function resolveWindowTemplates(registry: SharedRegistry): HelpShortcutEn
|
|
|
18
18
|
const allPlugins = registry.allPlugins ?? new Map<string, { name?: string }>();
|
|
19
19
|
|
|
20
20
|
return [...registry.paneTemplates.values()]
|
|
21
|
-
.filter((template) => template.shortcut)
|
|
21
|
+
.filter((template) => template.shortcut && template.listed !== false)
|
|
22
22
|
.filter((template) => {
|
|
23
23
|
const pluginId = registry.getPaneTemplatePluginId?.(template.id);
|
|
24
24
|
return !pluginId || !disabledPlugins.has(pluginId);
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import { t } from "../../../i18n";
|
|
23
23
|
import { useThemeColors } from "../../../theme/theme-context";
|
|
24
24
|
import { Box, useUiCapabilities } from "../../../ui";
|
|
25
|
-
import { badgeCell
|
|
25
|
+
import { badgeCell } from "./table-cells";
|
|
26
26
|
|
|
27
27
|
export interface ShortcutTableEntry {
|
|
28
28
|
id: string;
|
|
@@ -38,6 +38,7 @@ type ShortcutRow = SectionedRow<ShortcutTableEntry>;
|
|
|
38
38
|
export function ShortcutTable({
|
|
39
39
|
sections,
|
|
40
40
|
width,
|
|
41
|
+
keyWidth,
|
|
41
42
|
height: fillHeight,
|
|
42
43
|
after,
|
|
43
44
|
keyLabel = "KEY",
|
|
@@ -46,6 +47,8 @@ export function ShortcutTable({
|
|
|
46
47
|
sections: ReadonlyArray<TableSection<ShortcutTableEntry>>;
|
|
47
48
|
/** Content width available inside the tab body. */
|
|
48
49
|
width: number;
|
|
50
|
+
/** The key column's width, one for every table in Help so their descriptions line up. */
|
|
51
|
+
keyWidth: number;
|
|
49
52
|
/** Fill this many rows and scroll, instead of growing to fit every row. */
|
|
50
53
|
height?: number;
|
|
51
54
|
/** Sits under a full-height table inside the same frame. */
|
|
@@ -59,10 +62,6 @@ export function ShortcutTable({
|
|
|
59
62
|
() => buildSectionedRows(sections, (entry) => entry.id),
|
|
60
63
|
[sections],
|
|
61
64
|
);
|
|
62
|
-
const keyWidth = useMemo(
|
|
63
|
-
() => badgeColumnWidth(rows.filter(isSectionedItemRow).map((row) => row.item.badges), { min: 8, max: 24 }),
|
|
64
|
-
[rows],
|
|
65
|
-
);
|
|
66
65
|
const columns = useMemo<ShortcutColumn[]>(() => [
|
|
67
66
|
{ id: "key", label: keyLabel, width: keyWidth, align: "left" },
|
|
68
67
|
{ id: "description", label: descriptionLabel, width: 20, align: "left", flexGrow: 1 },
|
|
@@ -72,7 +71,7 @@ export function ShortcutTable({
|
|
|
72
71
|
if (!isSectionedItemRow(row)) return EMPTY_TABLE_CELL;
|
|
73
72
|
const run = row.item.run;
|
|
74
73
|
const cell: DataTableCell = column.id === "key"
|
|
75
|
-
? badgeCell(row.item.badges, column.width)
|
|
74
|
+
? badgeCell(row.item.badges, column.width, { wholeOnly: true })
|
|
76
75
|
: { text: t(row.item.description), color: colors.text };
|
|
77
76
|
if (!run) return cell;
|
|
78
77
|
return {
|
|
@@ -31,10 +31,21 @@ export function badgeColumnWidth(
|
|
|
31
31
|
return Math.max(min, Math.min(max, widest));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* The chips of a group that fit a column whole, in order. A chip that would be
|
|
36
|
+
* cut ("Ctrl+Hor") is left out instead, so what shows is always a real key; the
|
|
37
|
+
* first chip stays whatever the width.
|
|
38
|
+
*/
|
|
39
|
+
export function wholeBadges(labels: readonly string[], width: number): readonly string[] {
|
|
40
|
+
let count = Math.min(1, labels.length);
|
|
41
|
+
while (count < labels.length && badgeGroupWidth(labels.slice(0, count + 1)) <= width) count += 1;
|
|
42
|
+
return labels.slice(0, count);
|
|
43
|
+
}
|
|
44
|
+
|
|
34
45
|
export function badgeCell(
|
|
35
46
|
labels: readonly string[],
|
|
36
47
|
width: number,
|
|
37
|
-
options: { tone?: "neutral" | "accent"; emptyLabel?: string; emptyColor?: string } = {},
|
|
48
|
+
options: { tone?: "neutral" | "accent"; emptyLabel?: string; emptyColor?: string; wholeOnly?: boolean } = {},
|
|
38
49
|
): DataTableCell {
|
|
39
50
|
if (labels.length === 0) {
|
|
40
51
|
return options.emptyLabel
|
|
@@ -45,7 +56,7 @@ export function badgeCell(
|
|
|
45
56
|
text: labels.join(" "),
|
|
46
57
|
content: (
|
|
47
58
|
<Box flexDirection="row" gap={BADGE_GAP} width={width} height={1} overflow="hidden">
|
|
48
|
-
{labels.map((label, index) => (
|
|
59
|
+
{(options.wholeOnly ? wholeBadges(labels, width) : labels).map((label, index) => (
|
|
49
60
|
<Badge key={`${label}:${index}`} label={label} variant="solid" tone={options.tone ?? "neutral"} />
|
|
50
61
|
))}
|
|
51
62
|
</Box>
|
|
@@ -11,6 +11,7 @@ import { listingAbroad, type IssuerListingParams } from "../../../api-client/pat
|
|
|
11
11
|
import { createPluginCache } from "../../../data/plugin-cache";
|
|
12
12
|
import { secListingKey } from "../../../utils/sec";
|
|
13
13
|
import { finiteOrNull, recordOrNull } from "../../../utils/guards";
|
|
14
|
+
import { readCompanyFrom } from "../../../types/company-from";
|
|
14
15
|
import { cachedCloudResource, loadCloudResource, type CloudResource } from "../shared/cloud-resource";
|
|
15
16
|
import { CLOUD_SESSION_REQUIRED } from "../shared/research-cloud-session";
|
|
16
17
|
|
|
@@ -110,8 +111,11 @@ function normalizeBeneficialOwnersPayload(value: unknown, ticker: string): Benef
|
|
|
110
111
|
if (!raw || !Array.isArray(raw.owners)) throw new Error("The server returned an invalid 13D/13G list");
|
|
111
112
|
const coverage = recordOrNull(raw.coverage);
|
|
112
113
|
const nextOffset = finiteOrNull(raw.nextOffset);
|
|
114
|
+
const companyFrom = readCompanyFrom(raw.companyFrom);
|
|
115
|
+
const { companyFrom: _unread, ...rest } = raw;
|
|
113
116
|
return {
|
|
114
|
-
...
|
|
117
|
+
...rest,
|
|
118
|
+
...(companyFrom ? { companyFrom } : {}),
|
|
115
119
|
ticker: text(raw.ticker) ?? ticker,
|
|
116
120
|
cik: cikOrNull(raw.cik) ?? "",
|
|
117
121
|
companyName: text(raw.companyName) ?? "",
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type DataTableCell,
|
|
10
10
|
type DataTableKeyEvent,
|
|
11
11
|
} from "../../../components";
|
|
12
|
+
import { useCompanyDataFooter } from "../../../components/layout/pane/status-footer";
|
|
12
13
|
import { handleRefreshKey, loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
|
|
13
14
|
import type { IssuerListingParams } from "../../../api-client/paths";
|
|
14
15
|
import { useAsyncResource } from "../../../react/async-resource";
|
|
@@ -233,6 +234,8 @@ export function BeneficialOwnersView({
|
|
|
233
234
|
focused,
|
|
234
235
|
title: "13D/13G coverage",
|
|
235
236
|
});
|
|
237
|
+
// A foreign line's owners are its company's, read from the home line.
|
|
238
|
+
useCompanyDataFooter(payload?.companyFrom);
|
|
236
239
|
usePaneFooter("holders-13dg", () => ({
|
|
237
240
|
info: [
|
|
238
241
|
...(payload?.asOf ? [{ id: "as-of", parts: [{ text: `as of ${payload.asOf.slice(0, 10)}`, tone: "muted" as const }] }] : []),
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Quote } from "../../../types/financials";
|
|
2
|
+
import { quoteTradingExchange } from "../../../market-data/quotes/metadata";
|
|
3
|
+
import { isUsListingExchange } from "../../../utils/exchanges";
|
|
4
|
+
import { isFundType } from "../../../utils/sec";
|
|
5
|
+
import { isNoSourceAnswer } from "../../../sources/provider-errors";
|
|
6
|
+
import { logFailure } from "../../../utils/log-failure";
|
|
7
|
+
import { fetchFunds } from "../members/client";
|
|
8
|
+
import { coveredFund } from "../members/model";
|
|
9
|
+
|
|
10
|
+
type FundQuote = Pick<Quote, "instrumentType" | "tradingExchangeName" | "listingExchangeName" | "exchangeName">;
|
|
11
|
+
|
|
12
|
+
/** What a holder report says for a fund in place of its holders: the reason, and the commands that read the fund. */
|
|
13
|
+
export interface FundHoldersAnswer {
|
|
14
|
+
message: string;
|
|
15
|
+
/** One command a line, each for what it reads; empty for a fund abroad, which those do not cover. */
|
|
16
|
+
details: string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* What `holders`, `13f` and `fn HDS` say for a fund no holder source has an
|
|
21
|
+
* ownership breakdown of (XLE, SPY, EWJ), in place of the source's bare
|
|
22
|
+
* NO_DATA: that it is a fund, and for a US-listed one the commands that read
|
|
23
|
+
* it, each only where it runs: the 13F filers that hold it (`fn 13F`), what it
|
|
24
|
+
* holds where `fn MEMB` covers it, and its fund facts (`fn ETF`). Null for a
|
|
25
|
+
* listing that is not a fund, or a failure that is no answer (a timeout).
|
|
26
|
+
*/
|
|
27
|
+
export async function fundHoldersAnswer(
|
|
28
|
+
symbol: string,
|
|
29
|
+
error: unknown,
|
|
30
|
+
quote: FundQuote | null | undefined,
|
|
31
|
+
client: NonNullable<Parameters<typeof fetchFunds>[0]>,
|
|
32
|
+
): Promise<FundHoldersAnswer | null> {
|
|
33
|
+
if (!isNoSourceAnswer(error) || !quote || !isFundType(quote.instrumentType)) return null;
|
|
34
|
+
const fund = symbol.split(":")[0]!.trim().toUpperCase();
|
|
35
|
+
const message = `${fund} is a fund: there is no ownership breakdown for funds.`;
|
|
36
|
+
if (!isUsListingExchange(quoteTradingExchange(quote))) return { message, details: [] };
|
|
37
|
+
// A covered-fund list that cannot be read names no fn MEMB, which may not run for this fund.
|
|
38
|
+
const funds = await fetchFunds(client).then((payload) => payload.funds)
|
|
39
|
+
.catch(logFailure("holders.fund-holders", "Read the funds fn MEMB covers failed", null));
|
|
40
|
+
const covered = !!funds && !!coveredFund(funds, fund);
|
|
41
|
+
// Shares of an exchange-traded fund are 13F securities; a mutual fund's are not.
|
|
42
|
+
const traded = !/MUTUAL/i.test(quote.instrumentType ?? "");
|
|
43
|
+
return {
|
|
44
|
+
message,
|
|
45
|
+
details: [
|
|
46
|
+
...traded ? [`13F filers that hold it: gloom fn 13F ${fund}`] : [],
|
|
47
|
+
...covered ? [`What it holds: gloom fn MEMB ${fund}`] : [],
|
|
48
|
+
`Fund facts: gloom fn ETF ${fund}`,
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -7,7 +7,7 @@ import { loadHolderSnapshot } from "./client";
|
|
|
7
7
|
import { holderValueCurrency } from "./format";
|
|
8
8
|
import { logFailure } from "../../../utils/log-failure";
|
|
9
9
|
import type { HolderData } from "../../../types/financials";
|
|
10
|
-
import { SEC_FILINGS } from "../shared/report-freshness";
|
|
10
|
+
import { SEC_FILING_ROWS, SEC_FILINGS } from "../shared/report-freshness";
|
|
11
11
|
import type { BeneficialOwnersPayload } from "../../../api-client/beneficial-owners";
|
|
12
12
|
import { fetchBeneficialOwners, type BeneficialOwnersRequest } from "./beneficial-client";
|
|
13
13
|
import { resolveHeadlessInstrument, resolveHeadlessIssuerListing } from "../shared/headless-market-data";
|
|
@@ -33,6 +33,8 @@ import {
|
|
|
33
33
|
holderReportUnits,
|
|
34
34
|
} from "./report-rows";
|
|
35
35
|
import { REPORT_ROWS } from "../shared/headless-options";
|
|
36
|
+
import { fundHoldersAnswer } from "./fund-holders";
|
|
37
|
+
import { companyDataNotes } from "../../../types/company-from";
|
|
36
38
|
import {
|
|
37
39
|
HOLDER_ROWS_MAX,
|
|
38
40
|
indexedHoldersPartialNote,
|
|
@@ -196,7 +198,7 @@ export function createHoldersHeadless(
|
|
|
196
198
|
rows: limited,
|
|
197
199
|
// Reports that could not be read this time are missing from the rows.
|
|
198
200
|
complete: beneficialListComplete(payload),
|
|
199
|
-
freshness: { ...
|
|
201
|
+
freshness: { ...SEC_FILING_ROWS, basis: "13D/13G filings" },
|
|
200
202
|
metadata: {
|
|
201
203
|
symbol: payload.ticker || symbol,
|
|
202
204
|
name: payload.companyName || null,
|
|
@@ -211,6 +213,7 @@ export function createHoldersHeadless(
|
|
|
211
213
|
[payload.companyName || symbol, ...beneficialListFacts(payload, form, rows.length, history)].join(" · "),
|
|
212
214
|
...(legend ? [legend] : []),
|
|
213
215
|
...beneficialCoverageNotices(payload.coverage),
|
|
216
|
+
...companyDataNotes(payload.companyFrom),
|
|
214
217
|
],
|
|
215
218
|
returned: limited.length,
|
|
216
219
|
total: rows.length,
|
|
@@ -224,11 +227,27 @@ export function createHoldersHeadless(
|
|
|
224
227
|
.catch(logFailure("holders.headless", "Resolve the listing's venue for the 13F holder index failed", null)))?.exchange ?? "";
|
|
225
228
|
const indexTicker = indexHolderTicker(symbol, exchange);
|
|
226
229
|
const [snapshot, index] = await Promise.all([
|
|
227
|
-
dependencies.loadSnapshot(symbol, args, ctx)
|
|
230
|
+
dependencies.loadSnapshot(symbol, args, ctx).catch(async (error: unknown) => {
|
|
231
|
+
const quote = await ctx.marketData.getQuote(symbol)
|
|
232
|
+
.catch(logFailure("holders.headless", "Read the quote of a listing with no holders failed", null));
|
|
233
|
+
const fund = await fundHoldersAnswer(symbol, error, quote, ctx.apiClient);
|
|
234
|
+
if (fund) return fund;
|
|
235
|
+
throw error;
|
|
236
|
+
}),
|
|
228
237
|
indexTicker
|
|
229
238
|
? dependencies.loadIndexedHolders(indexTicker, limit, ctx).catch(logFailure("holders.headless", "Load 13F holder index failed", null))
|
|
230
239
|
: null,
|
|
231
240
|
]);
|
|
241
|
+
// A fund has no ownership breakdown: the report says so in place of rows, with what reads it, and fails as no data.
|
|
242
|
+
if ("message" in snapshot) {
|
|
243
|
+
return {
|
|
244
|
+
columns: HOLDER_REPORT_COLUMNS,
|
|
245
|
+
rows: [],
|
|
246
|
+
empty: [snapshot.message, ...snapshot.details].join("\n"),
|
|
247
|
+
unavailableSymbols: [symbol],
|
|
248
|
+
metadata: { symbol },
|
|
249
|
+
};
|
|
250
|
+
}
|
|
232
251
|
const { marketCap } = snapshot;
|
|
233
252
|
const indexed = !!index?.rows.length && indexHolderTicker(symbol, exchange, snapshot.data) != null;
|
|
234
253
|
const partialNote = indexed ? indexedHoldersPartialNote(index, limit) : null;
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type DataTableKeyEvent,
|
|
13
13
|
type PageRequest,
|
|
14
14
|
} from "../../../components";
|
|
15
|
+
import { useCompanyDataFooter } from "../../../components/layout/pane/status-footer";
|
|
15
16
|
import { handleRefreshKey, loadingErrorFooterInfo } from "../../../components/data-table/table-pane";
|
|
16
17
|
import { useAsyncResource } from "../../../react/async-resource";
|
|
17
18
|
import { useShortcut } from "../../../react/input";
|
|
@@ -321,6 +322,8 @@ export function HoldersView({ focused, width, height }: { focused: boolean; widt
|
|
|
321
322
|
}
|
|
322
323
|
}, [currency, fundMatches, marketCap]);
|
|
323
324
|
|
|
325
|
+
// Holders read from the company's home line say whose; the SEC index's rows are the listing's own.
|
|
326
|
+
useCompanyDataFooter(indexed ? null : listData?.companyFrom, viewMode !== "13dg");
|
|
324
327
|
// The 13D/G tab registers its own footer.
|
|
325
328
|
usePaneFooter("holders", () => {
|
|
326
329
|
if (viewMode === "13dg") return null;
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
import { HOLDER_ROWS_MAX } from "./index-holders";
|
|
26
26
|
import { buildRows, DEFAULT_SORT, sortRows } from "./table-model";
|
|
27
27
|
import type { HolderColumnId, SortPreference } from "./types";
|
|
28
|
+
import { companyDataNotes } from "../../../types/company-from";
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* A holder as `holders` and `fn HDS` report it; the keys are the JSON
|
|
@@ -231,7 +232,9 @@ export function holderReportNotices({
|
|
|
231
232
|
? `The source lists its ${reported} largest holders; fn 13F ${requested} lists all ${total.toLocaleString("en-US")}.`
|
|
232
233
|
: null;
|
|
233
234
|
return {
|
|
234
|
-
notices: [header, basis, cut, positionsBasis, holderShareBasisNote(data, shown), unvaluedHoldersNote(shown, sort)
|
|
235
|
+
notices: [header, basis, cut, positionsBasis, holderShareBasisNote(data, shown), unvaluedHoldersNote(shown, sort),
|
|
236
|
+
// The SEC index's rows are the listing's own; the source's, its company's home line's when it says so.
|
|
237
|
+
...(indexed ? [] : companyDataNotes(data.companyFrom))]
|
|
235
238
|
.filter((line): line is string => !!line),
|
|
236
239
|
valueBasis,
|
|
237
240
|
positionsBasis,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "./model";
|
|
21
21
|
import { isAmendedInsiderFiling, relevantInsiderAmendments } from "./amendments";
|
|
22
22
|
import { formatInsiderName } from "./display";
|
|
23
|
-
import {
|
|
23
|
+
import { SEC_FILING_ROWS } from "../shared/report-freshness";
|
|
24
24
|
import { resolveHeadlessInstrument, resolveHeadlessIssuerListing } from "../shared/headless-market-data";
|
|
25
25
|
import { noSecReportsNotice } from "../../../utils/sec";
|
|
26
26
|
import { parsePublicTickerKey } from "../../../utils/exchanges";
|
|
@@ -329,7 +329,7 @@ export function createInsiderHeadless(
|
|
|
329
329
|
): HeadlessPaneDefinition<"rows"> {
|
|
330
330
|
return {
|
|
331
331
|
shape: "rows",
|
|
332
|
-
freshness: { ...
|
|
332
|
+
freshness: { ...SEC_FILING_ROWS, basis: "Form 4 filings" },
|
|
333
333
|
argument: {
|
|
334
334
|
kind: "ticker",
|
|
335
335
|
optional: true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { apiClient } from "../../../api-client";
|
|
2
|
-
import type { IpoCalendarParams, IpoCalendarPayload, IpoDeal, IpoSourceHealth } from "../../../api-client/ipo";
|
|
2
|
+
import type { IpoCalendarParams, IpoCalendarPayload, IpoDeal, IpoLockup, IpoSourceHealth } from "../../../api-client/ipo";
|
|
3
3
|
import type { HeadlessPaneApiClient } from "../../../types/plugin";
|
|
4
4
|
import { createPluginCache } from "../../../data/plugin-cache";
|
|
5
5
|
import { cachedCloudResource, loadCloudResource, unavailableOnServer, type CloudResource } from "../shared/cloud-resource";
|
|
@@ -45,6 +45,21 @@ function validDeal(deal: IpoDeal): boolean {
|
|
|
45
45
|
&& validFirstDay(deal.firstDay);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
function validLockup(value: unknown): value is IpoLockup {
|
|
49
|
+
const lockup = value as IpoLockup | null;
|
|
50
|
+
return !!lockup && typeof lockup === "object" && typeof lockup.endsOn === "string" && dayOrNull(lockup.endsOn)
|
|
51
|
+
&& typeof lockup.days === "number" && Number.isFinite(lockup.days) && lockup.days > 0
|
|
52
|
+
&& (lockup.basis === "prospectus" || lockup.basis === "typical")
|
|
53
|
+
&& dayOrNull(lockup.prospectusDate ?? null) && textOrNull(lockup.prospectusUrl ?? null);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** A lock-up estimate the client cannot read is left off its deal; the deal stays. */
|
|
57
|
+
function withReadableLockup(deal: IpoDeal): IpoDeal {
|
|
58
|
+
if (deal.lockup == null || validLockup(deal.lockup)) return deal;
|
|
59
|
+
const { lockup: _unreadable, ...rest } = deal;
|
|
60
|
+
return rest;
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
function validSource(source: IpoSourceHealth): boolean {
|
|
49
64
|
return !!source && text(source.id) && Array.isArray(source.mics) && source.mics.every(text)
|
|
50
65
|
&& typeof source.ok === "boolean" && textOrNull(source.asOf);
|
|
@@ -61,7 +76,8 @@ export function validateIpoCalendar(data: IpoCalendarPayload): IpoCalendarPayloa
|
|
|
61
76
|
}
|
|
62
77
|
return {
|
|
63
78
|
asOf: data.asOf,
|
|
64
|
-
deals: data.deals.filter(validDeal).map(
|
|
79
|
+
deals: data.deals.filter(validDeal).map(withReadableLockup)
|
|
80
|
+
.map((deal) => (REGIONS.has(deal.region) ? deal : { ...deal, region: "other" })),
|
|
65
81
|
sources: data.sources.filter(validSource),
|
|
66
82
|
};
|
|
67
83
|
}
|