Browse Source

Merge branch 'main' into fix/currency-effect-percentage-reopened-position

pull/7283/head
JJ Teoh 1 day ago
committed by GitHub
parent
commit
cb79933ee1
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 46
      CHANGELOG.md
  2. 43
      README.md
  3. 26
      apps/api/project.json
  4. 53
      apps/api/src/app/app.module.ts
  5. 5
      apps/api/src/app/auth/auth.controller.ts
  6. 6
      apps/api/src/app/endpoints/market-data/market-data.controller.ts
  7. 8
      apps/api/src/app/endpoints/market-data/market-data.module.ts
  8. 13
      apps/api/src/app/info/info.service.ts
  9. 18
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  10. 30
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts
  11. 8
      apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts
  12. 11
      apps/api/src/app/redis-cache/redis-cache.module.ts
  13. 15
      apps/api/src/app/user/user.controller.ts
  14. 21
      apps/api/src/guards/custom-throttler.guard.ts
  15. 22
      apps/api/src/helper/redis.helper.ts
  16. 20
      apps/api/src/main.ts
  17. 29
      apps/api/src/services/configuration/configuration.service.ts
  18. 6
      apps/api/src/services/data-provider/data-provider.service.ts
  19. 32
      apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts
  20. 3
      apps/api/src/services/interfaces/environment.interface.ts
  21. 8
      apps/api/src/services/twitter-bot/twitter-bot.module.ts
  22. 10
      apps/api/src/services/twitter-bot/twitter-bot.service.ts
  23. 51
      apps/api/webpack.config.js
  24. 3
      apps/client/src/app/app.routes.ts
  25. 2
      apps/client/src/app/components/admin-settings/admin-settings.component.html
  26. 2
      apps/client/src/app/components/fear-and-greed-index/fear-and-greed-index.component.html
  27. 3
      apps/client/src/app/components/fear-and-greed-index/fear-and-greed-index.component.ts
  28. 15
      apps/client/src/app/components/header/header.component.ts
  29. 51
      apps/client/src/app/components/home-holdings/home-holdings.component.ts
  30. 2
      apps/client/src/app/components/home-market/home-market.component.ts
  31. 32
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts
  32. 54
      apps/client/src/app/components/user-account-membership/user-account-membership.component.ts
  33. 81
      apps/client/src/app/components/user-account-settings/user-account-settings.component.ts
  34. 48
      apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts
  35. 22
      apps/client/src/app/core/http-response.interceptor.ts
  36. 12
      apps/client/src/app/pages/about/about-page.component.ts
  37. 11
      apps/client/src/app/pages/admin/admin-page.component.ts
  38. 3
      apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts
  39. 3
      apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts
  40. 3
      apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts
  41. 3
      apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts
  42. 3
      apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts
  43. 3
      apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts
  44. 3
      apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts
  45. 3
      apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts
  46. 3
      apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts
  47. 3
      apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts
  48. 3
      apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts
  49. 3
      apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts
  50. 3
      apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts
  51. 3
      apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts
  52. 3
      apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts
  53. 3
      apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts
  54. 3
      apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts
  55. 3
      apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts
  56. 3
      apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts
  57. 3
      apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts
  58. 3
      apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts
  59. 3
      apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts
  60. 3
      apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.component.ts
  61. 3
      apps/client/src/app/pages/blog/2026/04/ghostfolio-3/ghostfolio-3-page.component.ts
  62. 7
      apps/client/src/app/pages/blog/blog-page.component.ts
  63. 3
      apps/client/src/app/pages/faq/faq-page.component.ts
  64. 6
      apps/client/src/app/pages/home/home-page.component.ts
  65. 88
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
  66. 2
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts
  67. 40
      apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts
  68. 3
      apps/client/src/app/pages/resources/resources-page.component.ts
  69. 12
      apps/client/src/app/pages/user-account/user-account-page.component.ts
  70. 3
      apps/client/src/app/pages/webauthn/webauthn-page.component.ts
  71. 6
      apps/client/src/app/pages/webauthn/webauthn-page.html
  72. 12
      apps/client/src/app/pages/zen/zen-page.component.ts
  73. 78
      apps/client/src/locales/messages.ca.xlf
  74. 76
      apps/client/src/locales/messages.de.xlf
  75. 76
      apps/client/src/locales/messages.es.xlf
  76. 76
      apps/client/src/locales/messages.fr.xlf
  77. 76
      apps/client/src/locales/messages.it.xlf
  78. 76
      apps/client/src/locales/messages.ja.xlf
  79. 170
      apps/client/src/locales/messages.ko.xlf
  80. 102
      apps/client/src/locales/messages.nl.xlf
  81. 76
      apps/client/src/locales/messages.pl.xlf
  82. 76
      apps/client/src/locales/messages.pt.xlf
  83. 80
      apps/client/src/locales/messages.tr.xlf
  84. 76
      apps/client/src/locales/messages.uk.xlf
  85. 74
      apps/client/src/locales/messages.xlf
  86. 88
      apps/client/src/locales/messages.zh.xlf
  87. 8
      apps/client/src/styles.scss
  88. 6
      libs/common/src/lib/config.ts
  89. 9
      libs/common/src/lib/personal-finance-tools.ts
  90. 2
      libs/common/src/lib/routes/interfaces/internal-route.interface.ts
  91. 3
      libs/common/src/lib/routes/routes.ts
  92. 5
      libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html
  93. 16
      libs/ui/src/lib/page-tabs/page-tabs.component.html
  94. 5
      libs/ui/src/lib/page-tabs/page-tabs.component.scss
  95. 5
      libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.html
  96. 10
      nx.json
  97. 174
      package-lock.json
  98. 9
      package.json

46
CHANGELOG.md

@ -5,11 +5,53 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## 3.25.0 - 2026-07-12
### Changed
- Changed the default value of the `DATA_SOURCE_FEAR_AND_GREED_INDEX_STOCKS` environment variable from `RAPID_API` to `MANUAL`
- Improved the language localization for Dutch (`nl`)
- Upgraded `helmet` from version `7.0.0` to `8.2.0`
### Fixed
- Fixed the misleading `netPerformancePercentWithCurrencyEffect` for reopened multi-trade positions by calculating it against the net invested capital
- Fixed the layout of the page tabs component by truncating long labels
- Fixed the display of assets without a currency in the search results of the assistant
- Fixed the display of assets without a currency in the symbol autocomplete component
### Todo
- **Breaking Change**: Set the environment variable `DATA_SOURCE_FEAR_AND_GREED_INDEX_STOCKS=RAPID_API` to keep using _Rapid API_ as the data source of the _Fear & Greed Index_ (market mood)
## 3.24.0 - 2026-07-11
### Added
- Exposed the `DATA_SOURCE_FEAR_AND_GREED_INDEX_STOCKS` environment variable to set the data source of the _Fear & Greed Index_ (market mood)
- Exposed the `ENABLE_FEATURE_RATE_LIMITING` environment variable to control rate limiting for authentication and sign-up endpoints
- Exposed the `TRUST_PROXY` environment variable to determine the client IP address when running behind a reverse proxy
### Changed
- Rounded the value of the _Fear & Greed Index_ (market mood)
- Improved the language localization for Korean (`ko`)
## 3.23.0 - 2026-07-10
### Changed
- Migrated the deprecated `@nx/webpack:webpack` executor to `@nx/webpack/plugin`
- Set the change detection strategy to `OnPush` in the about page
- Set the change detection strategy to `OnPush` in the admin control panel
- Set the change detection strategy to `OnPush` in the blog page components
- Set the change detection strategy to `OnPush` in the Frequently Asked Questions (FAQ) page
- Set the change detection strategy to `OnPush` in the home page
- Set the change detection strategy to `OnPush` in the markets overview
- Set the change detection strategy to `OnPush` in the resources page
- Set the change detection strategy to `OnPush` in the user account page
- Set the change detection strategy to `OnPush` in the _Zen Mode_
- Improved the language localization for Chinese (`zh`)
- Improved the language localization for German (`de`)
## 3.22.0 - 2026-07-08

43
README.md

