@gloom-sh/terminal 0.19.1 → 0.19.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/package.json +2 -1
- package/patches/electrobun@1.18.1.patch +108 -1
- package/src/account/upgrade-dialog.tsx +4 -23
- package/src/api-client/coalesce.ts +118 -0
- package/src/api-client/credit-boards.ts +13 -0
- package/src/api-client/crypto-etf-flows.ts +6 -0
- package/src/api-client/crypto-markets.ts +40 -0
- package/src/api-client/data.ts +201 -14
- package/src/api-client/equity-screener.ts +10 -0
- package/src/api-client/errors.ts +58 -0
- package/src/api-client/gpu.ts +29 -0
- package/src/api-client/index.ts +5 -2
- package/src/api-client/plan-access.ts +10 -1
- package/src/api-client/plan-rules.ts +35 -0
- package/src/api-client/research-activity.ts +1 -32
- package/src/api-client/types.ts +21 -1
- package/src/app/attention-notice.tsx +94 -0
- package/src/app/runtime/startup.ts +3 -1
- package/src/app.tsx +23 -1
- package/src/architecture/core-builtin-allowlist.json +2 -1
- package/src/capabilities/chart-series.ts +2 -1
- package/src/capabilities/factories.ts +1 -0
- package/src/cli/ascii-output.ts +42 -0
- package/src/cli/base-converter.ts +10 -2
- package/src/cli/command-options.ts +16 -1
- package/src/cli/commands/crypto-hints.ts +23 -4
- package/src/cli/commands/market.ts +101 -27
- package/src/cli/commands/news-search.ts +24 -5
- package/src/cli/commands/overview.ts +14 -10
- package/src/cli/commands/search.ts +84 -25
- package/src/cli/commands/system.ts +22 -30
- package/src/cli/commands/ticker.ts +49 -9
- package/src/cli/commands/version.ts +33 -0
- package/src/cli/context.ts +6 -9
- package/src/cli/data-dir.ts +7 -0
- package/src/cli/desktop-pane-shot-api-policy.ts +85 -0
- package/src/cli/desktop-pane-shot-browser.ts +320 -0
- package/src/cli/desktop-pane-shot-routes.ts +26 -1
- package/src/cli/desktop-pane-shot.ts +196 -256
- package/src/cli/early-command.ts +42 -0
- package/src/cli/earnings-calendar.ts +9 -0
- package/src/cli/entry.ts +19 -13
- package/src/cli/errors.ts +12 -2
- package/src/cli/glossary.ts +2 -1
- package/src/cli/help.ts +1 -1
- package/src/cli/history-export.ts +22 -2
- package/src/cli/history-rows.ts +189 -11
- package/src/cli/index.ts +18 -1
- package/src/cli/known-gaps.ts +51 -5
- package/src/cli/listing-arg.ts +63 -10
- package/src/cli/options.ts +1 -1
- package/src/cli/output-file.ts +60 -13
- package/src/cli/pane-functions/catalog.ts +14 -3
- package/src/cli/pane-functions/data.ts +1 -1
- package/src/cli/pane-functions/dom.ts +45 -0
- package/src/cli/pane-functions/freshness.ts +46 -9
- package/src/cli/pane-functions/function-help.ts +17 -9
- package/src/cli/pane-functions/headless.ts +22 -14
- package/src/cli/pane-functions/index.ts +6 -2
- package/src/cli/pane-functions/options.ts +6 -2
- package/src/cli/pane-functions/resolver.ts +27 -5
- package/src/cli/pane-functions/screenshot-assessment.ts +33 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +94 -13
- package/src/cli/pane-functions/screenshot-http.ts +70 -0
- package/src/cli/pane-functions/screenshot-render.ts +19 -5
- package/src/cli/quote-answer.ts +49 -6
- package/src/cli/registry.ts +41 -13
- package/src/cli/result.ts +12 -6
- package/src/cli/ticker-resolution.ts +2 -1
- package/src/cli/types.ts +2 -0
- package/src/components/chart/composite/format.ts +3 -0
- package/src/components/chart-table/header.tsx +1 -1
- package/src/components/chart-table/layout.ts +28 -11
- package/src/components/command-bar/action-runtime.ts +4 -0
- package/src/components/command-bar/commands/direct/index.ts +18 -33
- package/src/components/command-bar/commands/direct/runtime.ts +5 -0
- package/src/components/command-bar/commands/registry.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +9 -4
- package/src/components/command-bar/routes/root/runtime.ts +51 -6
- package/src/components/command-bar/selection-runtime.ts +12 -29
- package/src/components/command-bar/surface/index.tsx +9 -3
- package/src/components/company-logo.tsx +2 -1
- package/src/components/layout/detached-pane-shell.tsx +2 -2
- package/src/components/layout/header.tsx +10 -5
- package/src/components/layout/market-summary.ts +25 -7
- package/src/components/layout/pane/footer/index.tsx +8 -2
- package/src/components/layout/pane/footer/model.ts +73 -6
- package/src/components/layout/pane/header.tsx +2 -2
- package/src/components/layout/pane/status-footer.ts +2 -1
- package/src/components/market-board/index.tsx +3 -2
- package/src/components/onboarding/desks-step.tsx +12 -4
- package/src/components/onboarding/first-run-workspace.ts +81 -4
- package/src/components/onboarding/onboarding-frame.tsx +4 -2
- package/src/components/onboarding/onboarding-keyboard.ts +8 -5
- package/src/components/onboarding/onboarding-wizard.tsx +60 -26
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +7 -2
- package/src/components/onboarding/run-setup-again.ts +24 -0
- package/src/components/onboarding/use-onboarding-progress.ts +33 -15
- package/src/components/onboarding/use-onboarding-upgrade.ts +2 -6
- package/src/components/onboarding/wizard-model.ts +57 -3
- package/src/components/onboarding/wizard-positions.ts +1 -1
- package/src/components/ui/delayed-mark.tsx +56 -0
- package/src/components/ui/display.tsx +16 -5
- package/src/components/ui/external-link.tsx +3 -6
- package/src/components/ui/icon.tsx +16 -3
- package/src/components/ui/logo-mark.tsx +8 -5
- package/src/components/ui/stat-grid.tsx +263 -19
- package/src/core/app-services.ts +11 -2
- package/src/data/app-persistence.ts +9 -7
- package/src/data/config/store/node.ts +11 -5
- package/src/data/config/store/normalize.ts +16 -3
- package/src/data/plugin-cache.ts +15 -0
- package/src/data/plugin-state-store.ts +81 -24
- package/src/data/profile-permissions.ts +47 -0
- package/src/data/resource-store.ts +165 -90
- package/src/data/session-store.ts +31 -8
- package/src/data/sqlite/access.ts +324 -0
- package/src/data/sqlite/checkpointer.ts +285 -0
- package/src/data/sqlite/database.ts +80 -4
- package/src/data/sqlite/retry.ts +50 -9
- package/src/data/ticker-store.ts +57 -23
- package/src/docs/snapshot.json +191 -78
- package/src/i18n/es.ts +18 -2
- package/src/i18n/ja.ts +18 -2
- package/src/i18n/ko.ts +18 -2
- package/src/i18n/zh-cn.ts +18 -2
- package/src/i18n/zh-tw.ts +18 -2
- package/src/layout/desk-keys.ts +4 -1
- package/src/layout/desks.ts +38 -5
- package/src/layout-marketplace/gallery-desktop.tsx +45 -16
- package/src/market-data/batched-reads.ts +16 -0
- package/src/market-data/coordinator/auxiliary.ts +4 -2
- package/src/market-data/coordinator/index.ts +11 -2
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +3 -1
- package/src/market-data/market/index-level.ts +6 -4
- package/src/market-data/published-apac-sessions.ts +6 -0
- package/src/market-data/realized-volatility.ts +4 -2
- package/src/news/aggregator.ts +7 -4
- package/src/news/news-model.ts +11 -0
- package/src/news/story-id.ts +22 -0
- package/src/news/ticker-symbols.ts +17 -1
- package/src/notifications/app-notifier.ts +35 -14
- package/src/plugins/auto-update-node.ts +10 -6
- package/src/plugins/builtin/account-management/form-components.tsx +1 -1
- package/src/plugins/builtin/account-management/index.tsx +2 -3
- package/src/plugins/builtin/account-management/model.ts +1 -1
- package/src/plugins/builtin/alerts/cli-forms.ts +15 -1
- package/src/plugins/builtin/alerts/events-pane.tsx +7 -5
- package/src/plugins/builtin/alerts/events.ts +10 -2
- package/src/plugins/builtin/alerts/index.tsx +5 -5
- package/src/plugins/builtin/alerts/research-builder.ts +5 -1
- package/src/plugins/builtin/alerts/research-rules.ts +18 -0
- package/src/plugins/builtin/alerts/targets.ts +4 -1
- package/src/plugins/builtin/attention/headless.ts +1 -1
- package/src/plugins/builtin/attention/index.tsx +2 -4
- package/src/plugins/builtin/attention/listing.ts +1 -1
- package/src/plugins/builtin/attention/series.ts +1 -1
- package/src/plugins/builtin/awards/index.tsx +1 -2
- package/src/plugins/builtin/backtest/client.ts +1 -0
- package/src/plugins/builtin/backtest/index.tsx +1 -2
- package/src/plugins/builtin/backtest/rules.ts +3 -1
- package/src/plugins/builtin/backtest/window.ts +8 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +16 -3
- package/src/plugins/builtin/broker-manager/index.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +5 -0
- package/src/plugins/builtin/buildout/company/flow.tsx +367 -0
- package/src/plugins/builtin/buildout/company/id.ts +2 -0
- package/src/plugins/builtin/buildout/company/model.ts +247 -0
- package/src/plugins/builtin/buildout/company/pane.tsx +317 -0
- package/src/plugins/builtin/buildout/data-runtime.ts +31 -10
- package/src/plugins/builtin/buildout/facilities.ts +309 -0
- package/src/plugins/builtin/buildout/format.ts +9 -0
- package/src/plugins/builtin/buildout/index.tsx +51 -5
- package/src/plugins/builtin/buildout/model/index.ts +62 -10
- package/src/plugins/builtin/buildout/model/normalizers.ts +5 -0
- package/src/plugins/builtin/buildout/model/types.ts +11 -2
- package/src/plugins/builtin/buildout/pane/index.tsx +91 -20
- package/src/plugins/builtin/buildout/pane/status.tsx +1 -1
- package/src/plugins/builtin/buildout/pane/themes.tsx +110 -0
- package/src/plugins/builtin/buildout/table-model.ts +26 -2
- package/src/plugins/builtin/builtin-plugin-meta.ts +16 -0
- package/src/plugins/builtin/cds/headless.ts +10 -2
- package/src/plugins/builtin/cds/model.ts +7 -3
- package/src/plugins/builtin/central-bank-rates/index.tsx +1 -2
- package/src/plugins/builtin/central-bank-rates/pane.tsx +2 -1
- package/src/plugins/builtin/central-bank-rates/series.ts +2 -3
- package/src/plugins/builtin/changelog/index.tsx +3 -2
- package/src/plugins/builtin/chart-composer/cli-options.ts +16 -0
- package/src/plugins/builtin/chart-composer/headless-schema.ts +10 -0
- package/src/plugins/builtin/chart-composer/headless.ts +88 -21
- package/src/plugins/builtin/chart-composer/index.tsx +2 -3
- package/src/plugins/builtin/chart-composer/pane.tsx +30 -2
- package/src/plugins/builtin/chart-composer/series-expression.ts +3 -2
- package/src/plugins/builtin/chart-composer/session-range.ts +5 -2
- package/src/plugins/builtin/chart-composer/studies.ts +1 -1
- package/src/plugins/builtin/chat/controller/index.ts +1 -1
- package/src/plugins/builtin/chat/controller/messages.ts +15 -4
- package/src/plugins/builtin/chat/ghost-user.ts +8 -0
- package/src/plugins/builtin/chat/index.tsx +5 -5
- package/src/plugins/builtin/clinical-trials/index.tsx +1 -2
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
- package/src/plugins/builtin/cloud/index.tsx +1 -2
- package/src/plugins/builtin/cloud/plugin.tsx +6 -4
- package/src/plugins/builtin/cloud/team/module.tsx +1 -1
- package/src/plugins/builtin/cloud/thesis/module.tsx +1 -1
- package/src/plugins/builtin/cloud/trial-offer-status-widget.tsx +24 -1
- package/src/plugins/builtin/cloud/upgrade-status-widget.tsx +39 -15
- package/src/plugins/builtin/comment-letters/index.tsx +1 -2
- package/src/plugins/builtin/commodity-balances/client.ts +4 -1
- package/src/plugins/builtin/commodity-balances/index.tsx +3 -3
- package/src/plugins/builtin/commodity-balances/pane.tsx +2 -2
- package/src/plugins/builtin/congress-trades/aggregates.ts +13 -2
- package/src/plugins/builtin/congress-trades/detail.tsx +20 -4
- package/src/plugins/builtin/congress-trades/headless.ts +2 -0
- package/src/plugins/builtin/congress-trades/model.ts +92 -64
- package/src/plugins/builtin/congress-trades/table.tsx +14 -2
- package/src/plugins/builtin/connections/index.ts +2 -3
- package/src/plugins/builtin/cot/client.ts +28 -2
- package/src/plugins/builtin/cot/headless.ts +4 -1
- package/src/plugins/builtin/cot/index.tsx +5 -4
- package/src/plugins/builtin/cot/model.ts +58 -7
- package/src/plugins/builtin/cot/pane.tsx +6 -2
- package/src/plugins/builtin/cpi/client.ts +6 -5
- package/src/plugins/builtin/cpi/index.tsx +1 -2
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +2 -1
- package/src/plugins/builtin/credit-boards/client.ts +7 -2
- package/src/plugins/builtin/credit-boards/headless.ts +25 -12
- package/src/plugins/builtin/credit-boards/model.ts +29 -0
- package/src/plugins/builtin/credit-boards/series.ts +3 -4
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +9 -4
- package/src/plugins/builtin/credit-conditions/client.ts +22 -14
- package/src/plugins/builtin/crypto-board/bitcoin-network.ts +143 -0
- package/src/plugins/builtin/crypto-board/client.ts +5 -5
- package/src/plugins/builtin/crypto-board/headless.ts +4 -3
- package/src/plugins/builtin/crypto-board/index.tsx +4 -2
- package/src/plugins/builtin/crypto-board/series.ts +6 -4
- package/src/plugins/builtin/crypto-etf-flows/client.ts +9 -2
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +61 -6
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +1 -2
- package/src/plugins/builtin/crypto-etf-flows/model.ts +14 -1
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +8 -5
- package/src/plugins/builtin/debt-maturities/headless.ts +4 -3
- package/src/plugins/builtin/debt-maturities/model.ts +17 -1
- package/src/plugins/builtin/debt-maturities/pane.tsx +18 -4
- package/src/plugins/builtin/debt-maturities/series.ts +3 -3
- package/src/plugins/builtin/debug/index.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/client.ts +32 -2
- package/src/plugins/builtin/dividend-yield/headless.ts +58 -33
- package/src/plugins/builtin/dividend-yield/index.tsx +37 -2
- package/src/plugins/builtin/dividend-yield/pane.tsx +32 -13
- package/src/plugins/builtin/dividend-yield/ranking-reads.ts +73 -0
- package/src/plugins/builtin/dividend-yield/ranking-view.tsx +163 -0
- package/src/plugins/builtin/dividend-yield/ranking.ts +1 -1
- package/src/plugins/builtin/dividend-yield/view.ts +21 -0
- package/src/plugins/builtin/docs/index.tsx +2 -3
- package/src/plugins/builtin/doe/client.ts +6 -5
- package/src/plugins/builtin/doe/headless.ts +16 -3
- package/src/plugins/builtin/doe/index.tsx +5 -4
- package/src/plugins/builtin/doe/prices.ts +2 -3
- package/src/plugins/builtin/doe/series.ts +4 -4
- package/src/plugins/builtin/earnings/board.tsx +2 -1
- package/src/plugins/builtin/earnings/history.tsx +2 -1
- package/src/plugins/builtin/earnings-calls/calendar.tsx +10 -2
- package/src/plugins/builtin/earnings-calls/data.ts +19 -11
- package/src/plugins/builtin/earnings-calls/pane.tsx +27 -14
- package/src/plugins/builtin/earnings-ripple/client.ts +32 -7
- package/src/plugins/builtin/earnings-ripple/index.tsx +1 -2
- package/src/plugins/builtin/econ/calendar-model.ts +29 -6
- package/src/plugins/builtin/econ/detail-view.tsx +16 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +1 -2
- package/src/plugins/builtin/equity-screener/client.ts +1 -1
- package/src/plugins/builtin/equity-screener/headless.ts +1 -0
- package/src/plugins/builtin/equity-screener/ideas.ts +30 -1
- package/src/plugins/builtin/equity-screener/index.tsx +1 -2
- package/src/plugins/builtin/equity-screener/model.ts +28 -4
- package/src/plugins/builtin/equity-screener/pane.tsx +5 -0
- package/src/plugins/builtin/equity-screener/screen-check.ts +23 -1
- package/src/plugins/builtin/estimate-revisions/index.tsx +1 -2
- package/src/plugins/builtin/executives/data.ts +6 -1
- package/src/plugins/builtin/executives/pane.tsx +9 -21
- package/src/plugins/builtin/exposure/holdings.ts +35 -13
- package/src/plugins/builtin/exposure/index.tsx +1 -2
- package/src/plugins/builtin/fear-greed/cache.ts +4 -0
- package/src/plugins/builtin/fear-greed/cli.ts +44 -0
- package/src/plugins/builtin/fear-greed/index.tsx +5 -53
- package/src/plugins/builtin/fear-greed/pane.tsx +2 -1
- package/src/plugins/builtin/fear-greed/series.ts +6 -4
- package/src/plugins/builtin/fixed-income/index.tsx +1 -2
- package/src/plugins/builtin/futures/board-reads.ts +25 -0
- package/src/plugins/builtin/futures/coalesced-bump.ts +44 -0
- package/src/plugins/builtin/futures/index.tsx +15 -0
- package/src/plugins/builtin/futures/model.ts +14 -0
- package/src/plugins/builtin/futures/use-board-terms.ts +22 -15
- package/src/plugins/builtin/futures/use-front-returns.ts +20 -14
- package/src/plugins/builtin/futures-curve/headless.ts +6 -1
- package/src/plugins/builtin/futures-curve/index.tsx +1 -2
- package/src/plugins/builtin/fx-matrix/index.tsx +2 -2
- package/src/plugins/builtin/gpu/board.tsx +51 -12
- package/src/plugins/builtin/gpu/client.ts +19 -3
- package/src/plugins/builtin/gpu/equities.tsx +5 -2
- package/src/plugins/builtin/gpu/headless.ts +14 -2
- package/src/plugins/builtin/gpu/index.tsx +1 -2
- package/src/plugins/builtin/gpu/model.ts +20 -2
- package/src/plugins/builtin/gpu/pane.tsx +1 -1
- package/src/plugins/builtin/gpu/series.ts +2 -3
- package/src/plugins/builtin/help/index.tsx +1 -1
- package/src/plugins/builtin/holders/beneficial-view.tsx +1 -2
- package/src/plugins/builtin/holders/index-holders.ts +24 -12
- package/src/plugins/builtin/holders/index.tsx +2 -3
- package/src/plugins/builtin/ipo-calendar/index.tsx +1 -2
- package/src/plugins/builtin/iv-history/index.tsx +1 -2
- package/src/plugins/builtin/jodi/client.ts +4 -1
- package/src/plugins/builtin/jodi/index.tsx +1 -2
- package/src/plugins/builtin/kelly-sizer/index.tsx +1 -2
- package/src/plugins/builtin/layout-manager/index.tsx +9 -8
- package/src/plugins/builtin/macro-day/pane.tsx +4 -2
- package/src/plugins/builtin/market-halts/index.tsx +1 -2
- package/src/plugins/builtin/market-heatmap/index.tsx +11 -2
- package/src/plugins/builtin/market-movers/client.ts +1 -0
- package/src/plugins/builtin/market-movers/index.tsx +16 -5
- package/src/plugins/builtin/market-movers/screener.ts +23 -6
- package/src/plugins/builtin/market-movers/session-body.tsx +6 -2
- package/src/plugins/builtin/market-valuation/index.tsx +1 -2
- package/src/plugins/builtin/members/index.tsx +1 -2
- package/src/plugins/builtin/money-markets/index.tsx +1 -2
- package/src/plugins/builtin/money-markets/pane.tsx +2 -1
- package/src/plugins/builtin/money-markets/series.ts +3 -5
- package/src/plugins/builtin/news/headless.ts +7 -0
- package/src/plugins/builtin/news/wire/index.tsx +1 -1
- package/src/plugins/builtin/news/wire/news/pop-out.tsx +9 -3
- package/src/plugins/builtin/notes/index.tsx +3 -6
- package/src/plugins/builtin/openfda/index.tsx +1 -2
- package/src/plugins/builtin/options/view.tsx +6 -5
- package/src/plugins/builtin/options-calculator/index.tsx +1 -2
- package/src/plugins/builtin/options-positioning/index.tsx +1 -2
- package/src/plugins/builtin/options-scenario/index.tsx +2 -4
- package/src/plugins/builtin/perps/index.tsx +1 -2
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -3
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -1
- package/src/plugins/builtin/plugin-module.ts +16 -2
- package/src/plugins/builtin/portfolio-list/cli/render.ts +53 -3
- package/src/plugins/builtin/portfolio-list/index.tsx +1 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +11 -0
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +2 -2
- package/src/plugins/builtin/power/gas-client.ts +2 -1
- package/src/plugins/builtin/power/index.tsx +1 -2
- package/src/plugins/builtin/power/prices-client.ts +3 -2
- package/src/plugins/builtin/rate-path/index.tsx +1 -2
- package/src/plugins/builtin/realized-vol/headless.ts +2 -0
- package/src/plugins/builtin/realized-vol/index.tsx +1 -2
- package/src/plugins/builtin/realized-vol/model.ts +16 -2
- package/src/plugins/builtin/realized-vol/pane.tsx +3 -3
- package/src/plugins/builtin/relative-rotation/index.tsx +1 -2
- package/src/plugins/builtin/research/analyst-headless.ts +33 -6
- package/src/plugins/builtin/research/analyst-model.ts +37 -2
- package/src/plugins/builtin/research/analyst-pane.tsx +25 -5
- package/src/plugins/builtin/research/index.tsx +5 -8
- package/src/plugins/builtin/research-search/index.tsx +1 -2
- package/src/plugins/builtin/revenue-breakdown/headless.ts +22 -8
- package/src/plugins/builtin/revenue-breakdown/model.ts +23 -0
- package/src/plugins/builtin/reverse-dcf/pane.tsx +4 -2
- package/src/plugins/builtin/risk-factors/data.ts +8 -4
- package/src/plugins/builtin/risk-factors/index.tsx +3 -1
- package/src/plugins/builtin/risk-factors/pane.tsx +5 -8
- package/src/plugins/builtin/roadmap/index.tsx +2 -3
- package/src/plugins/builtin/roadmap/pane.tsx +49 -2
- package/src/plugins/builtin/scanner/hilo-model.ts +18 -1
- package/src/plugins/builtin/scanner/hilo-pane.tsx +12 -2
- package/src/plugins/builtin/scanner/live-pane.tsx +7 -4
- package/src/plugins/builtin/scanner/lock-note.ts +26 -3
- package/src/plugins/builtin/sec/filing-content.ts +38 -6
- package/src/plugins/builtin/sec/headless.ts +5 -1
- package/src/plugins/builtin/sec/index.tsx +4 -2
- package/src/plugins/builtin/sec/model.ts +2 -0
- package/src/plugins/builtin/sectors/index.tsx +11 -5
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/cloud-resource.ts +73 -8
- package/src/plugins/builtin/shared/cloud-upgrade.ts +24 -1
- package/src/plugins/builtin/shared/forming-bars.ts +29 -0
- package/src/plugins/builtin/shared/fred-points.ts +6 -1
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +17 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +23 -8
- package/src/plugins/builtin/shared/series-detail-chart.tsx +4 -2
- package/src/plugins/builtin/shared/series-warning.ts +13 -4
- package/src/plugins/builtin/shared/use-quote-board.ts +5 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +2 -1
- package/src/plugins/builtin/short-volume/pane.tsx +2 -1
- package/src/plugins/builtin/short-volume/series.ts +2 -3
- package/src/plugins/builtin/social-mentions/client.ts +15 -10
- package/src/plugins/builtin/social-mentions/index.tsx +1 -2
- package/src/plugins/builtin/social-mentions/pane.tsx +2 -1
- package/src/plugins/builtin/social-mentions/series.ts +2 -3
- package/src/plugins/builtin/supply-chain/client.ts +22 -1
- package/src/plugins/builtin/supply-chain/graph-client.ts +22 -1
- package/src/plugins/builtin/supply-chain/index.tsx +1 -2
- package/src/plugins/builtin/thirteenf/api.ts +127 -29
- package/src/plugins/builtin/thirteenf/data.ts +165 -35
- package/src/plugins/builtin/thirteenf/index.tsx +2 -4
- package/src/plugins/builtin/thirteenf/model.ts +2 -0
- package/src/plugins/builtin/thirteenf/overlap-pane.tsx +5 -1
- package/src/plugins/builtin/thirteenf/pane.tsx +41 -16
- package/src/plugins/builtin/thirteenf/types.ts +14 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +22 -6
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +81 -11
- package/src/plugins/builtin/ticker-detail/financials/model.ts +35 -2
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +53 -18
- package/src/plugins/builtin/ticker-detail/headless.ts +70 -11
- package/src/plugins/builtin/ticker-detail/index.tsx +5 -10
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +16 -6
- package/src/plugins/builtin/time-sales/index.tsx +1 -2
- package/src/plugins/builtin/time-sales/pane.tsx +3 -1
- package/src/plugins/builtin/trace-bonds/headless.ts +11 -2
- package/src/plugins/builtin/trace-bonds/model.ts +44 -10
- package/src/plugins/builtin/trace-bonds/pane.tsx +12 -7
- package/src/plugins/builtin/treasury-auctions/cache.ts +20 -8
- package/src/plugins/builtin/treasury-auctions/client.ts +3 -3
- package/src/plugins/builtin/treasury-auctions/headless.ts +3 -1
- package/src/plugins/builtin/treasury-auctions/pane.tsx +10 -4
- package/src/plugins/builtin/vol-surface/client.ts +18 -3
- package/src/plugins/builtin/vol-surface/index.tsx +1 -2
- package/src/plugins/builtin/volatility/client.ts +43 -16
- package/src/plugins/builtin/volatility/headless.ts +5 -2
- package/src/plugins/builtin/volatility/index.tsx +1 -2
- package/src/plugins/builtin/volatility/model.ts +17 -6
- package/src/plugins/builtin/volatility/pane.tsx +6 -2
- package/src/plugins/builtin/volatility/series.ts +2 -1
- package/src/plugins/builtin/world-indices/footer.ts +6 -1
- package/src/plugins/builtin/world-venue-map/client.ts +10 -1
- package/src/plugins/builtin/world-venue-map/index.ts +6 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +48 -7
- package/src/plugins/builtin/world-venue-map/layers.ts +17 -0
- package/src/plugins/builtin/world-venue-map/local-layers.ts +141 -0
- package/src/plugins/builtin/world-venue-map/map-symbols.ts +18 -0
- package/src/plugins/builtin/world-venue-map/map.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/scope.ts +63 -0
- package/src/plugins/builtin/yield-curve/client.ts +4 -6
- package/src/plugins/builtin/yield-curve/curves.ts +16 -2
- package/src/plugins/builtin/yield-curve/headless.ts +3 -3
- package/src/plugins/bundle.ts +52 -2
- package/src/plugins/catalog-browser.ts +2 -2
- package/src/plugins/catalog-cli.ts +20 -0
- package/src/plugins/host-link.ts +13 -1
- package/src/plugins/installer.ts +64 -42
- package/src/plugins/loader.ts +43 -11
- package/src/plugins/peer-imports.ts +201 -0
- package/src/plugins/peer-retry.ts +26 -29
- package/src/plugins/plugin-process.ts +128 -0
- package/src/plugins/redirection-guard.ts +45 -0
- package/src/remote/endpoint.ts +16 -3
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/http-proxy.ts +7 -123
- package/src/renderers/dom/desktop/icons.tsx +5 -2
- package/src/renderers/dom/host/image-surface.tsx +46 -21
- package/src/renderers/dom/styles.css +7 -0
- package/src/renderers/dom/toast-host.tsx +2 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +7 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +23 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +12 -3
- package/src/renderers/electrobun/bun/desktop/rpc-timing.ts +88 -0
- package/src/renderers/electrobun/bun/desktop/update.ts +20 -4
- package/src/renderers/electrobun/bun/desktop/view-ids.ts +8 -4
- package/src/renderers/electrobun/bun/external-plugins.ts +4 -0
- package/src/renderers/electrobun/bun/window/attention.ts +54 -0
- package/src/renderers/electrobun/bun/window/create.ts +6 -2
- package/src/renderers/electrobun/bun/window/native-timing.ts +48 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +82 -4
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +13 -5
- package/src/renderers/electrobun/view/desktop/window/snapshot.ts +3 -0
- package/src/renderers/electrobun/view/main.tsx +7 -2
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -0
- package/src/renderers/electrobun/view/ui-host.tsx +9 -2
- package/src/renderers/opentui/browser-open.ts +10 -4
- package/src/renderers/opentui/image/surface.tsx +1 -1
- package/src/renderers/opentui/start.tsx +12 -6
- package/src/renderers/opentui/toast-host.tsx +2 -1
- package/src/series/registry.ts +18 -0
- package/src/series/resolve.ts +2 -1
- package/src/series/standalone.ts +10 -1
- package/src/series/types.ts +12 -0
- package/src/series/validate.ts +11 -2
- package/src/sources/gloomberb-cloud/fred-series.ts +5 -3
- package/src/sources/gloomberb-cloud/index.ts +28 -5
- package/src/sources/gloomberb-cloud/news.ts +24 -3
- package/src/sources/gloomberb-cloud/normalizers.ts +17 -2
- package/src/sources/provider-errors.ts +26 -3
- package/src/sources/provider-router/history.ts +5 -0
- package/src/sources/provider-router/index.ts +13 -0
- package/src/sync/core-contributors.ts +32 -0
- package/src/telemetry/attention-counts.ts +64 -6
- package/src/telemetry/attention-setting.ts +33 -0
- package/src/telemetry/crash-reports-node.ts +3 -1
- package/src/telemetry/stall-clocks.ts +93 -0
- package/src/telemetry/stall-reports-node.ts +25 -9
- package/src/telemetry/stall-reports.ts +218 -13
- package/src/test-support/outage.ts +8 -0
- package/src/test-support/preload.ts +9 -0
- package/src/tickers/company-name-listing.ts +59 -29
- package/src/tickers/company-name.ts +84 -1
- package/src/tickers/listing-fate.ts +14 -3
- package/src/tickers/saved-instrument.ts +17 -0
- package/src/tickers/search/home-listing.ts +104 -8
- package/src/tickers/search/index.ts +5 -2
- package/src/tickers/search/types.ts +6 -1
- package/src/time-series/bar-aggregation.ts +7 -1
- package/src/time-series/base-series.ts +3 -3
- package/src/time-series/chart-bounds.ts +1 -1
- package/src/time-series/chart-data.ts +5 -2
- package/src/time-series/chart-seed.ts +1 -1
- package/src/time-series/coin-session-close.ts +211 -0
- package/src/time-series/live-bars.ts +13 -2
- package/src/time-series/live-quotes.ts +1 -1
- package/src/time-series/market.ts +5 -3
- package/src/time-series/official-close.ts +159 -0
- package/src/time-series/price-comparison.ts +75 -8
- package/src/time-series/resolve.ts +32 -4
- package/src/time-series/series-presentation.ts +1 -1
- package/src/time-series/studies/formula.ts +205 -0
- package/src/time-series/studies/indicators.ts +299 -0
- package/src/time-series/studies/leverage.ts +75 -0
- package/src/time-series/studies/pair.ts +138 -0
- package/src/time-series/studies/resolve.ts +333 -0
- package/src/time-series/studies/shared.ts +141 -0
- package/src/time-series/studies/units.ts +243 -0
- package/src/time-series/studies/vwap.ts +274 -0
- package/src/time-series/types.ts +7 -0
- package/src/types/config.ts +18 -2
- package/src/types/data-provider.ts +23 -0
- package/src/types/financials.ts +40 -3
- package/src/types/headless.ts +42 -3
- package/src/types/plugin.ts +32 -3
- package/src/ui/host.tsx +17 -1
- package/src/ui/toast.tsx +26 -1
- package/src/utils/ascii-text.ts +140 -0
- package/src/utils/cli-output.ts +91 -18
- package/src/utils/concurrency.ts +24 -0
- package/src/utils/exchanges.ts +6 -0
- package/src/utils/external-url.ts +20 -7
- package/src/utils/financial-statements.ts +73 -16
- package/src/utils/fundamentals.ts +17 -5
- package/src/utils/futures-generic.ts +4 -4
- package/src/utils/http-proxy-upstream.ts +124 -0
- package/src/utils/lease-liabilities.ts +54 -0
- package/src/utils/main-thread-stall.ts +122 -5
- package/src/utils/perf-marks.ts +58 -12
- package/src/utils/price-history-integrity.ts +47 -1
- package/src/utils/private-files.ts +141 -0
- package/src/utils/public-address.ts +99 -0
- package/src/account/upgrade-personalization.ts +0 -57
- package/src/account/upgrade-tickers.ts +0 -124
- package/src/api-client/upgrade-experiment.ts +0 -91
- package/src/plugins/builtin/cloud/browser.tsx +0 -3
- package/src/time-series/studies.ts +0 -1628
package/src/i18n/es.ts
CHANGED
|
@@ -169,6 +169,7 @@ export const es: Record<string, string> = {
|
|
|
169
169
|
"Export Config": "Exportar configuración",
|
|
170
170
|
"Import Config": "Importar configuración",
|
|
171
171
|
"Reset All Data": "Restablecer todos los datos",
|
|
172
|
+
"Run Setup Again": "Repetir la configuración",
|
|
172
173
|
"Reset Everything": "Restablecer todo",
|
|
173
174
|
"Reset Layout": "Restablecer diseño",
|
|
174
175
|
"Reset Current Layout": "Restablecer diseño actual",
|
|
@@ -186,6 +187,7 @@ export const es: Record<string, string> = {
|
|
|
186
187
|
"Save config to ~/gloomberb-config-backup.json": "Guardar configuración en ~/gloomberb-config-backup.json",
|
|
187
188
|
"Load config from ~/gloomberb-config-backup.json": "Cargar configuración desde ~/gloomberb-config-backup.json",
|
|
188
189
|
"Delete all data and reset to first-run state": "Borrar todos los datos y volver al estado inicial",
|
|
190
|
+
"Rebuild Home and setup's desk tabs; your other layouts stay": "Reconstruir Home y las pestañas de mesas de la configuración; tus otros diseños se quedan igual",
|
|
189
191
|
"Edit settings for the focused pane": "Editar ajustes del panel activo",
|
|
190
192
|
"Move or resize the focused window": "Mover o redimensionar la ventana activa",
|
|
191
193
|
"Add current ticker to active portfolio": "Agregar el ticker actual a la cartera activa",
|
|
@@ -1355,6 +1357,8 @@ export const es: Record<string, string> = {
|
|
|
1355
1357
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1356
1358
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1357
1359
|
"GLOOM SETUP": "CONFIGURACIÓN DE GLOOM",
|
|
1360
|
+
"Skip setup": "Omitir configuración",
|
|
1361
|
+
"Closing...": "Cerrando...",
|
|
1358
1362
|
"Gloom Cloud is connected": "Gloom Cloud está conectado",
|
|
1359
1363
|
"How do you want to start?": "¿Cómo quieres empezar?",
|
|
1360
1364
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "Se importaron {count} posiciones de {broker}. Tu espacio de trabajo está listo para explorar.",
|
|
@@ -1455,7 +1459,7 @@ export const es: Record<string, string> = {
|
|
|
1455
1459
|
"New accounts get a verification email.": "Las cuentas nuevas reciben un correo de verificación.",
|
|
1456
1460
|
"No exact ticker match": "Sin coincidencia exacta de ticker",
|
|
1457
1461
|
"No exact ticker match.": "Sin coincidencia exacta de ticker.",
|
|
1458
|
-
"No
|
|
1462
|
+
"No price yet. Enter the average cost.": "Aún no hay precio. Introduce el costo promedio.",
|
|
1459
1463
|
"Open the sign-in link, or scan the code with your phone.": "Abre el enlace de inicio de sesión o escanea el código con tu teléfono.",
|
|
1460
1464
|
"Positions ({count})": "Posiciones ({count})",
|
|
1461
1465
|
"Shares cannot be 0. Enter a negative number for a short.": "Las acciones no pueden ser 0. Introduce un número negativo para una posición corta.",
|
|
@@ -1476,7 +1480,7 @@ export const es: Record<string, string> = {
|
|
|
1476
1480
|
"Avg cost": "Coste medio",
|
|
1477
1481
|
"Currency": "Moneda",
|
|
1478
1482
|
"optional": "opcional",
|
|
1479
|
-
"
|
|
1483
|
+
"last price": "último precio",
|
|
1480
1484
|
"e.g. AAPL": "p. ej. AAPL",
|
|
1481
1485
|
"Add": "Añadir",
|
|
1482
1486
|
"Adding...": "Añadiendo...",
|
|
@@ -1509,6 +1513,18 @@ export const es: Record<string, string> = {
|
|
|
1509
1513
|
"b: sign in with the browser instead": "b: iniciar sesión con el navegador",
|
|
1510
1514
|
"Sign in with the browser instead": "Iniciar sesión con el navegador",
|
|
1511
1515
|
"Real-time market data": "Datos de mercado en tiempo real",
|
|
1516
|
+
// ── Onboarding desks ─────────────────────────────────────────
|
|
1517
|
+
"What do you trade most?": "¿Qué operas más?",
|
|
1518
|
+
"Pick up to 3; each adds a ready-made tab.": "Elige hasta 3; cada una añade una pestaña lista.",
|
|
1519
|
+
"Everything else is one search away.": "Todo lo demás está a una búsqueda.",
|
|
1520
|
+
"DESKS": "MESAS",
|
|
1521
|
+
"Skip": "Omitir",
|
|
1522
|
+
"Equities": "Renta variable",
|
|
1523
|
+
"Futures & commodities": "Futuros y materias primas",
|
|
1524
|
+
"Rates & credit": "Tipos y crédito",
|
|
1525
|
+
"FX & macro": "Divisas y macro",
|
|
1526
|
+
"Active trading": "Trading activo",
|
|
1527
|
+
"Your holdings as a heatmap, a watchlist, and {ticker} charted. Your desks are tabs at the bottom; {shortcut} adds more.": "Tus posiciones como mapa de calor, una lista de seguimiento y el gráfico de {ticker}. Tus mesas son pestañas abajo; {shortcut} añade más.",
|
|
1512
1528
|
// ── Upgrade sheet ─────────────────────────────────────────
|
|
1513
1529
|
"Start free trial": "Iniciar prueba gratis",
|
|
1514
1530
|
"Your last payment didn't go through": "Tu último pago no se completó",
|
package/src/i18n/ja.ts
CHANGED
|
@@ -170,6 +170,7 @@ export const ja: Record<string, string> = {
|
|
|
170
170
|
"Export Config": "設定をエクスポート",
|
|
171
171
|
"Import Config": "設定をインポート",
|
|
172
172
|
"Reset All Data": "すべてのデータをリセット",
|
|
173
|
+
"Run Setup Again": "セットアップをやり直す",
|
|
173
174
|
"Reset Everything": "すべてをリセット",
|
|
174
175
|
"Reset Layout": "レイアウトをリセット",
|
|
175
176
|
"Reset Current Layout": "現在のレイアウトをリセット",
|
|
@@ -187,6 +188,7 @@ export const ja: Record<string, string> = {
|
|
|
187
188
|
"Save config to ~/gloomberb-config-backup.json": "設定を ~/gloomberb-config-backup.json に保存",
|
|
188
189
|
"Load config from ~/gloomberb-config-backup.json": "~/gloomberb-config-backup.json から設定を読み込む",
|
|
189
190
|
"Delete all data and reset to first-run state": "すべてのデータを削除して初回起動状態に戻す",
|
|
191
|
+
"Rebuild Home and setup's desk tabs; your other layouts stay": "Home とセットアップのデスクタブを作り直す。ほかのレイアウトはそのまま",
|
|
190
192
|
"Edit settings for the focused pane": "フォーカスされたペインの設定を編集する",
|
|
191
193
|
"Move or resize the focused window": "フォーカスされたウィンドウを移動またはサイズ変更する",
|
|
192
194
|
"Add current ticker to active portfolio": "現在の銘柄を使用中のポートフォリオに追加",
|
|
@@ -1343,6 +1345,8 @@ export const ja: Record<string, string> = {
|
|
|
1343
1345
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1344
1346
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1345
1347
|
"GLOOM SETUP": "GLOOM セットアップ",
|
|
1348
|
+
"Skip setup": "セットアップをスキップ",
|
|
1349
|
+
"Closing...": "閉じています...",
|
|
1346
1350
|
"Gloom Cloud is connected": "Gloom Cloudに接続しました",
|
|
1347
1351
|
"How do you want to start?": "どの方法で始めますか?",
|
|
1348
1352
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "{broker}から{count}件のポジションをインポートしました。ワークスペースの準備が整いました。",
|
|
@@ -1451,7 +1455,7 @@ export const ja: Record<string, string> = {
|
|
|
1451
1455
|
"New accounts get a verification email.": "新規アカウントには確認メールが届きます。",
|
|
1452
1456
|
"No exact ticker match": "完全一致する銘柄なし",
|
|
1453
1457
|
"No exact ticker match.": "完全一致する銘柄がありません。",
|
|
1454
|
-
"No
|
|
1458
|
+
"No price yet. Enter the average cost.": "まだ価格がありません。平均取得単価を入力してください。",
|
|
1455
1459
|
"Open the sign-in link, or scan the code with your phone.": "ログインリンクを開くか、スマートフォンでコードを読み取ってください。",
|
|
1456
1460
|
"Positions ({count})": "ポジション({count})",
|
|
1457
1461
|
"Shares cannot be 0. Enter a negative number for a short.": "株数を 0 にすることはできません。ショートは負の数で入力してください。",
|
|
@@ -1472,7 +1476,7 @@ export const ja: Record<string, string> = {
|
|
|
1472
1476
|
"Avg cost": "平均取得価格",
|
|
1473
1477
|
"Currency": "通貨",
|
|
1474
1478
|
"optional": "任意",
|
|
1475
|
-
"
|
|
1479
|
+
"last price": "直近の価格",
|
|
1476
1480
|
"e.g. AAPL": "例: AAPL",
|
|
1477
1481
|
"Add": "追加",
|
|
1478
1482
|
"Adding...": "追加中...",
|
|
@@ -1505,6 +1509,18 @@ export const ja: Record<string, string> = {
|
|
|
1505
1509
|
"b: sign in with the browser instead": "b: ブラウザーでサインイン",
|
|
1506
1510
|
"Sign in with the browser instead": "ブラウザーでサインイン",
|
|
1507
1511
|
"Real-time market data": "リアルタイム市場データ",
|
|
1512
|
+
// ── Onboarding desks ─────────────────────────────────────────
|
|
1513
|
+
"What do you trade most?": "主に何を取引しますか?",
|
|
1514
|
+
"Pick up to 3; each adds a ready-made tab.": "最大3つまで選べます。それぞれ用意済みのタブを追加します。",
|
|
1515
|
+
"Everything else is one search away.": "その他はすべて検索ひとつで開けます。",
|
|
1516
|
+
"DESKS": "デスク",
|
|
1517
|
+
"Skip": "スキップ",
|
|
1518
|
+
"Equities": "株式",
|
|
1519
|
+
"Futures & commodities": "先物・コモディティ",
|
|
1520
|
+
"Rates & credit": "金利・クレジット",
|
|
1521
|
+
"FX & macro": "為替・マクロ",
|
|
1522
|
+
"Active trading": "アクティブトレード",
|
|
1523
|
+
"Your holdings as a heatmap, a watchlist, and {ticker} charted. Your desks are tabs at the bottom; {shortcut} adds more.": "保有銘柄のヒートマップ、ウォッチリスト、{ticker} のチャート。デスクは下部のタブにあり、{shortcut} で追加できます。",
|
|
1508
1524
|
// ── Upgrade sheet ─────────────────────────────────────────
|
|
1509
1525
|
"Start free trial": "無料トライアルを開始",
|
|
1510
1526
|
"Your last payment didn't go through": "前回のお支払いが完了しませんでした",
|
package/src/i18n/ko.ts
CHANGED
|
@@ -168,6 +168,7 @@ export const ko: Record<string, string> = {
|
|
|
168
168
|
"Export Config": "설정 내보내기",
|
|
169
169
|
"Import Config": "설정 가져오기",
|
|
170
170
|
"Reset All Data": "모든 데이터 재설정",
|
|
171
|
+
"Run Setup Again": "설정 다시 실행",
|
|
171
172
|
"Reset Everything": "모든 것을 재설정",
|
|
172
173
|
"Reset Layout": "레이아웃 재설정",
|
|
173
174
|
"Reset Current Layout": "현재 레이아웃 재설정",
|
|
@@ -185,6 +186,7 @@ export const ko: Record<string, string> = {
|
|
|
185
186
|
"Save config to ~/gloomberb-config-backup.json": "설정을 ~/gloomberb-config-backup.json에 저장",
|
|
186
187
|
"Load config from ~/gloomberb-config-backup.json": "~/gloomberb-config-backup.json에서 설정 불러오기",
|
|
187
188
|
"Delete all data and reset to first-run state": "모든 데이터를 삭제하고 최초 실행 상태로 재설정",
|
|
189
|
+
"Rebuild Home and setup's desk tabs; your other layouts stay": "Home과 설정이 만든 데스크 탭을 다시 만들고 다른 레이아웃은 유지",
|
|
188
190
|
"Edit settings for the focused pane": "포커스 패널 설정 편집",
|
|
189
191
|
"Move or resize the focused window": "포커스 창 이동 또는 크기 조정",
|
|
190
192
|
"Add current ticker to active portfolio": "현재 종목을 활성 포트폴리오에 추가",
|
|
@@ -1341,6 +1343,8 @@ export const ko: Record<string, string> = {
|
|
|
1341
1343
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1342
1344
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1343
1345
|
"GLOOM SETUP": "GLOOM 설정",
|
|
1346
|
+
"Skip setup": "설정 건너뛰기",
|
|
1347
|
+
"Closing...": "닫는 중...",
|
|
1344
1348
|
"Gloom Cloud is connected": "Gloom Cloud가 연결되었습니다",
|
|
1345
1349
|
"How do you want to start?": "어떻게 시작하시겠어요?",
|
|
1346
1350
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "{broker}에서 {count}개 보유 종목을 가져왔습니다. 이제 작업 공간을 둘러볼 수 있습니다.",
|
|
@@ -1449,7 +1453,7 @@ export const ko: Record<string, string> = {
|
|
|
1449
1453
|
"New accounts get a verification email.": "신규 계정에는 인증 이메일이 발송됩니다.",
|
|
1450
1454
|
"No exact ticker match": "정확히 일치하는 종목 없음",
|
|
1451
1455
|
"No exact ticker match.": "정확히 일치하는 종목이 없습니다.",
|
|
1452
|
-
"No
|
|
1456
|
+
"No price yet. Enter the average cost.": "아직 가격이 없습니다. 평균 단가를 입력하세요.",
|
|
1453
1457
|
"Open the sign-in link, or scan the code with your phone.": "로그인 링크를 열거나 휴대폰으로 코드를 스캔하세요.",
|
|
1454
1458
|
"Positions ({count})": "포지션 ({count})",
|
|
1455
1459
|
"Shares cannot be 0. Enter a negative number for a short.": "수량은 0일 수 없습니다. 공매도는 음수로 입력하세요.",
|
|
@@ -1470,7 +1474,7 @@ export const ko: Record<string, string> = {
|
|
|
1470
1474
|
"Avg cost": "평균 단가",
|
|
1471
1475
|
"Currency": "통화",
|
|
1472
1476
|
"optional": "선택",
|
|
1473
|
-
"
|
|
1477
|
+
"last price": "최근 가격",
|
|
1474
1478
|
"e.g. AAPL": "예: AAPL",
|
|
1475
1479
|
"Add": "추가",
|
|
1476
1480
|
"Adding...": "추가 중...",
|
|
@@ -1503,6 +1507,18 @@ export const ko: Record<string, string> = {
|
|
|
1503
1507
|
"b: sign in with the browser instead": "b: 브라우저로 로그인",
|
|
1504
1508
|
"Sign in with the browser instead": "브라우저로 로그인",
|
|
1505
1509
|
"Real-time market data": "실시간 시장 데이터",
|
|
1510
|
+
// ── Onboarding desks ─────────────────────────────────────────
|
|
1511
|
+
"What do you trade most?": "주로 무엇을 거래하나요?",
|
|
1512
|
+
"Pick up to 3; each adds a ready-made tab.": "최대 3개까지 고르세요. 각각 준비된 탭을 추가합니다.",
|
|
1513
|
+
"Everything else is one search away.": "나머지는 검색 한 번이면 됩니다.",
|
|
1514
|
+
"DESKS": "데스크",
|
|
1515
|
+
"Skip": "건너뛰기",
|
|
1516
|
+
"Equities": "주식",
|
|
1517
|
+
"Futures & commodities": "선물 및 원자재",
|
|
1518
|
+
"Rates & credit": "금리 및 크레딧",
|
|
1519
|
+
"FX & macro": "외환 및 매크로",
|
|
1520
|
+
"Active trading": "액티브 트레이딩",
|
|
1521
|
+
"Your holdings as a heatmap, a watchlist, and {ticker} charted. Your desks are tabs at the bottom; {shortcut} adds more.": "보유 종목 히트맵, 관심 목록, {ticker} 차트. 데스크는 하단 탭에 있고 {shortcut}로 더 추가합니다.",
|
|
1506
1522
|
// ── Upgrade sheet ─────────────────────────────────────────
|
|
1507
1523
|
"Start free trial": "무료 체험 시작",
|
|
1508
1524
|
"Your last payment didn't go through": "지난 결제가 처리되지 않았습니다",
|
package/src/i18n/zh-cn.ts
CHANGED
|
@@ -170,6 +170,7 @@ export const zhCN: Record<string, string> = {
|
|
|
170
170
|
"Export Config": "导出配置",
|
|
171
171
|
"Import Config": "导入配置",
|
|
172
172
|
"Reset All Data": "重置所有数据",
|
|
173
|
+
"Run Setup Again": "重新运行设置",
|
|
173
174
|
"Reset Everything": "全部重置",
|
|
174
175
|
"Reset Layout": "重置布局",
|
|
175
176
|
"Reset Current Layout": "重置当前布局",
|
|
@@ -187,6 +188,7 @@ export const zhCN: Record<string, string> = {
|
|
|
187
188
|
"Save config to ~/gloomberb-config-backup.json": "将配置保存到 ~/gloomberb-config-backup.json",
|
|
188
189
|
"Load config from ~/gloomberb-config-backup.json": "从 ~/gloomberb-config-backup.json 载入配置",
|
|
189
190
|
"Delete all data and reset to first-run state": "删除全部数据并恢复到初始状态",
|
|
191
|
+
"Rebuild Home and setup's desk tabs; your other layouts stay": "重建 Home 和设置创建的交易台标签页;其他布局保持不变",
|
|
190
192
|
"Edit settings for the focused pane": "编辑聚焦面板的设置",
|
|
191
193
|
"Move or resize the focused window": "移动或调整聚焦窗口大小",
|
|
192
194
|
"Add current ticker to active portfolio": "把当前股票加入活动投资组合",
|
|
@@ -1343,6 +1345,8 @@ export const zhCN: Record<string, string> = {
|
|
|
1343
1345
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1344
1346
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1345
1347
|
"GLOOM SETUP": "GLOOM 设置",
|
|
1348
|
+
"Skip setup": "跳过设置",
|
|
1349
|
+
"Closing...": "正在关闭...",
|
|
1346
1350
|
"Gloom Cloud is connected": "Gloom Cloud 已连接",
|
|
1347
1351
|
"How do you want to start?": "你想如何开始?",
|
|
1348
1352
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "已从 {broker} 导入 {count} 个持仓。你的工作区已准备好,可以开始探索。",
|
|
@@ -1451,7 +1455,7 @@ export const zhCN: Record<string, string> = {
|
|
|
1451
1455
|
"New accounts get a verification email.": "新账户会收到一封验证邮件。",
|
|
1452
1456
|
"No exact ticker match": "没有完全匹配的代码",
|
|
1453
1457
|
"No exact ticker match.": "没有完全匹配的代码。",
|
|
1454
|
-
"No
|
|
1458
|
+
"No price yet. Enter the average cost.": "暂无价格,请输入平均成本。",
|
|
1455
1459
|
"Open the sign-in link, or scan the code with your phone.": "打开登录链接,或用手机扫描二维码。",
|
|
1456
1460
|
"Positions ({count})": "持仓({count})",
|
|
1457
1461
|
"Shares cannot be 0. Enter a negative number for a short.": "数量不能为 0。做空请输入负数。",
|
|
@@ -1472,7 +1476,7 @@ export const zhCN: Record<string, string> = {
|
|
|
1472
1476
|
"Avg cost": "平均成本",
|
|
1473
1477
|
"Currency": "货币",
|
|
1474
1478
|
"optional": "可选",
|
|
1475
|
-
"
|
|
1479
|
+
"last price": "最新价格",
|
|
1476
1480
|
"e.g. AAPL": "例如 AAPL",
|
|
1477
1481
|
"Add": "添加",
|
|
1478
1482
|
"Adding...": "正在添加...",
|
|
@@ -1505,6 +1509,18 @@ export const zhCN: Record<string, string> = {
|
|
|
1505
1509
|
"b: sign in with the browser instead": "b:改用浏览器登录",
|
|
1506
1510
|
"Sign in with the browser instead": "改用浏览器登录",
|
|
1507
1511
|
"Real-time market data": "实时市场数据",
|
|
1512
|
+
// ── Onboarding desks ─────────────────────────────────────────
|
|
1513
|
+
"What do you trade most?": "你最常交易什么?",
|
|
1514
|
+
"Pick up to 3; each adds a ready-made tab.": "最多选 3 项,每项添加一个现成的标签页。",
|
|
1515
|
+
"Everything else is one search away.": "其他内容一搜即得。",
|
|
1516
|
+
"DESKS": "交易台",
|
|
1517
|
+
"Skip": "跳过",
|
|
1518
|
+
"Equities": "股票",
|
|
1519
|
+
"Futures & commodities": "期货与大宗商品",
|
|
1520
|
+
"Rates & credit": "利率与信用",
|
|
1521
|
+
"FX & macro": "外汇与宏观",
|
|
1522
|
+
"Active trading": "活跃交易",
|
|
1523
|
+
"Your holdings as a heatmap, a watchlist, and {ticker} charted. Your desks are tabs at the bottom; {shortcut} adds more.": "持仓热力图、自选列表和 {ticker} 的图表。你的交易台在底部标签页;{shortcut} 可添加更多。",
|
|
1508
1524
|
// ── Upgrade sheet ─────────────────────────────────────────
|
|
1509
1525
|
"Start free trial": "开始免费试用",
|
|
1510
1526
|
"Your last payment didn't go through": "上次付款未成功",
|
package/src/i18n/zh-tw.ts
CHANGED
|
@@ -170,6 +170,7 @@ export const zhTW: Record<string, string> = {
|
|
|
170
170
|
"Export Config": "匯出設定",
|
|
171
171
|
"Import Config": "匯入設定",
|
|
172
172
|
"Reset All Data": "重置所有資料",
|
|
173
|
+
"Run Setup Again": "重新執行設定",
|
|
173
174
|
"Reset Everything": "全部重置",
|
|
174
175
|
"Reset Layout": "重置版面設定",
|
|
175
176
|
"Reset Current Layout": "重置目前版面設定",
|
|
@@ -187,6 +188,7 @@ export const zhTW: Record<string, string> = {
|
|
|
187
188
|
"Save config to ~/gloomberb-config-backup.json": "將設定儲存到 ~/gloomberb-config-backup.json",
|
|
188
189
|
"Load config from ~/gloomberb-config-backup.json": "從 ~/gloomberb-config-backup.json 載入設定",
|
|
189
190
|
"Delete all data and reset to first-run state": "刪除全部資料並恢復到初始狀態",
|
|
191
|
+
"Rebuild Home and setup's desk tabs; your other layouts stay": "重建 Home 與設定建立的交易台分頁;其他版面設定保持不變",
|
|
190
192
|
"Edit settings for the focused pane": "編輯聚焦面板的設定",
|
|
191
193
|
"Move or resize the focused window": "移動或調整聚焦視窗大小",
|
|
192
194
|
"Add current ticker to active portfolio": "將目前股票加入使用中的投資組合",
|
|
@@ -1343,6 +1345,8 @@ export const zhTW: Record<string, string> = {
|
|
|
1343
1345
|
"GLOOM CLOUD": "GLOOM CLOUD",
|
|
1344
1346
|
"GLOOM CLOUD PRO": "GLOOM CLOUD PRO",
|
|
1345
1347
|
"GLOOM SETUP": "GLOOM 設定",
|
|
1348
|
+
"Skip setup": "跳過設定",
|
|
1349
|
+
"Closing...": "正在關閉...",
|
|
1346
1350
|
"Gloom Cloud is connected": "Gloom Cloud 已連線",
|
|
1347
1351
|
"How do you want to start?": "你想如何開始?",
|
|
1348
1352
|
"Imported {count} positions from {broker}. Your workspace is ready to explore.": "已從 {broker} 匯入 {count} 個部位。你的工作區已準備好,可以開始探索。",
|
|
@@ -1451,7 +1455,7 @@ export const zhTW: Record<string, string> = {
|
|
|
1451
1455
|
"New accounts get a verification email.": "新帳戶會收到一封驗證郵件。",
|
|
1452
1456
|
"No exact ticker match": "沒有完全相符的代號",
|
|
1453
1457
|
"No exact ticker match.": "沒有完全相符的代號。",
|
|
1454
|
-
"No
|
|
1458
|
+
"No price yet. Enter the average cost.": "尚無價格,請輸入平均成本。",
|
|
1455
1459
|
"Open the sign-in link, or scan the code with your phone.": "開啟登入連結,或用手機掃描 QR 碼。",
|
|
1456
1460
|
"Positions ({count})": "持倉({count})",
|
|
1457
1461
|
"Shares cannot be 0. Enter a negative number for a short.": "股數不能為 0。放空請輸入負數。",
|
|
@@ -1472,7 +1476,7 @@ export const zhTW: Record<string, string> = {
|
|
|
1472
1476
|
"Avg cost": "平均成本",
|
|
1473
1477
|
"Currency": "貨幣",
|
|
1474
1478
|
"optional": "選填",
|
|
1475
|
-
"
|
|
1479
|
+
"last price": "最新價格",
|
|
1476
1480
|
"e.g. AAPL": "例如 AAPL",
|
|
1477
1481
|
"Add": "新增",
|
|
1478
1482
|
"Adding...": "正在新增...",
|
|
@@ -1505,6 +1509,18 @@ export const zhTW: Record<string, string> = {
|
|
|
1505
1509
|
"b: sign in with the browser instead": "b:改用瀏覽器登入",
|
|
1506
1510
|
"Sign in with the browser instead": "改用瀏覽器登入",
|
|
1507
1511
|
"Real-time market data": "即時市場資料",
|
|
1512
|
+
// ── Onboarding desks ─────────────────────────────────────────
|
|
1513
|
+
"What do you trade most?": "你最常交易什麼?",
|
|
1514
|
+
"Pick up to 3; each adds a ready-made tab.": "最多選 3 項,每項新增一個現成的分頁。",
|
|
1515
|
+
"Everything else is one search away.": "其他內容一搜即得。",
|
|
1516
|
+
"DESKS": "交易台",
|
|
1517
|
+
"Skip": "略過",
|
|
1518
|
+
"Equities": "股票",
|
|
1519
|
+
"Futures & commodities": "期貨與大宗商品",
|
|
1520
|
+
"Rates & credit": "利率與信用",
|
|
1521
|
+
"FX & macro": "外匯與總經",
|
|
1522
|
+
"Active trading": "積極交易",
|
|
1523
|
+
"Your holdings as a heatmap, a watchlist, and {ticker} charted. Your desks are tabs at the bottom; {shortcut} adds more.": "持股熱力圖、觀察清單和 {ticker} 的圖表。你的交易台在底部分頁;{shortcut} 可新增更多。",
|
|
1508
1524
|
// ── Upgrade sheet ─────────────────────────────────────────
|
|
1509
1525
|
"Start free trial": "開始免費試用",
|
|
1510
1526
|
"Your last payment didn't go through": "上次付款未成功",
|
package/src/layout/desk-keys.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The desks offered when the app first runs ("What do you trade?"). Kept apart
|
|
2
|
+
* The desks offered when the app first runs ("What do you trade most?"). Kept apart
|
|
3
3
|
* from the desk layouts (desks.ts) so chat can name what someone trades
|
|
4
4
|
* without loading every layout. The server keeps the same keys.
|
|
5
5
|
*/
|
|
6
6
|
export const DESK_KEYS = ["equities", "options", "futures", "rates", "fx", "active"] as const;
|
|
7
7
|
export type DeskKey = (typeof DESK_KEYS)[number];
|
|
8
|
+
|
|
9
|
+
/** The most desks the step takes: the few someone trades most, not one of each. */
|
|
10
|
+
export const MAX_DESK_PICKS = 3;
|
package/src/layout/desks.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { DESK_KEYS, type DeskKey } from "./desk-keys";
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Desks: ready-made layout tabs for one kind of trading, offered when the app
|
|
31
|
-
* first runs ("What do you trade?") and later with DESK. A desk is a list of
|
|
31
|
+
* first runs ("What do you trade most?") and later with DESK. A desk is a list of
|
|
32
32
|
* functions as the command bar takes them, built through the same pane
|
|
33
33
|
* templates, so each tile is what typing the function opens. Only functions
|
|
34
34
|
* that show real data signed out and on Free go in a desk; a Pro-only function
|
|
@@ -56,8 +56,8 @@ interface DeskPane {
|
|
|
56
56
|
studies?: readonly BuiltinStudySelection[];
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export interface Desk {
|
|
60
|
-
key:
|
|
59
|
+
export interface Desk<K extends string = DeskKey> {
|
|
60
|
+
key: K;
|
|
61
61
|
/** What the picker calls it. */
|
|
62
62
|
label: string;
|
|
63
63
|
/** The tab's name. */
|
|
@@ -173,6 +173,39 @@ export const DESKS: readonly Desk[] = [
|
|
|
173
173
|
},
|
|
174
174
|
];
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Desks DESK offers that the first-run question does not: a workspace around
|
|
178
|
+
* one dataset rather than a kind of trading. TheBuildout's starts from its
|
|
179
|
+
* theme board, and every other pane follows the company selected there; the
|
|
180
|
+
* map-first desk is the same panes with the facilities map given the room.
|
|
181
|
+
*/
|
|
182
|
+
export const MORE_DESKS: readonly Desk<"buildout" | "buildout-map">[] = [
|
|
183
|
+
{
|
|
184
|
+
key: "buildout",
|
|
185
|
+
label: "AI buildout",
|
|
186
|
+
name: "Buildout",
|
|
187
|
+
panes: [
|
|
188
|
+
{ fn: "TBO" },
|
|
189
|
+
{ fn: "TBOC", follows: 1 },
|
|
190
|
+
{ fn: "MAP", arg: "facilities", follows: 1 },
|
|
191
|
+
{ fn: "TBOC", options: { tab: "signals" }, follows: 1 },
|
|
192
|
+
],
|
|
193
|
+
dock: row(0.5, pane(1), column(0.54, pane(2), row(0.5, pane(3), pane(4)))),
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
key: "buildout-map",
|
|
197
|
+
label: "AI buildout, map first",
|
|
198
|
+
name: "Buildout Map",
|
|
199
|
+
panes: [
|
|
200
|
+
{ fn: "TBO" },
|
|
201
|
+
{ fn: "MAP", arg: "facilities", follows: 1 },
|
|
202
|
+
{ fn: "TBOC", follows: 1 },
|
|
203
|
+
{ fn: "TBOC", options: { tab: "signals" }, follows: 1 },
|
|
204
|
+
],
|
|
205
|
+
dock: row(0.6, column(0.6, pane(2), pane(1)), column(0.55, pane(3), pane(4))),
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
|
|
176
209
|
export function getDesk(key: DeskKey): Desk {
|
|
177
210
|
return DESKS.find((desk) => desk.key === key)!;
|
|
178
211
|
}
|
|
@@ -204,7 +237,7 @@ export function isDeskStock(
|
|
|
204
237
|
}
|
|
205
238
|
|
|
206
239
|
/** The mnemonics a desk opens, for a one-line summary. */
|
|
207
|
-
export function deskFunctions(desk: Desk): string[] {
|
|
240
|
+
export function deskFunctions(desk: Desk<string>): string[] {
|
|
208
241
|
return [...new Set(desk.panes.map((entry) => entry.fn))];
|
|
209
242
|
}
|
|
210
243
|
|
|
@@ -298,7 +331,7 @@ export interface BuildDeskOptions {
|
|
|
298
331
|
* than shown as a placeholder, and its neighbours take the room. Null when
|
|
299
332
|
* the host has none of them.
|
|
300
333
|
*/
|
|
301
|
-
export async function buildDesk(desk: Desk
|
|
334
|
+
export async function buildDesk(desk: Desk<string>, { catalog, config, company, pro }: BuildDeskOptions): Promise<DeskLayout | null> {
|
|
302
335
|
const entries = pro && desk.pro?.length ? [...desk.panes, ...desk.pro] : desk.panes;
|
|
303
336
|
const available = entries.flatMap((entry, index) => {
|
|
304
337
|
const template = deskTemplate(catalog, entry.fn);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
|
|
2
2
|
import {
|
|
3
3
|
getPaneSidebarWidth,
|
|
4
|
+
getPaneSidebarWidthRange,
|
|
4
5
|
PaneSidebar,
|
|
5
6
|
PaneSidebarRow,
|
|
6
7
|
} from "../components/layout/pane/sidebar";
|
|
@@ -14,6 +15,7 @@ import { useShortcut } from "../react/input";
|
|
|
14
15
|
import { t, tf } from "../i18n";
|
|
15
16
|
import { useThemeColors } from "../theme/theme-context";
|
|
16
17
|
import { Box, ScrollBox, Text, TextAttributes, useUiCapabilities, type InputRenderable } from "../ui";
|
|
18
|
+
import { clipToDisplayWidth, displayWidth } from "../utils/format";
|
|
17
19
|
import { isPlainKey } from "../utils/keyboard";
|
|
18
20
|
import type { GallerySearchState, LayoutGalleryController } from "./gallery";
|
|
19
21
|
import { MiniWorkspace } from "./mini-workspace";
|
|
@@ -50,6 +52,24 @@ function useCursorRowInView(selected: boolean) {
|
|
|
50
52
|
/** Every sidebar row starts at the pane's inset; the row's fill still runs to the edge. */
|
|
51
53
|
const ROW_INSET = { paddingLeft: "var(--gloom-inset)", boxSizing: "border-box" } as const;
|
|
52
54
|
|
|
55
|
+
/** Cells a section header spends beside its label: the pane's inset, the disclosure marker and the gap after it. */
|
|
56
|
+
const SECTION_HEADER_CHROME = 4;
|
|
57
|
+
|
|
58
|
+
function sectionLabel(title: string, count: number): string {
|
|
59
|
+
return tf("{title} ({count})", { title: t(title), count: String(count) });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A header's label in `room` cells with its count kept: a long name gives up
|
|
64
|
+
* its own end, so the row never reads `Your layouts (1`.
|
|
65
|
+
*/
|
|
66
|
+
function fitSectionLabel(title: string, count: number, room: number): string {
|
|
67
|
+
const label = sectionLabel(title, count);
|
|
68
|
+
if (displayWidth(label) <= room) return label;
|
|
69
|
+
const total = displayWidth(` (${count})`);
|
|
70
|
+
return `${clipToDisplayWidth(t(title), Math.max(1, room - total))} (${count})`;
|
|
71
|
+
}
|
|
72
|
+
|
|
53
73
|
/** A collapsible group header, the same row the chat sidebar uses. */
|
|
54
74
|
function SidebarSection({
|
|
55
75
|
title,
|
|
@@ -68,7 +88,7 @@ function SidebarSection({
|
|
|
68
88
|
return (
|
|
69
89
|
<Box height={1} width={width} flexDirection="row" flexShrink={0} style={ROW_INSET}>
|
|
70
90
|
<ActionRow
|
|
71
|
-
label={
|
|
91
|
+
label={fitSectionLabel(title, count, width - SECTION_HEADER_CHROME)}
|
|
72
92
|
expanded={expanded}
|
|
73
93
|
width={Math.max(1, width - 1)}
|
|
74
94
|
onPress={onToggle}
|
|
@@ -232,19 +252,15 @@ function TeamStatus({ controller }: { controller: LayoutGalleryController }) {
|
|
|
232
252
|
}
|
|
233
253
|
|
|
234
254
|
function PreviewEmpty({ controller }: { controller: LayoutGalleryController }) {
|
|
235
|
-
const colors = useThemeColors();
|
|
236
255
|
const searching = controller.query.trim().length > 0;
|
|
237
256
|
return (
|
|
238
257
|
<Box
|
|
239
258
|
flexGrow={1}
|
|
240
|
-
|
|
241
|
-
|
|
259
|
+
paddingX={1}
|
|
260
|
+
paddingY={1}
|
|
242
261
|
data-gloom-role="layout-gallery-preview-empty"
|
|
243
|
-
padding={2}
|
|
244
262
|
>
|
|
245
|
-
<
|
|
246
|
-
{searching ? t("No layouts match this search.") : t("No layout selected.")}
|
|
247
|
-
</Text>
|
|
263
|
+
<EmptyState title={searching ? "No layouts match this search." : "No layout selected."} />
|
|
248
264
|
</Box>
|
|
249
265
|
);
|
|
250
266
|
}
|
|
@@ -256,6 +272,7 @@ function PreviewEmpty({ controller }: { controller: LayoutGalleryController }) {
|
|
|
256
272
|
*/
|
|
257
273
|
function PreviewPane({ controller, entry }: { controller: LayoutGalleryController; entry: GalleryEntry }) {
|
|
258
274
|
const colors = useThemeColors();
|
|
275
|
+
const panes = summarizeLayoutPanes(entry.layout, controller.panes);
|
|
259
276
|
const linked = entry.kind === "owned" ? entry.linked ?? null : null;
|
|
260
277
|
const metadata = [
|
|
261
278
|
entry.team ? `${entry.team.shortName}· ${entry.team.name}` : null,
|
|
@@ -296,13 +313,17 @@ function PreviewPane({ controller, entry }: { controller: LayoutGalleryControlle
|
|
|
296
313
|
</Box>
|
|
297
314
|
|
|
298
315
|
<Box flexGrow={1} minWidth={0} minHeight={8} overflow="hidden" padding={1}>
|
|
299
|
-
|
|
300
|
-
layout
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
316
|
+
{panes.length === 0 ? (
|
|
317
|
+
<EmptyState title="No panes in this layout." />
|
|
318
|
+
) : (
|
|
319
|
+
<MiniWorkspace
|
|
320
|
+
layout={entry.layout}
|
|
321
|
+
panes={controller.panes}
|
|
322
|
+
width={PREVIEW.width}
|
|
323
|
+
height={PREVIEW.height}
|
|
324
|
+
detail
|
|
325
|
+
/>
|
|
326
|
+
)}
|
|
306
327
|
</Box>
|
|
307
328
|
</Box>
|
|
308
329
|
);
|
|
@@ -323,8 +344,16 @@ export function LayoutGalleryDesktop({
|
|
|
323
344
|
height?: number;
|
|
324
345
|
}) {
|
|
325
346
|
const { nativePaneChrome } = useUiCapabilities();
|
|
326
|
-
const sidebarWidth = getPaneSidebarWidth(width, !!nativePaneChrome);
|
|
327
347
|
const selected = resolvePreviewEntry(controller);
|
|
348
|
+
// Wide enough for the fixed headers with their counts, which the default width cuts in a narrow pane.
|
|
349
|
+
const headerWidth = Math.max(
|
|
350
|
+
displayWidth(sectionLabel("Your layouts", controller.owned.length)),
|
|
351
|
+
displayWidth(sectionLabel("Discover", controller.community.length)),
|
|
352
|
+
) + SECTION_HEADER_CHROME;
|
|
353
|
+
const sidebarWidth = Math.max(
|
|
354
|
+
getPaneSidebarWidth(width, !!nativePaneChrome),
|
|
355
|
+
Math.min(headerWidth, getPaneSidebarWidthRange(width).max),
|
|
356
|
+
);
|
|
328
357
|
const inputRef = useRef<InputRenderable | null>(null);
|
|
329
358
|
const [localSearchActive, setLocalSearchActive] = useState(false);
|
|
330
359
|
const searchActive = search?.active ?? localSearchActive;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BatchedReadMethod, DataProvider } from "../types/data-provider";
|
|
2
|
+
import { logFailure } from "../utils/log-failure";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether `provider` sends reads of `method` asked together as batch requests
|
|
6
|
+
* (`DataProvider.batchesReads`), so a caller may ask them all at once instead
|
|
7
|
+
* of a few at a time. False for a provider that does not say, or whose
|
|
8
|
+
* answer fails.
|
|
9
|
+
*/
|
|
10
|
+
export async function readsInBatches(
|
|
11
|
+
provider: Pick<DataProvider, "batchesReads"> | null | undefined,
|
|
12
|
+
method: BatchedReadMethod,
|
|
13
|
+
): Promise<boolean> {
|
|
14
|
+
return Promise.resolve().then(() => provider?.batchesReads?.(method))
|
|
15
|
+
.then((answer) => answer === true, logFailure("market-data.batched-reads", "Ask whether a source batches reads failed", false));
|
|
16
|
+
}
|
|
@@ -48,11 +48,13 @@ interface AuxiliaryLoaderOptions<T> {
|
|
|
48
48
|
export function loadOptionsEntry(options: {
|
|
49
49
|
dataProvider: DataProvider;
|
|
50
50
|
forceRefresh?: boolean;
|
|
51
|
+
/** One of many expiries asked at once (`MarketDataRequestContext.batch`). */
|
|
52
|
+
batch?: boolean;
|
|
51
53
|
request: OptionsRequest;
|
|
52
54
|
store: QueryStore<OptionsChain>;
|
|
53
55
|
runSingleFlight: RunSingleFlight;
|
|
54
56
|
}): Promise<QueryEntry<OptionsChain>> {
|
|
55
|
-
const { dataProvider, forceRefresh = false, request, store, runSingleFlight } = options;
|
|
57
|
+
const { dataProvider, forceRefresh = false, batch = false, request, store, runSingleFlight } = options;
|
|
56
58
|
const key = buildOptionsKey(request);
|
|
57
59
|
return loadAuxiliaryEntry({
|
|
58
60
|
dataProvider,
|
|
@@ -72,7 +74,7 @@ export function loadOptionsEntry(options: {
|
|
|
72
74
|
request.instrument.symbol,
|
|
73
75
|
request.instrument.exchange ?? "",
|
|
74
76
|
request.expirationDate,
|
|
75
|
-
{ ...toMarketDataContext(request.instrument), cacheMode: forceRefresh ? "refresh" : "current" },
|
|
77
|
+
{ ...toMarketDataContext(request.instrument), cacheMode: forceRefresh ? "refresh" : "current", ...(batch ? { batch: true } : {}) },
|
|
76
78
|
);
|
|
77
79
|
const attempts = [createAttempt(dataProvider.id, startedAt, data.expirationDates.length > 0 ? "success" : "empty", data.expirationDates.length === 0 ? "NO_DATA" : undefined)];
|
|
78
80
|
return store.update(key, (current) => ({
|
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
type QuoteSubscriptionRequest,
|
|
84
84
|
} from "./quotes";
|
|
85
85
|
import { withSavedCopyMarkOf } from "../../data/saved-copies";
|
|
86
|
+
import { readsInBatches } from "../batched-reads";
|
|
86
87
|
|
|
87
88
|
/** How long a streamed tick may reuse the quote fields read from the cache. */
|
|
88
89
|
const STREAM_QUOTE_BASELINE_TTL_MS = 60_000;
|
|
@@ -479,9 +480,15 @@ export class MarketDataCoordinator {
|
|
|
479
480
|
});
|
|
480
481
|
}
|
|
481
482
|
|
|
483
|
+
/** Whether expiries asked together reach the source in batch requests (`DataProvider.batchesReads`). */
|
|
484
|
+
batchesOptions(): Promise<boolean> {
|
|
485
|
+
return readsInBatches(this.dataProvider, "getOptionsChain");
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/** `batch`: one of many expiries asked at once, from a source that batches them (`batchesOptions`). */
|
|
482
489
|
async loadOptions(
|
|
483
490
|
request: OptionsRequest,
|
|
484
|
-
options: { forceRefresh?: boolean } = {},
|
|
491
|
+
options: { forceRefresh?: boolean; batch?: boolean } = {},
|
|
485
492
|
): Promise<QueryEntry<OptionsChain>> {
|
|
486
493
|
const key = buildOptionsKey(request);
|
|
487
494
|
const loadingKey = options.forceRefresh ? `${key}|refresh` : key;
|
|
@@ -511,9 +518,11 @@ export class MarketDataCoordinator {
|
|
|
511
518
|
}
|
|
512
519
|
}
|
|
513
520
|
}
|
|
514
|
-
|
|
521
|
+
const context = { ...toMarketDataContext(request.instrument), ...(options.batch ? { batch: true } : {}) };
|
|
522
|
+
return this.loadCachedQuery("getOptionsChain", [request.instrument.symbol, request.instrument.exchange, request.expirationDate, context], key, this.optionsStore, options.forceRefresh, (value) => value.expirationDates.length === 0) ?? loadOptionsEntry({
|
|
515
523
|
dataProvider: this.dataProvider,
|
|
516
524
|
forceRefresh: options.forceRefresh,
|
|
525
|
+
batch: options.batch,
|
|
517
526
|
request,
|
|
518
527
|
store: this.optionsStore,
|
|
519
528
|
runSingleFlight: (flightKey, task) => this.runSingleFlight(flightKey, task),
|
|
@@ -104,7 +104,7 @@ export const FUTURES_CONTRACTS: FuturesContract[] = [
|
|
|
104
104
|
|
|
105
105
|
{ symbol: "CL=F", code: "CL", name: "WTI Crude Oil", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.01, aliases: ["oil"] },
|
|
106
106
|
{ symbol: "BZ=F", code: "BZ", name: "Brent Crude Oil", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.01 },
|
|
107
|
-
{ symbol: "NG=F", code: "NG", name: "Natural Gas", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.001 },
|
|
107
|
+
{ symbol: "NG=F", code: "NG", name: "Natural Gas", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.001, aliases: ["natgas", "nat gas"] },
|
|
108
108
|
// Quoted in euros per MWh.
|
|
109
109
|
{ symbol: "TTF=F", code: "TTF", name: "Dutch TTF Gas", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.001, unit: "EUR / MWh", bareCode: true },
|
|
110
110
|
{ symbol: "RB=F", code: "RB", name: "RBOB Gasoline", sector: "energy", venue: "NYM", everyMonth: true, tick: 0.0001 },
|
|
@@ -391,9 +391,11 @@ export function validateFuturesContractTerms(data: FuturesContractTermsPayload):
|
|
|
391
391
|
export async function loadFuturesContractTerms(
|
|
392
392
|
symbol: string,
|
|
393
393
|
client: Pick<typeof apiClient, "getCloudFuturesContract"> = apiClient,
|
|
394
|
+
/** `batch`: one of many asked at once (a futures board's rows), to go out in a batch request with them. */
|
|
395
|
+
options: { batch?: boolean } = {},
|
|
394
396
|
): Promise<FuturesContractTermsPayload> {
|
|
395
397
|
// The terms are the contract's wherever it is listed: GC=F:CMX asks for GC=F.
|
|
396
|
-
return validateFuturesContractTerms(await client.getCloudFuturesContract(parsePublicTickerKey(symbol).symbol));
|
|
398
|
+
return validateFuturesContractTerms(await client.getCloudFuturesContract(parsePublicTickerKey(symbol).symbol, options));
|
|
397
399
|
}
|
|
398
400
|
|
|
399
401
|
/**
|