@ -85,27 +85,28 @@ We provide official container images hosted on [Docker Hub](https://hub.docker.c
### Supported Environment Variables
| Name | Type | Default Value | Description |
| --------------------------- | --------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ACCESS_TOKEN_SALT` | `string` | | A random string used as salt for access tokens |
| `API_KEY_COINGECKO_DEMO` | `string` (optional) |   | The _CoinGecko_ Demo API key |
| `API_KEY_COINGECKO_PRO` | `string` (optional) | | The _CoinGecko_ Pro API key |
| `DATABASE_URL` | `string` | | The database connection URL. If using a connection pooler, use the pooled connection URL here. e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}` |
| `DIRECT_URL` | `string` (optional) | | The direct database connection URL used by the _Prisma CLI_ (e.g. for schema migrations) and seeding, bypassing any connection poolers (falls back to `DATABASE_URL`) |
| `ENABLE_FEATURE_AUTH_TOKEN` | `boolean` (optional) | `true` | Enables authentication via security token |
| `HOST` | `string` (optional) | `0.0.0.0` | The host where the Ghostfolio application will run on |
| `JWT_SECRET_KEY` | `string` | | A random string used for _JSON Web Tokens_ (JWT) |
| `LOG_LEVELS` | `string[]` (optional) | | The logging levels for the Ghostfolio application, e.g. `["debug","error","log","warn"]` |
| `PORT` | `number` (optional) | `3333` | The port where the Ghostfolio application will run on |
| `POSTGRES_DB` | `string` | | The name of the _PostgreSQL_ database |
| `POSTGRES_PASSWORD` | `string` | | The password of the _PostgreSQL_ database |
| `POSTGRES_USER` | `string` | | The user of the _PostgreSQL_ database |
| `REDIS_DB` | `number` (optional) | `0` | The database index of _Redis_ |
| `REDIS_HOST` | `string` | | The host where _Redis_ is running |
| `REDIS_PASSWORD` | `string` | | The password of _Redis_ |
| `REDIS_PORT` | `number` | | The port where _Redis_ is running |
| `REQUEST_TIMEOUT` | `number` (optional) | `2000` | The timeout of network requests to data providers in milliseconds |
| `ROOT_URL` | `string` (optional) | `http://0.0.0.0:3333` | The root URL of the Ghostfolio application, used for generating callback URLs and external links. |
| Name | Type | Default Value | Description |
| --------------------------- | --------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ACCESS_TOKEN_SALT` | `string` | | A random string used as salt for access tokens |
| `API_KEY_COINGECKO_DEMO` | `string` (optional) |   | The _CoinGecko_ Demo API key |
| `API_KEY_COINGECKO_PRO` | `string` (optional) | | The _CoinGecko_ Pro API key |
| `DATABASE_URL` | `string` | | The database connection URL. If using a connection pooler, use the pooled connection URL here. e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}` |
| `DIRECT_URL` | `string` (optional) | | The direct database connection URL used by the _Prisma CLI_ (e.g. for schema migrations) and seeding, bypassing any connection poolers (falls back to `DATABASE_URL`) |
| `ENABLE_FEATURE_AUTH_TOKEN` | `boolean` (optional) | `true` | Enables authentication via security token |
| `HOST` | `string` (optional) | `0.0.0.0` | The host where the Ghostfolio application will run on |
| `JWT_SECRET_KEY` | `string` | | A random string used for _JSON Web Tokens_ (JWT) |
| `LOG_LEVELS` | `string[]` (optional) | | The logging levels for the Ghostfolio application, e.g. `["debug","error","log","warn"]` |
| `PORT` | `number` (optional) | `3333` | The port where the Ghostfolio application will run on |
| `POSTGRES_DB` | `string` | | The name of the _PostgreSQL_ database |
| `POSTGRES_PASSWORD` | `string` | | The password of the _PostgreSQL_ database |
| `POSTGRES_USER` | `string` | | The user of the _PostgreSQL_ database |
| `REDIS_DB` | `number` (optional) | `0` | The database index of _Redis_ |
| `REDIS_HOST` | `string` | | The host where _Redis_ is running |
| `REDIS_PASSWORD` | `string` | | The password of _Redis_ |
| `REDIS_PORT` | `number` | | The port where _Redis_ is running |
| `REQUEST_TIMEOUT` | `number` (optional) | `2000` | The timeout of network requests to data providers in milliseconds |
| `ROOT_URL` | `string` (optional) | `http://0.0.0.0:3333` | The root URL of the Ghostfolio application, used for generating callback URLs and external links. |
| `TRUST_PROXY` | `string` (optional) | | The [trust proxy](https://expressjs.com/en/guide/behind-proxies.html) setting of _Express.js_ to determine the client IP address for rate limiting, e.g. `1` if the Ghostfolio application runs behind a single reverse proxy |
#### OpenID Connect OIDC (experimental)

26
apps/api/project.json

@ -7,32 +7,10 @@
"generators": {},
"targets": {
"build": {
"executor": "@nx/webpack:webpack",
"options": {
"compiler": "tsc",
"deleteOutputPath": false,
"main": "apps/api/src/main.ts",
"outputPath": "dist/apps/api",
"sourceMap": true,
"target": "node",
"tsConfig": "apps/api/tsconfig.app.json",
"webpackConfig": "apps/api/webpack.config.js"
},
"configurations": {
"production": {
"generatePackageJson": true,
"optimization": true,
"extractLicenses": true,
"inspect": false,
"fileReplacements": [
{
"replace": "apps/api/src/environments/environment.ts",
"with": "apps/api/src/environments/environment.prod.ts"
}
]
}
"production": {}
},
"outputs": ["{options.outputPath}"]
"outputs": ["{workspaceRoot}/dist/apps/api"]
},
"copy-assets": {
"executor": "nx:run-commands",

53
apps/api/src/app/app.module.ts

@ -1,7 +1,9 @@
import { EventsModule } from '@ghostfolio/api/events/events.module';
import { getRedisConnectionOptions } from '@ghostfolio/api/helper/redis.helper';
import { BullBoardAuthMiddleware } from '@ghostfolio/api/middlewares/bull-board-auth.middleware';
import { HtmlTemplateMiddleware } from '@ghostfolio/api/middlewares/html-template.middleware';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { CronModule } from '@ghostfolio/api/services/cron/cron.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
@ -13,18 +15,22 @@ import { PortfolioSnapshotQueueModule } from '@ghostfolio/api/services/queues/po
import {
BULL_BOARD_ROUTE,
DEFAULT_LANGUAGE_CODE,
SUPPORTED_LANGUAGE_CODES
SUPPORTED_LANGUAGE_CODES,
THROTTLE_DEFAULT_LIMIT,
THROTTLE_DEFAULT_TTL
} from '@ghostfolio/common/config';
import { ExpressAdapter } from '@bull-board/express';
import { BullBoardModule } from '@bull-board/nestjs';
import { ThrottlerStorageRedisService } from '@nest-lab/throttler-storage-redis';
import { BullModule } from '@nestjs/bull';
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { ScheduleModule } from '@nestjs/schedule';
import { ServeStaticModule } from '@nestjs/serve-static';
import { StatusCodes } from 'http-status-codes';
import { ThrottlerModule } from '@nestjs/throttler';
import { getReasonPhrase, StatusCodes } from 'http-status-codes';
import { join } from 'node:path';
import { AccessModule } from './access/access.module';
@ -95,12 +101,13 @@ import { UserModule } from './user/user.module';
middleware: BullBoardAuthMiddleware,
route: BULL_BOARD_ROUTE
}),
BullModule.forRoot({
redis: {
db: parseInt(process.env.REDIS_DB ?? '0', 10),
host: process.env.REDIS_HOST,
password: process.env.REDIS_PASSWORD,
port: parseInt(process.env.REDIS_PORT ?? '6379', 10)
BullModule.forRootAsync({
imports: [ConfigurationModule],
inject: [ConfigurationService],
useFactory: (configurationService: ConfigurationService) => {
return {
redis: getRedisConnectionOptions(configurationService)
};
}
}),
CacheModule,
@ -168,6 +175,36 @@ import { UserModule } from './user/user.module';
SubscriptionModule,
SymbolModule,
TagsModule,
ThrottlerModule.forRootAsync({
imports: [ConfigurationModule],
inject: [ConfigurationService],
useFactory: (configurationService: ConfigurationService) => {
const isRateLimitingEnabled = configurationService.get(
'ENABLE_FEATURE_RATE_LIMITING'
);
return {
errorMessage: getReasonPhrase(StatusCodes.TOO_MANY_REQUESTS),
skipIf: () => {
return !isRateLimitingEnabled;
},
storage: isRateLimitingEnabled
? new ThrottlerStorageRedisService({
...getRedisConnectionOptions(configurationService),
// Reject commands immediately while Redis is unavailable
enableOfflineQueue: false,
maxRetriesPerRequest: 1
})
: undefined,
throttlers: [
{
limit: THROTTLE_DEFAULT_LIMIT,
ttl: THROTTLE_DEFAULT_TTL
}
]
};
}
}),
UserModule,
WatchlistModule
],

5
apps/api/src/app/auth/auth.controller.ts

@ -1,4 +1,5 @@
import { WebAuthService } from '@ghostfolio/api/app/auth/web-auth.service';
import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config';
@ -39,6 +40,7 @@ export class AuthController {
* @deprecated
*/
@Get('anonymous/:accessToken')
@UseGuards(CustomThrottlerGuard)
public async accessTokenLoginGet(
@Param('accessToken') accessToken: string
): Promise<OAuthResponse> {
@ -55,6 +57,7 @@ export class AuthController {
}
@Post('anonymous')
@UseGuards(CustomThrottlerGuard)
public async accessTokenLogin(
@Body() body: { accessToken: string }
): Promise<OAuthResponse> {
@ -135,6 +138,7 @@ export class AuthController {
}
@Post('webauthn/generate-authentication-options')
@UseGuards(CustomThrottlerGuard)
public async generateAuthenticationOptions(
@Body() body: { deviceId: string }
) {
@ -156,6 +160,7 @@ export class AuthController {
}
@Post('webauthn/verify-authentication')
@UseGuards(CustomThrottlerGuard)
public async verifyAuthentication(
@Body() body: { deviceId: string; credential: AssertionCredentialJSON }
) {

6
apps/api/src/app/endpoints/market-data/market-data.controller.ts

@ -1,11 +1,11 @@
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service';
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import {
ghostfolioFearAndGreedIndexDataSourceCryptocurrencies,
ghostfolioFearAndGreedIndexDataSourceStocks,
ghostfolioFearAndGreedIndexSymbolCryptocurrencies,
ghostfolioFearAndGreedIndexSymbolStocks
} from '@ghostfolio/common/config';
@ -36,6 +36,7 @@ import { getReasonPhrase, StatusCodes } from 'http-status-codes';
@Controller('market-data')
export class MarketDataController {
public constructor(
private readonly dataProviderService: DataProviderService,
private readonly marketDataService: MarketDataService,
@Inject(REQUEST) private readonly request: RequestWithUser,
private readonly symbolProfileService: SymbolProfileService,
@ -64,7 +65,8 @@ export class MarketDataController {
this.symbolService.get({
includeHistoricalData,
dataGatheringItem: {
dataSource: ghostfolioFearAndGreedIndexDataSourceStocks,
dataSource:
this.dataProviderService.getDataSourceForFearAndGreedIndexStocks(),
symbol: ghostfolioFearAndGreedIndexSymbolStocks
},
useIntradayData: true

8
apps/api/src/app/endpoints/market-data/market-data.module.ts

@ -1,4 +1,5 @@
import { SymbolModule } from '@ghostfolio/api/app/symbol/symbol.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { MarketDataModule as MarketDataServiceModule } from '@ghostfolio/api/services/market-data/market-data.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module';
@ -8,6 +9,11 @@ import { MarketDataController } from './market-data.controller';
@Module({
controllers: [MarketDataController],
imports: [MarketDataServiceModule, SymbolModule, SymbolProfileModule]
imports: [
DataProviderModule,
MarketDataServiceModule,
SymbolModule,
SymbolProfileModule
]
})
export class MarketDataModule {}

13
apps/api/src/app/info/info.service.ts

@ -4,6 +4,7 @@ import { UserService } from '@ghostfolio/api/app/user/user.service';
import { encodeDataSource } from '@ghostfolio/api/helper/data-source.helper';
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import {
@ -15,8 +16,7 @@ import {
PROPERTY_GITHUB_STARGAZERS,
PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_SLACK_COMMUNITY_USERS,
PROPERTY_UPTIME,
ghostfolioFearAndGreedIndexDataSourceStocks
PROPERTY_UPTIME
} from '@ghostfolio/common/config';
import { InfoItem, Statistics } from '@ghostfolio/common/interfaces';
import { permissions } from '@ghostfolio/common/permissions';
@ -33,6 +33,7 @@ export class InfoService {
public constructor(
private readonly benchmarkService: BenchmarkService,
private readonly configurationService: ConfigurationService,
private readonly dataProviderService: DataProviderService,
private readonly exchangeRateDataService: ExchangeRateDataService,
private readonly jwtService: JwtService,
private readonly propertyService: PropertyService,
@ -60,13 +61,15 @@ export class InfoService {
}
if (this.configurationService.get('ENABLE_FEATURE_FEAR_AND_GREED_INDEX')) {
const fearAndGreedIndexDataSource =
this.dataProviderService.getDataSourceForFearAndGreedIndexStocks();
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
info.fearAndGreedDataSource = encodeDataSource(
ghostfolioFearAndGreedIndexDataSourceStocks
fearAndGreedIndexDataSource
);
} else {
info.fearAndGreedDataSource =
ghostfolioFearAndGreedIndexDataSourceStocks;
info.fearAndGreedDataSource = fearAndGreedIndexDataSource;
}
globalPermissions.push(permissions.enableFearAndGreedIndex);

18
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -141,9 +141,9 @@ export abstract class PortfolioCalculator {
}
return {
SymbolProfile,
tags,
type,
assetProfile: SymbolProfile,
date: format(date, DATE_FORMAT),
fee: new Big(feeInAssetProfileCurrency),
feeInBaseCurrency: new Big(feeInBaseCurrency),
@ -934,23 +934,23 @@ export abstract class PortfolioCalculator {
let lastTransactionPoint: TransactionPoint = null;
for (const {
assetProfile,
date,
fee,
feeInBaseCurrency,
quantity,
SymbolProfile,
tags,
type,
unitPrice
} of this.activities) {
let currentTransactionPointItem: TransactionPointSymbol;
const assetSubClass = SymbolProfile.assetSubClass;
const currency = SymbolProfile.currency;
const dataSource = SymbolProfile.dataSource;
const assetSubClass = assetProfile.assetSubClass;
const currency = assetProfile.currency;
const dataSource = assetProfile.dataSource;
const factor = getFactor(type);
const skipErrors = !!SymbolProfile.userId; // Skip errors for custom asset profiles
const symbol = SymbolProfile.symbol;
const skipErrors = !!assetProfile.userId; // Skip errors for custom asset profiles
const symbol = assetProfile.symbol;
const oldAccumulatedSymbol = symbols[symbol];
@ -1034,12 +1034,12 @@ export abstract class PortfolioCalculator {
'id'
);
symbols[SymbolProfile.symbol] = currentTransactionPointItem;
symbols[symbol] = currentTransactionPointItem;
const items = lastTransactionPoint?.items ?? [];
const newItems = items.filter(({ symbol }) => {
return symbol !== SymbolProfile.symbol;
return symbol !== assetProfile.symbol;
});
newItems.push(currentTransactionPointItem);

30
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts

@ -193,12 +193,12 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
// Clone orders to keep the original values in this.orders
let orders: PortfolioOrderItem[] = cloneDeep(
this.activities.filter(({ SymbolProfile }) => {
return SymbolProfile.symbol === symbol;
this.activities.filter(({ assetProfile }) => {
return assetProfile.symbol === symbol;
})
);
const isCash = orders[0]?.SymbolProfile?.assetSubClass === 'CASH';
const isCash = orders[0]?.assetProfile?.assetSubClass === 'CASH';
if (orders.length <= 0) {
return {
@ -300,32 +300,30 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
};
}
const assetProfile: PortfolioOrderItem['assetProfile'] = {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
};
// Add a synthetic order at the start and the end date
orders.push({
assetProfile,
date: startDateString,
fee: new Big(0),
feeInBaseCurrency: new Big(0),
itemType: 'start',
quantity: new Big(0),
SymbolProfile: {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
},
type: 'BUY',
unitPrice: unitPriceAtStartDate
});
orders.push({
assetProfile,
date: endDateString,
fee: new Big(0),
feeInBaseCurrency: new Big(0),
itemType: 'end',
SymbolProfile: {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
},
quantity: new Big(0),
type: 'BUY',
unitPrice: unitPriceAtEndDate
@ -358,15 +356,11 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
}
} else {
orders.push({
assetProfile,
date: dateString,
fee: new Big(0),
feeInBaseCurrency: new Big(0),
quantity: new Big(0),
SymbolProfile: {
dataSource,
symbol,
assetSubClass: isCash ? 'CASH' : undefined
},
type: 'BUY',
unitPrice: marketSymbolMap[dateString]?.[symbol] ?? lastUnitPrice,
unitPriceFromMarketData:

8
apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts

@ -1,13 +1,13 @@
import { Activity } from '@ghostfolio/common/interfaces';
export interface PortfolioOrder extends Pick<Activity, 'tags' | 'type'> {
assetProfile: Pick<
Activity['SymbolProfile'],
'assetSubClass' | 'currency' | 'dataSource' | 'name' | 'symbol' | 'userId'
>;
date: string;
fee: Big;
feeInBaseCurrency: Big;
quantity: Big;
SymbolProfile: Pick<
Activity['SymbolProfile'],
'assetSubClass' | 'currency' | 'dataSource' | 'name' | 'symbol' | 'userId'
>;
unitPrice: Big;
}

11
apps/api/src/app/redis-cache/redis-cache.module.ts

@ -1,3 +1,4 @@
import { getRedisConnectionUrl } from '@ghostfolio/api/helper/redis.helper';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
@ -14,16 +15,8 @@ import { RedisCacheService } from './redis-cache.service';
imports: [ConfigurationModule],
inject: [ConfigurationService],
useFactory: async (configurationService: ConfigurationService) => {
const redisPassword = encodeURIComponent(
configurationService.get('REDIS_PASSWORD')
);
return {
stores: [
createKeyv(
`redis://${redisPassword ? `:${redisPassword}` : ''}@${configurationService.get('REDIS_HOST')}:${configurationService.get('REDIS_PORT')}/${configurationService.get('REDIS_DB')}`
)
],
stores: [createKeyv(getRedisConnectionUrl(configurationService))],
ttl: configurationService.get('CACHE_TTL')
};
}

15
apps/api/src/app/user/user.controller.ts

@ -1,11 +1,16 @@
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator';
import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { RedactValuesInResponseInterceptor } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.interceptor';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { HEADER_KEY_IMPERSONATION } from '@ghostfolio/common/config';
import {
HEADER_KEY_IMPERSONATION,
THROTTLE_SIGNUP_LIMIT,
THROTTLE_SIGNUP_TTL
} from '@ghostfolio/common/config';
import {
DeleteOwnUserDto,
UpdateOwnAccessTokenDto,
@ -37,6 +42,7 @@ import {
import { REQUEST } from '@nestjs/core';
import { JwtService } from '@nestjs/jwt';
import { AuthGuard } from '@nestjs/passport';
import { Throttle } from '@nestjs/throttler';
import { User as UserModel } from '@prisma/client';
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { merge, size } from 'lodash';
@ -128,6 +134,13 @@ export class UserController {
}
@Post()
@Throttle({
default: {
limit: THROTTLE_SIGNUP_LIMIT,
ttl: THROTTLE_SIGNUP_TTL
}
})
@UseGuards(CustomThrottlerGuard)
public async signupUser(): Promise<UserItem> {
const isUserSignupEnabled =
await this.propertyService.isUserSignupEnabled();

21
apps/api/src/guards/custom-throttler.guard.ts

@ -0,0 +1,21 @@
import { ExecutionContext, Injectable, Logger } from '@nestjs/common';
import { ThrottlerException, ThrottlerGuard } from '@nestjs/throttler';
@Injectable()
export class CustomThrottlerGuard extends ThrottlerGuard {
private readonly logger = new Logger(CustomThrottlerGuard.name);
public async canActivate(context: ExecutionContext): Promise<boolean> {
try {
return await super.canActivate(context);
} catch (error) {
if (error instanceof ThrottlerException) {
throw error;
}
this.logger.error(error);
return true;
}
}
}

22
apps/api/src/helper/redis.helper.ts

@ -0,0 +1,22 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
export function getRedisConnectionOptions(
configurationService: ConfigurationService
) {
return {
db: configurationService.get('REDIS_DB'),
host: configurationService.get('REDIS_HOST'),
password: configurationService.get('REDIS_PASSWORD'),
port: configurationService.get('REDIS_PORT')
};
}
export function getRedisConnectionUrl(
configurationService: ConfigurationService
): string {
const { db, host, password, port } =
getRedisConnectionOptions(configurationService);
const encodedPassword = encodeURIComponent(password);
return `redis://${encodedPassword ? `:${encodedPassword}` : ''}@${host}:${port}/${db}`;
}

20
apps/api/src/main.ts

@ -1,3 +1,4 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import {
BULL_BOARD_ROUTE,
DEFAULT_HOST,
@ -39,6 +40,8 @@ async function bootstrap() {
) as LogLevel[];
} catch {}
await configApp.close();
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
logger:
customLogLevels ??
@ -97,6 +100,23 @@ async function bootstrap() {
});
}
const configurationService = app.get(ConfigurationService);
const trustProxy = configurationService.get('TRUST_PROXY');
if (trustProxy) {
app.set('trust proxy', trustProxy);
}
if (
configurationService.get('ENABLE_FEATURE_RATE_LIMITING') &&
trustProxy === ''
) {
logger.warn(
'Rate limiting is enabled, but TRUST_PROXY is not set. If the Ghostfolio application runs behind a reverse proxy, the rate limits are shared across all clients.'
);
}
const HOST = configService.get<string>('HOST') || DEFAULT_HOST;
const PORT = configService.get<number>('PORT') || DEFAULT_PORT;

29
apps/api/src/services/configuration/configuration.service.ts

@ -13,9 +13,31 @@ import {
import { Injectable } from '@nestjs/common';
import { DataSource } from '@prisma/client';
import { bool, cleanEnv, host, json, num, port, str, url } from 'envalid';
import {
bool,
cleanEnv,
host,
json,
makeValidator,
num,
port,
str,
url
} from 'envalid';
import ms from 'ms';
const trustProxy = makeValidator<boolean | number | string>((input) => {
if (/^\d+$/.test(input)) {
return Number(input);
} else if (input === 'false') {
return false;
} else if (input === 'true') {
return true;
}
return input;
});
@Injectable()
export class ConfigurationService {
private readonly environmentConfiguration: Environment;
@ -34,6 +56,9 @@ export class ConfigurationService {
CACHE_QUOTES_TTL: num({ default: ms('1 minute') }),
CACHE_TTL: num({ default: CACHE_TTL_NO_CACHE }),
DATA_SOURCE_EXCHANGE_RATES: str({ default: DataSource.YAHOO }),
DATA_SOURCE_FEAR_AND_GREED_INDEX_STOCKS: str({
default: DataSource.MANUAL
}),
DATA_SOURCE_IMPORT: str({ default: DataSource.YAHOO }),
DATA_SOURCES: json({
default: [DataSource.COINGECKO, DataSource.MANUAL, DataSource.YAHOO]
@ -47,6 +72,7 @@ export class ConfigurationService {
ENABLE_FEATURE_CRON: bool({ default: true }),
ENABLE_FEATURE_FEAR_AND_GREED_INDEX: bool({ default: false }),
ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: bool({ default: true }),
ENABLE_FEATURE_RATE_LIMITING: bool({ default: false }),
ENABLE_FEATURE_READ_ONLY_MODE: bool({ default: false }),
ENABLE_FEATURE_STATISTICS: bool({ default: false }),
ENABLE_FEATURE_SUBSCRIPTION: bool({ default: false }),
@ -111,6 +137,7 @@ export class ConfigurationService {
default: environment.rootUrl
}),
STRIPE_SECRET_KEY: str({ default: '' }),
TRUST_PROXY: trustProxy({ default: '' }),
TWITTER_ACCESS_TOKEN: str({ default: 'dummyAccessToken' }),
TWITTER_ACCESS_TOKEN_SECRET: str({ default: 'dummyAccessTokenSecret' }),
TWITTER_API_KEY: str({ default: 'dummyApiKey' }),

6
apps/api/src/services/data-provider/data-provider.service.ts

@ -177,6 +177,12 @@ export class DataProviderService implements OnModuleInit {
];
}
public getDataSourceForFearAndGreedIndexStocks(): DataSource {
return DataSource[
this.configurationService.get('DATA_SOURCE_FEAR_AND_GREED_INDEX_STOCKS')
];
}
public getDataSourceForImport(): DataSource {
return DataSource[this.configurationService.get('DATA_SOURCE_IMPORT')];
}

32
apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts

@ -64,13 +64,15 @@ export class RapidApiService implements DataProviderInterface {
if (symbol === ghostfolioFearAndGreedIndexSymbolStocks) {
const fgi = await this.getFearAndGreedIndex();
return {
[symbol]: {
[format(getYesterday(), DATE_FORMAT)]: {
marketPrice: fgi.previousClose.value
if (fgi) {
return {
[symbol]: {
[format(getYesterday(), DATE_FORMAT)]: {
marketPrice: fgi.previousClose.value
}
}
}
};
};
}
}
} catch (error) {
throw new Error(
@ -101,14 +103,16 @@ export class RapidApiService implements DataProviderInterface {
if (symbol === ghostfolioFearAndGreedIndexSymbolStocks) {
const fgi = await this.getFearAndGreedIndex();
return {
[symbol]: {
currency: undefined,
dataSource: this.getName(),
marketPrice: fgi.now.value,
marketState: 'open'
}
};
if (fgi) {
return {
[symbol]: {
currency: undefined,
dataSource: this.getName(),
marketPrice: fgi.now.value,
marketState: 'open'
}
};
}
}
} catch (error) {
this.logger.error(error);

3
apps/api/src/services/interfaces/environment.interface.ts

@ -13,6 +13,7 @@ export interface Environment extends CleanedEnvAccessors {
CACHE_QUOTES_TTL: number;
CACHE_TTL: number;
DATA_SOURCE_EXCHANGE_RATES: string;
DATA_SOURCE_FEAR_AND_GREED_INDEX_STOCKS: string;
DATA_SOURCE_IMPORT: string;
DATA_SOURCES: string[];
DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER: string[];
@ -22,6 +23,7 @@ export interface Environment extends CleanedEnvAccessors {
ENABLE_FEATURE_CRON: boolean;
ENABLE_FEATURE_FEAR_AND_GREED_INDEX: boolean;
ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: boolean;
ENABLE_FEATURE_RATE_LIMITING: boolean;
ENABLE_FEATURE_READ_ONLY_MODE: boolean;
ENABLE_FEATURE_STATISTICS: boolean;
ENABLE_FEATURE_SUBSCRIPTION: boolean;
@ -56,6 +58,7 @@ export interface Environment extends CleanedEnvAccessors {
REQUEST_TIMEOUT: number;
ROOT_URL: string;
STRIPE_SECRET_KEY: string;
TRUST_PROXY: boolean | number | string;
TWITTER_ACCESS_TOKEN: string;
TWITTER_ACCESS_TOKEN_SECRET: string;
TWITTER_API_KEY: string;

8
apps/api/src/services/twitter-bot/twitter-bot.module.ts

@ -1,13 +1,19 @@
import { SymbolModule } from '@ghostfolio/api/app/symbol/symbol.module';
import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { TwitterBotService } from '@ghostfolio/api/services/twitter-bot/twitter-bot.service';
import { Module } from '@nestjs/common';
@Module({
exports: [TwitterBotService],
imports: [BenchmarkModule, ConfigurationModule, SymbolModule],
imports: [
BenchmarkModule,
ConfigurationModule,
DataProviderModule,
SymbolModule
],
providers: [TwitterBotService]
})
export class TwitterBotModule {}

10
apps/api/src/services/twitter-bot/twitter-bot.service.ts

@ -1,10 +1,8 @@
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service';
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import {
ghostfolioFearAndGreedIndexDataSourceStocks,
ghostfolioFearAndGreedIndexSymbolStocks
} from '@ghostfolio/common/config';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ghostfolioFearAndGreedIndexSymbolStocks } from '@ghostfolio/common/config';
import {
resolveFearAndGreedIndex,
resolveMarketCondition
@ -24,6 +22,7 @@ export class TwitterBotService implements OnModuleInit {
public constructor(
private readonly benchmarkService: BenchmarkService,
private readonly configurationService: ConfigurationService,
private readonly dataProviderService: DataProviderService,
private readonly symbolService: SymbolService
) {}
@ -49,7 +48,8 @@ export class TwitterBotService implements OnModuleInit {
try {
const symbolItem = await this.symbolService.get({
dataGatheringItem: {
dataSource: ghostfolioFearAndGreedIndexDataSourceStocks,
dataSource:
this.dataProviderService.getDataSourceForFearAndGreedIndexStocks(),
symbol: ghostfolioFearAndGreedIndexSymbolStocks
}
});

51
apps/api/webpack.config.js

@ -1,6 +1,49 @@
const { composePlugins, withNx } = require('@nx/webpack');
const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
const path = require('path');
module.exports = composePlugins(withNx(), (config, { options, context }) => {
// Customize webpack config here
return config;
// These options were migrated by @nx/webpack:convert-to-inferred from
// the project.json file and merged with the options in this file
const configValues = {
build: {
default: {
compiler: 'tsc',
deleteOutputPath: false,
main: './src/main.ts',
outputPath: 'dist/apps/api',
outputHashing: 'none',
sourceMap: true,
target: 'node',
tsConfig: './tsconfig.app.json'
},
production: {
extractLicenses: true,
fileReplacements: [
{
replace: path.resolve(__dirname, './src/environments/environment.ts'),
with: path.resolve(
__dirname,
'./src/environments/environment.prod.ts'
)
}
],
generatePackageJson: true,
inspect: false,
optimization: true
}
}
};
// Determine the correct configValue to use based on the configuration
const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
const buildOptions = {
...configValues.build.default,
...configValues.build[configuration]
};
/**
* @type {import('webpack').WebpackOptionsNormalized}
*/
module.exports = async () => ({
plugins: [new NxAppWebpackPlugin(buildOptions)]
});

3
apps/client/src/app/app.routes.ts

@ -128,8 +128,7 @@ export const routes: Routes = [
import('./pages/webauthn/webauthn-page.component').then(
(c) => c.GfWebauthnPageComponent
),
path: internalRoutes.webauthn.path,
title: internalRoutes.webauthn.title
path: internalRoutes.webauthn.path
},
{
path: internalRoutes.zen.path,

2
apps/client/src/app/components/admin-settings/admin-settings.component.html

@ -76,7 +76,7 @@
<span
class="badge badge-pill badge-secondary ml-2 text-uppercase"
i18n
>new</span
>popular</span
>
}
</a>

2
apps/client/src/app/components/fear-and-greed-index/fear-and-greed-index.component.html

@ -5,7 +5,7 @@
<div class="h4 mb-0">
<span class="mr-2">{{ fearAndGreedIndexText }}</span>
<small class="text-muted"
><strong>{{ fearAndGreedIndex }}</strong
><strong>{{ fearAndGreedIndex | number: '1.0-0' }}</strong
>/100</small
>
</div>

3
apps/client/src/app/components/fear-and-greed-index/fear-and-greed-index.component.ts

@ -1,6 +1,7 @@
import { resolveFearAndGreedIndex } from '@ghostfolio/common/helper';
import { translate } from '@ghostfolio/ui/i18n';
import { DecimalPipe } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
@ -11,7 +12,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [NgxSkeletonLoaderModule],
imports: [DecimalPipe, NgxSkeletonLoaderModule],
selector: 'gf-fear-and-greed-index',
styleUrls: ['./fear-and-greed-index.component.scss'],
templateUrl: './fear-and-greed-index.component.html'

15
apps/client/src/app/components/header/header.component.ts

@ -22,6 +22,7 @@ import { NotificationService } from '@ghostfolio/ui/notifications';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { DataService } from '@ghostfolio/ui/services';
import { HttpErrorResponse } from '@angular/common/http';
import {
ChangeDetectionStrategy,
Component,
@ -42,6 +43,7 @@ import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
import { MatToolbarModule } from '@angular/material/toolbar';
import { Router, RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
import { StatusCodes } from 'http-status-codes';
import { addIcons } from 'ionicons';
import {
closeOutline,
@ -315,10 +317,15 @@ export class GfHeaderComponent implements OnChanges {
this.dataService
.loginAnonymous(data?.accessToken)
.pipe(
catchError(() => {
this.notificationService.alert({
title: $localize`Oops! Incorrect Security Token.`
});
catchError((error: HttpErrorResponse) => {
if (error.status !== StatusCodes.TOO_MANY_REQUESTS) {
// The notification for too many requests is handled in the
// HttpResponseInterceptor
this.notificationService.alert({
title: $localize`Oops! Incorrect Security Token.`
});
}
return EMPTY;
}),

51
apps/client/src/app/components/home-holdings/home-holdings.component.ts

@ -20,6 +20,7 @@ import {
Component,
CUSTOM_ELEMENTS_SCHEMA,
DestroyRef,
inject,
OnInit
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@ -53,32 +54,34 @@ import { DeviceDetectorService } from 'ngx-device-detector';
export class GfHomeHoldingsComponent implements OnInit {
public static DEFAULT_HOLDINGS_VIEW_MODE: HoldingsViewMode = 'TABLE';
public deviceType: string;
public hasImpersonationId: boolean;
public hasPermissionToAccessHoldingsChart: boolean;
public hasPermissionToCreateActivity: boolean;
public holdings: PortfolioPosition[];
public holdingType: HoldingType = 'ACTIVE';
public holdingTypeOptions: ToggleOption[] = [
protected deviceType: string;
protected hasImpersonationId: boolean;
protected hasPermissionToAccessHoldingsChart: boolean;
protected hasPermissionToCreateActivity: boolean;
protected holdings: PortfolioPosition[];
protected holdingType: HoldingType = 'ACTIVE';
protected readonly holdingTypeOptions: ToggleOption[] = [
{ label: $localize`Active`, value: 'ACTIVE' },
{ label: $localize`Closed`, value: 'CLOSED' }
];
public routerLinkPortfolioActivities =
protected readonly routerLinkPortfolioActivities =
internalRoutes.portfolio.subRoutes.activities.routerLink;
public user: User;
public viewModeFormControl = new FormControl<HoldingsViewMode>(
protected user: User;
protected readonly viewModeFormControl = new FormControl<HoldingsViewMode>(
GfHomeHoldingsComponent.DEFAULT_HOLDINGS_VIEW_MODE
);
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private destroyRef: DestroyRef,
private deviceDetectorService: DeviceDetectorService,
private impersonationStorageService: ImpersonationStorageService,
private router: Router,
private userService: UserService
) {
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly dataService = inject(DataService);
private readonly destroyRef = inject(DestroyRef);
private readonly deviceDetectorService = inject(DeviceDetectorService);
private readonly impersonationStorageService = inject(
ImpersonationStorageService
);
private readonly router = inject(Router);
private readonly userService = inject(UserService);
public constructor() {
addIcons({ gridOutline, reorderFourOutline });
}
@ -119,6 +122,10 @@ export class GfHomeHoldingsComponent implements OnInit {
this.viewModeFormControl.valueChanges
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((holdingsViewMode) => {
if (!holdingsViewMode) {
return;
}
this.dataService
.putUserSetting({ holdingsViewMode })
.pipe(takeUntilDestroyed(this.destroyRef))
@ -135,13 +142,13 @@ export class GfHomeHoldingsComponent implements OnInit {
});
}
public onChangeHoldingType(aHoldingType: HoldingType) {
protected onChangeHoldingType(aHoldingType: HoldingType) {
this.holdingType = aHoldingType;
this.initialize();
}
public onHoldingClicked({ dataSource, symbol }: AssetProfileIdentifier) {
protected onHoldingClicked({ dataSource, symbol }: AssetProfileIdentifier) {
if (dataSource && symbol) {
this.router.navigate([], {
queryParams: { dataSource, symbol, holdingDetailDialog: true }
@ -185,7 +192,7 @@ export class GfHomeHoldingsComponent implements OnInit {
);
}
this.holdings = undefined;
this.holdings = [];
this.fetchHoldings()
.pipe(takeUntilDestroyed(this.destroyRef))

2
apps/client/src/app/components/home-market/home-market.component.ts

@ -14,6 +14,7 @@ import { GfLineChartComponent } from '@ghostfolio/ui/line-chart';
import { DataService } from '@ghostfolio/ui/services';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
computed,
@ -27,6 +28,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DeviceDetectorService } from 'ngx-device-detector';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
GfBenchmarkComponent,
GfFearAndGreedIndexComponent,

32
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts

@ -8,10 +8,10 @@ import { GfValueComponent } from '@ghostfolio/ui/value';
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
inject,
Input,
OnChanges,
Output
output
} from '@angular/core';
import { MatTooltipModule } from '@angular/material/tooltip';
import { IonIcon } from '@ionic/angular/standalone';
@ -40,44 +40,46 @@ export class GfPortfolioSummaryComponent implements OnChanges {
@Input() summary: PortfolioSummary;
@Input() user: User;
@Output() emergencyFundChanged = new EventEmitter<number>();
public emergencyFundChanged = output<number>();
public buyAndSellActivitiesTooltip = translate(
protected readonly buyAndSellActivitiesTooltip = translate(
'BUY_AND_SELL_ACTIVITIES_TOOLTIP'
);
public precision = 2;
public timeInMarket: string;
protected precision = 2;
protected timeInMarket: string | undefined;
public get buyingPowerPercentage() {
private readonly notificationService = inject(NotificationService);
public constructor() {
addIcons({ ellipsisHorizontalCircleOutline, informationCircleOutline });
}
protected get buyingPowerPercentage() {
return this.summary?.totalValueInBaseCurrency
? this.summary.cash / this.summary.totalValueInBaseCurrency
: 0;
}
public get emergencyFundPercentage() {
protected get emergencyFundPercentage() {
return this.summary?.totalValueInBaseCurrency
? (this.summary.emergencyFund?.total || 0) /
this.summary.totalValueInBaseCurrency
: 0;
}
public get excludedFromAnalysisPercentage() {
protected get excludedFromAnalysisPercentage() {
return this.summary?.totalValueInBaseCurrency
? this.summary.excludedAccountsAndActivities /
this.summary.totalValueInBaseCurrency
: 0;
}
public constructor(private notificationService: NotificationService) {
addIcons({ ellipsisHorizontalCircleOutline, informationCircleOutline });
}
public ngOnChanges() {
if (this.summary) {
if (
this.deviceType === 'mobile' &&
this.summary.totalValueInBaseCurrency >=
(this.summary.totalValueInBaseCurrency ?? 0) >=
NUMERICAL_PRECISION_THRESHOLD_6_FIGURES
) {
this.precision = 0;
@ -98,7 +100,7 @@ export class GfPortfolioSummaryComponent implements OnChanges {
}
}
public onEditEmergencyFund() {
protected onEditEmergencyFund() {
this.notificationService.prompt({
confirmFn: (value) => {
const emergencyFund = parseFloat(value.trim()) || 0;

54
apps/client/src/app/components/user-account-membership/user-account-membership.component.ts

@ -3,7 +3,6 @@ import { ConfirmationDialogType } from '@ghostfolio/common/enums';
import { getDateFormatString } from '@ghostfolio/common/helper';
import { User } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfMembershipCardComponent } from '@ghostfolio/ui/membership-card';
import { NotificationService } from '@ghostfolio/ui/notifications';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
@ -14,7 +13,8 @@ import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef
DestroyRef,
inject
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatButtonModule } from '@angular/material/button';
@ -40,29 +40,29 @@ import { catchError } from 'rxjs/operators';
templateUrl: './user-account-membership.html'
})
export class GfUserAccountMembershipComponent {
public baseCurrency: string;
public coupon: number;
public couponId: string;
public defaultDateFormat: string;
public durationExtension: StringValue;
public hasPermissionForSubscription: boolean;
public hasPermissionToCreateApiKey: boolean;
public hasPermissionToUpdateUserSettings: boolean;
public price: number;
public priceId: string;
public routerLinkPricing = publicRoutes.pricing.routerLink;
public trySubscriptionMail =
protected readonly baseCurrency: string;
protected coupon: number | undefined;
protected defaultDateFormat: string;
protected durationExtension: StringValue | undefined;
protected readonly hasPermissionForSubscription: boolean;
protected hasPermissionToCreateApiKey: boolean;
protected hasPermissionToUpdateUserSettings: boolean;
protected price: number;
protected readonly trySubscriptionMail =
'mailto:hi@ghostfol.io?subject=Ghostfolio Premium Trial&body=Hello%0D%0DI am interested in Ghostfolio Premium. Can you please send me a coupon code to try it for some time?%0D%0DKind regards';
public user: User;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private destroyRef: DestroyRef,
private notificationService: NotificationService,
private snackBar: MatSnackBar,
private userService: UserService
) {
protected user: User;
private couponId: string | undefined;
private priceId: string;
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly dataService = inject(DataService);
private readonly destroyRef = inject(DestroyRef);
private readonly notificationService = inject(NotificationService);
private readonly snackBar = inject(MatSnackBar);
private readonly userService = inject(UserService);
public constructor() {
const { baseCurrency, globalPermissions } = this.dataService.fetchInfo();
this.baseCurrency = baseCurrency;
@ -104,7 +104,7 @@ export class GfUserAccountMembershipComponent {
});
}
public onCheckout() {
protected onCheckout() {
this.dataService
.createStripeCheckoutSession({
couponId: this.couponId,
@ -125,7 +125,7 @@ export class GfUserAccountMembershipComponent {
});
}
public onGenerateApiKey() {
protected onGenerateApiKey() {
this.notificationService.confirm({
confirmFn: () => {
this.dataService
@ -158,7 +158,7 @@ export class GfUserAccountMembershipComponent {
});
}
public onRedeemCoupon() {
protected onRedeemCoupon() {
this.notificationService.prompt({
confirmFn: (value) => {
const couponCode = value?.trim();

81
apps/client/src/app/components/user-account-settings/user-account-settings.component.ts

@ -20,11 +20,12 @@ import {
Component,
CUSTOM_ELEMENTS_SCHEMA,
DestroyRef,
inject,
OnInit
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import {
FormBuilder,
NonNullableFormBuilder,
FormsModule,
ReactiveFormsModule,
Validators
@ -69,22 +70,22 @@ import { catchError } from 'rxjs/operators';
templateUrl: './user-account-settings.html'
})
export class GfUserAccountSettingsComponent implements OnInit {
public appearancePlaceholder = $localize`Auto`;
public baseCurrency: string;
public closeUserAccountMail: string;
public currencies: string[] = [];
public deleteOwnUserForm = this.formBuilder.group({
protected readonly appearancePlaceholder = $localize`Auto`;
protected readonly baseCurrency: string;
protected closeUserAccountMail: string;
protected readonly currencies: string[] = [];
protected readonly deleteOwnUserForm = inject(NonNullableFormBuilder).group({
accessToken: ['', Validators.required]
});
public hasPermissionToDeleteOwnUser: boolean;
public hasPermissionToRequestOwnUserDeletion: boolean;
public hasPermissionToUpdateViewMode: boolean;
public hasPermissionToUpdateUserSettings: boolean;
public isAccessTokenHidden = true;
public isFingerprintSupported = this.doesBrowserSupportAuthn();
public isWebAuthnEnabled: boolean;
public language = document.documentElement.lang;
public locales = [
protected hasPermissionToDeleteOwnUser: boolean;
protected hasPermissionToRequestOwnUserDeletion: boolean;
protected hasPermissionToUpdateViewMode: boolean;
protected hasPermissionToUpdateUserSettings: boolean;
protected isAccessTokenHidden = true;
protected readonly isFingerprintSupported = this.doesBrowserSupportAuthn();
protected isWebAuthnEnabled: boolean;
protected readonly language = document.documentElement.lang;
protected locales = [
'ca',
'de',
'de-CH',
@ -102,19 +103,18 @@ export class GfUserAccountSettingsComponent implements OnInit {
'uk',
'zh'
];
public user: User;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
private destroyRef: DestroyRef,
private formBuilder: FormBuilder,
private notificationService: NotificationService,
private settingsStorageService: SettingsStorageService,
private snackBar: MatSnackBar,
private userService: UserService,
public webAuthnService: WebAuthnService
) {
protected user: User;
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly dataService = inject(DataService);
private readonly destroyRef = inject(DestroyRef);
private readonly notificationService = inject(NotificationService);
private readonly settingsStorageService = inject(SettingsStorageService);
private readonly snackBar = inject(MatSnackBar);
private readonly userService = inject(UserService);
private readonly webAuthnService = inject(WebAuthnService);
public constructor() {
const { baseCurrency, currencies } = this.dataService.fetchInfo();
this.baseCurrency = baseCurrency;
@ -148,7 +148,10 @@ export class GfUserAccountSettingsComponent implements OnInit {
permissions.updateViewMode
);
this.locales.push(this.user.settings.locale);
if (this.user.settings.locale) {
this.locales.push(this.user.settings.locale);
}
this.locales = Array.from(new Set(this.locales)).sort();
this.changeDetectorRef.markForCheck();
@ -162,11 +165,11 @@ export class GfUserAccountSettingsComponent implements OnInit {
this.update();
}
public isCommunityLanguage() {
protected isCommunityLanguage() {
return !['de', 'en'].includes(this.language);
}
public onChangeUserSetting(aKey: string, aValue: string) {
protected onChangeUserSetting(aKey: string, aValue: string) {
this.dataService
.putUserSetting({ [aKey]: aValue })
.pipe(takeUntilDestroyed(this.destroyRef))
@ -190,12 +193,12 @@ export class GfUserAccountSettingsComponent implements OnInit {
});
}
public onCloseAccount() {
protected onCloseAccount() {
this.notificationService.confirm({
confirmFn: () => {
this.dataService
.deleteOwnUser({
accessToken: this.deleteOwnUserForm.get('accessToken').value
accessToken: this.deleteOwnUserForm.controls.accessToken.value
})
.pipe(
catchError(() => {
@ -218,7 +221,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
});
}
public onExperimentalFeaturesChange(aEvent: MatSlideToggleChange) {
protected onExperimentalFeaturesChange(aEvent: MatSlideToggleChange) {
this.dataService
.putUserSetting({ isExperimentalFeatures: aEvent.checked })
.pipe(takeUntilDestroyed(this.destroyRef))
@ -234,13 +237,13 @@ export class GfUserAccountSettingsComponent implements OnInit {
});
}
public onExport() {
protected onExport() {
this.dataService
.fetchExport()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((data) => {
for (const activity of data.activities) {
delete activity.id;
delete (activity as Omit<typeof activity, 'id'> & { id?: string }).id;
}
downloadAsFile({
@ -254,7 +257,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
});
}
public onRestrictedViewChange(aEvent: MatSlideToggleChange) {
protected onRestrictedViewChange(aEvent: MatSlideToggleChange) {
this.dataService
.putUserSetting({ isRestrictedView: aEvent.checked })
.pipe(takeUntilDestroyed(this.destroyRef))
@ -270,7 +273,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
});
}
public async onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) {
protected async onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) {
if (aEvent.checked) {
try {
await this.registerDevice();
@ -293,7 +296,7 @@ export class GfUserAccountSettingsComponent implements OnInit {
}
}
public onViewModeChange(aEvent: MatSlideToggleChange) {
protected onViewModeChange(aEvent: MatSlideToggleChange) {
this.dataService
.putUserSetting({ viewMode: aEvent.checked === true ? 'ZEN' : 'DEFAULT' })
.pipe(takeUntilDestroyed(this.destroyRef))

48
apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts

@ -9,7 +9,7 @@ import {
Component,
CUSTOM_ELEMENTS_SCHEMA,
DestroyRef,
Inject,
inject,
OnInit
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@ -49,28 +49,30 @@ import {
templateUrl: './user-detail-dialog.html'
})
export class GfUserDetailDialogComponent implements OnInit {
public baseCurrency: string;
public readonly getCountryName = getCountryName;
public subscriptionsDataSource = new MatTableDataSource<Subscription>();
public subscriptionsDisplayedColumns = [
protected readonly baseCurrency: string;
protected readonly getCountryName = getCountryName;
protected readonly subscriptionsDataSource =
new MatTableDataSource<Subscription>();
protected readonly subscriptionsDisplayedColumns = [
'createdAt',
'type',
'price',
'expiresAt'
];
public user: AdminUserResponse;
public constructor(
private adminService: AdminService,
private changeDetectorRef: ChangeDetectorRef,
@Inject(MAT_DIALOG_DATA) public data: UserDetailDialogParams,
private dataService: DataService,
private destroyRef: DestroyRef,
public dialogRef: MatDialogRef<
GfUserDetailDialogComponent,
UserDetailDialogResult
>
) {
protected user: AdminUserResponse;
protected readonly data = inject<UserDetailDialogParams>(MAT_DIALOG_DATA);
private readonly adminService = inject(AdminService);
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly dataService = inject(DataService);
private readonly destroyRef = inject(DestroyRef);
private readonly dialogRef =
inject<MatDialogRef<GfUserDetailDialogComponent, UserDetailDialogResult>>(
MatDialogRef
);
public constructor() {
this.baseCurrency = this.dataService.fetchInfo().baseCurrency;
addIcons({
@ -98,26 +100,26 @@ export class GfUserDetailDialogComponent implements OnInit {
});
}
public deleteUser() {
protected deleteUser() {
this.dialogRef.close({
action: 'delete',
userId: this.data.userId
});
}
public getSum() {
protected getSum() {
return getSum(
this.subscriptionsDataSource.data
.filter(({ price }) => {
return price !== null;
})
.map(({ price }) => {
return new Big(price);
return new Big(price ?? 0);
})
).toNumber();
}
public getType({ createdAt, expiresAt, price }: Subscription) {
protected getType({ createdAt, expiresAt, price }: Subscription) {
if (price) {
return $localize`Paid`;
}
@ -127,7 +129,7 @@ export class GfUserDetailDialogComponent implements OnInit {
: $localize`Coupon`;
}
public onClose() {
protected onClose() {
this.dialogRef.close();
}
}

22
apps/client/src/app/core/http-response.interceptor.ts

@ -98,15 +98,23 @@ export class HttpResponseInterceptor implements HttpInterceptor {
});
}
} else if (error.status === StatusCodes.TOO_MANY_REQUESTS) {
if (!this.snackBarRef) {
this.snackBarRef = this.snackBar.open(
$localize`Oops! It looks like you’re making too many requests. Please slow down a bit.`
);
// Replace an already visible snack bar so that the rate limiting
// feedback is not swallowed
const snackBarRef = this.snackBar.open(
$localize`Oops! It looks like you’re making too many requests. Please slow down a bit.`,
undefined,
{
duration: ms('6 seconds')
}
);
this.snackBarRef?.afterDismissed().subscribe(() => {
snackBarRef.afterDismissed().subscribe(() => {
if (this.snackBarRef === snackBarRef) {
this.snackBarRef = undefined;
});
}
}
});
this.snackBarRef = snackBarRef;
} else if (error.status === StatusCodes.UNAUTHORIZED) {
if (!error.url?.includes('/data-providers/ghostfolio/status')) {
if (this.webAuthnService.isEnabled()) {

12
apps/client/src/app/pages/about/about-page.component.ts

@ -8,7 +8,12 @@ import {
} from '@ghostfolio/ui/page-tabs';
import { DataService } from '@ghostfolio/ui/services';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { addIcons } from 'ionicons';
import {
@ -21,6 +26,7 @@ import {
} from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPageTabsComponent],
selector: 'gf-about-page',
@ -83,8 +89,6 @@ export class AboutPageComponent {
});
this.user = state.user;
this.changeDetectorRef.markForCheck();
}
this.tabs.push({
@ -92,6 +96,8 @@ export class AboutPageComponent {
label: publicRoutes.about.subRoutes.ossFriends.title,
routerLink: publicRoutes.about.subRoutes.ossFriends.routerLink
});
this.changeDetectorRef.markForCheck();
});
addIcons({

11
apps/client/src/app/pages/admin/admin-page.component.ts

@ -12,7 +12,12 @@ import {
TabConfiguration
} from '@ghostfolio/ui/page-tabs';
import { Component, inject } from '@angular/core';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
inject
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { addIcons } from 'ionicons';
import {
@ -24,6 +29,7 @@ import {
} from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPageTabsComponent],
selector: 'gf-admin-page',
@ -35,6 +41,7 @@ export class AdminPageComponent {
private user: User;
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly tokenStorageService = inject(TokenStorageService);
private readonly userService = inject(UserService);
@ -45,6 +52,8 @@ export class AdminPageComponent {
this.user = state?.user;
this.initializeTabs();
this.changeDetectorRef.markForCheck();
});
addIcons({

3
apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hallo-ghostfolio-page',

3
apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hello-ghostfolio-page',

3
apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-first-months-in-open-source-page',

3
apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-ghostfolio-meets-internet-identity-page',

3
apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-how-do-i-get-my-finances-in-order-page',

3
apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-500-stars-on-github-page',

3
apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hacktoberfest-2022-page',

3
apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts

@ -1,11 +1,12 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule],
selector: 'gf-black-friday-2022-page',

3
apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-the-importance-of-tracking-your-personal-finances-page',

3
apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-ghostfolio-auf-sackgeld-vorgestellt-page',

3
apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-ghostfolio-meets-umbrel-page',

3
apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-1000-stars-on-github-page',

3
apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-unlock-your-financial-potential-with-ghostfolio-page',

3
apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-exploring-the-path-to-fire-page-page',

3
apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-ghostfolio-joins-oss-friends-page',

3
apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-ghostfolio-2-page',

3
apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hacktoberfest-2023-page',

3
apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts

@ -1,11 +1,12 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule],
selector: 'gf-black-week-2023-page',

3
apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hacktoberfest-2023-debriefing-page',

3
apps/client/src/app/pages/blog/2024/09/hacktoberfest-2024/hacktoberfest-2024-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hacktoberfest-2024-page',

3
apps/client/src/app/pages/blog/2024/11/black-weeks-2024/black-weeks-2024-page.component.ts

@ -1,11 +1,12 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule],
selector: 'gf-black-weeks-2024-page',

3
apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-hacktoberfest-2025-page',

3
apps/client/src/app/pages/blog/2025/11/black-weeks-2025/black-weeks-2025-page.component.ts

@ -1,11 +1,12 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule],
selector: 'gf-black-weeks-2025-page',

3
apps/client/src/app/pages/blog/2026/04/ghostfolio-3/ghostfolio-3-page.component.ts

@ -1,10 +1,11 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { RouterModule } from '@angular/router';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [MatButtonModule, RouterModule],
selector: 'gf-ghostfolio-3-page',

7
apps/client/src/app/pages/blog/blog-page.component.ts

@ -1,7 +1,11 @@
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { DataService } from '@ghostfolio/ui/services';
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import {
ChangeDetectionStrategy,
Component,
CUSTOM_ELEMENTS_SCHEMA
} from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { RouterModule } from '@angular/router';
import { IonIcon } from '@ionic/angular/standalone';
@ -9,6 +13,7 @@ import { addIcons } from 'ionicons';
import { chevronForwardOutline } from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [IonIcon, MatCardModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],

3
apps/client/src/app/pages/faq/faq-page.component.ts

@ -6,11 +6,12 @@ import {
} from '@ghostfolio/ui/page-tabs';
import { DataService } from '@ghostfolio/ui/services';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { addIcons } from 'ionicons';
import { cloudyOutline, readerOutline, serverOutline } from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPageTabsComponent],
selector: 'gf-faq-page',

6
apps/client/src/app/pages/home/home-page.component.ts

@ -9,6 +9,7 @@ import {
} from '@ghostfolio/ui/page-tabs';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef,
@ -25,6 +26,7 @@ import {
} from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPageTabsComponent],
selector: 'gf-home-page',
@ -85,9 +87,9 @@ export class GfHomePageComponent implements OnInit {
: internalRoutes.home.subRoutes.markets.routerLink
}
];
this.changeDetectorRef.markForCheck();
}
this.changeDetectorRef.markForCheck();
});
addIcons({

88
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts

@ -20,7 +20,7 @@ import {
ChangeDetectorRef,
Component,
DestroyRef,
Inject
inject
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import {
@ -75,42 +75,46 @@ import { ActivityType } from './types/activity-type.type';
templateUrl: 'create-or-update-activity-dialog.html'
})
export class GfCreateOrUpdateActivityDialogComponent {
public activityForm: FormGroup;
public assetClassOptions: AssetClassSelectorOption[] = Object.keys(AssetClass)
.map((id) => {
return { id, label: translate(id) } as AssetClassSelectorOption;
})
.sort((a, b) => {
return a.label.localeCompare(b.label);
});
protected activityForm: FormGroup;
public assetSubClassOptions: AssetClassSelectorOption[] = [];
public currencies: string[] = [];
public currencyOfAssetProfile: string | undefined;
public currentMarketPrice: number | null = null;
public defaultDateFormat: string;
public defaultLookupItems: LookupItem[] = [];
public hasPermissionToCreateOwnTag: boolean | undefined;
public isLoading = false;
public isToday = isToday;
public mode: 'create' | 'update';
public tagsAvailable: Tag[] = [];
public total = 0;
public typesTranslationMap = new Map<Type, string>();
public Validators = Validators;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
@Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateActivityDialogParams,
private dataService: DataService,
private dateAdapter: DateAdapter<Date, string>,
private destroyRef: DestroyRef,
public dialogRef: MatDialogRef<GfCreateOrUpdateActivityDialogComponent>,
private formBuilder: FormBuilder,
@Inject(MAT_DATE_LOCALE) private locale: string,
private userService: UserService
) {
protected readonly assetClassOptions: AssetClassSelectorOption[] =
Object.keys(AssetClass)
.map((id) => {
return { id, label: translate(id) } as AssetClassSelectorOption;
})
.sort((a, b) => {
return a.label.localeCompare(b.label);
});
protected assetSubClassOptions: AssetClassSelectorOption[] = [];
protected currencies: string[] = [];
protected currencyOfAssetProfile: string | undefined;
protected currentMarketPrice: number | null = null;
protected defaultDateFormat: string;
protected defaultLookupItems: LookupItem[] = [];
protected hasPermissionToCreateOwnTag: boolean | undefined;
protected isLoading = false;
protected readonly isToday = isToday;
protected mode: 'create' | 'update';
protected tagsAvailable: Tag[] = [];
protected total = 0;
protected readonly typesTranslationMap = new Map<Type, string>();
protected readonly Validators = Validators;
protected readonly data =
inject<CreateOrUpdateActivityDialogParams>(MAT_DIALOG_DATA);
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly dataService = inject(DataService);
private readonly dateAdapter = inject<DateAdapter<Date, string>>(DateAdapter);
private readonly destroyRef = inject(DestroyRef);
private readonly dialogRef =
inject<MatDialogRef<GfCreateOrUpdateActivityDialogComponent>>(MatDialogRef);
private readonly formBuilder = inject(FormBuilder);
private locale = inject<string>(MAT_DATE_LOCALE);
private readonly userService = inject(UserService);
public constructor() {
addIcons({ calendarClearOutline, refreshOutline });
}
@ -138,7 +142,9 @@ export class GfCreateOrUpdateActivityDialogComponent {
return !['CASH'].includes(assetProfile.assetSubClass);
})
.sort((a, b) => {
return a.assetProfile.name?.localeCompare(b.assetProfile.name);
return (a.assetProfile.name ?? '').localeCompare(
b.assetProfile.name ?? ''
);
})
.map(({ assetProfile }) => {
return {
@ -463,14 +469,14 @@ export class GfCreateOrUpdateActivityDialogComponent {
}
}
public applyCurrentMarketPrice() {
protected applyCurrentMarketPrice() {
this.activityForm.patchValue({
currencyOfUnitPrice: this.activityForm.get('currency')?.value,
unitPrice: this.currentMarketPrice
});
}
public dateFilter(aDate: Date) {
protected dateFilter(aDate: Date) {
if (!aDate) {
return true;
}
@ -478,11 +484,11 @@ export class GfCreateOrUpdateActivityDialogComponent {
return isAfter(aDate, new Date(0));
}
public onCancel() {
protected onCancel() {
this.dialogRef.close();
}
public async onSubmit() {
protected async onSubmit() {
const activity: CreateOrderDto | UpdateOrderDto = {
accountId: this.activityForm.get('accountId')?.value,
assetClass: this.activityForm.get('assetClass')?.value,

2
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts

@ -151,7 +151,7 @@ export class GfImportActivitiesDialogComponent {
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(({ holdings }) => {
this.holdings = sortBy(holdings, ({ assetProfile }) => {
return assetProfile.name.toLowerCase();
return assetProfile.name?.toLowerCase();
});
this.assetProfileForm.controls.assetProfileIdentifier.enable();

40
apps/client/src/app/pages/register/user-account-registration-dialog/user-account-registration-dialog.component.ts

@ -9,8 +9,8 @@ import {
Component,
CUSTOM_ELEMENTS_SCHEMA,
DestroyRef,
Inject,
ViewChild
inject,
viewChild
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@ -53,26 +53,28 @@ import { UserAccountRegistrationDialogParams } from './interfaces/interfaces';
templateUrl: 'user-account-registration-dialog.html'
})
export class GfUserAccountRegistrationDialogComponent {
@ViewChild(MatStepper) stepper!: MatStepper;
protected readonly stepper = viewChild.required(MatStepper);
public accessToken: string;
public authToken: string;
public isCreateAccountButtonDisabled = true;
public isDisclaimerChecked = false;
public role: string;
public routerLinkAboutTermsOfService =
protected accessToken: string | undefined;
protected authToken: string;
protected isCreateAccountButtonDisabled = true;
protected isDisclaimerChecked = false;
protected role: string;
protected readonly routerLinkAboutTermsOfService =
publicRoutes.about.subRoutes.termsOfService.routerLink;
public constructor(
private changeDetectorRef: ChangeDetectorRef,
@Inject(MAT_DIALOG_DATA) public data: UserAccountRegistrationDialogParams,
private dataService: DataService,
private destroyRef: DestroyRef
) {
protected readonly data =
inject<UserAccountRegistrationDialogParams>(MAT_DIALOG_DATA);
private readonly changeDetectorRef = inject(ChangeDetectorRef);
private readonly dataService = inject(DataService);
private readonly destroyRef = inject(DestroyRef);
public constructor() {
addIcons({ arrowForwardOutline, checkmarkOutline, copyOutline });
}
public createAccount() {
protected createAccount() {
this.dataService
.postUser()
.pipe(takeUntilDestroyed(this.destroyRef))
@ -81,17 +83,17 @@ export class GfUserAccountRegistrationDialogComponent {
this.authToken = authToken;
this.role = role;
this.stepper.next();
this.stepper().next();
this.changeDetectorRef.markForCheck();
});
}
public enableCreateAccountButton() {
protected enableCreateAccountButton() {
this.isCreateAccountButtonDisabled = false;
}
public onChangeDislaimerChecked() {
protected onChangeDislaimerChecked() {
this.isDisclaimerChecked = !this.isDisclaimerChecked;
}
}

3
apps/client/src/app/pages/resources/resources-page.component.ts

@ -4,7 +4,7 @@ import {
TabConfiguration
} from '@ghostfolio/ui/page-tabs';
import { Component } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { addIcons } from 'ionicons';
import {
bookOutline,
@ -14,6 +14,7 @@ import {
} from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPageTabsComponent],
selector: 'gf-resources-page',

12
apps/client/src/app/pages/user-account/user-account-page.component.ts

@ -6,12 +6,18 @@ import {
TabConfiguration
} from '@ghostfolio/ui/page-tabs';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { addIcons } from 'ionicons';
import { diamondOutline, keyOutline, settingsOutline } from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPageTabsComponent],
selector: 'gf-user-account-page',
@ -52,9 +58,9 @@ export class GfUserAccountPageComponent {
routerLink: internalRoutes.account.subRoutes.access.routerLink
}
];
this.changeDetectorRef.markForCheck();
}
this.changeDetectorRef.markForCheck();
});
addIcons({ diamondOutline, keyOutline, settingsOutline });

3
apps/client/src/app/pages/webauthn/webauthn-page.component.ts

@ -1,6 +1,5 @@
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service';
import { GfLogoComponent } from '@ghostfolio/ui/logo';
import {
ChangeDetectorRef,
@ -15,7 +14,7 @@ import { Router } from '@angular/router';
@Component({
host: { class: 'page' },
imports: [GfLogoComponent, MatButtonModule, MatProgressSpinnerModule],
imports: [MatButtonModule, MatProgressSpinnerModule],
selector: 'gf-webauthn-page',
styleUrls: ['./webauthn-page.scss'],
templateUrl: './webauthn-page.html'

6
apps/client/src/app/pages/webauthn/webauthn-page.html

@ -1,12 +1,6 @@
<div class="container">
<div class="row">
<div class="col">
<div
class="align-items-center d-flex flex-column justify-content-center mb-4 w-100"
>
<gf-logo size="medium" />
</div>
@if (!hasError) {
<div class="col d-flex justify-content-center">
<mat-spinner [diameter]="20" />

12
apps/client/src/app/pages/zen/zen-page.component.ts

@ -6,12 +6,18 @@ import {
TabConfiguration
} from '@ghostfolio/ui/page-tabs';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { addIcons } from 'ionicons';
import { albumsOutline, analyticsOutline } from 'ionicons/icons';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'page' },
imports: [GfPageTabsComponent],
selector: 'gf-zen-page',
@ -44,9 +50,9 @@ export class GfZenPageComponent {
}
];
this.user = state.user;
this.changeDetectorRef.markForCheck();
}
this.changeDetectorRef.markForCheck();
});
addIcons({ albumsOutline, analyticsOutline });

78
apps/client/src/locales/messages.ca.xlf

@ -599,7 +599,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -623,7 +623,7 @@
<target state="translated">Suprimir</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -907,7 +907,7 @@
<target state="translated">Punts de referència</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="8298612418414367990" datatype="html">
@ -915,7 +915,7 @@
<target state="translated">Divises</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -935,7 +935,7 @@
<target state="translated">ETFs sense País</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -943,7 +943,7 @@
<target state="translated">ETFs sense Sector</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
@ -951,7 +951,7 @@
<target state="translated">Filtra per...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -987,7 +987,7 @@
<target state="translated">Nombre d’Activitats</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -995,7 +995,7 @@
<target state="translated">Dades Històriques</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -1007,7 +1007,7 @@
<target state="translated">Nombre de Sectors</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -1031,7 +1031,7 @@
<target state="translated">Nombre de Països</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -1039,7 +1039,7 @@
<target state="translated">Recopilar Dades del Perfil</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1919,7 +1919,7 @@
<target state="translated">Por</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1935,7 +1935,7 @@
<target state="translated">Cobdícia</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2969,10 +2969,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">D’acord</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -3454,6 +3450,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="new">Duration</target>
@ -4069,7 +4073,7 @@
</trans-unit>
<trans-unit id="8065260392868074625" datatype="html">
<source>How does <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> work?</source>
<target state="translatetd">Com ho fa <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> treballar?</target>
<target state="translated">Com ho fa <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> treballar?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
<context context-type="linenumber">286</context>
@ -4784,7 +4788,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -4804,11 +4808,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -4828,7 +4832,7 @@
<target state="translated">Mensualment</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
@ -4836,7 +4840,7 @@
<target state="translated">Anualment</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="1600023202562292052" datatype="html">
@ -5933,7 +5937,7 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
@ -6285,7 +6289,7 @@
<target state="new">No Activities</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -7043,6 +7047,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7273,7 +7281,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7695,7 +7703,7 @@
<target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7775,7 +7783,7 @@
<target state="new">Open Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8012,7 +8020,7 @@
<target state="new">Gather Recent Historical Market Data</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8020,7 +8028,7 @@
<target state="new">Gather All Historical Market Data</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="new">new</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="new">Investment</target>

76
apps/client/src/locales/messages.de.xlf

@ -238,7 +238,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -262,7 +262,7 @@
<target state="translated">Löschen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -526,7 +526,7 @@
<target state="translated">Historische Daten</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -570,7 +570,7 @@
<target state="translated">Letzte historische Marktdaten synchronisieren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -578,7 +578,7 @@
<target state="translated">Alle historischen Marktdaten synchronisieren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -586,7 +586,7 @@
<target state="translated">Profildaten synchronisieren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1188,10 +1188,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">Okay</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -1741,6 +1737,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="translated">beliebt</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="translated">Dauer</target>
@ -2506,7 +2510,7 @@
<target state="translated">{VAR_PLURAL, plural, =1 {Profil} other {Profile}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="2893955285486651896" datatype="html">
@ -2686,7 +2690,7 @@
<target state="translated">Monatlich</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="5211792611718918888" datatype="html">
@ -2738,7 +2742,7 @@
<target state="translated">Anzahl Länder</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="6130372166370766747" datatype="html">
@ -2746,7 +2750,7 @@
<target state="translated">Anzahl Sektoren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -2770,7 +2774,7 @@
<target state="translated">Angst</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2786,7 +2790,7 @@
<target state="translated">Gier</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2802,7 +2806,7 @@
<target state="translated">Filtern nach...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="1965206604774400" datatype="html">
@ -3342,7 +3346,7 @@
<target state="translated">Anzahl Aktivitäten</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="1102717806459547726" datatype="html">
@ -3402,7 +3406,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -3538,7 +3542,7 @@
<target state="translated">Jährlich</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="72640258012696878" datatype="html">
@ -3606,7 +3610,7 @@
<target state="translated">Keine Aktivitäten</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -4822,7 +4826,7 @@
<target state="translated">ETFs ohne Länder</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -4830,7 +4834,7 @@
<target state="translated">ETFs ohne Sektoren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="1647750822609779679" datatype="html">
@ -5066,7 +5070,7 @@
<target state="translated">Währungen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -6248,11 +6252,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6709,7 +6713,7 @@
<target state="translated">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7067,6 +7071,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7297,7 +7305,7 @@
<target state="translated"><x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/> löschen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7719,7 +7727,7 @@
<target state="translated">KI-Anweisung wurde in die Zwischenablage kopiert</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7799,7 +7807,7 @@
<target state="translated">Öffne Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">neu</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Investition</target>

76
apps/client/src/locales/messages.es.xlf

@ -239,7 +239,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -263,7 +263,7 @@
<target state="translated">Eliminar</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -527,7 +527,7 @@
<target state="translated">Datos históricos</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -571,7 +571,7 @@
<target state="translated">Recopilar datos del perfil</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1173,10 +1173,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">De acuerdo</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -1726,6 +1722,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="translated">Duración</target>
@ -2491,7 +2495,7 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="2893955285486651896" datatype="html">
@ -2715,7 +2719,7 @@
<target state="translated">Mensual</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="6130372166370766747" datatype="html">
@ -2723,7 +2727,7 @@
<target state="translated">Número de sectores</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -2747,7 +2751,7 @@
<target state="translated">Número de países</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5486880308148746399" datatype="html">
@ -2755,7 +2759,7 @@
<target state="translated">Miedo</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2771,7 +2775,7 @@
<target state="translated">Codicia</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2787,7 +2791,7 @@
<target state="translated">Filtrar por...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="5342721262799645301" datatype="html">
@ -3327,7 +3331,7 @@
<target state="translated">Número de operaciones</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="1102717806459547726" datatype="html">
@ -3379,7 +3383,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -3523,7 +3527,7 @@
<target state="translated">Anual</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="72640258012696878" datatype="html">
@ -3591,7 +3595,7 @@
<target state="translated">Sin operaciones</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -4799,7 +4803,7 @@
<target state="translated">ETFs sin países</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -4807,7 +4811,7 @@
<target state="translated">ETFs sin sectores</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="1647750822609779679" datatype="html">
@ -5043,7 +5047,7 @@
<target state="translated">Divisas</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -6225,11 +6229,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6686,7 +6690,7 @@
<target state="translated">Índices de referencia</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7044,6 +7048,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7274,7 +7282,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7696,7 +7704,7 @@
<target state="translated">El prompt para la IA ha sido copiado al portapapeles</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7776,7 +7784,7 @@
<target state="translated">Abrir Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8013,7 +8021,7 @@
<target state="translated">Recopilar datos históricos recientes del mercado</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8021,7 +8029,7 @@
<target state="translated">Recopilar todos los datos históricos del mercado</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8359,14 +8367,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">nuevo</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Inversión</target>

76
apps/client/src/locales/messages.fr.xlf

@ -302,7 +302,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -326,7 +326,7 @@
<target state="translated">Supprimer</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -570,7 +570,7 @@
<target state="translated">Filtrer par...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -606,7 +606,7 @@
<target state="translated">Nombre d’Activités</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -614,7 +614,7 @@
<target state="translated">Données Historiques</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -626,7 +626,7 @@
<target state="translated">Nombre de Secteurs</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -650,7 +650,7 @@
<target state="translated">Nombre de Pays</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -658,7 +658,7 @@
<target state="translated">Obtenir les Données du Profil</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1078,7 +1078,7 @@
<target state="translated">Peur</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1094,7 +1094,7 @@
<target state="translated">Avidité</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1484,10 +1484,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">D’accord</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -2061,6 +2057,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="translated">Durée</target>
@ -2614,7 +2618,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -2642,7 +2646,7 @@
<target state="translated">Mensuel</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -3046,7 +3050,7 @@
<target state="translated">{VAR_PLURAL, plural, =1 {Profil} other {Profils}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="2893955285486651896" datatype="html">
@ -3522,7 +3526,7 @@
<target state="translated">Annuel</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="72640258012696878" datatype="html">
@ -3590,7 +3594,7 @@
<target state="translated">Aucune Activité</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -4798,7 +4802,7 @@
<target state="translated">ETF sans Pays</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -4806,7 +4810,7 @@
<target state="translated">ETF sans Secteurs</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="1647750822609779679" datatype="html">
@ -5042,7 +5046,7 @@
<target state="translated">Devises</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -6224,11 +6228,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6685,7 +6689,7 @@
<target state="translated">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7043,6 +7047,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7273,7 +7281,7 @@
<target state="translated">Supprimer <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7695,7 +7703,7 @@
<target state="translated">Le prompt IA a été copié dans le presse-papiers</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7775,7 +7783,7 @@
<target state="translated">Ouvrir Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8012,7 +8020,7 @@
<target state="translated">Collecter les données récentes du marché historique</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8020,7 +8028,7 @@
<target state="translated">Collecter toutes les données du marché historique</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">nouveau</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Investissement</target>

76
apps/client/src/locales/messages.it.xlf

@ -239,7 +239,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -263,7 +263,7 @@
<target state="translated">Elimina</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -527,7 +527,7 @@
<target state="translated">Dati storici</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -571,7 +571,7 @@
<target state="translated">Raccogli i dati del profilo</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1173,10 +1173,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">Bene</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -1726,6 +1722,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="new">Duration</target>
@ -2491,7 +2495,7 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="2893955285486651896" datatype="html">
@ -2715,7 +2719,7 @@
<target state="translated">Mensile</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="6130372166370766747" datatype="html">
@ -2723,7 +2727,7 @@
<target state="translated">Numero di settori</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -2747,7 +2751,7 @@
<target state="translated">Numero di paesi</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5486880308148746399" datatype="html">
@ -2755,7 +2759,7 @@
<target state="translated">Paura</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2771,7 +2775,7 @@
<target state="translated">Avidità</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2787,7 +2791,7 @@
<target state="translated">Filtra per...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="5342721262799645301" datatype="html">
@ -3327,7 +3331,7 @@
<target state="translated">Conteggio attività</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="1102717806459547726" datatype="html">
@ -3379,7 +3383,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -3523,7 +3527,7 @@
<target state="translated">Annuale</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="72640258012696878" datatype="html">
@ -3591,7 +3595,7 @@
<target state="new">No Activities</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -4799,7 +4803,7 @@
<target state="translated">ETF senza paesi</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -4807,7 +4811,7 @@
<target state="translated">ETF senza settori</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="1647750822609779679" datatype="html">
@ -5043,7 +5047,7 @@
<target state="translated">Valute</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -6225,11 +6229,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6686,7 +6690,7 @@
<target state="translated">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7044,6 +7048,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7274,7 +7282,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7696,7 +7704,7 @@
<target state="translated">L’AI prompt è stato copiato negli appunti</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7776,7 +7784,7 @@
<target state="translated">Apri Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8013,7 +8021,7 @@
<target state="translated">Raccogli dati storici di mercato recenti</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8021,7 +8029,7 @@
<target state="translated">Raccogli tutti i dati storici di mercato</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8359,14 +8367,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">nuovo</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Investimento</target>

76
apps/client/src/locales/messages.ja.xlf

@ -532,7 +532,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -556,7 +556,7 @@
<target state="translated">削除</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -796,7 +796,7 @@
<target state="translated">通貨</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -816,7 +816,7 @@
<target state="translated">国に縛られないETF</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -824,7 +824,7 @@
<target state="translated">セクター別ではないETF</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="6786981261778452561" datatype="html">
@ -844,7 +844,7 @@
<target state="translated">絞り込み...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -880,7 +880,7 @@
<target state="translated">アクティビティ数</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -888,7 +888,7 @@
<target state="translated">過去データ</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -900,7 +900,7 @@
<target state="translated">セクター数</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -924,7 +924,7 @@
<target state="translated">国の数</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="4396995010887588291" datatype="html">
@ -932,7 +932,7 @@
<target state="translated">直近の市場実績データを収集する</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -940,7 +940,7 @@
<target state="translated">すべての過去の市場データを収集する</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -948,7 +948,7 @@
<target state="translated">プロファイルデータを収集する</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1664,7 +1664,7 @@
<target state="translated">恐怖</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1680,7 +1680,7 @@
<target state="new">Greed</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2694,10 +2694,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">オッケー</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -3151,6 +3147,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="translated">持続時間</target>
@ -4440,7 +4444,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -4468,7 +4472,7 @@
<target state="translated">毎月</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
@ -4476,7 +4480,7 @@
<target state="translated">年次</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -5413,7 +5417,7 @@
<target state="translated">{VAR_PLURAL, plural, =1 {プロフィール} other {プロフィール}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
@ -5741,7 +5745,7 @@
<target state="translated">アクティビティなし</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -6273,11 +6277,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6710,7 +6714,7 @@
<target state="new">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="7798195225890418363" datatype="html">
@ -7060,6 +7064,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7298,7 +7306,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7720,7 +7728,7 @@
<target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7800,7 +7808,7 @@
<target state="new">Open Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8359,14 +8367,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="new">new</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="new">Investment</target>

170
apps/client/src/locales/messages.ko.xlf

@ -433,7 +433,7 @@
</trans-unit>
<trans-unit id="4323470180912194028" datatype="html">
<source>Copy</source>
<target state="new">Copy</target>
<target state="translated">복사</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/notifications/alert-dialog/alert-dialog.html</context>
<context context-type="linenumber">20</context>
@ -532,7 +532,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -556,7 +556,7 @@
<target state="translated">삭제</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -605,7 +605,7 @@
</trans-unit>
<trans-unit id="8282940047848889809" datatype="html">
<source>Paid</source>
<target state="new">Paid</target>
<target state="translated">유료</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts</context>
<context context-type="linenumber">122</context>
@ -693,7 +693,7 @@
</trans-unit>
<trans-unit id="5611965261696422586" datatype="html">
<source>and is driven by the efforts of its <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio/graphs/contributors&quot; i18n-title title=&quot;Contributors to Ghostfolio&quot; &gt;"/>contributors<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></source>
<target state="new"><x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio/graphs/contributors&quot; title=&quot;Contributors to Ghostfolio&quot; &gt;"/>기여자<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>들의 노력으로 발전하고 있습니다</target>
<target state="translated"><x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio/graphs/contributors&quot; title=&quot;Contributors to Ghostfolio&quot; &gt;"/>기여자<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>들의 노력으로 발전하고 있습니다</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">50</context>
@ -769,7 +769,7 @@
</trans-unit>
<trans-unit id="8410000928786197012" datatype="html">
<source>Watch the Ghostfol.io Trailer on YouTube</source>
<target state="new">Watch the Ghostfol.io Trailer on YouTube</target>
<target state="translated">YouTube에서 Ghostfol.io 트레일러 보기</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
<context context-type="linenumber">19</context>
@ -796,7 +796,7 @@
<target state="translated">통화</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -805,7 +805,7 @@
</trans-unit>
<trans-unit id="1806667489382256324" datatype="html">
<source>Category</source>
<target state="new">Category</target>
<target state="translated">카테고리</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.html</context>
<context context-type="linenumber">77</context>
@ -816,7 +816,7 @@
<target state="translated">국가 정보 없는 ETF</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -824,7 +824,7 @@
<target state="translated">섹터 정보 없는 ETF</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="6786981261778452561" datatype="html">
@ -844,7 +844,7 @@
<target state="translated">다음 기준으로 필터...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -869,7 +869,7 @@
</trans-unit>
<trans-unit id="6418462810730461014" datatype="html">
<source>Data Gathering Frequency</source>
<target state="new">Data Gathering Frequency</target>
<target state="translated">데이터 수집 빈도</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
<context context-type="linenumber">454</context>
@ -880,7 +880,7 @@
<target state="translated">거래 건수</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -888,7 +888,7 @@
<target state="translated">과거 데이터</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -900,7 +900,7 @@
<target state="translated">섹터 수</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -913,7 +913,7 @@
</trans-unit>
<trans-unit id="6135731497699355929" datatype="html">
<source>Subscription History</source>
<target state="new">Subscription History</target>
<target state="translated">구독 내역</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">136</context>
@ -924,7 +924,7 @@
<target state="translated">국가 수</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="4396995010887588291" datatype="html">
@ -932,7 +932,7 @@
<target state="translated">최근 과거 시장 데이터 수집</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -940,7 +940,7 @@
<target state="translated">전체 과거 시장 데이터 수집</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -948,7 +948,7 @@
<target state="translated">프로필 데이터 수집</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1097,7 +1097,7 @@
</trans-unit>
<trans-unit id="5915287617703658226" datatype="html">
<source>Total</source>
<target state="new">Total</target>
<target state="translated">합계</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">155</context>
@ -1664,7 +1664,7 @@
<target state="translated">두려움</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1680,7 +1680,7 @@
<target state="translated">탐욕</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1721,7 +1721,7 @@
</trans-unit>
<trans-unit id="5289957034780335504" datatype="html">
<source>The source code is fully available as <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; i18n-title title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) under the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 license<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></source>
<target state="new">소스 코드는 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>오픈 소스 소프트웨어<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>로 완전히 공개되어 있으며, <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 라이선스<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> 하에 제공됩니다</target>
<target state="translated">소스 코드는 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>오픈 소스 소프트웨어<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>로 완전히 공개되어 있으며, <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 라이선스<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> 하에 제공됩니다</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">16</context>
@ -2293,7 +2293,7 @@
</trans-unit>
<trans-unit id="8793726805339626615" datatype="html">
<source>Ghostfolio in Numbers: Monthly Active Users (MAU)</source>
<target state="new">Ghostfolio in Numbers: Monthly Active Users (MAU)</target>
<target state="translated">Ghostfolio 통계: 월간 활성 사용자 수(MAU)</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
<context context-type="linenumber">63</context>
@ -2333,7 +2333,7 @@
</trans-unit>
<trans-unit id="4037247308022519888" datatype="html">
<source>The value has been copied to the clipboard</source>
<target state="new">The value has been copied to the clipboard</target>
<target state="translated">값이 클립보드에 복사되었습니다.</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/notifications/alert-dialog/alert-dialog.component.ts</context>
<context context-type="linenumber">46</context>
@ -2493,7 +2493,7 @@
</trans-unit>
<trans-unit id="5463045633785723738" datatype="html">
<source>Coupon</source>
<target state="new">Coupon</target>
<target state="translated">쿠폰</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts</context>
<context context-type="linenumber">127</context>
@ -2529,7 +2529,7 @@
</trans-unit>
<trans-unit id="8664947843178872012" datatype="html">
<source>Close Account</source>
<target state="new">Close Account</target>
<target state="translated">계정 폐쇄</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.html</context>
<context context-type="linenumber">337</context>
@ -2549,7 +2549,7 @@
</trans-unit>
<trans-unit id="4102764207131986196" datatype="html">
<source>Contributors to Ghostfolio</source>
<target state="new">Contributors to Ghostfolio</target>
<target state="translated">Ghostfolio의 기여자</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">54</context>
@ -2694,10 +2694,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">좋아요</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -2889,7 +2885,7 @@
</trans-unit>
<trans-unit id="8643034887919513109" datatype="html">
<source>Financial Planning</source>
<target state="new">Financial Planning</target>
<target state="translated">재무 설계</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">108</context>
@ -3151,6 +3147,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="translated">기간</target>
@ -3217,7 +3221,7 @@
</trans-unit>
<trans-unit id="4489207161748215824" datatype="html">
<source>For security reasons, please delete all activities and accounts first before your Ghostfolio account can be closed.</source>
<target state="new">For security reasons, please delete all activities and accounts first before your Ghostfolio account can be closed.</target>
<target state="translated">보안을 위해 Ghostfolio 계정을 폐쇄하려면 먼저 모든 거래 내역과 계좌를 삭제해 주세요.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.html</context>
<context context-type="linenumber">348</context>
@ -3345,7 +3349,7 @@
</trans-unit>
<trans-unit id="2047393478951255414" datatype="html">
<source>Creation</source>
<target state="new">Creation</target>
<target state="translated">생성</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">185</context>
@ -3385,7 +3389,7 @@
</trans-unit>
<trans-unit id="4733690367258997247" datatype="html">
<source>just now</source>
<target state="new">just now</target>
<target state="translated">방금 전</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.component.ts</context>
<context context-type="linenumber">217</context>
@ -3709,7 +3713,7 @@
</trans-unit>
<trans-unit id="2756436642316668410" datatype="html">
<source>Oops! Could not delete the asset profiles.</source>
<target state="new">Oops! Could not delete the asset profiles.</target>
<target state="translated">이런! 자산 프로필을 삭제할 수 없습니다.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.service.ts</context>
<context context-type="linenumber">52</context>
@ -3797,7 +3801,7 @@
</trans-unit>
<trans-unit id="3824165347269033834" datatype="html">
<source>At Ghostfolio, transparency is at the core of our values. We publish the source code as <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; i18n-title title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) under the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 license<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> and we openly share aggregated key metrics of the platform’s operational status.</source>
<target state="new">Ghostfolio는 투명성을 핵심 가치로 삼습니다. 우리는 소스 코드를 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>오픈 소스 소프트웨어<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>로 공개하며, <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 라이선스<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> 하에 배포합니다. 또한 플랫폼 운영 현황에 대한 집계된 핵심 지표를 공개적으로 공유합니다.</target>
<target state="translated">Ghostfolio는 투명성을 핵심 가치로 삼습니다. 우리는 소스 코드를 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>오픈 소스 소프트웨어<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>로 공개하며, <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 라이선스<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> 하에 배포합니다. 또한 플랫폼 운영 현황에 대한 집계된 핵심 지표를 공개적으로 공유합니다.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
<context context-type="linenumber">7</context>
@ -3893,7 +3897,7 @@
</trans-unit>
<trans-unit id="6075566839446502414" datatype="html">
<source>Available on</source>
<target state="new">Available on</target>
<target state="translated">이용 가능 플랫폼</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.html</context>
<context context-type="linenumber">130</context>
@ -4201,7 +4205,7 @@
</trans-unit>
<trans-unit id="8894377483833272091" datatype="html">
<source>Price</source>
<target state="new">Price</target>
<target state="translated">가격</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">171</context>
@ -4301,7 +4305,7 @@
</trans-unit>
<trans-unit id="6999515396807067782" datatype="html">
<source>Trial</source>
<target state="new">Trial</target>
<target state="translated">체험판</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.component.ts</context>
<context context-type="linenumber">126</context>
@ -4432,7 +4436,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -4460,7 +4464,7 @@
<target state="translated">월간</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
@ -4468,7 +4472,7 @@
<target state="translated">매년</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -4609,7 +4613,7 @@
</trans-unit>
<trans-unit id="2640607428459636406" datatype="html">
<source>Hourly</source>
<target state="new">Hourly</target>
<target state="translated">매시간</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts</context>
<context context-type="linenumber">214</context>
@ -4721,7 +4725,7 @@
</trans-unit>
<trans-unit id="3323137014509063489" datatype="html">
<source>Expiration</source>
<target state="new">Expiration</target>
<target state="translated">만료</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">204</context>
@ -5030,7 +5034,7 @@
</trans-unit>
<trans-unit id="237127378624497814" datatype="html">
<source>Upgrade to Ghostfolio Premium</source>
<target state="new">Upgrade to Ghostfolio Premium</target>
<target state="translated">Ghostfolio 프리미엄으로 업그레이드</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/premium-indicator/premium-indicator.component.html</context>
<context context-type="linenumber">4</context>
@ -5118,7 +5122,7 @@
</trans-unit>
<trans-unit id="2191562378582791940" datatype="html">
<source>Stock Tracking</source>
<target state="new">Stock Tracking</target>
<target state="translated">주식 추적</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">111</context>
@ -5142,7 +5146,7 @@
</trans-unit>
<trans-unit id="9167786874272926575" datatype="html">
<source>Web</source>
<target state="new">Web</target>
<target state="translated">웹</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">120</context>
@ -5338,7 +5342,7 @@
</trans-unit>
<trans-unit id="9028573429495160158" datatype="html">
<source>Portfolio Filters</source>
<target state="new">Portfolio Filters</target>
<target state="translated">포트폴리오 필터</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">63</context>
@ -5402,10 +5406,10 @@
</trans-unit>
<trans-unit id="1541521390115871091" datatype="html">
<source>{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</source>
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<target state="translated">{VAR_PLURAL, plural, =1 {프로필} other {프로필}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
@ -5714,7 +5718,7 @@
</trans-unit>
<trans-unit id="6300009182465422833" datatype="html">
<source>Ghostfolio in Numbers: Pulls on Docker Hub</source>
<target state="new">Ghostfolio in Numbers: Pulls on Docker Hub</target>
<target state="translated">Ghostfolio 통계: Docker Hub 다운로드 수</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
<context context-type="linenumber">101</context>
@ -5733,7 +5737,7 @@
<target state="translated">거래 내역 없음</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -6273,11 +6277,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6346,7 +6350,7 @@
</trans-unit>
<trans-unit id="3995811497329884593" datatype="html">
<source>Expires <x id="INTERPOLATION" equiv-text="{{ formatDistanceToNow(element.subscription.expiresAt) }}"/> (<x id="INTERPOLATION_1" equiv-text="{{ element.subscription.expiresAt | date: defaultDateFormat }}"/>)</source>
<target state="new">Expires <x id="INTERPOLATION" equiv-text="{{ formatDistanceToNow(element.subscription.expiresAt) }}"/> (<x id="INTERPOLATION_1" equiv-text="{{ element.subscription.expiresAt | date: defaultDateFormat }}"/>)</target>
<target state="translated"><x id="INTERPOLATION" equiv-text="{{ formatDistanceToNow(element.subscription.expiresAt) }}"/> 만료 (<x id="INTERPOLATION_1" equiv-text="{{ element.subscription.expiresAt | date: defaultDateFormat }}"/>)</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-users/admin-users.html</context>
<context context-type="linenumber">34</context>
@ -6507,7 +6511,7 @@
</trans-unit>
<trans-unit id="2988589012964101797" datatype="html">
<source>Daily</source>
<target state="new">Daily</target>
<target state="translated">매일</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts</context>
<context context-type="linenumber">210</context>
@ -6710,7 +6714,7 @@
<target state="translated">벤치마크</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="7798195225890418363" datatype="html">
@ -6807,7 +6811,7 @@
</trans-unit>
<trans-unit id="1284643802050750978" datatype="html">
<source>Oops! Could not delete the asset profile.</source>
<target state="new">Oops! Could not delete the asset profile.</target>
<target state="translated">이런! 자산 프로필을 삭제할 수 없습니다.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.service.ts</context>
<context context-type="linenumber">51</context>
@ -6927,7 +6931,7 @@
</trans-unit>
<trans-unit id="1518717392874668219" datatype="html">
<source>Do you really want to delete these <x id="count" equiv-text="assetProfileCount"/> asset profiles?</source>
<target state="new">Do you really want to delete these <x id="count" equiv-text="assetProfileCount"/> asset profiles?</target>
<target state="translated">이 <x id="count" equiv-text="assetProfileCount"/>개의 자산 프로필을 정말 삭제하시겠습니까?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.service.ts</context>
<context context-type="linenumber">67</context>
@ -7060,6 +7064,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7151,7 +7159,7 @@
</trans-unit>
<trans-unit id="6608617124920241143" datatype="html">
<source><x id="START_BLOCK_IF" equiv-text="@if ( assetProfile?.currency &amp;&amp; data.baseCurrency !== assetProfile?.currency ) {"/> Performance with currency effect <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> Performance <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></source>
<target state="new"><x id="START_BLOCK_IF" equiv-text="@if ( SymbolProfile?.currency &amp;&amp; data.baseCurrency !== SymbolProfile?.currency ) {"/> 환율 효과 반영 수익률 <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> 수익률 <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></target>
<target state="translated"><x id="START_BLOCK_IF" equiv-text="@if ( assetProfile?.currency &amp;&amp; data.baseCurrency !== assetProfile?.currency ) {"/> 환율 효과 반영 수익률 <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> 수익률 <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">83</context>
@ -7167,7 +7175,7 @@
</trans-unit>
<trans-unit id="6586833258036069278" datatype="html">
<source>Tax Reporting</source>
<target state="new">Tax Reporting</target>
<target state="translated">세금 보고</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">112</context>
@ -7175,7 +7183,7 @@
</trans-unit>
<trans-unit id="8375528527939577247" datatype="html">
<source><x id="START_BLOCK_IF" equiv-text="@if ( assetProfile?.currency &amp;&amp; data.baseCurrency !== assetProfile?.currency ) {"/> Change with currency effect <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> Change <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></source>
<target state="new"><x id="START_BLOCK_IF" equiv-text="@if ( SymbolProfile?.currency &amp;&amp; data.baseCurrency !== SymbolProfile?.currency ) {"/> 환율 효과 반영 변동 <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> 변동 <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></target>
<target state="translated"><x id="START_BLOCK_IF" equiv-text="@if ( assetProfile?.currency &amp;&amp; data.baseCurrency !== assetProfile?.currency ) {"/> 환율 효과 반영 변동 <x id="CLOSE_BLOCK_IF" equiv-text="}"/><x id="START_BLOCK_ELSE" equiv-text="@else {"/> 변동 <x id="CLOSE_BLOCK_ELSE" equiv-text="}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html</context>
<context context-type="linenumber">63</context>
@ -7191,7 +7199,7 @@
</trans-unit>
<trans-unit id="6389025757025171607" datatype="html">
<source>Compare Ghostfolio to <x id="INTERPOLATION" equiv-text="{{ personalFinanceTool.name }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ personalFinanceTool.slogan }}"/></source>
<target state="new">Compare Ghostfolio to <x id="INTERPOLATION" equiv-text="{{ personalFinanceTool.name }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ personalFinanceTool.slogan }}"/></target>
<target state="translated">Ghostfolio와 <x id="INTERPOLATION" equiv-text="{{ personalFinanceTool.name }}"/> 비교 - <x id="INTERPOLATION_1" equiv-text="{{ personalFinanceTool.slogan }}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html</context>
<context context-type="linenumber">32</context>
@ -7231,7 +7239,7 @@
</trans-unit>
<trans-unit id="3527222903865200876" datatype="html">
<source>Dividend Tracking</source>
<target state="new">Dividend Tracking</target>
<target state="translated">배당 추적</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">105</context>
@ -7295,10 +7303,10 @@
</trans-unit>
<trans-unit id="7547813413369998179" datatype="html">
<source>Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></source>
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<target state="translated"><x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/> 삭제</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7411,7 +7419,7 @@
</trans-unit>
<trans-unit id="1550367033316836764" datatype="html">
<source>Investment Research</source>
<target state="new">Investment Research</target>
<target state="translated">투자 리서치</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">109</context>
@ -7693,7 +7701,7 @@
</trans-unit>
<trans-unit id="4060547242431613838" datatype="html">
<source>Net Worth Tracking</source>
<target state="new">Net Worth Tracking</target>
<target state="translated">순자산 추적</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">110</context>
@ -7720,7 +7728,7 @@
<target state="translated">AI 프롬프트가 클립보드에 복사되었습니다.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7800,7 +7808,7 @@
<target state="translated">오픈 Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -7825,7 +7833,7 @@
</trans-unit>
<trans-unit id="1237494164624005096" datatype="html">
<source>Ghostfolio in Numbers: Stars on GitHub</source>
<target state="new">Ghostfolio in Numbers: Stars on GitHub</target>
<target state="translated">Ghostfolio 통계: GitHub 스타 수</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
<context context-type="linenumber">82</context>
@ -8131,7 +8139,7 @@
</trans-unit>
<trans-unit id="3910789128199500333" datatype="html">
<source>ETF Tracking</source>
<target state="new">ETF Tracking</target>
<target state="translated">ETF 추적</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">106</context>
@ -8297,7 +8305,7 @@
</trans-unit>
<trans-unit id="2813837590488774096" datatype="html">
<source>Post to Ghostfolio on X (formerly Twitter)</source>
<target state="new">Post to Ghostfolio on X (formerly Twitter)</target>
<target state="translated">X(이전의 Twitter)에서 Ghostfolio에 게시하세요.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">85</context>
@ -8359,14 +8367,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">새로운</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">투자</target>
@ -8526,7 +8526,7 @@
</trans-unit>
<trans-unit id="5199695670214400859" datatype="html">
<source>If you encounter a bug, would like to suggest an improvement or a new <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkFeatures&quot;&gt;"/>feature<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>, please join the Ghostfolio <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg&quot; i18n-title title=&quot;Join the Ghostfolio Slack community&quot; &gt;"/>Slack<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> community, post to <x id="START_LINK_2" equiv-text="&lt;a href=&quot;https://x.com/ghostfolio_&quot; i18n-title title=&quot;Post to Ghostfolio on X (formerly Twitter)&quot; &gt;"/>@ghostfolio_<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></source>
<target state="new">버그가 발생하거나 개선 사항이나 새로운 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkFeatures&quot;&gt;"/>기능<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>을 제안하고 싶다면 Ghostfolio <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg&quot; title=&quot;Join the Ghostfolio Slack community&quot; &gt;"/>슬랙<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> 커뮤니티에 가입하고 <x id="START_LINK_2" equiv-text="&lt;a href=&quot;https://x.com/ghostfolio_&quot; title=&quot;Post to Ghostfolio on X (formerly Twitter)&quot; &gt;"/>@ghostfolio_<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>에 게시하세요.</target>
<target state="translated">버그가 발생하거나 개선 사항이나 새로운 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkFeatures&quot;&gt;"/>기능<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>을 제안하고 싶다면 Ghostfolio <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg&quot; title=&quot;Join the Ghostfolio Slack community&quot; &gt;"/>슬랙<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> 커뮤니티에 가입하고 <x id="START_LINK_2" equiv-text="&lt;a href=&quot;https://x.com/ghostfolio_&quot; title=&quot;Post to Ghostfolio on X (formerly Twitter)&quot; &gt;"/>@ghostfolio_<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>에 게시하세요.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">71</context>

102
apps/client/src/locales/messages.nl.xlf

@ -238,7 +238,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -262,7 +262,7 @@
<target state="translated">Verwijderen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -451,7 +451,7 @@
</trans-unit>
<trans-unit id="3973560112150137298" datatype="html">
<source>Find an account...</source>
<target state="new">Find an account...</target>
<target state="translated">Zoek een account...</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/assistant/assistant.component.ts</context>
<context context-type="linenumber">447</context>
@ -526,7 +526,7 @@
<target state="translated">Historische gegevens</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -570,7 +570,7 @@
<target state="translated">Verzamel profielgegevens</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1172,10 +1172,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">Oké</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -1419,7 +1415,7 @@
</trans-unit>
<trans-unit id="4037247308022519888" datatype="html">
<source>The value has been copied to the clipboard</source>
<target state="new">The value has been copied to the clipboard</target>
<target state="translated">De waarde is naar het klembord gekopieerd</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/notifications/alert-dialog/alert-dialog.component.ts</context>
<context context-type="linenumber">46</context>
@ -1503,7 +1499,7 @@
</trans-unit>
<trans-unit id="4323470180912194028" datatype="html">
<source>Copy</source>
<target state="new">Copy</target>
<target state="translated">Kopiëren</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/notifications/alert-dialog/alert-dialog.html</context>
<context context-type="linenumber">20</context>
@ -1725,6 +1721,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="translated">populair</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="translated">Looptijd</target>
@ -2490,7 +2494,7 @@
<target state="translated">{VAR_PLURAL, plural, =1 {Profiel} other {Profielen}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="2893955285486651896" datatype="html">
@ -2714,7 +2718,7 @@
<target state="translated">Maandelijks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="6130372166370766747" datatype="html">
@ -2722,7 +2726,7 @@
<target state="translated">Aantal sectoren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -2746,7 +2750,7 @@
<target state="translated">Aantal landen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5486880308148746399" datatype="html">
@ -2754,7 +2758,7 @@
<target state="translated">Angst</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2770,7 +2774,7 @@
<target state="translated">Hebzucht</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2786,7 +2790,7 @@
<target state="translated">Filter op...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="5342721262799645301" datatype="html">
@ -2879,7 +2883,7 @@
</trans-unit>
<trans-unit id="8664947843178872012" datatype="html">
<source>Close Account</source>
<target state="new">Close Account</target>
<target state="translated">Account Sluiten</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.html</context>
<context context-type="linenumber">337</context>
@ -3326,7 +3330,7 @@
<target state="translated">Aantal activiteiten</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="1102717806459547726" datatype="html">
@ -3378,7 +3382,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -3522,7 +3526,7 @@
<target state="translated">Jaarlijks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="72640258012696878" datatype="html">
@ -3590,7 +3594,7 @@
<target state="translated">Geen activiteiten</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -4399,7 +4403,7 @@
</trans-unit>
<trans-unit id="4489207161748215824" datatype="html">
<source>For security reasons, please delete all activities and accounts first before your Ghostfolio account can be closed.</source>
<target state="new">For security reasons, please delete all activities and accounts first before your Ghostfolio account can be closed.</target>
<target state="translated">Verwijder om veiligheidsredenen eerst alle activiteiten en rekeningen voordat uw Ghostfolio account kan worden gesloten.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-settings/user-account-settings.html</context>
<context context-type="linenumber">348</context>
@ -4798,7 +4802,7 @@
<target state="translated">ETF’s zonder Landen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -4806,7 +4810,7 @@
<target state="translated">ETF’s zonder Sectoren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="1647750822609779679" datatype="html">
@ -4859,7 +4863,7 @@
</trans-unit>
<trans-unit id="5289957034780335504" datatype="html">
<source>The source code is fully available as <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; i18n-title title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) under the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 license<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></source>
<target state="new">De broncode is volledig beschikbaar als <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) onder de <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0-licentie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></target>
<target state="translated">De broncode is volledig beschikbaar als <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; i18n-title title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) onder de <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0-licentie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">16</context>
@ -4947,7 +4951,7 @@
</trans-unit>
<trans-unit id="3824165347269033834" datatype="html">
<source>At Ghostfolio, transparency is at the core of our values. We publish the source code as <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; i18n-title title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) under the <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 license<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> and we openly share aggregated key metrics of the platform’s operational status.</source>
<target state="new">Bij Ghostfolio is transparantie één van onze kernwaarden. We publiceren de broncode als <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) onder de <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 licentie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> en we delen openlijk geaggregeerde kerncijfers van de operationele status van het platform.</target>
<target state="translated">Bij Ghostfolio is transparantie één van onze kernwaarden. We publiceren de broncode als <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;https://github.com/ghostfolio/ghostfolio&quot; i18n-title title=&quot;Find Ghostfolio on GitHub&quot; &gt;"/>open source software<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> (OSS) onder de <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.html&quot; title=&quot;GNU Affero General Public License&quot; &gt;"/>AGPL-3.0 licentie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> en we delen openlijk geaggregeerde kerncijfers van de operationele status van het platform.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
<context context-type="linenumber">7</context>
@ -5042,7 +5046,7 @@
<target state="translated">Valuta</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -6224,11 +6228,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6685,7 +6689,7 @@
<target state="translated">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7043,6 +7047,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7086,7 +7094,7 @@
</trans-unit>
<trans-unit id="6586833258036069278" datatype="html">
<source>Tax Reporting</source>
<target state="new">Tax Reporting</target>
<target state="translated">Belastingrapportage</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">112</context>
@ -7210,7 +7218,7 @@
</trans-unit>
<trans-unit id="2137905359212133111" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ product1().name }}"/> is Open Source Software</source>
<target state="new"><x id="INTERPOLATION" equiv-text="{{ product1().name }}"/> is Open Source Software</target>
<target state="translated"><x id="INTERPOLATION" equiv-text="{{ product1().name }}"/> is open source software</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.html</context>
<context context-type="linenumber">183</context>
@ -7250,7 +7258,7 @@
</trans-unit>
<trans-unit id="7522916136412124285" datatype="html">
<source>to use our referral link and get a Ghostfolio Premium membership for one year</source>
<target state="new">to use our referral link and get a Ghostfolio Premium membership for one year</target>
<target state="translated">om onze referral link te gebruiken en een jaar lang Ghostfolio Premium-lidmaatschap te krijgen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/pricing/pricing-page.html</context>
<context context-type="linenumber">340</context>
@ -7273,7 +7281,7 @@
<target state="translated">Verwijder <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7668,7 +7676,7 @@
</trans-unit>
<trans-unit id="4060547242431613838" datatype="html">
<source>Net Worth Tracking</source>
<target state="new">Net Worth Tracking</target>
<target state="translated">Netto waarde volgen</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">110</context>
@ -7695,7 +7703,7 @@
<target state="translated">AI-prompt is naar het klembord gekopieerd</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7775,7 +7783,7 @@
<target state="translated">Open Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8012,7 +8020,7 @@
<target state="translated">Verzamel Recente Marktgegevens</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8020,7 +8028,7 @@
<target state="translated">Verzamel Alle Marktgegevens</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8288,7 +8296,7 @@
</trans-unit>
<trans-unit id="2813837590488774096" datatype="html">
<source>Post to Ghostfolio on X (formerly Twitter)</source>
<target state="new">Post to Ghostfolio on X (formerly Twitter)</target>
<target state="translated">Post naar Ghostfolio op X (voorheen Twitter)</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">85</context>
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">nieuw</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Investering</target>
@ -8533,7 +8533,7 @@
</trans-unit>
<trans-unit id="5199695670214400859" datatype="html">
<source>If you encounter a bug, would like to suggest an improvement or a new <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkFeatures&quot;&gt;"/>feature<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>, please join the Ghostfolio <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg&quot; i18n-title title=&quot;Join the Ghostfolio Slack community&quot; &gt;"/>Slack<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> community, post to <x id="START_LINK_2" equiv-text="&lt;a href=&quot;https://x.com/ghostfolio_&quot; i18n-title title=&quot;Post to Ghostfolio on X (formerly Twitter)&quot; &gt;"/>@ghostfolio_<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></source>
<target state="new">Als je een bug tegenkomt, een verbetering wilt voorstellen of een nieuwe <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkFeatures&quot;&gt;"/>functie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> wilt toevoegen, word dan lid van de Ghostfolio <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg&quot; title=&quot;Join the Ghostfolio Slack community&quot; &gt;"/>Slack-community<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>. Stuur een bericht naar <x id="START_LINK_2" equiv-text="&lt;a href=&quot;https://x.com/ghostfolio_&quot; title=&quot;Post to Ghostfolio on X (formerly Twitter)&quot; &gt;"/>@ghostfolio_<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></target>
<target state="translated">Als je een bug tegenkomt, een verbetering wilt voorstellen of een nieuwe <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkFeatures&quot;&gt;"/>functie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/> wilt toevoegen, word dan lid van de Ghostfolio <x id="START_LINK_1" equiv-text="&lt;a href=&quot;https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg&quot; i18n-title title=&quot;Join the Ghostfolio Slack community&quot; &gt;"/>Slack-community<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/>. Stuur een bericht naar <x id="START_LINK_2" equiv-text="&lt;a href=&quot;https://x.com/ghostfolio_&quot; i18n-title title=&quot;Post to Ghostfolio on X (formerly Twitter)&quot; &gt;"/>@ghostfolio_<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a &gt;"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/overview/about-overview-page.html</context>
<context context-type="linenumber">71</context>

76
apps/client/src/locales/messages.pl.xlf

@ -523,7 +523,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -547,7 +547,7 @@
<target state="translated">Usuń</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -787,7 +787,7 @@
<target state="translated">Waluty</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -807,7 +807,7 @@
<target state="translated">ETF-y bez Krajów</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -815,7 +815,7 @@
<target state="translated">ETF-y bez Sektorów</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="6786981261778452561" datatype="html">
@ -835,7 +835,7 @@
<target state="translated">Filtruj według...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -871,7 +871,7 @@
<target state="translated">Liczba Aktywności</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -879,7 +879,7 @@
<target state="translated">Dane Historyczne</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -891,7 +891,7 @@
<target state="translated">Liczba Sektorów</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -915,7 +915,7 @@
<target state="translated">Liczba Krajów</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -923,7 +923,7 @@
<target state="translated">Zbierz Dane Profilu</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1631,7 +1631,7 @@
<target state="translated">Zagrożenie</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1647,7 +1647,7 @@
<target state="translated">Zachłanność</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2661,10 +2661,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">Okej</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -3118,6 +3114,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="new">Duration</target>
@ -4399,7 +4403,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -4427,7 +4431,7 @@
<target state="translated">Miesięcznie</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
@ -4435,7 +4439,7 @@
<target state="translated">Rocznie</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -5328,7 +5332,7 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
@ -5656,7 +5660,7 @@
<target state="translated">Brak transakcji</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -6224,11 +6228,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6685,7 +6689,7 @@
<target state="translated">Punkty Odniesienia</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7043,6 +7047,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7273,7 +7281,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7695,7 +7703,7 @@
<target state="translated">Prompt AI został skopiowany do schowka</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7775,7 +7783,7 @@
<target state="translated">Otwórz Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8012,7 +8020,7 @@
<target state="translated">Zbierz najnowsze historyczne dane rynkowe</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8020,7 +8028,7 @@
<target state="translated">Zbierz wszystkie historyczne dane rynkowe</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">nowy</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Inwestycja</target>

76
apps/client/src/locales/messages.pt.xlf

@ -302,7 +302,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -326,7 +326,7 @@
<target state="translated">Eliminar</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -570,7 +570,7 @@
<target state="translated">Filtrar por...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -598,7 +598,7 @@
<target state="translated">Dados Históricos</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -610,7 +610,7 @@
<target state="translated">Contagem de Países</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="6130372166370766747" datatype="html">
@ -618,7 +618,7 @@
<target state="translated">Contagem de Setores</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -642,7 +642,7 @@
<target state="translated">Recolher Dados de Perfíl</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -930,7 +930,7 @@
<target state="translated">Medo</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -946,7 +946,7 @@
<target state="translated">Ganância</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1472,10 +1472,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">OK</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -2037,6 +2033,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="new">Duration</target>
@ -2550,7 +2554,7 @@
<target state="translated">Mensalmente</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -2938,7 +2942,7 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="2893955285486651896" datatype="html">
@ -3338,7 +3342,7 @@
<target state="translated">Nº de Atividades</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="1102717806459547726" datatype="html">
@ -3454,7 +3458,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -3522,7 +3526,7 @@
<target state="translated">Anualmente</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="72640258012696878" datatype="html">
@ -3590,7 +3594,7 @@
<target state="new">No Activities</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -4798,7 +4802,7 @@
<target state="translated">ETFs sem países</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -4806,7 +4810,7 @@
<target state="translated">ETFs sem setores</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="1647750822609779679" datatype="html">
@ -5042,7 +5046,7 @@
<target state="translated">Moedas</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -6224,11 +6228,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6685,7 +6689,7 @@
<target state="translated">Referências</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7043,6 +7047,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7273,7 +7281,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7695,7 +7703,7 @@
<target state="new">AI prompt has been copied to the clipboard</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7775,7 +7783,7 @@
<target state="new">Open Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8012,7 +8020,7 @@
<target state="new">Gather Recent Historical Market Data</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8020,7 +8028,7 @@
<target state="new">Gather All Historical Market Data</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="new">new</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="new">Investment</target>

80
apps/client/src/locales/messages.tr.xlf

@ -483,7 +483,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -507,7 +507,7 @@
<target state="translated">Sil</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -751,7 +751,7 @@
<target state="translated">Para Birimleri</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -771,7 +771,7 @@
<target state="translated">Ülkesi Olmayan ETF’ler</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -779,7 +779,7 @@
<target state="translated">Sektörü Olmayan ETF’ler</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
@ -787,7 +787,7 @@
<target state="translated">Filtrele...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -823,7 +823,7 @@
<target state="translated">İşlem Sayısı</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -831,7 +831,7 @@
<target state="translated">Tarihsel Veri</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -843,7 +843,7 @@
<target state="translated">Sektör Sayısı</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -867,7 +867,7 @@
<target state="translated">Ülke Sayısı</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -875,7 +875,7 @@
<target state="translated">Profil Verisini Getir</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1479,7 +1479,7 @@
<target state="translated">Korku</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1495,7 +1495,7 @@
<target state="translated">Açgözlülük</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2096,7 +2096,7 @@
</trans-unit>
<trans-unit id="8768104874317770689" datatype="html">
<source>1Y</source>
<target state="trasnlated">1Y</target>
<target state="translated">1Y</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts</context>
<context context-type="linenumber">232</context>
@ -2185,10 +2185,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">Tamam</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -2610,6 +2606,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="new">Duration</target>
@ -3803,7 +3807,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -3831,7 +3835,7 @@
<target state="translated">Aylık</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
@ -3839,7 +3843,7 @@
<target state="translated">Yıllık</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -4269,7 +4273,7 @@
</trans-unit>
<trans-unit id="9040028765832531851" datatype="html">
<source>This overview page features a curated collection of personal finance tools compared to the open source alternative <x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkAbout&quot;&gt;"/>Ghostfolio<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management.</source>
<target state="translatedew">Bu genel bakış sayfası, diğer kişisel finans araçlarının seçilmiş bir koleksiyonunun açık kaynak alternatifi<x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkAbout&quot;&gt;"/>Ghostfolio ile karşılaştırmasını sunmaktadır.<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>. Şeffaflığa, veri gizliliğine ve topluluk işbirliğine değer veriyorsanız Ghostfolio, finansal yönetiminizin kontrolünü ele almak için mükemmel Şeffaflığa, veri gizliliğine ve topluluk işbirliğine değer veriyorsanız Ghostfolio, finansal yönetiminizin kontrolünü ele almak için mükemmel bir fırsat sunuyor.</target>
<target state="translated">Bu genel bakış sayfası, diğer kişisel finans araçlarının seçilmiş bir koleksiyonunun açık kaynak alternatifi<x id="START_LINK" ctype="x-a" equiv-text="&lt;a [routerLink]=&quot;routerLinkAbout&quot;&gt;"/>Ghostfolio ile karşılaştırmasını sunmaktadır.<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>. Şeffaflığa, veri gizliliğine ve topluluk işbirliğine değer veriyorsanız Ghostfolio, finansal yönetiminizin kontrolünü ele almak için mükemmel bir fırsat sunuyor.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html</context>
<context context-type="linenumber">9</context>
@ -4996,7 +5000,7 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
@ -5324,7 +5328,7 @@
<target state="new">No Activities</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -6224,11 +6228,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6685,7 +6689,7 @@
<target state="translated">Kıyaslamalar</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7043,6 +7047,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7273,7 +7281,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7695,7 +7703,7 @@
<target state="translated">Yapay zeka istemi panoya kopyalandı</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7775,7 +7783,7 @@
<target state="translated">Duck.ai’yi aç</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8012,7 +8020,7 @@
<target state="translated">Yakın Geçmiş Piyasa Verilerini Topla</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8020,7 +8028,7 @@
<target state="translated">Tüm Geçmiş Piyasa Verilerini Topla</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">yeni</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Yatırım</target>

76
apps/client/src/locales/messages.uk.xlf

@ -623,7 +623,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -647,7 +647,7 @@
<target state="translated">Видалити</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -879,7 +879,7 @@
<target state="translated">Порівняльні показники</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="8298612418414367990" datatype="html">
@ -887,7 +887,7 @@
<target state="translated">Валюти</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -907,7 +907,7 @@
<target state="translated">ETF без країн</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -915,7 +915,7 @@
<target state="translated">ETF без секторів</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="4550487415324294802" datatype="html">
@ -923,7 +923,7 @@
<target state="translated">Фільтрувати за...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="8410000928786197012" datatype="html">
@ -983,7 +983,7 @@
<target state="translated">Кількість активностей</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -991,7 +991,7 @@
<target state="translated">Історичні дані</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -1003,7 +1003,7 @@
<target state="translated">Кількість секторів</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -1027,7 +1027,7 @@
<target state="translated">Кількість країн</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -1035,7 +1035,7 @@
<target state="translated">Зібрати дані профілю</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -2063,7 +2063,7 @@
<target state="translated">Страх</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2079,7 +2079,7 @@
<target state="translated">Жадібність</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2857,10 +2857,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">ОК</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -3750,6 +3746,14 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="translated">Тривалість</target>
@ -5124,7 +5128,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -5144,11 +5148,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -5168,7 +5172,7 @@
<target state="translated">Щомісячно</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
@ -5176,7 +5180,7 @@
<target state="translated">Щорічно</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="1600023202562292052" datatype="html">
@ -6219,7 +6223,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -6739,7 +6743,7 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
@ -7085,6 +7089,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7227,7 +7235,7 @@
<target state="new">No Activities</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -7703,7 +7711,7 @@
<target state="translated">Запит AI скопійовано в буфер обміну</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="8540986733881734625" datatype="html">
@ -7775,7 +7783,7 @@
<target state="new">Open Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8012,7 +8020,7 @@
<target state="new">Gather Recent Historical Market Data</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8020,7 +8028,7 @@
<target state="new">Gather All Historical Market Data</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8358,14 +8366,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">новий</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">Інвестиція</target>

74
apps/client/src/locales/messages.xlf

@ -501,7 +501,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -524,7 +524,7 @@
<source>Delete</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -744,7 +744,7 @@
<source>Currencies</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -762,14 +762,14 @@
<source>ETFs without Countries</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
<source>ETFs without Sectors</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="6786981261778452561" datatype="html">
@ -787,7 +787,7 @@
<source>Filter by...</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -820,14 +820,14 @@
<source>Activities Count</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
<source>Historical Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -838,7 +838,7 @@
<source>Sectors Count</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -859,28 +859,28 @@
<source>Countries Count</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="4396995010887588291" datatype="html">
<source>Gather Recent Historical Market Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
<source>Gather All Historical Market Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
<source>Gather Profile Data</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1527,7 +1527,7 @@
<source>Fear</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1542,7 +1542,7 @@
<source>Greed</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -2460,10 +2460,6 @@
</trans-unit>
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -2891,6 +2887,13 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<context-group purpose="location">
@ -4051,7 +4054,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -4076,14 +4079,14 @@
<source>Monthly</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
<source>Yearly</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -4926,7 +4929,7 @@
<source>{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
@ -5226,7 +5229,7 @@
<source>No Activities</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -5704,11 +5707,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6093,7 +6096,7 @@
<source>Benchmarks</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="7798195225890418363" datatype="html">
@ -6416,6 +6419,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -6628,7 +6635,7 @@
<source>Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7009,7 +7016,7 @@
<source>AI prompt has been copied to the clipboard</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7079,7 +7086,7 @@
<source>Open Duck.ai</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -7579,13 +7586,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<context-group purpose="location">

88
apps/client/src/locales/messages.zh.xlf

@ -532,7 +532,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">278</context>
<context context-type="linenumber">284</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-platform/admin-platform.component.html</context>
@ -556,7 +556,7 @@
<target state="translated">删除</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">301</context>
<context context-type="linenumber">307</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -796,7 +796,7 @@
<target state="translated">货币</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">135</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -816,7 +816,7 @@
<target state="translated">没有国家的 ETF</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">140</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="2346990364415437072" datatype="html">
@ -824,7 +824,7 @@
<target state="translated">无行业类别的 ETF</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">145</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="6786981261778452561" datatype="html">
@ -844,7 +844,7 @@
<target state="translated">过滤...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">374</context>
<context context-type="linenumber">366</context>
</context-group>
</trans-unit>
<trans-unit id="6182733719813772142" datatype="html">
@ -880,7 +880,7 @@
<target state="translated">活动计数</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">156</context>
<context context-type="linenumber">162</context>
</context-group>
</trans-unit>
<trans-unit id="9004532723522060201" datatype="html">
@ -888,7 +888,7 @@
<target state="translated">历史数据</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">165</context>
<context context-type="linenumber">171</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html</context>
@ -900,7 +900,7 @@
<target state="translated">行业数</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">174</context>
<context context-type="linenumber">180</context>
</context-group>
</trans-unit>
<trans-unit id="6131560364436366828" datatype="html">
@ -924,7 +924,7 @@
<target state="translated">国家数</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">189</context>
</context-group>
</trans-unit>
<trans-unit id="5274897475180636586" datatype="html">
@ -932,7 +932,7 @@
<target state="translated">收集个人资料数据</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">234</context>
<context context-type="linenumber">240</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html</context>
@ -1341,7 +1341,7 @@
</trans-unit>
<trans-unit id="7701575534145602925" datatype="html">
<source>Explore <x id="INTERPOLATION" equiv-text="{{ item.title }}"/></source>
<target state="new">Explore <x id="INTERPOLATION" equiv-text="{{ item.title }}"/></target>
<target state="translated">探索 <x id="INTERPOLATION" equiv-text="{{ item.title }}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/overview/resources-overview.component.html</context>
<context context-type="linenumber">11</context>
@ -1640,7 +1640,7 @@
<target state="translated">恐惧</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">46</context>
<context context-type="linenumber">48</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1656,7 +1656,7 @@
<target state="translated">贪婪</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/home-market/home-market.component.ts</context>
<context context-type="linenumber">47</context>
<context context-type="linenumber">49</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/markets/markets.component.ts</context>
@ -1789,7 +1789,7 @@
</trans-unit>
<trans-unit id="8186013988289067040" datatype="html">
<source>Code</source>
<target state="new">Code</target>
<target state="translated">代码</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">159</context>
@ -2670,10 +2670,6 @@
<trans-unit id="1579692722565712588" datatype="html">
<source>Okay</source>
<target state="translated">好的</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/core/http-response.interceptor.ts</context>
<context context-type="linenumber">86</context>
@ -3127,9 +3123,17 @@
<context context-type="linenumber">32</context>
</context-group>
</trans-unit>
<trans-unit id="7407646470109951507" datatype="html">
<source>popular</source>
<target state="new">popular</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="7410432243549869948" datatype="html">
<source>Duration</source>
<target state="new">Duration</target>
<target state="translated">持续时间</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.html</context>
<context context-type="linenumber">172</context>
@ -4416,7 +4420,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">78</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
@ -4444,7 +4448,7 @@
<target state="translated">每月</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">92</context>
<context context-type="linenumber">94</context>
</context-group>
</trans-unit>
<trans-unit id="8036977202721714375" datatype="html">
@ -4452,7 +4456,7 @@
<target state="translated">每年</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">93</context>
<context context-type="linenumber">95</context>
</context-group>
</trans-unit>
<trans-unit id="6293970137138896363" datatype="html">
@ -5389,12 +5393,12 @@
<target state="new">{VAR_PLURAL, plural, =1 {Profile} other {Profiles}}</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">255</context>
</context-group>
</trans-unit>
<trans-unit id="5515771028435710194" datatype="html">
<source>Loan</source>
<target state="new">Loan</target>
<target state="translated">贷款</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
<context context-type="linenumber">64</context>
@ -5714,10 +5718,10 @@
</trans-unit>
<trans-unit id="9218541487912911620" datatype="html">
<source>No Activities</source>
<target state="new">No Activities</target>
<target state="translated">暂无活动</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">150</context>
<context context-type="linenumber">147</context>
</context-group>
</trans-unit>
<trans-unit id="9219851060664514927" datatype="html">
@ -6249,11 +6253,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">82</context>
<context context-type="linenumber">84</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts</context>
@ -6686,7 +6690,7 @@
<target state="translated">基准</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">127</context>
</context-group>
</trans-unit>
<trans-unit id="1358239534403218079" datatype="html">
@ -7044,6 +7048,10 @@
<context context-type="sourcefile">apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html</context>
<context context-type="linenumber">80</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-account-membership/user-account-membership.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html</context>
<context context-type="linenumber">239</context>
@ -7167,7 +7175,7 @@
</trans-unit>
<trans-unit id="8466521722895614996" datatype="html">
<source><x id="PH" equiv-text="codeToCopy"/> has been copied to the clipboard</source>
<target state="new"><x id="PH" equiv-text="codeToCopy"/> has been copied to the clipboard</target>
<target state="translated"><x id="PH" equiv-text="codeToCopy"/> 已复制到剪贴板</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-overview/admin-overview.component.ts</context>
<context context-type="linenumber">388</context>
@ -7274,7 +7282,7 @@
<target state="new">Delete <x id="INTERPOLATION" equiv-text="{{ selection.selected.length &gt; 1 ? selection.selected.length : &apos;&apos; }}"/> <x id="ICU" equiv-text="{selection.selected.length, plural, =1 {Profile} other {Profiles} }"/></target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">244</context>
<context context-type="linenumber">250</context>
</context-group>
</trans-unit>
<trans-unit id="6979762073619328236" datatype="html">
@ -7696,7 +7704,7 @@
<target state="translated">AI 提示已复制到剪贴板</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">211</context>
<context context-type="linenumber">217</context>
</context-group>
</trans-unit>
<trans-unit id="1616747898909934803" datatype="html">
@ -7776,7 +7784,7 @@
<target state="translated">打开 Duck.ai</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">212</context>
<context context-type="linenumber">218</context>
</context-group>
</trans-unit>
<trans-unit id="5674286808255988565" datatype="html">
@ -8013,7 +8021,7 @@
<target state="translated">收集近期历史市场数据</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">225</context>
<context context-type="linenumber">231</context>
</context-group>
</trans-unit>
<trans-unit id="4333079359502738389" datatype="html">
@ -8021,7 +8029,7 @@
<target state="translated">收集所有历史市场数据</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.html</context>
<context context-type="linenumber">230</context>
<context context-type="linenumber">236</context>
</context-group>
</trans-unit>
<trans-unit id="2960393019464273155" datatype="html">
@ -8359,14 +8367,6 @@
<context context-type="linenumber">224</context>
</context-group>
</trans-unit>
<trans-unit id="7387635272539030076" datatype="html">
<source>new</source>
<target state="translated">新增</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-settings/admin-settings.component.html</context>
<context context-type="linenumber">79</context>
</context-group>
</trans-unit>
<trans-unit id="rule.accountClusterRiskCurrentInvestment" datatype="html">
<source>Investment</source>
<target state="translated">投资</target>

8
apps/client/src/styles.scss

@ -376,12 +376,16 @@ ngx-skeleton-loader {
visibility: hidden;
}
.lead {
font-weight: unset;
}
.line-height-1 {
line-height: 1;
}
.lead {
font-weight: unset;
.line-height-normal {
line-height: normal;
}
.mat-mdc-button-base {

6
libs/common/src/lib/config.ts

@ -11,7 +11,6 @@ export const ghostfolioScraperApiSymbolPrefix = `_${ghostfolioPrefix}_`;
export const ghostfolioFearAndGreedIndexDataSourceCryptocurrencies =
DataSource.MANUAL;
export const ghostfolioFearAndGreedIndexDataSourceStocks = DataSource.RAPID_API;
export const ghostfolioFearAndGreedIndexSymbolCryptocurrencies = `${ghostfolioPrefix}_FEAR_AND_GREED_INDEX_CRYPTOCURRENCIES`;
export const ghostfolioFearAndGreedIndexSymbolStocks = `${ghostfolioPrefix}_FEAR_AND_GREED_INDEX_STOCKS`;
@ -330,4 +329,9 @@ export const TAG_ID_EXCLUDE_FROM_ANALYSIS =
'f2e868af-8333-459f-b161-cbc6544c24bd';
export const TAG_ID_DEMO = 'efa08cb3-9b9d-4974-ac68-db13a19c4874';
export const THROTTLE_DEFAULT_LIMIT = 10;
export const THROTTLE_DEFAULT_TTL = ms('1 minute');
export const THROTTLE_SIGNUP_LIMIT = 5;
export const THROTTLE_SIGNUP_TTL = ms('1 hour');
export const UNKNOWN_KEY = 'UNKNOWN';

9
libs/common/src/lib/personal-finance-tools.ts

@ -14,6 +14,13 @@ export const personalFinanceTools: Product[] = [
slogan: 'Lifetime Personal Finance Control, One Single Payment.',
url: 'https://www.mechcad.net'
},
{
categories: ['WEALTH_MANAGEMENT'],
key: 'akkuro',
name: 'Akkuro',
slogan: 'Composable Banking',
url: 'https://akkuro.com'
},
{
categories: ['ETF_TRACKING', 'STOCK_TRACKING'],
founded: 2023,
@ -215,7 +222,7 @@ export const personalFinanceTools: Product[] = [
name: 'Buxfer',
origin: 'US',
platforms: ['WEB'],
pricingPerYear: '$48',
pricingPerYear: '$96',
regions: ['Global'],
slogan: 'Take control of your financial future',
url: 'https://www.buxfer.com'

2
libs/common/src/lib/routes/interfaces/internal-route.interface.ts

@ -5,5 +5,5 @@ export interface InternalRoute {
path?: string;
routerLink: string[];
subRoutes?: Record<string, InternalRoute>;
title: string;
title?: string;
}

3
libs/common/src/lib/routes/routes.ts

@ -153,8 +153,7 @@ export const internalRoutes = {
webauthn: {
excludeFromAssistant: true,
path: 'webauthn',
routerLink: ['/webauthn'],
title: $localize`Sign in`
routerLink: ['/webauthn']
},
zen: {
excludeFromAssistant: true,

5
libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html

@ -8,7 +8,10 @@
@if (item && isAsset(item)) {
<br />
<small class="text-muted"
>{{ item?.symbol ?? '' | gfSymbol }} · {{ item?.currency }}
>{{ item?.symbol ?? '' | gfSymbol }}
@if (item.currency) {
· {{ item.currency }}
}
@if (item?.assetSubClassString) {
· {{ item.assetSubClassString }}
}

16
libs/ui/src/lib/page-tabs/page-tabs.component.html

@ -45,9 +45,15 @@
</nav>
<ng-template #tabContent let-tab>
<ion-icon
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<div class="d-none d-sm-block ml-1" [innerHTML]="tab.label"></div>
<span class="align-items-center d-flex justify-content-start text-left w-100">
<ion-icon
class="flex-shrink-0"
[name]="tab.iconName"
[size]="deviceType === 'mobile' ? 'large' : 'small'"
/>
<span
class="d-none d-sm-block line-height-normal ml-1 overflow-hidden p-0 text-truncate"
[innerHTML]="tab.label"
></span>
</span>
</ng-template>

5
libs/ui/src/lib/page-tabs/page-tabs.component.scss

@ -56,6 +56,11 @@
padding: 2rem 0;
width: 14rem;
.mat-mdc-tab-list,
.mat-mdc-tab-links {
width: 100%;
}
.mat-mdc-tab-links {
flex-direction: column;

5
libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.html

@ -25,7 +25,10 @@
}
</span>
<small class="text-muted"
>{{ lookupItem.symbol | gfSymbol }} · {{ lookupItem.currency }}
>{{ lookupItem.symbol | gfSymbol }}
@if (lookupItem.currency) {
· {{ lookupItem.currency }}
}
@if (lookupItem.assetSubClass) {
· {{ lookupItem.assetSubClassString }}
}

10
nx.json

@ -67,6 +67,16 @@
}
},
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"plugins": [
{
"plugin": "@nx/webpack/plugin",
"options": {
"buildTargetName": "build",
"serveTargetName": "serve",
"previewTargetName": "preview"
}
}
],
"targetDefaults": {
"build": {
"dependsOn": ["^build"],

174
package-lock.json

@ -1,12 +1,12 @@
{
"name": "ghostfolio",
"version": "3.22.0",
"version": "3.25.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ghostfolio",
"version": "3.22.0",
"version": "3.25.0",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {
@ -29,6 +29,7 @@
"@internationalized/number": "3.6.7",
"@ionic/angular": "8.8.12",
"@keyv/redis": "5.1.6",
"@nest-lab/throttler-storage-redis": "1.2.0",
"@nestjs/bull": "11.0.4",
"@nestjs/cache-manager": "3.1.3",
"@nestjs/common": "11.1.27",
@ -40,6 +41,7 @@
"@nestjs/platform-express": "11.1.27",
"@nestjs/schedule": "6.1.3",
"@nestjs/serve-static": "5.0.5",
"@nestjs/throttler": "6.5.0",
"@openrouter/ai-sdk-provider": "2.9.1",
"@prisma/adapter-pg": "7.8.0",
"@prisma/client": "7.8.0",
@ -70,7 +72,7 @@
"fast-redact": "3.5.0",
"fuse.js": "7.3.0",
"google-spreadsheet": "3.2.0",
"helmet": "7.0.0",
"helmet": "8.2.0",
"http-status-codes": "2.3.0",
"ionicons": "8.0.13",
"jsonpath": "1.3.0",
@ -164,7 +166,8 @@
"ts-jest": "29.4.0",
"ts-node": "10.9.2",
"tslib": "2.8.1",
"typescript": "5.9.2"
"typescript": "5.9.2",
"webpack-cli": "7.1.0"
},
"engines": {
"node": ">=22.18.0"
@ -6955,6 +6958,39 @@
"tslib": "^2.4.0"
}
},
"node_modules/@nest-lab/throttler-storage-redis": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@nest-lab/throttler-storage-redis/-/throttler-storage-redis-1.2.0.tgz",
"integrity": "sha512-tMkUyo68NCKTR+zILk+EC35SMYBtDPZY2mCj7ZaCietWGVTnuP4zwq9ERYfvU6kJv6h8teNZrC6MJCmY6/dljw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
"@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
"@nestjs/throttler": ">=6.0.0",
"ioredis": ">=5.0.0",
"reflect-metadata": "^0.2.1"
},
"peerDependenciesMeta": {
"@nestjs/common": {
"optional": false
},
"@nestjs/core": {
"optional": false
},
"@nestjs/throttler": {
"optional": false
},
"ioredis": {
"optional": false
},
"reflect-metadata": {
"optional": false
}
}
},
"node_modules/@nestjs/bull": {
"version": "11.0.4",
"resolved": "https://registry.npmjs.org/@nestjs/bull/-/bull-11.0.4.tgz",
@ -7440,6 +7476,17 @@
}
}
},
"node_modules/@nestjs/throttler": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@nestjs/throttler/-/throttler-6.5.0.tgz",
"integrity": "sha512-9j0ZRfH0QE1qyrj9JjIRDz5gQLPqq9yVC2nHsrosDVAfI5HHw08/aUAWx9DZLSdQf4HDkmhTTEGLrRFHENvchQ==",
"license": "MIT",
"peerDependencies": {
"@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
"@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
"reflect-metadata": "^0.1.13 || ^0.2.0"
}
},
"node_modules/@ngtools/webpack": {
"version": "21.2.6",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-21.2.6.tgz",
@ -19378,6 +19425,19 @@
"node": ">=18"
}
},
"node_modules/envinfo": {
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz",
"integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==",
"dev": true,
"license": "MIT",
"bin": {
"envinfo": "dist/cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/environment": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
@ -21837,12 +21897,15 @@
}
},
"node_modules/helmet": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-7.0.0.tgz",
"integrity": "sha512-MsIgYmdBh460ZZ8cJC81q4XJknjG567wzEmv46WOBblDb6TUd3z8/GhgmsM9pn8g2B80tAJ4m5/d3Bi1KrSUBQ==",
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-8.2.0.tgz",
"integrity": "sha512-DRgTIUgnWcJ62KyarxxziuqYxKGnR6Rgg19BlbucN/dpmJbl1XOit6qvoOX0ZT+HhWe5OUVhU/a1zpGyc1xA0Q==",
"license": "MIT",
"engines": {
"node": ">=16.0.0"
"node": ">=18.0.0"
},
"funding": {
"url": "https://github.com/sponsors/EvanHahn"
}
},
"node_modules/hono": {
@ -34613,6 +34676,101 @@
}
}
},
"node_modules/webpack-cli": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.1.0.tgz",
"integrity": "sha512-pSJ5p5PkXRD88sfCq5Wo+coc42QykwRu5Md0DyESj0rT6PPPA2wTNabpHPKgqH8EMkfTDo3IWx3iiNXMu8XDBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@discoveryjs/json-ext": "^1.1.0",
"commander": "^14.0.3",
"cross-spawn": "^7.0.6",
"envinfo": "^7.21.0",
"import-local": "^3.2.0",
"interpret": "^3.1.1",
"rechoir": "^0.8.0",
"webpack-merge": "^6.0.1"
},
"bin": {
"webpack-cli": "bin/cli.js"
},
"engines": {
"node": ">=20.9.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"js-yaml": "^4.0.0 || ^5.0.0",
"json5": "^2.2.3",
"toml": "^3.0.0 || ^4.0.0",
"webpack": "^5.101.0",
"webpack-bundle-analyzer": "^4.0.0 || ^5.0.0",
"webpack-dev-server": "^5.0.0"
},
"peerDependenciesMeta": {
"js-yaml": {
"optional": true
},
"json5": {
"optional": true
},
"toml": {
"optional": true
},
"webpack-bundle-analyzer": {
"optional": true
},
"webpack-dev-server": {
"optional": true
}
}
},
"node_modules/webpack-cli/node_modules/@discoveryjs/json-ext": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-1.1.0.tgz",
"integrity": "sha512-Xc3VhU02wqZ1HvHRJUwL09HkZSTvidqY5Ya0NXBSYOxAp+Ln9dcJr9fySI+CkONzP3PekQo9WdzCv0PGER/mOA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.17.0"
}
},
"node_modules/webpack-cli/node_modules/commander": {
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
}
},
"node_modules/webpack-cli/node_modules/interpret": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
"integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/webpack-cli/node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
"integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"resolve": "^1.20.0"
},
"engines": {
"node": ">= 10.13.0"
}
},
"node_modules/webpack-dev-middleware": {
"version": "7.4.5",
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz",

9
package.json

@ -1,6 +1,6 @@
{
"name": "ghostfolio",
"version": "3.22.0",
"version": "3.25.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio",
@ -73,6 +73,7 @@
"@internationalized/number": "3.6.7",
"@ionic/angular": "8.8.12",
"@keyv/redis": "5.1.6",
"@nest-lab/throttler-storage-redis": "1.2.0",
"@nestjs/bull": "11.0.4",
"@nestjs/cache-manager": "3.1.3",
"@nestjs/common": "11.1.27",
@ -84,6 +85,7 @@
"@nestjs/platform-express": "11.1.27",
"@nestjs/schedule": "6.1.3",
"@nestjs/serve-static": "5.0.5",
"@nestjs/throttler": "6.5.0",
"@openrouter/ai-sdk-provider": "2.9.1",
"@prisma/adapter-pg": "7.8.0",
"@prisma/client": "7.8.0",
@ -114,7 +116,7 @@
"fast-redact": "3.5.0",
"fuse.js": "7.3.0",
"google-spreadsheet": "3.2.0",
"helmet": "7.0.0",
"helmet": "8.2.0",
"http-status-codes": "2.3.0",
"ionicons": "8.0.13",
"jsonpath": "1.3.0",
@ -208,7 +210,8 @@
"ts-jest": "29.4.0",
"ts-node": "10.9.2",
"tslib": "2.8.1",
"typescript": "5.9.2"
"typescript": "5.9.2",
"webpack-cli": "7.1.0"
},
"engines": {
"node": ">=22.18.0"

Loading…
Cancel
Save