diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 000000000..8592824fa --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +# Check formatting on modified and uncommitted files, stop the commit if issues are found +npm run format:write --uncommitted || exit 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e5c1116f..c476bacce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,93 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the error message of the currency code validation +- Tightened the currency code validation by requiring uppercase letters + +### Fixed + +- Improved the file selector of the activities import functionality to accept case-insensitive file extensions (`.CSV` and `.JSON`) + +## 2.155.0 - 2025-04-23 + +### Added + +- Added the endpoints (`DELETE`, `GET` and `POST`) for the watchlist + +### Changed + +- Simplified the data source check in the DTO of the activity creation +- Simplified the data source check in the DTO of the asset profile update +- Renamed `User` to `user` in the `Subscription` database schema +- Migrated the `@ghostfolio/ui/assistant` component to control flow +- Migrated the `@ghostfolio/ui/value` component to control flow + +### Fixed + +- Fixed an issue in the settings dialog to customize the rule thresholds of the _X-ray_ page (experimental) + +## 2.154.0 - 2025-04-21 + +### Added + +- Extended the benchmark detail dialog by the current market price +- Added the performance calculation type to the user settings (experimental) +- Added `watchlist` to the `User` database schema as a preparation for watching assets + +### Changed + +- Made the historical market data editor expandable in the admin control panel +- Renamed `Subscription` to `subscriptions` in the `User` database schema +- Parallelized the requests in the get quotes functionality of the _Financial Modeling Prep_ service +- Migrated the lookup functionality by `isin` of the _Financial Modeling Prep_ service to its stable API version +- Improved the language localization for German (`de`) + +### Fixed + +- Fixed the word wrap in the menu of the historical market data table in the admin control panel + +## 2.153.0 - 2025-04-18 + +### Changed + +- Added support for activities in a custom currency +- Refreshed the cryptocurrencies list +- Upgraded `chart.js` from version `4.4.7` to `4.4.9` +- Upgraded `uuid` from version `11.0.5` to `11.1.0` + +### Fixed + +- Fixed the functionality to open an asset profile of a custom currency in the admin control panel +- Fixed the asset class parsing in the _Financial Modeling Prep_ service for exchange rates + +## 2.152.1 - 2025-04-17 + +### Changed + +- Deactivated asset profiles automatically on delisting in the _Yahoo Finance_ service +- Optimized the query of the data range functionality (`getRange()`) in the market data service +- Moved the subscription offer from the info to the user service +- Upgraded `Nx` from version `20.7.1` to `20.8.0` +- Upgraded `prisma` from version `6.5.0` to `6.6.0` +- Upgraded `storybook` from version `8.4.7` to `8.6.12` + +## 2.151.0 - 2025-04-11 + +### Added + +- Added the data gathering status column to the historical market data table of the admin control + +### Changed + +- Set the maximum number of symbols per request in the _Financial Modeling Prep_ service +- Migrated the get quotes functionality of the _Financial Modeling Prep_ service to its stable API version +- Improved the language localization for Enlish (`en`) - Upgraded `eslint` dependencies +- Upgraded `Nx` from version `20.6.4` to `20.7.1` + +### Fixed + +- Fixed the link to the pricing page in the premium indicator component ## 2.150.0 - 2025-04-05 diff --git a/apps/api/src/app/admin/admin.controller.ts b/apps/api/src/app/admin/admin.controller.ts index fc6292246..b3293095f 100644 --- a/apps/api/src/app/admin/admin.controller.ts +++ b/apps/api/src/app/admin/admin.controller.ts @@ -9,8 +9,8 @@ import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathe import { DATA_GATHERING_QUEUE_PRIORITY_HIGH, DATA_GATHERING_QUEUE_PRIORITY_MEDIUM, - GATHER_ASSET_PROFILE_PROCESS, - GATHER_ASSET_PROFILE_PROCESS_OPTIONS + GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, + GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS } from '@ghostfolio/common/config'; import { getAssetProfileIdentifier } from '@ghostfolio/common/helper'; import { @@ -92,9 +92,9 @@ export class AdminController { dataSource, symbol }, - name: GATHER_ASSET_PROFILE_PROCESS, + name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, opts: { - ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, + ...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS, jobId: getAssetProfileIdentifier({ dataSource, symbol }), priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM } @@ -136,9 +136,9 @@ export class AdminController { dataSource, symbol }, - name: GATHER_ASSET_PROFILE_PROCESS, + name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, opts: { - ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, + ...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS, jobId: getAssetProfileIdentifier({ dataSource, symbol }), priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM } @@ -159,9 +159,9 @@ export class AdminController { dataSource, symbol }, - name: GATHER_ASSET_PROFILE_PROCESS, + name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, opts: { - ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, + ...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS, jobId: getAssetProfileIdentifier({ dataSource, symbol }), priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH } diff --git a/apps/api/src/app/admin/admin.module.ts b/apps/api/src/app/admin/admin.module.ts index b02c0203b..be92405b1 100644 --- a/apps/api/src/app/admin/admin.module.ts +++ b/apps/api/src/app/admin/admin.module.ts @@ -1,5 +1,4 @@ import { OrderModule } from '@ghostfolio/api/app/order/order.module'; -import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module'; import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module'; import { ApiModule } from '@ghostfolio/api/services/api/api.module'; import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module'; @@ -32,7 +31,6 @@ import { QueueModule } from './queue/queue.module'; PrismaModule, PropertyModule, QueueModule, - SubscriptionModule, SymbolProfileModule, SymbolProfileOverwriteModule, TransformDataSourceInRequestModule diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 701d95d8f..393ecdffd 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -1,5 +1,4 @@ import { OrderService } from '@ghostfolio/api/app/order/order.service'; -import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service'; import { environment } from '@ghostfolio/api/environments/environment'; import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -62,7 +61,6 @@ export class AdminService { private readonly orderService: OrderService, private readonly prismaService: PrismaService, private readonly propertyService: PropertyService, - private readonly subscriptionService: SubscriptionService, private readonly symbolProfileService: SymbolProfileService ) {} @@ -249,6 +247,7 @@ export class AdminService { currency: true, dataSource: true, id: true, + isActive: true, isUsedByUsersWithSubscription: true, name: true, Order: { @@ -310,6 +309,7 @@ export class AdminService { currency, dataSource, id, + isActive, isUsedByUsersWithSubscription, name, Order, @@ -369,6 +369,7 @@ export class AdminService { countriesCount, dataSource, id, + isActive, lastMarketPrice, name, symbol, @@ -454,7 +455,8 @@ export class AdminService { currency, dataSource, dateOfFirstActivity, - symbol + symbol, + isActive: true } }; } @@ -649,7 +651,7 @@ export class AdminService { Order: { where: { User: { - Subscription: { + subscriptions: { some: { expiresAt: { gt: new Date() @@ -754,6 +756,7 @@ export class AdminService { countriesCount: 0, date: dateOfFirstActivity, id: undefined, + isActive: true, name: symbol, sectorsCount: 0, tags: [] @@ -810,26 +813,33 @@ export class AdminService { createdAt: true, id: true, role: true, - Subscription: true + subscriptions: { + orderBy: { + expiresAt: 'desc' + }, + take: 1, + where: { + expiresAt: { + gt: new Date() + } + } + } } }); return usersWithAnalytics.map( - ({ _count, Analytics, createdAt, id, role, Subscription }) => { + ({ _count, Analytics, createdAt, id, role, subscriptions }) => { const daysSinceRegistration = differenceInDays(new Date(), createdAt) + 1; const engagement = Analytics ? Analytics.activityCount / daysSinceRegistration : undefined; - const subscription = this.configurationService.get( - 'ENABLE_FEATURE_SUBSCRIPTION' - ) - ? this.subscriptionService.getSubscription({ - createdAt, - subscriptions: Subscription - }) - : undefined; + const subscription = + this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && + subscriptions?.length > 0 + ? subscriptions[0] + : undefined; return { createdAt, diff --git a/apps/api/src/app/admin/update-asset-profile.dto.ts b/apps/api/src/app/admin/update-asset-profile.dto.ts index a03b3b074..8d6dfd085 100644 --- a/apps/api/src/app/admin/update-asset-profile.dto.ts +++ b/apps/api/src/app/admin/update-asset-profile.dto.ts @@ -38,7 +38,7 @@ export class UpdateAssetProfileDto { @IsOptional() currency?: string; - @IsEnum(DataSource, { each: true }) + @IsEnum(DataSource) @IsOptional() dataSource?: DataSource; diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 99080e1e1..0aca4e62c 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -38,6 +38,7 @@ import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfol import { MarketDataModule } from './endpoints/market-data/market-data.module'; import { PublicModule } from './endpoints/public/public.module'; import { TagsModule } from './endpoints/tags/tags.module'; +import { WatchlistModule } from './endpoints/watchlist/watchlist.module'; import { ExchangeRateModule } from './exchange-rate/exchange-rate.module'; import { ExportModule } from './export/export.module'; import { HealthModule } from './health/health.module'; @@ -128,7 +129,8 @@ import { UserModule } from './user/user.module'; SymbolModule, TagsModule, TwitterBotModule, - UserModule + UserModule, + WatchlistModule ], providers: [CronService] }) diff --git a/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts b/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts index 83c7317f0..83e1b5ced 100644 --- a/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts +++ b/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts @@ -24,6 +24,7 @@ import { } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; +import { isISIN } from 'class-validator'; import { getReasonPhrase, StatusCodes } from 'http-status-codes'; import { GetDividendsDto } from './get-dividends.dto'; @@ -301,7 +302,9 @@ export class GhostfolioController { try { const result = await this.ghostfolioService.lookup({ includeIndices, - query: query.toLowerCase() + query: isISIN(query.toUpperCase()) + ? query.toUpperCase() + : query.toLowerCase() }); await this.ghostfolioService.incrementDailyRequests({ diff --git a/apps/api/src/app/endpoints/watchlist/create-watchlist-item.dto.ts b/apps/api/src/app/endpoints/watchlist/create-watchlist-item.dto.ts new file mode 100644 index 000000000..663965ef1 --- /dev/null +++ b/apps/api/src/app/endpoints/watchlist/create-watchlist-item.dto.ts @@ -0,0 +1,10 @@ +import { DataSource } from '@prisma/client'; +import { IsEnum, IsString } from 'class-validator'; + +export class CreateWatchlistItemDto { + @IsEnum(DataSource) + dataSource: DataSource; + + @IsString() + symbol: string; +} diff --git a/apps/api/src/app/endpoints/watchlist/watchlist.controller.ts b/apps/api/src/app/endpoints/watchlist/watchlist.controller.ts new file mode 100644 index 000000000..0d25172c8 --- /dev/null +++ b/apps/api/src/app/endpoints/watchlist/watchlist.controller.ts @@ -0,0 +1,85 @@ +import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; +import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor'; +import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor'; +import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; +import { permissions } from '@ghostfolio/common/permissions'; +import { RequestWithUser } from '@ghostfolio/common/types'; + +import { + Body, + Controller, + Delete, + Get, + HttpException, + Inject, + Param, + Post, + UseGuards, + UseInterceptors +} from '@nestjs/common'; +import { REQUEST } from '@nestjs/core'; +import { AuthGuard } from '@nestjs/passport'; +import { DataSource } from '@prisma/client'; +import { StatusCodes, getReasonPhrase } from 'http-status-codes'; + +import { CreateWatchlistItemDto } from './create-watchlist-item.dto'; +import { WatchlistService } from './watchlist.service'; + +@Controller('watchlist') +export class WatchlistController { + public constructor( + @Inject(REQUEST) private readonly request: RequestWithUser, + private readonly watchlistService: WatchlistService + ) {} + + @Post() + @HasPermission(permissions.createWatchlistItem) + @UseGuards(AuthGuard('jwt')) + @UseInterceptors(TransformDataSourceInRequestInterceptor) + public async createWatchlistItem(@Body() data: CreateWatchlistItemDto) { + return this.watchlistService.createWatchlistItem({ + dataSource: data.dataSource, + symbol: data.symbol, + userId: this.request.user.id + }); + } + + @Delete(':dataSource/:symbol') + @HasPermission(permissions.deleteWatchlistItem) + @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + @UseInterceptors(TransformDataSourceInRequestInterceptor) + public async deleteWatchlistItem( + @Param('dataSource') dataSource: DataSource, + @Param('symbol') symbol: string + ) { + const watchlistItem = await this.watchlistService + .getWatchlistItems(this.request.user.id) + .then((items) => { + return items.find((item) => { + return item.dataSource === dataSource && item.symbol === symbol; + }); + }); + + if (!watchlistItem) { + throw new HttpException( + getReasonPhrase(StatusCodes.NOT_FOUND), + StatusCodes.NOT_FOUND + ); + } + + return this.watchlistService.deleteWatchlistItem({ + dataSource, + symbol, + userId: this.request.user.id + }); + } + + @Get() + @HasPermission(permissions.readWatchlist) + @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + @UseInterceptors(TransformDataSourceInResponseInterceptor) + public async getWatchlistItems(): Promise { + return this.watchlistService.getWatchlistItems(this.request.user.id); + } +} diff --git a/apps/api/src/app/endpoints/watchlist/watchlist.module.ts b/apps/api/src/app/endpoints/watchlist/watchlist.module.ts new file mode 100644 index 000000000..15115888b --- /dev/null +++ b/apps/api/src/app/endpoints/watchlist/watchlist.module.ts @@ -0,0 +1,19 @@ +import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module'; +import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module'; +import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; + +import { Module } from '@nestjs/common'; + +import { WatchlistController } from './watchlist.controller'; +import { WatchlistService } from './watchlist.service'; + +@Module({ + controllers: [WatchlistController], + imports: [ + PrismaModule, + TransformDataSourceInRequestModule, + TransformDataSourceInResponseModule + ], + providers: [WatchlistService] +}) +export class WatchlistModule {} diff --git a/apps/api/src/app/endpoints/watchlist/watchlist.service.ts b/apps/api/src/app/endpoints/watchlist/watchlist.service.ts new file mode 100644 index 000000000..fdb9dd97a --- /dev/null +++ b/apps/api/src/app/endpoints/watchlist/watchlist.service.ts @@ -0,0 +1,79 @@ +import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; +import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; + +import { Injectable, NotFoundException } from '@nestjs/common'; +import { DataSource } from '@prisma/client'; + +@Injectable() +export class WatchlistService { + public constructor(private readonly prismaService: PrismaService) {} + + public async createWatchlistItem({ + dataSource, + symbol, + userId + }: { + dataSource: DataSource; + symbol: string; + userId: string; + }): Promise { + const symbolProfile = await this.prismaService.symbolProfile.findUnique({ + where: { + dataSource_symbol: { dataSource, symbol } + } + }); + + if (!symbolProfile) { + throw new NotFoundException( + `Asset profile not found for ${symbol} (${dataSource})` + ); + } + + await this.prismaService.user.update({ + data: { + watchlist: { + connect: { + dataSource_symbol: { dataSource, symbol } + } + } + }, + where: { id: userId } + }); + } + + public async deleteWatchlistItem({ + dataSource, + symbol, + userId + }: { + dataSource: DataSource; + symbol: string; + userId: string; + }) { + await this.prismaService.user.update({ + data: { + watchlist: { + disconnect: { + dataSource_symbol: { dataSource, symbol } + } + } + }, + where: { id: userId } + }); + } + + public async getWatchlistItems( + userId: string + ): Promise { + const user = await this.prismaService.user.findUnique({ + select: { + watchlist: { + select: { dataSource: true, symbol: true } + } + }, + where: { id: userId } + }); + + return user.watchlist ?? []; + } +} diff --git a/apps/api/src/app/export/export.service.ts b/apps/api/src/app/export/export.service.ts index f0449dc14..5efa429c7 100644 --- a/apps/api/src/app/export/export.service.ts +++ b/apps/api/src/app/export/export.service.ts @@ -120,6 +120,7 @@ export class ExportService { ({ accountId, comment, + currency, date, fee, id, @@ -137,7 +138,7 @@ export class ExportService { quantity, type, unitPrice, - currency: SymbolProfile.currency, + currency: currency ?? SymbolProfile.currency, dataSource: SymbolProfile.dataSource, date: date.toISOString(), symbol: ['FEE', 'INTEREST', 'ITEM', 'LIABILITY'].includes(type) diff --git a/apps/api/src/app/import/import.controller.ts b/apps/api/src/app/import/import.controller.ts index b276a3c3d..15631a3e8 100644 --- a/apps/api/src/app/import/import.controller.ts +++ b/apps/api/src/app/import/import.controller.ts @@ -98,12 +98,9 @@ export class ImportController { @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ): Promise { - const userCurrency = this.request.user.Settings.settings.baseCurrency; - const activities = await this.importService.getDividends({ dataSource, - symbol, - userCurrency + symbol }); return { activities }; diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index f25433916..0e73e04bb 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -10,12 +10,10 @@ import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.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 { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DATA_GATHERING_QUEUE_PRIORITY_HIGH } from '@ghostfolio/common/config'; import { - DATE_FORMAT, getAssetProfileIdentifier, parseDate } from '@ghostfolio/common/helper'; @@ -29,8 +27,8 @@ import { import { Injectable } from '@nestjs/common'; import { DataSource, Prisma, SymbolProfile } from '@prisma/client'; import { Big } from 'big.js'; -import { endOfToday, format, isAfter, isSameSecond, parseISO } from 'date-fns'; -import { isNumber, uniqBy } from 'lodash'; +import { endOfToday, isAfter, isSameSecond, parseISO } from 'date-fns'; +import { uniqBy } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; @Injectable() @@ -40,7 +38,6 @@ export class ImportService { private readonly configurationService: ConfigurationService, private readonly dataGatheringService: DataGatheringService, private readonly dataProviderService: DataProviderService, - private readonly exchangeRateDataService: ExchangeRateDataService, private readonly orderService: OrderService, private readonly platformService: PlatformService, private readonly portfolioService: PortfolioService, @@ -49,9 +46,8 @@ export class ImportService { public async getDividends({ dataSource, - symbol, - userCurrency - }: AssetProfileIdentifier & { userCurrency: string }): Promise { + symbol + }: AssetProfileIdentifier): Promise { try { const { firstBuyDate, historicalData, orders } = await this.portfolioService.getPosition(dataSource, undefined, symbol); @@ -121,22 +117,16 @@ export class ImportService { currency: undefined, createdAt: undefined, fee: 0, - feeInBaseCurrency: 0, + feeInAssetProfileCurrency: 0, id: assetProfile.id, isDraft: false, SymbolProfile: assetProfile, symbolProfileId: assetProfile.id, type: 'DIVIDEND', unitPrice: marketPrice, + unitPriceInAssetProfileCurrency: marketPrice, updatedAt: undefined, - userId: Account?.userId, - valueInBaseCurrency: - await this.exchangeRateDataService.toCurrencyAtDate( - value, - assetProfile.currency, - userCurrency, - date - ) + userId: Account?.userId }; }) ); @@ -266,17 +256,17 @@ export class ImportService { const activities: Activity[] = []; - for (const [index, activity] of activitiesExtendedWithErrors.entries()) { + for (const activity of activitiesExtendedWithErrors) { const accountId = activity.accountId; const comment = activity.comment; const currency = activity.currency; const date = activity.date; const error = activity.error; - let fee = activity.fee; + const fee = activity.fee; const quantity = activity.quantity; const SymbolProfile = activity.SymbolProfile; const type = activity.type; - let unitPrice = activity.unitPrice; + const unitPrice = activity.unitPrice; const assetProfile = assetProfiles[ getAssetProfileIdentifier({ @@ -284,7 +274,6 @@ export class ImportService { symbol: SymbolProfile.symbol }) ] ?? { - currency: SymbolProfile.currency, dataSource: SymbolProfile.dataSource, symbol: SymbolProfile.symbol }; @@ -320,35 +309,6 @@ export class ImportService { Account?: { id: string; name: string }; }); - if (SymbolProfile.currency !== assetProfile.currency) { - // Convert the unit price and fee to the asset currency if the imported - // activity is in a different currency - unitPrice = await this.exchangeRateDataService.toCurrencyAtDate( - unitPrice, - SymbolProfile.currency, - assetProfile.currency, - date - ); - - if (!isNumber(unitPrice)) { - throw new Error( - `activities.${index} historical exchange rate at ${format( - date, - DATE_FORMAT - )} is not available from "${SymbolProfile.currency}" to "${ - assetProfile.currency - }"` - ); - } - - fee = await this.exchangeRateDataService.toCurrencyAtDate( - fee, - SymbolProfile.currency, - assetProfile.currency, - date - ); - } - if (isDryRun) { order = { comment, @@ -400,6 +360,7 @@ export class ImportService { order = await this.orderService.createOrder({ comment, + currency, date, fee, quantity, @@ -439,21 +400,8 @@ export class ImportService { ...order, error, value, - feeInBaseCurrency: await this.exchangeRateDataService.toCurrencyAtDate( - fee, - assetProfile.currency, - userCurrency, - date - ), // @ts-ignore - SymbolProfile: assetProfile, - valueInBaseCurrency: - await this.exchangeRateDataService.toCurrencyAtDate( - value, - assetProfile.currency, - userCurrency, - date - ) + SymbolProfile: assetProfile }); } @@ -520,7 +468,8 @@ export class ImportService { return ( activity.accountId === accountId && activity.comment === comment && - activity.SymbolProfile.currency === currency && + (activity.currency === currency || + activity.SymbolProfile.currency === currency) && activity.SymbolProfile.dataSource === dataSource && isSameSecond(activity.date, date) && activity.fee === fee && @@ -538,6 +487,7 @@ export class ImportService { return { accountId, comment, + currency, date, error, fee, @@ -545,7 +495,6 @@ export class ImportService { type, unitPrice, SymbolProfile: { - currency, dataSource, symbol, activitiesCount: undefined, @@ -553,6 +502,7 @@ export class ImportService { assetSubClass: undefined, countries: undefined, createdAt: undefined, + currency: undefined, holdings: undefined, id: undefined, isActive: true, diff --git a/apps/api/src/app/info/info.module.ts b/apps/api/src/app/info/info.module.ts index d7a5ed641..9ded44600 100644 --- a/apps/api/src/app/info/info.module.ts +++ b/apps/api/src/app/info/info.module.ts @@ -1,5 +1,6 @@ import { PlatformModule } from '@ghostfolio/api/app/platform/platform.module'; import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; +import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module'; import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module'; import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module'; @@ -31,6 +32,7 @@ import { InfoService } from './info.service'; PlatformModule, PropertyModule, RedisCacheModule, + SubscriptionModule, SymbolProfileModule, TransformDataSourceInResponseModule, UserModule diff --git a/apps/api/src/app/info/info.service.ts b/apps/api/src/app/info/info.service.ts index 780860232..9581807b9 100644 --- a/apps/api/src/app/info/info.service.ts +++ b/apps/api/src/app/info/info.service.ts @@ -1,5 +1,6 @@ import { PlatformService } from '@ghostfolio/api/app/platform/platform.service'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service'; import { UserService } from '@ghostfolio/api/app/user/user.service'; import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -13,7 +14,6 @@ import { PROPERTY_DEMO_USER_ID, PROPERTY_IS_READ_ONLY_MODE, PROPERTY_SLACK_COMMUNITY_USERS, - PROPERTY_STRIPE_CONFIG, ghostfolioFearAndGreedIndexDataSource } from '@ghostfolio/common/config'; import { @@ -21,13 +21,8 @@ import { encodeDataSource, extractNumberFromString } from '@ghostfolio/common/helper'; -import { - InfoItem, - Statistics, - SubscriptionOffer -} from '@ghostfolio/common/interfaces'; +import { InfoItem, Statistics } from '@ghostfolio/common/interfaces'; import { permissions } from '@ghostfolio/common/permissions'; -import { SubscriptionOfferKey } from '@ghostfolio/common/types'; import { Injectable, Logger } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; @@ -46,6 +41,7 @@ export class InfoService { private readonly platformService: PlatformService, private readonly propertyService: PropertyService, private readonly redisCacheService: RedisCacheService, + private readonly subscriptionService: SubscriptionService, private readonly userService: UserService ) {} @@ -101,7 +97,7 @@ export class InfoService { isUserSignupEnabled, platforms, statistics, - subscriptionOffers + subscriptionOffer ] = await Promise.all([ this.benchmarkService.getBenchmarkAssetProfiles(), this.getDemoAuthToken(), @@ -110,7 +106,7 @@ export class InfoService { orderBy: { name: 'asc' } }), this.getStatistics(), - this.getSubscriptionOffers() + this.subscriptionService.getSubscriptionOffer({ key: 'default' }) ]); if (isUserSignupEnabled) { @@ -125,7 +121,7 @@ export class InfoService { isReadOnlyMode, platforms, statistics, - subscriptionOffers, + subscriptionOffer, baseCurrency: DEFAULT_CURRENCY, currencies: this.exchangeRateDataService.getCurrencies() }; @@ -299,19 +295,6 @@ export class InfoService { return statistics; } - private async getSubscriptionOffers(): Promise<{ - [offer in SubscriptionOfferKey]: SubscriptionOffer; - }> { - if (!this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { - return undefined; - } - - return ( - ((await this.propertyService.getByKey(PROPERTY_STRIPE_CONFIG)) as any) ?? - {} - ); - } - private async getUptime(): Promise { { try { diff --git a/apps/api/src/app/order/create-order.dto.ts b/apps/api/src/app/order/create-order.dto.ts index f40e65ba1..c2b10fd81 100644 --- a/apps/api/src/app/order/create-order.dto.ts +++ b/apps/api/src/app/order/create-order.dto.ts @@ -49,7 +49,7 @@ export class CreateOrderDto { @IsOptional() customCurrency?: string; - @IsEnum(DataSource, { each: true }) + @IsEnum(DataSource) @IsOptional() dataSource?: DataSource; diff --git a/apps/api/src/app/order/interfaces/activities.interface.ts b/apps/api/src/app/order/interfaces/activities.interface.ts index b16d10b7d..0c25c8ef8 100644 --- a/apps/api/src/app/order/interfaces/activities.interface.ts +++ b/apps/api/src/app/order/interfaces/activities.interface.ts @@ -11,12 +11,12 @@ export interface Activities { export interface Activity extends Order { Account?: AccountWithPlatform; error?: ActivityError; - feeInBaseCurrency: number; + feeInAssetProfileCurrency: number; SymbolProfile?: EnhancedSymbolProfile; tags?: Tag[]; + unitPriceInAssetProfileCurrency: number; updateAccountBalance?: boolean; value: number; - valueInBaseCurrency: number; } export interface ActivityError { diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 572904f3d..73289711e 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -7,8 +7,8 @@ import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathe import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DATA_GATHERING_QUEUE_PRIORITY_HIGH, - GATHER_ASSET_PROFILE_PROCESS, - GATHER_ASSET_PROFILE_PROCESS_OPTIONS + GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, + GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS } from '@ghostfolio/common/config'; import { getAssetProfileIdentifier } from '@ghostfolio/common/helper'; import { @@ -168,9 +168,9 @@ export class OrderService { dataSource: data.SymbolProfile.connectOrCreate.create.dataSource, symbol: data.SymbolProfile.connectOrCreate.create.symbol }, - name: GATHER_ASSET_PROFILE_PROCESS, + name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, opts: { - ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, + ...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS, jobId: getAssetProfileIdentifier({ dataSource: data.SymbolProfile.connectOrCreate.create.dataSource, symbol: data.SymbolProfile.connectOrCreate.create.symbol @@ -584,18 +584,25 @@ export class OrderService { return { ...order, value, - feeInBaseCurrency: + feeInAssetProfileCurrency: await this.exchangeRateDataService.toCurrencyAtDate( order.fee, + order.currency ?? order.SymbolProfile.currency, order.SymbolProfile.currency, - userCurrency, order.date ), SymbolProfile: assetProfile, + unitPriceInAssetProfileCurrency: + await this.exchangeRateDataService.toCurrencyAtDate( + order.unitPrice, + order.currency ?? order.SymbolProfile.currency, + order.SymbolProfile.currency, + order.date + ), valueInBaseCurrency: await this.exchangeRateDataService.toCurrencyAtDate( value, - order.SymbolProfile.currency, + order.currency ?? order.SymbolProfile.currency, userCurrency, order.date ) diff --git a/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts deleted file mode 100644 index c5d73e6d6..000000000 --- a/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts +++ /dev/null @@ -1,595 +0,0 @@ -import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; -import { OrderService } from '@ghostfolio/api/app/order/order.service'; -import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; -import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; -import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; -import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; -import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; -import { Filter, HistoricalDataItem } from '@ghostfolio/common/interfaces'; - -import { Inject, Logger } from '@nestjs/common'; -import { Big } from 'big.js'; -import { - addDays, - eachDayOfInterval, - endOfDay, - format, - isAfter, - isBefore, - subDays -} from 'date-fns'; - -import { CurrentRateService } from '../../current-rate.service'; -import { DateQuery } from '../../interfaces/date-query.interface'; -import { PortfolioOrder } from '../../interfaces/portfolio-order.interface'; -import { RoaiPortfolioCalculator } from '../roai/portfolio-calculator'; - -export class CPRPortfolioCalculator extends RoaiPortfolioCalculator { - private holdings: { [date: string]: { [symbol: string]: Big } } = {}; - private holdingCurrencies: { [symbol: string]: string } = {}; - - constructor( - { - accountBalanceItems, - activities, - configurationService, - currency, - currentRateService, - exchangeRateDataService, - portfolioSnapshotService, - redisCacheService, - userId, - filters - }: { - accountBalanceItems: HistoricalDataItem[]; - activities: Activity[]; - configurationService: ConfigurationService; - currency: string; - currentRateService: CurrentRateService; - exchangeRateDataService: ExchangeRateDataService; - portfolioSnapshotService: PortfolioSnapshotService; - redisCacheService: RedisCacheService; - filters: Filter[]; - userId: string; - }, - @Inject() - private orderService: OrderService - ) { - super({ - accountBalanceItems, - activities, - configurationService, - currency, - filters, - currentRateService, - exchangeRateDataService, - portfolioSnapshotService, - redisCacheService, - userId - }); - } - - @LogPerformance - public async getPerformanceWithTimeWeightedReturn({ - start, - end - }: { - start: Date; - end: Date; - }): Promise<{ chart: HistoricalDataItem[] }> { - const item = await super.getPerformance({ - end, - start - }); - - const itemResult = item.chart; - const dates = itemResult.map((item) => parseDate(item.date)); - const timeWeighted = await this.getTimeWeightedChartData({ - dates - }); - - item.chart = itemResult.map((itemInt) => { - const timeWeightedItem = timeWeighted.find( - (timeWeightedItem) => timeWeightedItem.date === itemInt.date - ); - if (timeWeightedItem) { - itemInt.timeWeightedPerformance = - timeWeightedItem.netPerformanceInPercentage; - itemInt.timeWeightedPerformanceWithCurrencyEffect = - timeWeightedItem.netPerformanceInPercentageWithCurrencyEffect; - } - - return itemInt; - }); - return item; - } - - @LogPerformance - public async getUnfilteredNetWorth(currency: string): Promise { - const activities = await this.orderService.getOrders({ - userId: this.userId, - userCurrency: currency, - types: ['BUY', 'SELL', 'STAKE'], - withExcludedAccounts: true - }); - const orders = this.activitiesToPortfolioOrder(activities.activities); - const start = orders.reduce( - (date, order) => - parseDate(date.date).getTime() < parseDate(order.date).getTime() - ? date - : order, - { date: orders[0].date } - ).date; - - const end = new Date(Date.now()); - - const holdings = await this.getHoldings(orders, parseDate(start), end); - const marketMap = await this.currentRateService.getValues({ - dataGatheringItems: this.mapToDataGatheringItems(orders), - dateQuery: { in: [end] } - }); - const endString = format(end, DATE_FORMAT); - const exchangeRates = await Promise.all( - Object.keys(holdings[endString]).map(async (holding) => { - const symbolCurrency = this.getCurrencyFromActivities(orders, holding); - const exchangeRate = - await this.exchangeRateDataService.toCurrencyAtDate( - 1, - symbolCurrency, - this.currency, - end - ); - return { symbolCurrency, exchangeRate }; - }) - ); - const currencyRates = exchangeRates.reduce<{ [currency: string]: number }>( - (all, currency): { [currency: string]: number } => { - all[currency.symbolCurrency] ??= currency.exchangeRate; - return all; - }, - {} - ); - - const totalInvestment = await Object.keys(holdings[endString]).reduce( - (sum, holding) => { - if (!holdings[endString][holding].toNumber()) { - return sum; - } - const symbol = marketMap.values.find((m) => m.symbol === holding); - - if (symbol?.marketPrice === undefined) { - Logger.warn( - `Missing historical market data for ${holding} (${end})`, - 'PortfolioCalculator' - ); - return sum; - } else { - const symbolCurrency = this.getCurrency(holding); - const price = new Big(currencyRates[symbolCurrency]).mul( - symbol.marketPrice - ); - return sum.plus(new Big(price).mul(holdings[endString][holding])); - } - }, - new Big(0) - ); - return totalInvestment; - } - - @LogPerformance - protected async getTimeWeightedChartData({ - dates - }: { - dates?: Date[]; - }): Promise { - dates = dates.sort((a, b) => a.getTime() - b.getTime()); - const start = dates[0]; - const end = dates[dates.length - 1]; - const marketMapTask = this.computeMarketMap({ - gte: start, - lt: addDays(end, 1) - }); - const timelineHoldings = await this.getHoldings( - this.activities, - start, - end - ); - - const data: HistoricalDataItem[] = []; - const startString = format(start, DATE_FORMAT); - - data.push({ - date: startString, - netPerformanceInPercentage: 0, - netPerformanceInPercentageWithCurrencyEffect: 0, - investmentValueWithCurrencyEffect: 0, - netPerformance: 0, - netPerformanceWithCurrencyEffect: 0, - netWorth: 0, - totalAccountBalance: 0, - totalInvestment: 0, - totalInvestmentValueWithCurrencyEffect: 0, - value: 0, - valueWithCurrencyEffect: 0 - }); - - this.marketMap = await marketMapTask; - - let totalInvestment = Object.keys(timelineHoldings[startString]).reduce( - (sum, holding) => { - return sum.plus( - timelineHoldings[startString][holding].mul( - this.marketMap[startString][holding] ?? new Big(0) - ) - ); - }, - new Big(0) - ); - - let previousNetPerformanceInPercentage = new Big(0); - let previousNetPerformanceInPercentageWithCurrencyEffect = new Big(0); - - for (let i = 1; i < dates.length; i++) { - const date = format(dates[i], DATE_FORMAT); - const previousDate = format(dates[i - 1], DATE_FORMAT); - const holdings = timelineHoldings[previousDate]; - let newTotalInvestment = new Big(0); - let netPerformanceInPercentage = new Big(0); - let netPerformanceInPercentageWithCurrencyEffect = new Big(0); - - for (const holding of Object.keys(holdings)) { - ({ - netPerformanceInPercentage, - netPerformanceInPercentageWithCurrencyEffect, - newTotalInvestment - } = await this.handleSingleHolding( - previousDate, - holding, - date, - totalInvestment, - timelineHoldings, - netPerformanceInPercentage, - netPerformanceInPercentageWithCurrencyEffect, - newTotalInvestment - )); - } - totalInvestment = newTotalInvestment; - - previousNetPerformanceInPercentage = previousNetPerformanceInPercentage - .plus(1) - .mul(netPerformanceInPercentage.plus(1)) - .minus(1); - previousNetPerformanceInPercentageWithCurrencyEffect = - previousNetPerformanceInPercentageWithCurrencyEffect - .plus(1) - .mul(netPerformanceInPercentageWithCurrencyEffect.plus(1)) - .minus(1); - - data.push({ - date, - netPerformanceInPercentage: previousNetPerformanceInPercentage - .mul(100) - .toNumber(), - netPerformanceInPercentageWithCurrencyEffect: - previousNetPerformanceInPercentageWithCurrencyEffect - .mul(100) - .toNumber() - }); - } - - return data; - } - - @LogPerformance - protected async handleSingleHolding( - previousDate: string, - holding: string, - date: string, - totalInvestment: Big, - timelineHoldings: { [date: string]: { [symbol: string]: Big } }, - netPerformanceInPercentage: Big, - netPerformanceInPercentageWithCurrencyEffect: Big, - newTotalInvestment: Big - ) { - const previousPrice = - Object.keys(this.marketMap).indexOf(previousDate) > 0 - ? this.marketMap[previousDate][holding] - : undefined; - const priceDictionary = this.marketMap[date]; - let currentPrice = - priceDictionary !== undefined ? priceDictionary[holding] : previousPrice; - currentPrice ??= previousPrice; - const previousHolding = timelineHoldings[previousDate][holding]; - - const priceInBaseCurrency = currentPrice - ? new Big( - await this.exchangeRateDataService.toCurrencyAtDate( - currentPrice?.toNumber() ?? 0, - this.getCurrency(holding), - this.currency, - parseDate(date) - ) - ) - : new Big(0); - - if (previousHolding.eq(0)) { - return { - netPerformanceInPercentage: netPerformanceInPercentage, - netPerformanceInPercentageWithCurrencyEffect: - netPerformanceInPercentageWithCurrencyEffect, - newTotalInvestment: newTotalInvestment.plus( - timelineHoldings[date][holding].mul(priceInBaseCurrency) - ) - }; - } - if (previousPrice === undefined || currentPrice === undefined) { - Logger.warn( - `Missing historical market data for ${holding} (${previousPrice === undefined ? previousDate : date}})`, - 'PortfolioCalculator' - ); - return { - netPerformanceInPercentage: netPerformanceInPercentage, - netPerformanceInPercentageWithCurrencyEffect: - netPerformanceInPercentageWithCurrencyEffect, - newTotalInvestment: newTotalInvestment.plus( - timelineHoldings[date][holding].mul(priceInBaseCurrency) - ) - }; - } - const previousPriceInBaseCurrency = previousPrice - ? new Big( - await this.exchangeRateDataService.toCurrencyAtDate( - previousPrice?.toNumber() ?? 0, - this.getCurrency(holding), - this.currency, - parseDate(previousDate) - ) - ) - : new Big(0); - const portfolioWeight = totalInvestment.toNumber() - ? previousHolding.mul(previousPriceInBaseCurrency).div(totalInvestment) - : new Big(0); - - netPerformanceInPercentage = netPerformanceInPercentage.plus( - currentPrice.div(previousPrice).minus(1).mul(portfolioWeight) - ); - - netPerformanceInPercentageWithCurrencyEffect = - netPerformanceInPercentageWithCurrencyEffect.plus( - priceInBaseCurrency - .div(previousPriceInBaseCurrency) - .minus(1) - .mul(portfolioWeight) - ); - - newTotalInvestment = newTotalInvestment.plus( - timelineHoldings[date][holding].mul(priceInBaseCurrency) - ); - return { - netPerformanceInPercentage, - netPerformanceInPercentageWithCurrencyEffect, - newTotalInvestment - }; - } - - @LogPerformance - protected getCurrency(symbol: string) { - return this.getCurrencyFromActivities(this.activities, symbol); - } - - @LogPerformance - protected getCurrencyFromActivities( - activities: PortfolioOrder[], - symbol: string - ) { - if (!this.holdingCurrencies[symbol]) { - this.holdingCurrencies[symbol] = activities.find( - (a) => a.SymbolProfile.symbol === symbol - ).SymbolProfile.currency; - } - - return this.holdingCurrencies[symbol]; - } - - @LogPerformance - protected async getHoldings( - activities: PortfolioOrder[], - start: Date, - end: Date - ) { - if ( - this.holdings && - Object.keys(this.holdings).some((h) => - isAfter(parseDate(h), subDays(end, 1)) - ) && - Object.keys(this.holdings).some((h) => - isBefore(parseDate(h), addDays(start, 1)) - ) - ) { - return this.holdings; - } - - this.computeHoldings(activities, start, end); - return this.holdings; - } - - @LogPerformance - protected async computeHoldings( - activities: PortfolioOrder[], - start: Date, - end: Date - ) { - const investmentByDate = this.getInvestmentByDate(activities); - this.calculateHoldings(investmentByDate, start, end); - } - - private calculateHoldings( - investmentByDate: { [date: string]: PortfolioOrder[] }, - start: Date, - end: Date - ) { - const transactionDates = Object.keys(investmentByDate).sort(); - const dates = eachDayOfInterval({ start, end }, { step: 1 }) - .map((date) => { - return resetHours(date); - }) - .sort((a, b) => a.getTime() - b.getTime()); - const currentHoldings: { [date: string]: { [symbol: string]: Big } } = {}; - - this.calculateInitialHoldings(investmentByDate, start, currentHoldings); - - for (let i = 1; i < dates.length; i++) { - const dateString = format(dates[i], DATE_FORMAT); - const previousDateString = format(dates[i - 1], DATE_FORMAT); - if (transactionDates.some((d) => d === dateString)) { - const holdings = { ...currentHoldings[previousDateString] }; - investmentByDate[dateString].forEach((trade) => { - holdings[trade.SymbolProfile.symbol] ??= new Big(0); - holdings[trade.SymbolProfile.symbol] = holdings[ - trade.SymbolProfile.symbol - ].plus(trade.quantity.mul(getFactor(trade.type))); - }); - currentHoldings[dateString] = holdings; - } else { - currentHoldings[dateString] = currentHoldings[previousDateString]; - } - } - - this.holdings = currentHoldings; - } - - @LogPerformance - protected calculateInitialHoldings( - investmentByDate: { [date: string]: PortfolioOrder[] }, - start: Date, - currentHoldings: { [date: string]: { [symbol: string]: Big } } - ) { - const preRangeTrades = Object.keys(investmentByDate) - .filter((date) => resetHours(new Date(date)) <= start) - .map((date) => investmentByDate[date]) - .reduce((a, b) => a.concat(b), []) - .reduce((groupBySymbol, trade) => { - if (!groupBySymbol[trade.SymbolProfile.symbol]) { - groupBySymbol[trade.SymbolProfile.symbol] = []; - } - - groupBySymbol[trade.SymbolProfile.symbol].push(trade); - - return groupBySymbol; - }, {}); - - currentHoldings[format(start, DATE_FORMAT)] = {}; - - for (const symbol of Object.keys(preRangeTrades)) { - const trades: PortfolioOrder[] = preRangeTrades[symbol]; - const startQuantity = trades.reduce((sum, trade) => { - return sum.plus(trade.quantity.mul(getFactor(trade.type))); - }, new Big(0)); - currentHoldings[format(start, DATE_FORMAT)][symbol] = startQuantity; - } - } - - @LogPerformance - protected getInvestmentByDate(activities: PortfolioOrder[]): { - [date: string]: PortfolioOrder[]; - } { - return activities.reduce((groupedByDate, order) => { - if (!groupedByDate[order.date]) { - groupedByDate[order.date] = []; - } - - groupedByDate[order.date].push(order); - - return groupedByDate; - }, {}); - } - - @LogPerformance - protected mapToDataGatheringItems( - orders: PortfolioOrder[] - ): IDataGatheringItem[] { - return orders - .map((activity) => { - return { - symbol: activity.SymbolProfile.symbol, - dataSource: activity.SymbolProfile.dataSource - }; - }) - .filter( - (gathering, i, arr) => - arr.findIndex((t) => t.symbol === gathering.symbol) === i - ); - } - - @LogPerformance - protected async computeMarketMap(dateQuery: DateQuery): Promise<{ - [date: string]: { [symbol: string]: Big }; - }> { - const dataGatheringItems: IDataGatheringItem[] = - this.mapToDataGatheringItems(this.activities); - const { values: marketSymbols } = await this.currentRateService.getValues({ - dataGatheringItems, - dateQuery - }); - - const marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - } = {}; - - for (const marketSymbol of marketSymbols) { - const date = format(marketSymbol.date, DATE_FORMAT); - - if (!marketSymbolMap[date]) { - marketSymbolMap[date] = {}; - } - - if (marketSymbol.marketPrice) { - marketSymbolMap[date][marketSymbol.symbol] = new Big( - marketSymbol.marketPrice - ); - } - } - - return marketSymbolMap; - } - - @LogPerformance - protected activitiesToPortfolioOrder( - activities: Activity[] - ): PortfolioOrder[] { - return activities - .map( - ({ - date, - fee, - quantity, - SymbolProfile, - tags = [], - type, - unitPrice - }) => { - if (isAfter(date, new Date(Date.now()))) { - // Adapt date to today if activity is in future (e.g. liability) - // to include it in the interval - date = endOfDay(new Date(Date.now())); - } - - return { - SymbolProfile, - tags, - type, - date: format(date, DATE_FORMAT), - fee: new Big(fee), - quantity: new Big(quantity), - unitPrice: new Big(unitPrice) - }; - } - ) - .sort((a, b) => { - return a.date?.localeCompare(b.date); - }); - } -} diff --git a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts index fab15e6e7..1460892fa 100644 --- a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts @@ -4,12 +4,17 @@ import { SymbolMetrics } from '@ghostfolio/common/interfaces'; import { PortfolioSnapshot } from '@ghostfolio/common/models'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; export class MwrPortfolioCalculator extends PortfolioCalculator { protected calculateOverallPerformance(): PortfolioSnapshot { throw new Error('Method not implemented.'); } + protected getPerformanceCalculationType() { + return PerformanceCalculationType.MWR; + } + protected getSymbolMetrics({}: { end: Date; exchangeRates: { [dateString: string]: number }; diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts index c5a902c29..2c9f7b6f3 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts @@ -6,10 +6,11 @@ export const activityDummyData = { comment: undefined, createdAt: new Date(), currency: undefined, - feeInBaseCurrency: undefined, + fee: undefined, id: undefined, isDraft: false, symbolProfileId: undefined, + unitPrice: undefined, updatedAt: new Date(), userId: undefined, value: undefined, diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index 6dd3210e2..fe4b04cff 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -6,21 +6,17 @@ import { ConfigurationService } from '@ghostfolio/api/services/configuration/con import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { Filter, HistoricalDataItem } from '@ghostfolio/common/interfaces'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Injectable } from '@nestjs/common'; +import { OrderService } from '../../order/order.service'; import { MwrPortfolioCalculator } from './mwr/portfolio-calculator'; import { PortfolioCalculator } from './portfolio-calculator'; import { RoaiPortfolioCalculator } from './roai/portfolio-calculator'; +import { RoiPortfolioCalculator } from './roi/portfolio-calculator'; import { TwrPortfolioCalculator } from './twr/portfolio-calculator'; -export enum PerformanceCalculationType { - MWR = 'MWR', // Money-Weighted Rate of Return - ROAI = 'ROAI', // Return on Average Investment - TWR = 'TWR', // Time-Weighted Rate of Return - CPR = 'CPR' // Constant Portfolio Rate of Return -} - @Injectable() export class PortfolioCalculatorFactory { public constructor( @@ -28,7 +24,8 @@ export class PortfolioCalculatorFactory { private readonly currentRateService: CurrentRateService, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly portfolioSnapshotService: PortfolioSnapshotService, - private readonly redisCacheService: RedisCacheService + private readonly redisCacheService: RedisCacheService, + private readonly orderService: OrderService ) {} @LogPerformance @@ -59,8 +56,10 @@ export class PortfolioCalculatorFactory { currentRateService: this.currentRateService, exchangeRateDataService: this.exchangeRateDataService, portfolioSnapshotService: this.portfolioSnapshotService, - redisCacheService: this.redisCacheService + redisCacheService: this.redisCacheService, + orderService: this.orderService }); + case PerformanceCalculationType.ROAI: return new RoaiPortfolioCalculator({ accountBalanceItems, @@ -72,23 +71,27 @@ export class PortfolioCalculatorFactory { currentRateService: this.currentRateService, exchangeRateDataService: this.exchangeRateDataService, portfolioSnapshotService: this.portfolioSnapshotService, - redisCacheService: this.redisCacheService + redisCacheService: this.redisCacheService, + orderService: this.orderService }); - case PerformanceCalculationType.TWR: - return new TwrPortfolioCalculator({ + + case PerformanceCalculationType.ROI: + return new RoiPortfolioCalculator({ accountBalanceItems, activities, currency, - currentRateService: this.currentRateService, + filters, userId, configurationService: this.configurationService, + currentRateService: this.currentRateService, exchangeRateDataService: this.exchangeRateDataService, portfolioSnapshotService: this.portfolioSnapshotService, redisCacheService: this.redisCacheService, - filters + orderService: this.orderService }); - case PerformanceCalculationType.CPR: - return new RoaiPortfolioCalculator({ + + case PerformanceCalculationType.TWR: + return new TwrPortfolioCalculator({ accountBalanceItems, activities, currency, @@ -98,8 +101,10 @@ export class PortfolioCalculatorFactory { exchangeRateDataService: this.exchangeRateDataService, portfolioSnapshotService: this.portfolioSnapshotService, redisCacheService: this.redisCacheService, + orderService: this.orderService, filters }); + default: throw new Error('Invalid calculation type'); } diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index dd83e798e..629c4b33e 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -35,11 +35,13 @@ import { } from '@ghostfolio/common/interfaces'; import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; import { GroupBy } from '@ghostfolio/common/types'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; import { plainToClass } from 'class-transformer'; import { + addDays, differenceInDays, eachDayOfInterval, endOfDay, @@ -51,6 +53,8 @@ import { } from 'date-fns'; import { isNumber, sortBy, sum, uniqBy } from 'lodash'; +import { OrderService } from '../../order/order.service'; + export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -63,6 +67,7 @@ export abstract class PortfolioCalculator { private dataProviderInfos: DataProviderInfo[]; private endDate: Date; protected exchangeRateDataService: ExchangeRateDataService; + protected orderService: OrderService; private filters: Filter[]; private portfolioSnapshotService: PortfolioSnapshotService; private redisCacheService: RedisCacheService; @@ -72,6 +77,8 @@ export abstract class PortfolioCalculator { private transactionPoints: TransactionPoint[]; protected userId: string; protected marketMap: { [date: string]: { [symbol: string]: Big } } = {}; + private holdings: { [date: string]: { [symbol: string]: Big } } = {}; + private holdingCurrencies: { [symbol: string]: string } = {}; public constructor({ accountBalanceItems, @@ -83,7 +90,8 @@ export abstract class PortfolioCalculator { filters, portfolioSnapshotService, redisCacheService, - userId + userId, + orderService }: { accountBalanceItems: HistoricalDataItem[]; activities: Activity[]; @@ -95,6 +103,7 @@ export abstract class PortfolioCalculator { portfolioSnapshotService: PortfolioSnapshotService; redisCacheService: RedisCacheService; userId: string; + orderService: OrderService; }) { this.accountBalanceItems = accountBalanceItems; this.configurationService = configurationService; @@ -102,6 +111,7 @@ export abstract class PortfolioCalculator { this.currentRateService = currentRateService; this.exchangeRateDataService = exchangeRateDataService; this.filters = filters; + this.orderService = orderService; let dateOfFirstActivity = new Date(); @@ -113,12 +123,12 @@ export abstract class PortfolioCalculator { .map( ({ date, - fee, + feeInAssetProfileCurrency, quantity, SymbolProfile, tags = [], type, - unitPrice + unitPriceInAssetProfileCurrency }) => { if (isBefore(date, dateOfFirstActivity)) { dateOfFirstActivity = date; @@ -135,9 +145,9 @@ export abstract class PortfolioCalculator { tags, type, date: format(date, DATE_FORMAT), - fee: new Big(fee), + fee: new Big(feeInAssetProfileCurrency), quantity: new Big(quantity), - unitPrice: new Big(unitPrice) + unitPrice: new Big(unitPriceInAssetProfileCurrency) }; } ) @@ -612,6 +622,78 @@ export abstract class PortfolioCalculator { }; } + @LogPerformance + public async getUnfilteredNetWorth(currency: string): Promise { + const activities = await this.orderService.getOrders({ + userId: this.userId, + userCurrency: currency, + types: ['BUY', 'SELL', 'STAKE'], + withExcludedAccounts: true + }); + const orders = this.activitiesToPortfolioOrder(activities.activities); + const start = orders.reduce( + (date, order) => + parseDate(date.date).getTime() < parseDate(order.date).getTime() + ? date + : order, + { date: orders[0].date } + ).date; + + const end = new Date(Date.now()); + + const holdings = await this.getHoldings(orders, parseDate(start), end); + const marketMap = await this.currentRateService.getValues({ + dataGatheringItems: this.mapToDataGatheringItems(orders), + dateQuery: { in: [end] } + }); + const endString = format(end, DATE_FORMAT); + const exchangeRates = await Promise.all( + Object.keys(holdings[endString]).map(async (holding) => { + const symbolCurrency = this.getCurrencyFromActivities(orders, holding); + const exchangeRate = + await this.exchangeRateDataService.toCurrencyAtDate( + 1, + symbolCurrency, + this.currency, + end + ); + return { symbolCurrency, exchangeRate }; + }) + ); + const currencyRates = exchangeRates.reduce<{ [currency: string]: number }>( + (all, currency): { [currency: string]: number } => { + all[currency.symbolCurrency] ??= currency.exchangeRate; + return all; + }, + {} + ); + + const totalInvestment = await Object.keys(holdings[endString]).reduce( + (sum, holding) => { + if (!holdings[endString][holding].toNumber()) { + return sum; + } + const symbol = marketMap.values.find((m) => m.symbol === holding); + + if (symbol?.marketPrice === undefined) { + Logger.warn( + `Missing historical market data for ${holding} (${end})`, + 'PortfolioCalculator' + ); + return sum; + } else { + const symbolCurrency = this.getCurrency(holding); + const price = new Big(currencyRates[symbolCurrency]).mul( + symbol.marketPrice + ); + return sum.plus(new Big(price).mul(holdings[endString][holding])); + } + }, + new Big(0) + ); + return totalInvestment; + } + @LogPerformance public getDataProviderInfos() { return this.dataProviderInfos; @@ -802,6 +884,25 @@ export abstract class PortfolioCalculator { return this.snapshot; } + @LogPerformance + protected getCurrency(symbol: string) { + return this.getCurrencyFromActivities(this.activities, symbol); + } + + @LogPerformance + protected getCurrencyFromActivities( + activities: PortfolioOrder[], + symbol: string + ) { + if (!this.holdingCurrencies[symbol]) { + this.holdingCurrencies[symbol] = activities.find( + (a) => a.SymbolProfile.symbol === symbol + ).SymbolProfile.currency; + } + + return this.holdingCurrencies[symbol]; + } + @LogPerformance protected computeTransactionPoints() { this.transactionPoints = []; @@ -985,6 +1086,7 @@ export abstract class PortfolioCalculator { // Compute in the background this.portfolioSnapshotService.addJobToQueue({ data: { + calculationType: this.getPerformanceCalculationType(), filters: this.filters, userCurrency: this.currency, userId: this.userId @@ -1001,6 +1103,7 @@ export abstract class PortfolioCalculator { // Wait for computation await this.portfolioSnapshotService.addJobToQueue({ data: { + calculationType: this.getPerformanceCalculationType(), filters: this.filters, userCurrency: this.currency, userId: this.userId @@ -1023,6 +1126,173 @@ export abstract class PortfolioCalculator { } } + @LogPerformance + protected activitiesToPortfolioOrder( + activities: Activity[] + ): PortfolioOrder[] { + return activities + .map( + ({ + date, + fee, + quantity, + SymbolProfile, + tags = [], + type, + unitPrice + }) => { + if (isAfter(date, new Date(Date.now()))) { + // Adapt date to today if activity is in future (e.g. liability) + // to include it in the interval + date = endOfDay(new Date(Date.now())); + } + + return { + SymbolProfile, + tags, + type, + date: format(date, DATE_FORMAT), + fee: new Big(fee), + quantity: new Big(quantity), + unitPrice: new Big(unitPrice) + }; + } + ) + .sort((a, b) => { + return a.date?.localeCompare(b.date); + }); + } + + @LogPerformance + protected async getHoldings( + activities: PortfolioOrder[], + start: Date, + end: Date + ) { + if ( + this.holdings && + Object.keys(this.holdings).some((h) => + isAfter(parseDate(h), subDays(end, 1)) + ) && + Object.keys(this.holdings).some((h) => + isBefore(parseDate(h), addDays(start, 1)) + ) + ) { + return this.holdings; + } + + this.computeHoldings(activities, start, end); + return this.holdings; + } + + @LogPerformance + protected async computeHoldings( + activities: PortfolioOrder[], + start: Date, + end: Date + ) { + const investmentByDate = this.getInvestmentByDate(activities); + this.calculateHoldings(investmentByDate, start, end); + } + + @LogPerformance + protected calculateInitialHoldings( + investmentByDate: { [date: string]: PortfolioOrder[] }, + start: Date, + currentHoldings: { [date: string]: { [symbol: string]: Big } } + ) { + const preRangeTrades = Object.keys(investmentByDate) + .filter((date) => resetHours(new Date(date)) <= start) + .map((date) => investmentByDate[date]) + .reduce((a, b) => a.concat(b), []) + .reduce((groupBySymbol, trade) => { + if (!groupBySymbol[trade.SymbolProfile.symbol]) { + groupBySymbol[trade.SymbolProfile.symbol] = []; + } + + groupBySymbol[trade.SymbolProfile.symbol].push(trade); + + return groupBySymbol; + }, {}); + + currentHoldings[format(start, DATE_FORMAT)] = {}; + + for (const symbol of Object.keys(preRangeTrades)) { + const trades: PortfolioOrder[] = preRangeTrades[symbol]; + const startQuantity = trades.reduce((sum, trade) => { + return sum.plus(trade.quantity.mul(getFactor(trade.type))); + }, new Big(0)); + currentHoldings[format(start, DATE_FORMAT)][symbol] = startQuantity; + } + } + + @LogPerformance + protected getInvestmentByDate(activities: PortfolioOrder[]): { + [date: string]: PortfolioOrder[]; + } { + return activities.reduce((groupedByDate, order) => { + if (!groupedByDate[order.date]) { + groupedByDate[order.date] = []; + } + + groupedByDate[order.date].push(order); + + return groupedByDate; + }, {}); + } + + @LogPerformance + protected mapToDataGatheringItems( + orders: PortfolioOrder[] + ): IDataGatheringItem[] { + return orders + .map((activity) => { + return { + symbol: activity.SymbolProfile.symbol, + dataSource: activity.SymbolProfile.dataSource + }; + }) + .filter( + (gathering, i, arr) => + arr.findIndex((t) => t.symbol === gathering.symbol) === i + ); + } + + private calculateHoldings( + investmentByDate: { [date: string]: PortfolioOrder[] }, + start: Date, + end: Date + ) { + const transactionDates = Object.keys(investmentByDate).sort(); + const dates = eachDayOfInterval({ start, end }, { step: 1 }) + .map((date) => { + return resetHours(date); + }) + .sort((a, b) => a.getTime() - b.getTime()); + const currentHoldings: { [date: string]: { [symbol: string]: Big } } = {}; + + this.calculateInitialHoldings(investmentByDate, start, currentHoldings); + + for (let i = 1; i < dates.length; i++) { + const dateString = format(dates[i], DATE_FORMAT); + const previousDateString = format(dates[i - 1], DATE_FORMAT); + if (transactionDates.some((d) => d === dateString)) { + const holdings = { ...currentHoldings[previousDateString] }; + investmentByDate[dateString].forEach((trade) => { + holdings[trade.SymbolProfile.symbol] ??= new Big(0); + holdings[trade.SymbolProfile.symbol] = holdings[ + trade.SymbolProfile.symbol + ].plus(trade.quantity.mul(getFactor(trade.type))); + }); + currentHoldings[dateString] = holdings; + } else { + currentHoldings[dateString] = currentHoldings[previousDateString]; + } + } + + this.holdings = currentHoldings; + } + private getChartDateMap({ endDate, startDate, @@ -1110,4 +1380,6 @@ export abstract class PortfolioCalculator { protected abstract calculateOverallPerformance( positions: TimelinePosition[] ): PortfolioSnapshot; + + protected abstract getPerformanceCalculationType(): PerformanceCalculationType; } diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index c5325ee7f..4c46ae6d1 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PortfolioCalculatorFactory, - PerformanceCalculationType -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -17,6 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -79,7 +77,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -91,7 +90,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2021-11-22'), - fee: 1.55, + feeInAssetProfileCurrency: 1.55, quantity: 2, SymbolProfile: { ...symbolProfileDummyData, @@ -101,12 +100,12 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW' }, type: 'BUY', - unitPrice: 142.9 + unitPriceInAssetProfileCurrency: 142.9 }, { ...activityDummyData, date: new Date('2021-11-30'), - fee: 1.65, + feeInAssetProfileCurrency: 1.65, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -116,12 +115,12 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW' }, type: 'SELL', - unitPrice: 136.6 + unitPriceInAssetProfileCurrency: 136.6 }, { ...activityDummyData, date: new Date('2021-11-30'), - fee: 0, + feeInAssetProfileCurrency: 0, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -131,7 +130,7 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW' }, type: 'SELL', - unitPrice: 136.6 + unitPriceInAssetProfileCurrency: 136.6 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts index 8ca8d8c2f..a65ee9c90 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -17,6 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -79,7 +77,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -91,7 +90,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2021-11-22'), - fee: 1.55, + feeInAssetProfileCurrency: 1.55, quantity: 2, SymbolProfile: { ...symbolProfileDummyData, @@ -101,12 +100,12 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW' }, type: 'BUY', - unitPrice: 142.9 + unitPriceInAssetProfileCurrency: 142.9 }, { ...activityDummyData, date: new Date('2021-11-30'), - fee: 1.65, + feeInAssetProfileCurrency: 1.65, quantity: 2, SymbolProfile: { ...symbolProfileDummyData, @@ -116,7 +115,7 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW' }, type: 'SELL', - unitPrice: 136.6 + unitPriceInAssetProfileCurrency: 136.6 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts index 63a4d77b4..b123647c1 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-baln-buy.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PortfolioCalculatorFactory, - PerformanceCalculationType -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -17,6 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -79,7 +77,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -91,7 +90,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2021-11-30'), - fee: 1.55, + feeInAssetProfileCurrency: 1.55, quantity: 2, SymbolProfile: { ...symbolProfileDummyData, @@ -101,7 +100,7 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW' }, type: 'BUY', - unitPrice: 136.6 + unitPriceInAssetProfileCurrency: 136.6 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 2853e3d87..2ad0f84bc 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PortfolioCalculatorFactory, - PerformanceCalculationType -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -18,6 +15,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -92,7 +90,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -105,7 +104,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2015-01-01'), - fee: 0, + feeInAssetProfileCurrency: 0, quantity: 2, SymbolProfile: { ...symbolProfileDummyData, @@ -115,12 +114,12 @@ describe('PortfolioCalculator', () => { symbol: 'BTCUSD' }, type: 'BUY', - unitPrice: 320.43 + unitPriceInAssetProfileCurrency: 320.43 }, { ...activityDummyData, date: new Date('2017-12-31'), - fee: 0, + feeInAssetProfileCurrency: 0, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -130,7 +129,7 @@ describe('PortfolioCalculator', () => { symbol: 'BTCUSD' }, type: 'SELL', - unitPrice: 14156.4 + unitPriceInAssetProfileCurrency: 14156.4 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts index b96e4f540..fb8f81c41 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PortfolioCalculatorFactory, - PerformanceCalculationType -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -17,6 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -79,7 +77,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -91,7 +90,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2021-09-01'), - fee: 49, + feeInAssetProfileCurrency: 49, quantity: 0, SymbolProfile: { ...symbolProfileDummyData, @@ -101,7 +100,7 @@ describe('PortfolioCalculator', () => { symbol: '2c463fb3-af07-486e-adb0-8301b3d72141' }, type: 'FEE', - unitPrice: 0 + unitPriceInAssetProfileCurrency: 0 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts index a80dd192e..8ed8b4830 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-googl-buy.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PortfolioCalculatorFactory, - PerformanceCalculationType -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -18,6 +15,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -92,7 +90,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -104,7 +103,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2023-01-03'), - fee: 1, + feeInAssetProfileCurrency: 1, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -114,7 +113,7 @@ describe('PortfolioCalculator', () => { symbol: 'GOOGL' }, type: 'BUY', - unitPrice: 89.12 + unitPriceInAssetProfileCurrency: 89.12 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-item.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-item.spec.ts index d226fe6f8..47ffa7d32 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-item.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-item.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PortfolioCalculatorFactory, - PerformanceCalculationType -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -17,6 +14,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -79,7 +77,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -91,7 +90,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2022-01-01'), - fee: 0, + feeInAssetProfileCurrency: 0, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -101,7 +100,7 @@ describe('PortfolioCalculator', () => { symbol: 'dac95060-d4f2-4653-a253-2c45e6fb5cde' }, type: 'ITEM', - unitPrice: 500000 + unitPriceInAssetProfileCurrency: 500000 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-liability.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-liability.spec.ts index 569212b9a..50b701415 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-liability.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-liability.spec.ts @@ -1,13 +1,11 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { activityDummyData, symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PortfolioCalculatorFactory, - PerformanceCalculationType -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -17,6 +15,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -57,6 +56,7 @@ describe('PortfolioCalculator', () => { let portfolioCalculatorFactory: PortfolioCalculatorFactory; let portfolioSnapshotService: PortfolioSnapshotService; let redisCacheService: RedisCacheService; + let orderServiceMock: OrderService; beforeEach(() => { configurationService = new ConfigurationService(); @@ -74,12 +74,15 @@ describe('PortfolioCalculator', () => { redisCacheService = new RedisCacheService(null, null); + orderServiceMock = new OrderService(null, null, null, null, null, null); + portfolioCalculatorFactory = new PortfolioCalculatorFactory( configurationService, currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + orderServiceMock ); }); @@ -91,7 +94,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2023-01-01'), // Date in future - fee: 0, + feeInAssetProfileCurrency: 0, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -101,7 +104,7 @@ describe('PortfolioCalculator', () => { symbol: '55196015-1365-4560-aa60-8751ae6d18f8' }, type: 'LIABILITY', - unitPrice: 3000 + unitPriceInAssetProfileCurrency: 3000 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts index 4c54ba7aa..2dcb12753 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -4,10 +4,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -18,6 +15,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -92,7 +90,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -104,7 +103,7 @@ describe('PortfolioCalculator', () => { { ...activityDummyData, date: new Date('2021-09-16'), - fee: 19, + feeInAssetProfileCurrency: 19, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -114,12 +113,12 @@ describe('PortfolioCalculator', () => { symbol: 'MSFT' }, type: 'BUY', - unitPrice: 298.58 + unitPriceInAssetProfileCurrency: 298.58 }, { ...activityDummyData, date: new Date('2021-11-16'), - fee: 0, + feeInAssetProfileCurrency: 0, quantity: 1, SymbolProfile: { ...symbolProfileDummyData, @@ -129,7 +128,7 @@ describe('PortfolioCalculator', () => { symbol: 'MSFT' }, type: 'DIVIDEND', - unitPrice: 0.62 + unitPriceInAssetProfileCurrency: 0.62 } ]; diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts index 77e3f6157..ad33e6b82 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-no-orders.spec.ts @@ -1,8 +1,5 @@ import { userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -12,6 +9,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; @@ -74,7 +72,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index 895118ac4..9399f93dd 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -6,10 +6,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -19,6 +16,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; import { join } from 'path'; @@ -93,7 +91,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -105,13 +104,15 @@ describe('PortfolioCalculator', () => { ...activityDummyData, ...activity, date: parseDate(activity.date), + feeInAssetProfileCurrency: activity.fee, SymbolProfile: { ...symbolProfileDummyData, currency: activity.currency, dataSource: activity.dataSource, name: 'Novartis AG', symbol: activity.symbol - } + }, + unitPriceInAssetProfileCurrency: activity.unitPrice })); const portfolioCalculator = portfolioCalculatorFactory.createCalculator({ diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell.spec.ts index 589f4c0ac..e1f98d293 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -6,10 +6,7 @@ import { symbolProfileDummyData, userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; @@ -19,6 +16,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Big } from 'big.js'; import { join } from 'path'; @@ -93,7 +91,8 @@ describe('PortfolioCalculator', () => { currentRateService, exchangeRateDataService, portfolioSnapshotService, - redisCacheService + redisCacheService, + null ); }); @@ -105,13 +104,15 @@ describe('PortfolioCalculator', () => { ...activityDummyData, ...activity, date: parseDate(activity.date), + feeInAssetProfileCurrency: activity.fee, SymbolProfile: { ...symbolProfileDummyData, currency: activity.currency, dataSource: activity.dataSource, name: 'Novartis AG', symbol: activity.symbol - } + }, + unitPriceInAssetProfileCurrency: activity.unitPrice })); const portfolioCalculator = portfolioCalculatorFactory.createCalculator({ diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts index 8ff3f1de0..4fa07e1ac 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts @@ -9,6 +9,7 @@ import { } from '@ghostfolio/common/interfaces'; import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; import { DateRange } from '@ghostfolio/common/types'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; @@ -112,6 +113,10 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { }; } + protected getPerformanceCalculationType() { + return PerformanceCalculationType.ROAI; + } + protected getSymbolMetrics({ chartDateMap, dataSource, diff --git a/apps/api/src/app/portfolio/calculator/roi/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/roi/portfolio-calculator.ts new file mode 100644 index 000000000..b4929c570 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/roi/portfolio-calculator.ts @@ -0,0 +1,29 @@ +import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; +import { + AssetProfileIdentifier, + SymbolMetrics +} from '@ghostfolio/common/interfaces'; +import { PortfolioSnapshot } from '@ghostfolio/common/models'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; + +export class RoiPortfolioCalculator extends PortfolioCalculator { + protected calculateOverallPerformance(): PortfolioSnapshot { + throw new Error('Method not implemented.'); + } + + protected getPerformanceCalculationType() { + return PerformanceCalculationType.ROI; + } + + protected getSymbolMetrics({}: { + end: Date; + exchangeRates: { [dateString: string]: number }; + marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + }; + start: Date; + step?: number; + } & AssetProfileIdentifier): SymbolMetrics { + throw new Error('Method not implemented.'); + } +} diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 6499ca3db..8a58f816a 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -4,12 +4,17 @@ import { SymbolMetrics } from '@ghostfolio/common/interfaces'; import { PortfolioSnapshot } from '@ghostfolio/common/models'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; export class TwrPortfolioCalculator extends PortfolioCalculator { protected calculateOverallPerformance(): PortfolioSnapshot { throw new Error('Method not implemented.'); } + protected getPerformanceCalculationType() { + return PerformanceCalculationType.TWR; + } + protected getSymbolMetrics({}: { end: Date; exchangeRates: { [dateString: string]: number }; diff --git a/apps/api/src/app/portfolio/current-rate.service.spec.ts b/apps/api/src/app/portfolio/current-rate.service.spec.ts index d0e61c8ce..d8b7482e7 100644 --- a/apps/api/src/app/portfolio/current-rate.service.spec.ts +++ b/apps/api/src/app/portfolio/current-rate.service.spec.ts @@ -6,6 +6,7 @@ import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { DataSource, MarketData } from '@prisma/client'; import { CurrentRateService } from './current-rate.service'; +import { DateQuery } from './interfaces/date-query.interface'; import { GetValuesObject } from './interfaces/get-values-object.interface'; jest.mock('@ghostfolio/api/services/market-data/market-data.service', () => { @@ -25,33 +26,40 @@ jest.mock('@ghostfolio/api/services/market-data/market-data.service', () => { }, getRange: ({ assetProfileIdentifiers, - dateRangeEnd, - dateRangeStart + dateQuery }: { assetProfileIdentifiers: AssetProfileIdentifier[]; - dateRangeEnd: Date; - dateRangeStart: Date; + dateQuery: DateQuery; + skip?: number; + take?: number; }) => { return Promise.resolve([ { - createdAt: dateRangeStart, + createdAt: dateQuery.gte, dataSource: assetProfileIdentifiers[0].dataSource, - date: dateRangeStart, + date: dateQuery.gte, id: '8fa48fde-f397-4b0d-adbc-fb940e830e6d', marketPrice: 1841.823902, state: 'CLOSE', symbol: assetProfileIdentifiers[0].symbol }, { - createdAt: dateRangeEnd, + createdAt: dateQuery.lt, dataSource: assetProfileIdentifiers[0].dataSource, - date: dateRangeEnd, + date: dateQuery.lt, id: '082d6893-df27-4c91-8a5d-092e84315b56', marketPrice: 1847.839966, state: 'CLOSE', symbol: assetProfileIdentifiers[0].symbol } ]); + }, + getRangeCount: ({}: { + assetProfileIdentifiers: AssetProfileIdentifier[]; + dateRangeEnd: Date; + dateRangeStart: Date; + }) => { + return Promise.resolve(2); } }; }) @@ -128,9 +136,15 @@ describe('CurrentRateService', () => { values: [ { dataSource: 'YAHOO', - date: undefined, + date: new Date('2020-01-01T00:00:00.000Z'), marketPrice: 1841.823902, symbol: 'AMZN' + }, + { + dataSource: 'YAHOO', + date: new Date('2020-01-02T00:00:00.000Z'), + marketPrice: 1847.839966, + symbol: 'AMZN' } ] }); diff --git a/apps/api/src/app/portfolio/current-rate.service.ts b/apps/api/src/app/portfolio/current-rate.service.ts index 058bf1dd5..5d39a54bb 100644 --- a/apps/api/src/app/portfolio/current-rate.service.ts +++ b/apps/api/src/app/portfolio/current-rate.service.ts @@ -21,6 +21,8 @@ import { GetValuesParams } from './interfaces/get-values-params.interface'; @Injectable() export class CurrentRateService { + private static readonly MARKET_DATA_PAGE_SIZE = 50000; + public constructor( private readonly dataProviderService: DataProviderService, private readonly marketDataService: MarketDataService, @@ -41,42 +43,37 @@ export class CurrentRateService { (!dateQuery.gte || isBefore(dateQuery.gte, new Date())) && (!dateQuery.in || this.containsToday(dateQuery.in)); - const promises: Promise[] = []; const quoteErrors: ResponseError['errors'] = []; const today = resetHours(new Date()); + const values: GetValueObject[] = []; if (includesToday) { - promises.push( - this.dataProviderService - .getQuotes({ items: dataGatheringItems, user: this.request?.user }) - .then((dataResultProvider) => { - const result: GetValueObject[] = []; - - for (const { dataSource, symbol } of dataGatheringItems) { - if (dataResultProvider?.[symbol]?.dataProviderInfo) { - dataProviderInfos.push( - dataResultProvider[symbol].dataProviderInfo - ); - } + const quotesBySymbol = await this.dataProviderService.getQuotes({ + items: dataGatheringItems, + user: this.request?.user + }); - if (dataResultProvider?.[symbol]?.marketPrice) { - result.push({ - dataSource, - symbol, - date: today, - marketPrice: dataResultProvider?.[symbol]?.marketPrice - }); - } else { - quoteErrors.push({ - dataSource, - symbol - }); - } - } + for (const { dataSource, symbol } of dataGatheringItems) { + const quote = quotesBySymbol[symbol]; - return result; - }) - ); + if (quote?.dataProviderInfo) { + dataProviderInfos.push(quote.dataProviderInfo); + } + + if (quote?.marketPrice) { + values.push({ + dataSource, + symbol, + date: today, + marketPrice: quote.marketPrice + }); + } else { + quoteErrors.push({ + dataSource, + symbol + }); + } + } } const assetProfileIdentifiers: AssetProfileIdentifier[] = @@ -84,34 +81,42 @@ export class CurrentRateService { return { dataSource, symbol }; }); - promises.push( - this.marketDataService - .getRange({ - assetProfileIdentifiers, - dateQuery - }) - .then((data) => { - return data.map(({ dataSource, date, marketPrice, symbol }) => { - return { - dataSource, - date, - marketPrice, - symbol - }; - }); - }) - ); - - const values = await Promise.all(promises).then((array) => { - return array.flat(); + const marketDataCount = await this.marketDataService.getRangeCount({ + assetProfileIdentifiers, + dateQuery }); + for ( + let i = 0; + i < marketDataCount; + i += CurrentRateService.MARKET_DATA_PAGE_SIZE + ) { + // Use page size to limit the number of records fetched at once + const data = await this.marketDataService.getRange({ + assetProfileIdentifiers, + dateQuery, + skip: i, + take: CurrentRateService.MARKET_DATA_PAGE_SIZE + }); + + values.push( + ...data.map(({ dataSource, date, marketPrice, symbol }) => ({ + dataSource, + date, + marketPrice, + symbol + })) + ); + } + const response: GetValuesObject = { dataProviderInfos, errors: quoteErrors.map(({ dataSource, symbol }) => { return { dataSource, symbol }; }), - values: uniqBy(values, ({ date, symbol }) => `${date}-${symbol}`) + values: uniqBy(values, ({ date, symbol }) => { + return `${date}-${symbol}`; + }) }; if (!isEmpty(quoteErrors)) { diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index c00db4b40..92371fb26 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -506,8 +506,7 @@ export class PortfolioController { @Query('range') dateRange: DateRange = 'max', @Query('symbol') filterBySymbol?: string, @Query('tags') filterByTags?: string, - @Query('withExcludedAccounts') withExcludedAccounts = false, - @Query('timeWeightedPerformance') calculateTimeWeightedPerformance = false + @Query('withExcludedAccounts') withExcludedAccounts = false ): Promise { const filters = this.apiService.buildFiltersFromQueryParams({ filterByAccounts, @@ -522,8 +521,7 @@ export class PortfolioController { filters, impersonationId, withExcludedAccounts, - userId: this.request.user.id, - calculateTimeWeightedPerformance + userId: this.request.user.id }); if ( diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 11d7125bf..2fab5e5ec 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -51,13 +51,14 @@ import { UserSettings } from '@ghostfolio/common/interfaces'; import { TimelinePosition } from '@ghostfolio/common/models'; -import type { +import { AccountWithValue, DateRange, GroupBy, RequestWithUser, UserWithSettings } from '@ghostfolio/common/types'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Inject, Injectable } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; @@ -85,12 +86,8 @@ import { } from 'date-fns'; import { isEmpty, uniqBy } from 'lodash'; -import { CPRPortfolioCalculator } from './calculator/constantPortfolioReturn/portfolio-calculator'; import { PortfolioCalculator } from './calculator/portfolio-calculator'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from './calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from './calculator/portfolio-calculator.factory'; import { PortfolioHoldingDetail } from './interfaces/portfolio-holding-detail.interface'; import { RulesService } from './rules.service'; @@ -251,10 +248,14 @@ export class PortfolioService { activities: Activity[]; groupBy?: GroupBy; }): Promise { - let dividends = activities.map(({ date, valueInBaseCurrency }) => { + let dividends = activities.map(({ currency, date, value }) => { return { date: format(date, DATE_FORMAT), - investment: valueInBaseCurrency + investment: this.exchangeRateDataService.toCurrency( + value, + currency, + this.getUserCurrency() + ) }; }); @@ -280,14 +281,16 @@ export class PortfolioService { savingsRate: number; }): Promise { const userId = await this.getUserId(impersonationId, this.request.user.id); + const user = await this.userService.user({ id: userId }); + const userCurrency = this.getUserCurrency(user); const { endDate, startDate } = getIntervalFromDateRange(dateRange); const { activities } = await this.orderService.getOrdersForPortfolioCalculator({ filters, - userId, - userCurrency: this.getUserCurrency() + userCurrency, + userId }); if (activities.length === 0) { @@ -301,8 +304,8 @@ export class PortfolioService { activities, filters, userId, - calculationType: PerformanceCalculationType.ROAI, - currency: this.request.user.Settings.settings.baseCurrency + calculationType: this.getUserPerformanceCalculationType(user), + currency: userCurrency }); const { historicalData } = await portfolioCalculator.getSnapshot(); @@ -379,7 +382,7 @@ export class PortfolioService { activities, filters, userId, - calculationType: PerformanceCalculationType.ROAI, + calculationType: this.getUserPerformanceCalculationType(user), currency: userCurrency }); @@ -693,7 +696,7 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, userId, - calculationType: PerformanceCalculationType.ROAI, + calculationType: this.getUserPerformanceCalculationType(user), currency: userCurrency }); @@ -957,12 +960,13 @@ export class PortfolioService { })?.id; const userId = await this.getUserId(impersonationId, this.request.user.id); const user = await this.userService.user({ id: userId }); + const userCurrency = this.getUserCurrency(user); const { activities } = await this.orderService.getOrdersForPortfolioCalculator({ filters, - userId, - userCurrency: this.getUserCurrency() + userCurrency, + userId }); if (activities.length === 0) { @@ -976,8 +980,8 @@ export class PortfolioService { activities, filters, userId, - calculationType: PerformanceCalculationType.ROAI, - currency: this.request.user.Settings.settings.baseCurrency + calculationType: this.getUserPerformanceCalculationType(user), + currency: userCurrency }); const portfolioSnapshot = await portfolioCalculator.getSnapshot(); @@ -1097,15 +1101,13 @@ export class PortfolioService { dateRange = 'max', filters, impersonationId, - userId, - calculateTimeWeightedPerformance = false + userId }: { dateRange?: DateRange; filters?: Filter[]; impersonationId: string; userId: string; withExcludedAccounts?: boolean; - calculateTimeWeightedPerformance?: boolean; }): Promise { userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); @@ -1146,18 +1148,14 @@ export class PortfolioService { activities, filters, userId, - calculationType: PerformanceCalculationType.ROAI, + calculationType: this.getUserPerformanceCalculationType(user), currency: userCurrency }); const { endDate, startDate } = getIntervalFromDateRange(dateRange); const range = { end: endDate, start: startDate }; - const { chart } = await (calculateTimeWeightedPerformance - ? ( - portfolioCalculator as CPRPortfolioCalculator - ).getPerformanceWithTimeWeightedReturn(range) - : portfolioCalculator.getPerformance(range)); + const { chart } = await portfolioCalculator.getPerformance(range); const { netPerformance, @@ -1927,17 +1925,9 @@ export class PortfolioService { .plus(totalOfExcludedActivities) .toNumber(); - const netWorth = - portfolioCalculator instanceof CPRPortfolioCalculator - ? await (portfolioCalculator as CPRPortfolioCalculator) - .getUnfilteredNetWorth(this.getUserCurrency()) - .then((value) => value.toNumber()) - : new Big(balanceInBaseCurrency) - .plus(currentValueInBaseCurrency) - .plus(valuables) - .plus(excludedAccountsAndActivities) - .minus(liabilities) - .toNumber(); + const netWorth = await portfolioCalculator + .getUnfilteredNetWorth(this.getUserCurrency()) + .then((value) => value.toNumber()); const daysInMarket = differenceInDays(new Date(), firstOrderDate); @@ -2057,6 +2047,12 @@ export class PortfolioService { return impersonationUserId || aUserId; } + private getUserPerformanceCalculationType( + aUser: UserWithSettings + ): PerformanceCalculationType { + return aUser?.Settings?.settings.performanceCalculationType; + } + @LogPerformance private async getValueOfAccountsAndPlatforms({ activities, diff --git a/apps/api/src/app/subscription/subscription.service.ts b/apps/api/src/app/subscription/subscription.service.ts index ae0260d8c..063c40608 100644 --- a/apps/api/src/app/subscription/subscription.service.ts +++ b/apps/api/src/app/subscription/subscription.service.ts @@ -122,7 +122,7 @@ export class SubscriptionService { data: { expiresAt, price, - User: { + user: { connect: { id: userId } @@ -158,38 +158,67 @@ export class SubscriptionService { } } - public getSubscription({ + public async getSubscription({ createdAt, subscriptions }: { createdAt: UserWithSettings['createdAt']; subscriptions: Subscription[]; - }): UserWithSettings['subscription'] { + }): Promise { if (subscriptions.length > 0) { const { expiresAt, price } = subscriptions.reduce((a, b) => { return new Date(a.expiresAt) > new Date(b.expiresAt) ? a : b; }); - let offer: SubscriptionOfferKey = price ? 'renewal' : 'default'; + let offerKey: SubscriptionOfferKey = price ? 'renewal' : 'default'; if (isBefore(createdAt, parseDate('2023-01-01'))) { - offer = 'renewal-early-bird-2023'; + offerKey = 'renewal-early-bird-2023'; } else if (isBefore(createdAt, parseDate('2024-01-01'))) { - offer = 'renewal-early-bird-2024'; + offerKey = 'renewal-early-bird-2024'; } + const offer = await this.getSubscriptionOffer({ + key: offerKey + }); + return { - expiresAt, offer, + expiresAt: isBefore(new Date(), expiresAt) ? expiresAt : undefined, type: isBefore(new Date(), expiresAt) ? SubscriptionType.Premium : SubscriptionType.Basic }; } else { + const offer = await this.getSubscriptionOffer({ + key: 'default' + }); + return { - offer: 'default', + offer, type: SubscriptionType.Basic }; } } + + public async getSubscriptionOffer({ + key + }: { + key: SubscriptionOfferKey; + }): Promise { + if (!this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { + return undefined; + } + + const offers: { + [offer in SubscriptionOfferKey]: SubscriptionOffer; + } = + ((await this.propertyService.getByKey(PROPERTY_STRIPE_CONFIG)) as any) ?? + {}; + + return { + ...offers[key], + isRenewal: key.startsWith('renewal') + }; + } } diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index e9b8078b1..b6b31dada 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -41,6 +41,7 @@ import { permissions } from '@ghostfolio/common/permissions'; import { UserWithSettings } from '@ghostfolio/common/types'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { Injectable } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; @@ -189,7 +190,7 @@ export class UserService { provider, role, Settings, - Subscription, + subscriptions, thirdPartyId, updatedAt } = await this.prismaService.user.findUnique({ @@ -200,7 +201,7 @@ export class UserService { }, Analytics: true, Settings: true, - Subscription: true + subscriptions: true }, where: userWhereUniqueInput }); @@ -246,6 +247,12 @@ export class UserService { ? 'max' : ((user.Settings.settings as UserSettings)?.dateRange ?? 'max'); + // Set default value for performance calculation type + if (!(user.Settings.settings as UserSettings)?.performanceCalculationType) { + (user.Settings.settings as UserSettings).performanceCalculationType = + PerformanceCalculationType.ROAI; + } + // Set default value for view mode if (!(user.Settings.settings as UserSettings).viewMode) { (user.Settings.settings as UserSettings).viewMode = 'DEFAULT'; @@ -339,9 +346,9 @@ export class UserService { } if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { - user.subscription = this.subscriptionService.getSubscription({ - createdAt: user.createdAt, - subscriptions: Subscription + user.subscription = await this.subscriptionService.getSubscription({ + subscriptions, + createdAt: user.createdAt }); if (user.subscription?.type === 'Basic') { @@ -392,6 +399,12 @@ export class UserService { currentPermissions, permissions.deleteOwnUser ); + + // Reset offer + user.subscription.offer.coupon = undefined; + user.subscription.offer.couponId = undefined; + user.subscription.offer.durationExtension = undefined; + user.subscription.offer.label = undefined; } } diff --git a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json index 6ac25e5d9..475cc6217 100644 --- a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json +++ b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json @@ -20,6 +20,7 @@ "2025": "2025 TOKEN", "2049": "TOKEN 2049", "2192": "LERNITAS", + "4444": "4444 Meme", "$MAID": "MaidCoin", "$TREAM": "World Stream Finance", "00": "ZER0ZER0", @@ -63,6 +64,7 @@ "1MIL": "1MillionNFTs", "1MT": "1Move", "1NFT": "1NFT", + "1OZT": "Tala", "1PECO": "1peco", "1SG": "1SG", "1SOL": "1Sol", @@ -116,6 +118,7 @@ "4MW": "For Meta World", "4P": "4P FOUR", "4RZ": "4REALZA COIN", + "4THPILLAR": "4th Pillar Four Token", "4TOKEN": "Ignore Fud", "4WIN": "4TRUMP", "4WMM": "4-Way Mirror Money", @@ -189,6 +192,7 @@ "ABOND": "ApeBond", "ABONDV1": "ApeSwap", "ABR": "Allbridge", + "ABSIMPSON": "abstract simpson", "ABT": "ArcBlock", "ABTC": "aBTC", "ABUL": "Abulaba", @@ -228,6 +232,7 @@ "ACPT": "Crypto Accept", "ACQ": "Acquire.Fi", "ACRE": "Arable Protocol", + "ACRED": "Apollo Diversified Credit Securitize Fund", "ACRIA": "Acria.AI", "ACS": "Access Protocol", "ACSI": "ACryptoSI", @@ -289,6 +294,7 @@ "AEG": "Aether Games", "AEGGS": "aEGGS", "AEGIS": "Aegis", + "AEGS": "Aegisum", "AELIN": "Aelin", "AEN": "Aenco", "AENS": "AEN Smart", @@ -306,6 +312,7 @@ "AETH": "Aave ETH", "AETHC": "Ankr Reward-Bearing Staked ETH", "AETHERV2": "AetherV2", + "AETHRA": "Aethra AI", "AEUR": "Anchored Coins AEUR", "AEVO": "Aevo", "AEVUM": "Aevum", @@ -325,6 +332,7 @@ "AFRO": "Afrostar", "AFROX": "AfroDex", "AFSUI": "Aftermath Staked SUI", + "AFT": "AIFlow Token", "AFTT": "Africa Trading Chain", "AFX": "Afrix", "AFYON": "Afyonspor Fan Token", @@ -353,6 +361,7 @@ "AGLD": "Adventure Gold", "AGM": "Argoneum", "AGN": "Agnus Ai", + "AGNT": "iAgent Protocol", "AGO": "AgoDefi", "AGON": "Arabian Dragon", "AGOV": "Answer Governance", @@ -385,6 +394,7 @@ "AIBK": "AIB Utility Token", "AIBU": "AIBUZZ TOKEN", "AIC": "AI Companions", + "AICE": "Aicean", "AICELL": "AICell", "AICH": "AIChain", "AICO": "AICON", @@ -435,6 +445,7 @@ "AIOS": "INT OS", "AIOT": "AIOT Token", "AIOZ": "AIOZ Network", + "AIP": "AI Protocol", "AIPAD": "AIPAD", "AIPE": "AI Prediction Ecosystem", "AIPEPE": "AI PEPE KING", @@ -446,6 +457,7 @@ "AIRBTC": "AIRBTC", "AIRDROP": "AIRDROP2049", "AIRE": "Tokenaire", + "AIRENE": "AIRENE by Virtuals", "AIREVOLUTION": "AI Revolution Coin", "AIRI": "aiRight", "AIRIAN": "AIRian", @@ -461,6 +473,7 @@ "AITECH": "Artificial Intelligence Utility Token", "AITEK": "AI Technology", "AITHEON": "Aitheon", + "AITHER": "Aither Protocol", "AITIGER": "BNB Tiger AI", "AITK": "AITK", "AITN": "Artificial Intelligence Technology Network", @@ -509,8 +522,10 @@ "ALC": "Arab League Coin", "ALCAZAR": "Alcazar", "ALCE": "Alcedo", - "ALCH": "Alchemy", + "ALCH": "Alchemist AI", "ALCHE": "Alchemist", + "ALCHEMYV1": "Alchemy v1", + "ALCHEMYV2": "Alchemy", "ALCX": "Alchemix", "ALD": "AladdinDAO", "ALDIN": "Alaaddin.ai", @@ -519,6 +534,7 @@ "ALEPH": "Aleph.im", "ALEX": "ALEX Lab", "ALEXANDRITE": "Alexandrite", + "ALEXIUS": "Alexius Maximus", "ALF": "AlphaCoin", "ALG": "Algory", "ALGB": "Algebra", @@ -536,6 +552,7 @@ "ALICEW": "Alice Weidel", "ALIEN": "AlienCoin", "ALIENPEP": "Alien Pepe", + "ALIENS": "Aliens", "ALIF": " ALIF COIN", "ALINK": "Aave LINK v1", "ALIS": "ALISmedia", @@ -630,6 +647,7 @@ "AMP": "Amp", "AMPL": "Ampleforth", "AMPLIFI": "AmpliFi", + "AMR": "Amero", "AMS": "Amsterdam Coin", "AMT": "Acumen", "AMU": "Amulet", @@ -686,6 +704,7 @@ "ANLOG": "Analog", "ANML": "Animal Concerts", "ANN": "Annex Finance", + "ANNE": "ANNE", "ANON": "ANON", "ANONCOIN": "Anoncoin", "ANRX": "AnRKey X", @@ -707,6 +726,7 @@ "ANY": "Anyswap", "ANYONE": "ANyONe Protocol", "ANZENUSD": "Anzen Finance", + "AO": "AO", "AOC": "Alickshundra Occasional-Cortex", "AOG": "AgeOfGods", "AOK": "AOK", @@ -758,6 +778,7 @@ "APS": "APRES", "APT": "Aptos", "APTCOIN": "Aptcoin", + "APTM": "Apertum", "APTOGE": "Aptoge", "APTR": "Aperture Finance", "APU": "Apu Apustaja", @@ -771,6 +792,7 @@ "APY": "APY.Finance", "APYS": "APYSwap", "APZ": "Alprockz", + "AQA": " AQA Token", "AQT": "Alpha Quark Token", "AQTIS": "AQTIS", "AQU": "aQuest", @@ -783,6 +805,7 @@ "AQUARI": "Aquari", "AR": "Arweave", "ARA": "Ara Token", + "ARACOIN": "Ara", "ARATA": "Arata", "ARAW": "Araw", "ARB": "Arbitrum", @@ -858,6 +881,7 @@ "ARPA": "ARPA Chain", "ARPAC": "ArpaCoin", "ARQ": "ArQmA", + "ARQX": "ARQx AI", "ARR": "ARROUND", "ARRO": "Arro Social", "ARRR": "Pirate Chain", @@ -896,6 +920,7 @@ "ASAFE2": "Allsafe", "ASAN": "ASAN VERSE", "ASAP": "Asap Sniper Bot", + "ASBNB": "Astherus Staked BNB", "ASC": "Ascend", "ASD": "AscendEX Token", "ASDEX": "AstraDEX", @@ -909,6 +934,7 @@ "ASIA": "Asia Coin", "ASIMI": "ASIMI", "ASIX": "ASIX+", + "ASIXDEV": "ASIX", "ASK": "Permission Coin", "ASKAI": "ASKAI", "ASKO": "Asko", @@ -947,6 +973,7 @@ "ASTROS": "AstroSwap", "ASTX": "Asterix Labs", "ASUNA": "Asuna Hentai", + "ASUSDF": "Astherus Staked USDF", "ASUSHI": "Sushi (Arbitrum Bridge)", "ASVA": "Asva", "ASW": "AdaSwap", @@ -985,7 +1012,8 @@ "ATMCOIN": "ATM", "ATMI": "Atonomi", "ATMOS": "Novusphere", - "ATN": "ATN", + "ATN": "ATHENE NETWORK", + "ATNIO": "ATN", "ATNT": "Artizen", "ATO": "Atocha Protocol", "ATOLO": "RIZON", @@ -1047,6 +1075,7 @@ "AUX": "Auxilium", "AV": "Avatar Coin", "AVA": "Travala", + "AVAAI": "Ava AI", "AVACN": "AVACOIN", "AVAI": "Orca AVAI", "AVAIL": "Avail", @@ -1067,6 +1096,7 @@ "AVE": "Avesta", "AVEN": "Aventis AI", "AVENT": "Aventa", + "AVERY": "Avery Games", "AVG": "Avocado DAO", "AVH": "Animation Vision Cash", "AVI": "Aviator", @@ -1078,6 +1108,7 @@ "AVN": "AVNRich", "AVO": "Avoteo", "AVR": "Avrora Metaverse", + "AVRK": "Avarik Saga", "AVS": "Aves", "AVT": "Aventus", "AVTM": "Aventis Metaverse", @@ -1141,6 +1172,7 @@ "B": "BankCoin", "B01": "b0rder1ess", "B1P": "B ONE PAYMENT", + "B2": "B² Network", "B20": "B20", "B21": "B21", "B26": "B26 Finance", @@ -1149,6 +1181,7 @@ "B2X": "SegWit2x", "B3": "B3", "B3COIN": "B3 Coin", + "B3TR": "VeBetterDAO", "B3X": "Bnext Token", "B91": "B91", "BA": "BAHA", @@ -1208,6 +1241,8 @@ "BABYKABOSU": "Baby Kabosu", "BABYKEKIUS": "Baby Kekius Maximus", "BABYKITTY": "BabyKitty", + "BABYKOMA": "Baby Koma", + "BABYLON": "Babylon", "BABYLONG": "Baby Long", "BABYM": "BabyMAGA", "BABYMAGA": "Baby Maga", @@ -1216,6 +1251,7 @@ "BABYMIGGLES": "Baby Miggles", "BABYMO": "Baby Moon Floki", "BABYMU": "Baby Musk", + "BABYMUB": "Baby Mubarak", "BABYMUSK": "Baby Musk", "BABYMYRO": "Babymyro", "BABYNEIRO": "Baby Neiro", @@ -1223,6 +1259,7 @@ "BABYOKX": "BABYOKX", "BABYP": "BabyPepe", "BABYPEIPEI": "Baby PeiPei", + "BABYPENGU": "BABY PENGU", "BABYPEPE": "Babypepe (BSC)", "BABYPNUT": "Baby Pnut", "BABYPOPCAT": "Baby PopCat", @@ -1275,6 +1312,7 @@ "BAKED": "Baked", "BAKEDB": "Baked Beans Token", "BAKEDTOKEN": "Baked", + "BAKENEKO": "BAKENEKO", "BAKSO": "Disney Sumatran Tiger", "BAKT": "Backed Protocol", "BAL": "Balancer", @@ -1298,6 +1336,7 @@ "BANANACHARITY": "BANANA", "BANANAF": "Banana For Scale", "BANANAS": "Monkey Peepo", + "BANANAS31": "Banana For Scale", "BANANO": "Banano", "BANC": "Babes and Nerds", "BANCA": "BANCA", @@ -1322,6 +1361,7 @@ "BAOS": "BaoBaoSol", "BAR": "FC Barcelona Fan Token", "BARA": "Capybara", + "BARAKATUH": "Barakatuh", "BARC": "The Blu Arctic Water Company", "BAREBEARS": "BAREBEARS", "BARIO": "Bario", @@ -1338,6 +1378,7 @@ "BASECOIN": "BASECOIN", "BASED": "Based Money", "BASEDAI": "BasedAI", + "BASEDALF": "Based Alf", "BASEDCHILL": "Based Chill Guy", "BASEDCOPE": "COPE", "BASEDFINANCE": "Based", @@ -1398,6 +1439,7 @@ "BBONK": "BitBonk", "BBOS": "Blackbox Foundation", "BBP": "BiblePay", + "BBQ": "BBQ COIN", "BBR": "Boolberry", "BBRETT": "Baby Brett", "BBROCCOLI": "Baby Broccoli", @@ -1477,6 +1519,8 @@ "BDR": "BlueDragon", "BDRM": "Bodrumspor Fan Token", "BDROP": "BlockDrop", + "BDSM": "BTC DOGE SOL MOON", + "BDTC": "BDTCOIN", "BDX": "Beldex", "BDY": "Buddy DAO", "BEA": "Beagle Inu", @@ -1660,6 +1704,7 @@ "BIGFACTS": "BIGFACTS", "BIGFOOT": "BigFoot Town", "BIGHAN": "BighanCoin", + "BIGJIM": "BIG JIM", "BIGLEZ": "THE BIG LEZ SHOW", "BIGMIKE": "Big Mike", "BIGSB": "BigShortBets", @@ -1668,6 +1713,7 @@ "BIH": "BitHostCoin", "BIHU": "Key", "BIIS": "biis (Ordinals)", + "BIKE": "White Bike", "BIKI": "BIKI", "BILL": "TillBilly", "BILLI": "Billi", @@ -1675,6 +1721,8 @@ "BILLY": "Billy ", "BILLYBSC": "BILLY", "BIM": "BitminerCoin", + "BINA": "Binance Mascort Dog", + "BINAN": "Binance Mascot", "BINANCED": "BinanceDog On Sol", "BINANCEDOG": "Binancedog", "BIND": "Compendia", @@ -1759,6 +1807,7 @@ "BITTO": "BITTO", "BITTON": "Bitton", "BITUNE": "Bitune", + "BITUPTOKEN": "BitUP Token", "BITUSD": "bitUSD", "BITV": "Bitvolt", "BITVOLT": "BitVolt", @@ -1823,6 +1872,7 @@ "BLHC": "BlackholeCoin", "BLI": "BALI TOKEN", "BLID": "Bolide", + "BLIFFY": "BLIFFY", "BLIN": "Blin Metaverse", "BLIND": "Blindsight", "BLING": "PLEB DREKE", @@ -1871,6 +1921,7 @@ "BLU": "BlueCoin", "BLUB": "BLUB", "BLUE": "Bluefin", + "BLUEBASE": "Blue", "BLUEBUTT": "BLUE BUTT CHEESE", "BLUEG": "Blue Guy", "BLUEM": "BlueMove", @@ -1901,6 +1952,7 @@ "BMARS": "Binamars", "BMBO": "Bamboo Coin", "BMC": "Blackmoon Crypto", + "BMCHAIN": "BMChain", "BMDA": "Bermuda", "BME": "BitcoMine", "BMEX": "BitMEX", @@ -1915,7 +1967,7 @@ "BMONEY": "B-money", "BMP": "Brother Music Platform", "BMS": "BMS COIN", - "BMT": "BMChain", + "BMT": "Bubblemaps", "BMTC": "Metabit", "BMW": "BMW", "BMWUKONG": "Black Myth WuKong", @@ -1926,8 +1978,10 @@ "BNANA": "Chimpion", "BNB": "Binance Coin", "BNBAI": "BNB Agents", + "BNBAICLUB": "BNB AI Agent", "BNBBONK": "BNB BONK", "BNBBUNNY": "BNB BUNNY", + "BNBCARD": "BNB Card", "BNBCAT": "BNBcat", "BNBCH": "BNB Cash", "BNBD": "BNBDOG", @@ -1935,6 +1989,7 @@ "BNBDOGE": "BNBdoge", "BNBDRGN": "BNBDragon", "BNBE": "BNBEE", + "BNBETF": "BNB ETF", "BNBFLOKI": "BNB FLOKI", "BNBFROG": "BNBFROG", "BNBH": "BnbHeroes Token", @@ -1954,6 +2009,7 @@ "BNF": "BonFi", "BNIX": "BNIX Token", "BNK": "Bankera", + "BNKR": "BankrCoin", "BNN": "Banyan Network", "BNOM": "BitNomad", "BNP": "BenePit", @@ -1996,6 +2052,7 @@ "BOBOT": "Bobo The Bear", "BOBS": "Bob's Repair", "BOBT": "BOB Token", + "BOBTHE": "Bob The Builder", "BOBUKI": "Bobuki Neko", "BOBY": "BOBY", "BOC": "BOCOIN", @@ -2019,6 +2076,8 @@ "BOGE": "Boge", "BOGEY": "Bogey", "BOGGY": "Boggy Coin", + "BOHR": "BOHR", + "BOHRV1": "BOHR v1", "BOJAK": "Based Wojak", "BOJI": "BOJI Token", "BOJIV1": "BOJI Token v1", @@ -2035,6 +2094,7 @@ "BOMA": "Book of Maga", "BOMB": "BOMB", "BOMBC": "BombCoin", + "BOMBLOONG": "Bombloong", "BOMBM": "Bomb Money", "BOMBO": "BOMBO", "BOMBS": "Bomb Shelter Inu", @@ -2085,6 +2145,7 @@ "BOOF": "Boofus by Virtuals", "BOOFI": "Boo Finance", "BOOG": "BOOG base", + "BOOGIE": "Boogie", "BOOK": "Solbook", "BOOKIE": "BookieBot", "BOOKO": "Book of Pets", @@ -2139,7 +2200,7 @@ "BOWE": "Book of Whales", "BOWSC": "BowsCoin", "BOWSER": "Bowser", - "BOX": "ContentBox", + "BOX": "DeBoxToken", "BOXETH": "Cat-in-a-Box Ether", "BOXT": "BOX Token", "BOXX": "Blockparty", @@ -2185,13 +2246,14 @@ "BQQQ": "Bitsdaq Token", "BQT": "Blockchain Quotations Index Token", "BQTX": "BQT", - "BR": "BOHR", + "BR": "Bedrock", "BR34P": "BR34P", "BRACE": "Bitci Racing Token", "BRAI": "Brain Frog", "BRAIN": "BrainCoin", "BRAINERS": "Brainers", "BRAINLET": "Brainlet", + "BRAINROT": "AI Brainrot", "BRAINZ": "Brainz Finance", "BRAM": "Defibox bRAM", "BRANA": "Branaverse", @@ -2453,6 +2515,7 @@ "BTZN": "Bitzon", "BU": "BUMO", "BUB": "BUBCAT", + "BUBB": "Bubb", "BUBBA": "Bubba", "BUBBLE": "Bubble", "BUBBLES": "BUBBLES", @@ -2476,10 +2539,13 @@ "BUGATTI": "BUGATTI", "BUGG": "Bugg Inu", "BUGS": "Bugs Bunny", - "BUIDL": "Starter.xyz", + "BUI": "Build forward", + "BUIDL": "BlackRock USD Institutional Digital Liquidity Fund", + "BUIDLI": "BlackRock USD Institutional Digital Liquidity Fund - I Class", "BUIL": "BUILD", "BUILD": "BuildAI", "BUILDIN": "Buildin Token", + "BUILDON": "Build On BNB", "BUILDTEAM": "BuildTeam", "BUILT": "Built Different", "BUK": "CryptoBuk", @@ -2498,6 +2564,7 @@ "BULLMOON": "Bull Moon", "BULLPEPE": "Bullpepe", "BULLS": "Bull Coin", + "BULLSEYE": "bulls-eye", "BULLSH": "Bullshit Inu", "BULLY": "Dolos The Bully", "BULLYINGCAT": "Bullying Cat", @@ -2530,7 +2597,7 @@ "BUSD": "Binance USD", "BUSDC": "BUSD", "BUSY": "Busy DAO", - "BUT": "BitUP Token", + "BUT": "Bucket Token", "BUTT": "Buttercat", "BUTTCOIN": "The Next Bitcoin", "BUTTHOLE": "Butthole Coin", @@ -2574,6 +2641,7 @@ "BXX": "Baanx", "BXY": "Beaxy", "BYAT": "Byat", + "BYB": "BiorBank", "BYC": "ByteCent", "BYG": "Black Eye Galaxy", "BYT": "ByteAI", @@ -2621,9 +2689,10 @@ "CAG": "Change", "CAGA": "Crypto Asset Governance Alliance", "CAH": "Moon Tropica", - "CAI": "Cai Token", + "CAI": "Chasm", "CAID": "ClearAid", "CAIR": "Crypto-AI-Robo.com", + "CAITOKEN": "Cai Token", "CAIV": "CARVIS", "CAIX": "CAIx", "CAIZ": "Caizcoin", @@ -2636,6 +2705,7 @@ "CALC": "CaliphCoin", "CALI": "CaliCoin", "CALL": "Global Crypto Alliance", + "CALLS": "OnlyCalls by Virtuals", "CALO": "Calo", "CAM": "Consumption Avatar Matrix", "CAMC": "Camcoin", @@ -2832,6 +2902,7 @@ "CCXC": "CoolinDarkCoin", "CCXX": "CounosX", "CDAI": "Compound Dai", + "CDBIO": "CDbio", "CDCETH": "Crypto.com Staked ETH", "CDEX": "Cryptodex", "CDL": "CoinDeal Token", @@ -2915,6 +2986,7 @@ "CHACHA": "Chacha", "CHAD": "Chad Coin", "CHADCAT": "CHAD CAT", + "CHADETTE": "Chadette", "CHADS": "CHADS VC", "CHAI": "Chroma AI", "CHAIN": "Chain Games", @@ -3231,6 +3303,7 @@ "COCONUT": "Coconut", "COCOR": "Cocoro", "COCORO": "Cocoro", + "COCOROERC": "COCORO", "COD": "Chief of Deswamp", "CODA": "CODA", "CODAI": "CODAI", @@ -3280,6 +3353,7 @@ "COLLG": "Collateral Pay Governance", "COLON": "Colon", "COLR": "colR Coin", + "COLS": "Cointel", "COLT": "Collateral Network", "COLX": "ColossusCoinXT", "COM": "Coliseum", @@ -3310,6 +3384,7 @@ "CONK": "ShibaPoconk", "CONS": "ConSpiracy Coin", "CONSENTIUM": "Consentium", + "CONTENTBOX": "ContentBox", "CONTROL": "Control Token", "CONV": "Convergence", "CONVO": "Prefrontal Cortex Convo Agent by Virtuals", @@ -3330,6 +3405,7 @@ "COPYCAT": "Copycat Finance", "COQ": "Coq Inu", "COR": "Coreto", + "CORA": "Cora by Virtuals", "CORAL": "CoralPay", "CORE": "Core", "COREC": "CoreConnect", @@ -3341,11 +3417,13 @@ "CORGIAI": "CorgiAI", "CORGIB": "The Corgi of PolkaBridge", "CORION": "Corion", - "CORN": "CORN", + "CORN": "Corn", "CORNELLA": "CORNELLA", + "CORNFIELDFARM": "CORN", "CORSI": "Cane Corso", "CORTEX": "Cortex Protocol", "CORX": "CorionX", + "CORXB": "CorionX BSC", "COS": "Contentos", "COSHI": "CoShi Inu", "COSM": "CosmoChain", @@ -3430,6 +3508,7 @@ "CRAVE": "CraveCoin", "CRAYRABBIT": "CrazyRabbit", "CRAZ": "CRAZY FLOKI", + "CRAZE": "Craze", "CRAZYB": "Crazy Bunny", "CRAZYBONK": "CRAZY BONK", "CRAZYBUNNY": "Crazy Bunny", @@ -3538,6 +3617,7 @@ "CRYO": "CryoDAO", "CRYP": "CrypticCoin", "CRYPT": "CryptCoin", + "CRYPTAL": "CrypTalk", "CRYPTER": "Crypteriumcoin", "CRYPTOA": "CryptoAI", "CRYPTOAGENT": "CRYPTO AGENT TRUMP", @@ -3590,6 +3670,7 @@ "CSTC": "CryptosTribe", "CSTL": "Castle", "CSTR": "CoreStarter", + "CSUSDL": "Coinshift USDL Morpho Vault", "CSUSHI": "cSUSHI", "CSW": "Crosswalk", "CSWAP": "ChainSwap", @@ -3605,6 +3686,7 @@ "CTEX": "Crypto tex", "CTF": "CyberTime Finance", "CTG": "City Tycoon Games", + "CTH": "Changcoin", "CTI": "ClinTex CTi", "CTIC": "Coinmatic", "CTK": "Shentu", @@ -3659,6 +3741,7 @@ "CURRY": "CurrySwap", "CUSD": "Carbon", "CUSDC": "Compound USD Coin", + "CUSDO": "Compounding Open Dollar", "CUSDT": "cUSDT", "CUSDTBULL": "3X Long Compound USDT Token", "CUST": "Custody Token", @@ -3763,6 +3846,7 @@ "CZSHARES": "CZshares", "CZUSD": "CZUSD", "CZZ": "ClassZZ", + "D": "Dar Open Network", "D11": "DeFi11", "D2O": "DAM Finance", "D2T": "Dash 2 Trade", @@ -3803,6 +3887,7 @@ "DAIN": "Dain Token", "DAIQ": "Daiquilibrium", "DAISY": "Daisy Launch Pad", + "DAIWO": "D.A.I.Wo", "DAK": "dak", "DAKU": "Der Daku", "DAL": "DAOLaunch", @@ -3863,6 +3948,7 @@ "DATAB": "Databot", "DATAO": "Data Ownership Protocol", "DATAWALLET": "DataWallet", + "DATBOI": "Dat Boi", "DATOM": "Drop Staked ATOM", "DATP": "Decentralized Asset Trading Platform", "DATX": "DATx", @@ -3870,6 +3956,7 @@ "DAV": "DAV", "DAVE": "DAVE", "DAVID": "David", + "DAVINC": "DaVinci Protocol", "DAVINCI": "Davincigraph", "DAVIS": "Davis Cup Fan Token", "DAVP": "Davion", @@ -3978,8 +4065,12 @@ "DEEP": "DeepBook Protocol", "DEEPCLOUD": "DeepCloud AI", "DEEPG": "Deep Gold", + "DEEPS": "DeepSeek AI", + "DEEPSE": "DeepSeek AI Assistant", "DEEPSEARCH": "Grok 3 DeepSearch", + "DEEPSEE": "DeepSeek AI", "DEEPSEEK": "Global DePIN Chain", + "DEEPSEEKAI": "DeepSeek AI Agent", "DEEPSEEKR1": "DeepSeek R1", "DEER": "ToxicDeer Finance", "DEERSEIZED": "Deer Seized by US Government", @@ -4060,6 +4151,7 @@ "DETH": "DarkEther", "DETO": "Delta Exchange", "DEUR": "DigiEuro", + "DEURO": "DecentralizedEURO", "DEUS": "DEUS Finance", "DEUSD": "Elixir deUSD", "DEV": "Deviant Coin", @@ -4151,6 +4243,7 @@ "DIABLO": "Diablo IV", "DIAM": "Diamond", "DIAMND": "Projekt Diamond", + "DIAMO": "Diamond Launch", "DIAMOND": "Diamond Coin", "DIAMONDINU": "Diamond", "DIBBLE": "Dibbles", @@ -4160,6 +4253,7 @@ "DICEM": "DICE Money", "DICETRX": "TRONbetDice", "DICK": "adDICKted", + "DICKBUTT": "Dickbutt", "DICKCOIN": "DickCoin", "DID": "Didcoin", "DIDDY": "DIDDY", @@ -4174,13 +4268,15 @@ "DIGAU": "Dignity Gold", "DIGEX": "Digex", "DIGG": "DIGG", - "DIGI": "Digiverse", + "DIGGAI": "DIGGER AI", + "DIGI": "Digicoin", "DIGIC": "DigiCube", "DIGIF": "DigiFel", "DIGIMON": "Digimon", "DIGIT": "Digital Asset Rights Token", "DIGITAL": "Digital Reserve Currency", "DIGITS": "Digits DAO", + "DIGIV": "Digiverse", "DIGNITY": "Dignity", "DIGS": "Diggits", "DIK": "DikDok", @@ -4239,7 +4335,7 @@ "DLA": "Dolla", "DLANCE": "DeeLance", "DLB": "DiemLibre", - "DLC": "Diamond Launch", + "DLC": "DeepLink", "DLCBTC": "DLC.Link", "DLISK": "Dlisk", "DLLR": "Sovryn Dollar", @@ -4278,6 +4374,7 @@ "DMZ": "DeMon Token", "DN8": "Pldgr", "DNA": "Metaverse", + "DNAPEPE": "DNA PEPE", "DND": "Diamond DND", "DNET": "DeNet", "DNF": "DNFT Protocol", @@ -4353,9 +4450,11 @@ "DOGEGROKAI": "Doge Of Grok AI", "DOGEI": "Dogei", "DOGEIN": "Doge In Glasses", + "DOGEIUS": "DOGEIUS", "DOGEKING": "DogeKing", "DOGELEGION": "DOGE LEGION", "DOGEM": "Doge Matrix", + "DOGEMARS": "DOGE TO MARS", "DOGEMETA": "Dogemetaverse", "DOGEMOB": "DOGEMOB", "DOGEMOON": "DOGE TO MOON", @@ -4414,6 +4513,7 @@ "DOLLAR": "Dollar", "DOLLARCOIN": "DollarCoin", "DOLLUR": "Dollur Go Brrr", + "DOLLY": "DOLLY", "DOLPHY": "Dolphy", "DOLZ": "DOLZ", "DOM": "Ancient Kingdom", @@ -4437,6 +4537,7 @@ "DONU": "Donu", "DONUT": "Donut", "DONUTS": "The Simpsons", + "DOODI": "Doodipals", "DOODOO": "Doodoo", "DOOGLE": "Doogle", "DOOH": "Bidooh", @@ -4446,6 +4547,7 @@ "DOPE": "Dopamine App", "DOPEC": "DOPE Coin", "DOPECOIN": "DopeCoin", + "DOPEX": "DOPE", "DOPU": "DOPU The Dog with A Purpose", "DOR": "Dorado", "DORA": "Dora Factory", @@ -4468,6 +4570,7 @@ "DOVIS": "Dovish Finance", "DOVU": "DOVU", "DOWS": "Shadows", + "DOYOUR": "Do Your Own Research", "DP": "DigitalPrice", "DPAD": "Dpad Finance", "DPAY": "Devour", @@ -4477,6 +4580,7 @@ "DPI": "DeFiPulse Index", "DPIE": "DeFiPie", "DPIN": "DPIN", + "DPINO": "DarkPino", "DPLAT": "zbyte", "DPLN": "DePlan", "DPLTR": "Palantir Tokenized Stock Defichain", @@ -4501,6 +4605,7 @@ "DRAGONKING": "DragonKing", "DRAGONMA": "Dragon Mainland Shards", "DRAGONX": "DragonX", + "DRAGONZ": "Dragonz Land", "DRAGU": "DRAGU", "DRAGY": "Dragy", "DRAKO": "Drako", @@ -4519,7 +4624,8 @@ "DRGN": "Dragonchain", "DRIFT": "Drift protocol", "DRINK": "DrinkChain", - "DRIP": "Drip Network", + "DRIP": "Metadrip", + "DRIPNET": "Drip Network", "DRIV": "DRIVEZ", "DRIVECRYPTO": "Drive Crypto", "DRKC": "DarkCash", @@ -4534,6 +4640,7 @@ "DROVERS": "Drover Inu", "DRP": "DCORP", "DRPU": "DRP Utility", + "DRPXBT": "Hunter by Virtuals", "DRS": "Digital Rupees", "DRT": "DomRaider", "DRUGS": "Big Pharmai", @@ -4552,6 +4659,7 @@ "DSG": "Dinosaureggs", "DSH": "Dashcoin", "DSHARE": "Dibs Share", + "DSHELL": "diamondshell", "DSHIB": "DOLLAR SHIBA INU", "DSK": "Darüşşafaka Spor Kulübü Token", "DSLA": "DSLA Protocol", @@ -4596,6 +4704,7 @@ "DUBI": "Decentralized Universal Basic Income", "DUBX": "DUBXCOIN", "DUC": "DucatusCoin", + "DUCAT": "Ducat", "DUCATO": "Ducato Protocol Token", "DUCK": "Unit Protocol New", "DUCKAI": "Duck AI", @@ -4604,6 +4713,7 @@ "DUCKER": "Ducker", "DUCKIES": "Yellow Duckies", "DUCKO": "Duck Off Coin", + "DUCKV1": "COL", "DUCKY": "Ducky Duck", "DUCX": "DucatusX", "DUDE": "DuDe", @@ -4622,6 +4732,7 @@ "DUN": "Dune", "DUNG": "Scarab Tools", "DUO": "ParallelCoin", + "DUOLINGOAI": "DUOLINGO AI", "DUOT": "DUO Network", "DUREV": "Povel Durev", "DUROV": "FREE DUROV", @@ -4629,6 +4740,7 @@ "DUSD": "Decentralized USD", "DUSK": "Dusk Network", "DUST": "DUST Protocol", + "DUSTY": "Dusty", "DUX": "DuxCoin", "DUZCE": "Duzce Token", "DV": "Dreamverse", @@ -4694,6 +4806,7 @@ "DYST": "Dystopia", "DYT": "DoYourTip", "DYZILLA": "DYZilla", + "DZA": "DZA", "DZAR": "Digital Rand", "DZCC": "DZCC", "DZDD": "DZD", @@ -4943,6 +5056,7 @@ "ELU": "Elumia", "ELUSKMON": "Elusk Mon", "ELV": "Elvantis", + "ELVIS": "ELVIS", "ELVN": "11Minutes", "ELX": "Elixir Network", "ELY": "Elysian", @@ -5026,6 +5140,7 @@ "ENV": "ENVOY", "ENVIENTA": "Envienta", "ENVION": "Envion", + "ENVOY": "Envoy A.I", "ENX": "ENEX", "EOC": "EveryonesCoin", "EON": "Exscudo", @@ -5043,7 +5158,8 @@ "EPENDLE": "Equilibria Pendle", "EPEP": "Epep", "EPETS": "Etherpets", - "EPIC": "Epic Cash", + "EPIC": "Epic Chain", + "EPICCASH": "Epic Cash", "EPIK": "EPIK Token", "EPIKO": "Epiko", "EPIX": "Byepix", @@ -5108,6 +5224,7 @@ "ESGC": "ESG Chain", "ESH": "Switch", "ESHIB": "Euro Shiba Inu", + "ESIM": "EvoSimGame", "ESM": "EL SALVADOR MEME", "ESN": "Ethersocial", "ESNC": "Galaxy Arena Metaverse", @@ -5298,6 +5415,7 @@ "EXOS": "Exobots", "EXP": "Expanse", "EXPAND": "Gems", + "EXPERIENCE": "Experience Points", "EXPERT": "EXPERT_MONEY", "EXPO": "Exponential Capital", "EXRD": "Radix", @@ -5348,6 +5466,7 @@ "FAH": "Falcons", "FAI": "Freysa AI", "FAIR": "FairCoin", + "FAIR3": "Fair and Free", "FAIRC": "Faireum Token", "FAIRG": "FairGame", "FAIRUM": "Fairum", @@ -5384,6 +5503,7 @@ "FARTBOY": "Fartboy", "FARTCOIN": "Fartcoin", "FARTDEV": "Fart Dev", + "FARTIMUS": "Fartimus Prime", "FARTING": "Farting Unicorn", "FAS": "fast construction coin", "FAST": "Fastswap", @@ -5483,6 +5603,7 @@ "FGT": "Flozo Game Token", "FGZ": "Free Game Zone", "FHB": "FHB", + "FHE": "MindNetwork FHE Token", "FHM": "FantOHM", "FI": "Fideum", "FIA": "FIA Protocol", @@ -5541,7 +5662,9 @@ "FIRU": "Firulais Finance", "FIS": "Stafi", "FISH": "Polycat Finance", + "FISH2": "FISH2", "FISHK": "Fishkoin", + "FISHW": "Fishwar", "FIST": "Fistbump", "FISTBUMP": "FistBump", "FIT": "Financial Investment Token", @@ -5606,6 +5729,7 @@ "FLOCK": "FLock.io", "FLOCKA": "Waka Flocka", "FLOCKE": "Flockerz", + "FLOCO": "flocoin", "FLOKA": "FLOKA", "FLOKEI": "FLOKEI", "FLOKI": "Floki Inu", @@ -5732,7 +5856,9 @@ "FOREX": "handle.fi", "FOREXCOIN": "FOREXCOIN", "FORK": "Gastro Advisor Token", - "FORM": "Formation FI", + "FORM": "Four", + "FORMATION": "Formation FI", + "FORMNET": "Form", "FORS": "Forus", "FORT": "Forta", "FORTH": "Ampleforth Governance Token", @@ -5746,7 +5872,7 @@ "FOTTIE": "Fottie", "FOUND": "ccFound", "FOUNTAIN": "Fountain", - "FOUR": "4THPILLAR TECHNOLOGIES", + "FOUR": "4", "FOX": "ShapeShift FOX Token", "FOXAI": "FOXAI", "FOXD": "Foxdcoin", @@ -5800,6 +5926,7 @@ "FRENS": "Farmer Friends", "FRESCO": "Fresco", "FRF": "France REV Finance", + "FRGB": "Pepe's Frogbar", "FRGST": "Froggies Token", "FRGX": "FRGX", "FRIC": "Fric", @@ -5840,6 +5967,7 @@ "FRV": "Fitrova", "FRWC": "Frankywillcoin", "FRXETH": "Frax Ether", + "FRXUSD": "Frax USD", "FRZ": "Frozy Inu", "FRZSS": "Frz Solar System", "FRZSSCOIN": "FRZ Solar System Coin", @@ -6000,6 +6128,7 @@ "GAMBL": "Metagamble", "GAME": "GameBuild", "GAMEBUD": "GAMEBUD", + "GAMEBYV": "GAME by Virtuals", "GAMEC": "Game", "GAMECO": "Game.com", "GAMECRED": "GameCredits", @@ -6039,7 +6168,8 @@ "GAS": "Gas", "GASDAO": "Gas DAO", "GASG": "Gasgains", - "GASP": "gAsp", + "GASP": "GASP", + "GASPCOIN": "gAsp", "GASTRO": "GastroCoin", "GAT": "GATCOIN", "GATE": "GATENet", @@ -6094,6 +6224,7 @@ "GDCC": "GLOBAL DIGITAL CLUSTER COIN", "GDDY": "Giddy", "GDE": "Golden Eagle", + "GDIGIT": "GoldDigitStandart", "GDL": "GodlyCoin", "GDO": "GroupDao", "GDOG": "GDOG", @@ -6205,6 +6336,14 @@ "GHD": "Giftedhands", "GHDV1": "Giftedhands v1", "GHE": "GHETTO PEPE", + "GHHS": "GHHS Healthcare", + "GHI": "Ghibli HeYi", + "GHIB": "GhibliCZ", + "GHIBL": "Ghibli Zao", + "GHIBLI": "Ghiblification", + "GHIBLIAI": "Ghibli AI Agent", + "GHIBLIDOGE": "Ghibli Doge", + "GHIBLIELON": "Ghibli Elon", "GHNY": "Grizzly Honey", "GHO": "GHO", "GHOAD": "GhoadCoin", @@ -6241,6 +6380,7 @@ "GIMMERV1": "Gimmer v1", "GIN": "GINcoin", "GINGER": "GINGER", + "GINI": "Kalp", "GINNAN": "Ginnan The Cat", "GINOA": "Ginoa", "GINU": "Green Shiba Inu", @@ -6271,7 +6411,7 @@ "GLD": "Goldario", "GLDGOV": "Gold DAO", "GLDR": "Golder Coin", - "GLDS": "Gdigit", + "GLDS": "Glades", "GLDX": "Goldex", "GLDY": "Buzzshow", "GLE": "Green Life Energy", @@ -6298,6 +6438,7 @@ "GLR": "Glory Finance", "GLS": "Glacier", "GLT": "GlobalToken", + "GLUE": "Glue", "GLX": "GalaxyCoin", "GLYPH": "GlyphCoin", "GM": "GM", @@ -6334,6 +6475,7 @@ "GMT": "STEPN", "GMTO": "Game Meteor Coin", "GMTT": "GMT Token", + "GMUBARAK": "Ghibli Mubarak", "GMUSD": "GND Protocol", "GMX": "GMX", "GN": "GN", @@ -6479,6 +6621,7 @@ "GPX": "GPEX", "GQ": "Galactic Quadrant", "GR": "GROM", + "GRAB": "GRABWAY", "GRACY": "Gracy", "GRAI": "Gravita Protocol", "GRAIL": "Camelot Token", @@ -6639,7 +6782,8 @@ "GUMMIES": "GUMMIES", "GUMMY": "GUMMY", "GUMSHOOS": "GUMSHOOS TRUMP", - "GUN": "GunCoin", + "GUN": "GUNZ", + "GUNCOIN": "GunCoin", "GUNS": "GeoFunders", "GUP": "Guppy", "GURL": "Gently Used Girl", @@ -6981,6 +7125,7 @@ "HNST": "Honest", "HNT": "Helium", "HNTR": "Hunter", + "HNTV1": "Helium v1", "HNX": "HeartX Utility Token", "HNY": "Honey", "HNZO": "Hanzo Inu", @@ -6991,7 +7136,9 @@ "HOBO": "HOBO THE BEAR", "HOCAI": "Heroes of Crypto AI", "HOD": "HoDooi.com", - "HODL": "HOdlcoin", + "HODLC": "HOdlcoin", + "HODLV1": "HODL v1", + "HODLV2": "HODL", "HOG": "Hog", "HOGE": "Hoge Finance", "HOGONSOLANA": "HOG", @@ -7011,6 +7158,7 @@ "HOMER": "Homer Simpson", "HOMERB": "Homer BSC", "HOMERO": "Homer Of Meme", + "HOMERS": "Homer", "HOMI": "HOMIHELP", "HOMIECOIN": "Homie Wars", "HOMMIES": "HOMMIES", @@ -7029,6 +7177,7 @@ "HOOPS": "Hoops", "HOOT": "HOOT", "HOP": "Hop Protocol", + "HOPECOIN": "Hopecoin", "HOPPY": "Hoppy", "HOPPYTOKEN": "Hoppy", "HOPR": "HOPR", @@ -7174,6 +7323,7 @@ "HYPERD": "HyperDAO", "HYPERIONX": "HyperionX", "HYPERS": "HyperSpace", + "HYPERSKIDS": "HYPERSKIDS", "HYPES": "Supreme Finance", "HYPEV1": "Hype v1", "HYPR": "Hypr Network", @@ -7192,15 +7342,18 @@ "IAG": "IAGON", "IAI": "inheritance Art", "IAM": "IAME Identity", + "IAOMIN": "Yao Ming", "IB": "Iron Bank", "IBANK": "iBankCoin", "IBAT": "Battle Infinity", + "IBERA": "Infrared Bera", "IBETH": "Interest Bearing ETH", "IBEUR": "Iron Bank EURO", "IBFK": "İstanbul Başakşehir Fan Token", "IBFN": "IBF Net", "IBFR": "iBuffer Token", "IBG": "iBG Token", + "IBGT": "Infrared BGT", "IBIT": "InfinityBit Token", "IBNB": "iBNB", "IBP": "Innovation Blockchain Payment", @@ -7305,6 +7458,7 @@ "ILC": "ILCOIN", "ILCT": "ILCoin Token", "ILK": "Inlock", + "ILLUMINAT": "Illuminat", "ILT": "iOlite", "ILV": "Illuvium", "IMARO": "IMARO", @@ -7313,7 +7467,9 @@ "IMC": "i Money Crypto", "IME": "Imperium Empires", "IMG": "ImageCoin", + "IMGN": "IMGN Labs", "IMGNAI": "Image Generation AI", + "IMGX10": "IMGx10", "IMGZ": "Imigize", "IMI": "Influencer", "IML": "IMMLA", @@ -7442,6 +7598,7 @@ "IOI": "IOI Token", "ION": "Ionomy", "IONC": "IONChain", + "IONP": "Ion Power Token", "IONX": "Charged Particles", "IONZ": "IONZ", "IOP": "Internet of People", @@ -7587,6 +7744,7 @@ "JAPAN": "Japan Open Chain", "JAR": "Jarvis+", "JARED": "Jared From Subway", + "JARVIS": "Jarvis AI", "JARY": "JeromeAndGary", "JASMY": "JasmyCoin", "JASON": "Jason Derulo", @@ -7773,6 +7931,7 @@ "JWL": "Jewels", "JYAI": "Jerry The Turtle By Matt Furie", "JYC": "Joe-Yo Coin", + "K": "Kinto", "K21": "K21", "K2G": "Kasko2go", "KAAI": "KanzzAI", @@ -7910,9 +8069,11 @@ "KEPT": "KeptChain", "KERMIT": "KermitTheCoin", "KERN": "Kernel", - "KET": "KET", + "KERNEL": "KernelDAO", + "KET": "Ket", "KETAMINE": "Ketamine", "KETAN": "Ketan", + "KETCOIN": "KET", "KEVIN": "Kevin (kevinonbase.xyz)", "KEVINTOKENME": "KEVIN (kevintoken.me)", "KEVINTOKENNET": "Kevin", @@ -7951,6 +8112,7 @@ "KILLA": "The Bitcoin Killa", "KILLER": "Fat Cat Killer", "KILLSOLANA": "KillSolana", + "KILO": "KiloEx", "KILT": "KILT Protocol", "KIM": "King Money", "KIMBO": "Kimbo", @@ -8023,6 +8185,7 @@ "KLIMA": "KlimaDAO", "KLK": "Klickzie", "KLKS": "Kalkulus", + "KLKSYNC": "KLK Sync Protocol", "KLO": "Kalao", "KLON": "Klondike Finance", "KLP": "Kulupu", @@ -8059,6 +8222,7 @@ "KNT": "Knekted", "KNTO": "Kento", "KNU": "Keanu", + "KNUT": "Knut From Zoo", "KNW": "Knowledge", "KOAI": "KOI", "KOBE": "Shabu Shabu", @@ -8156,6 +8320,7 @@ "KSWAP": "KyotoSwap", "KSYS": "K-Systems", "KT": "Kuai Token", + "KTA": "Keeta", "KTC": "KTX.Finance", "KTK": "KryptCoin", "KTN": "Kattana", @@ -8173,6 +8338,7 @@ "KUE": "Kuende", "KUJI": "Kujira", "KUKU": "KuKu", + "KULA": "Kula", "KUMA": "Kuma Inu", "KUMU": "Kumu Finance", "KUNAI": "KunaiKash", @@ -8230,6 +8396,7 @@ "LABUBU": "Labubu", "LABX": "Stakinglab", "LABZ": "Insane Labz", + "LABZBASE": "Insane Labz (Base)", "LACCOIN": "LocalAgro", "LACE": "Lovelace World", "LAD": "LADA", @@ -8344,6 +8511,7 @@ "LEE": "Love Earn Enjoy", "LEET": "LeetSwap", "LEG": "Legia Warsaw Fan Token", + "LEGAL": "LegalX", "LEGEND": "Legend", "LEGION": "LEGION", "LEGIT": "LEGIT", @@ -8482,7 +8650,8 @@ "LINU": "Luna Inu", "LINX": "Linx", "LIO": "Lio", - "LION": "Lion Token", + "LION": "Loaded Lions", + "LIONT": "Lion Token", "LIPC": "LIpcoin", "LIPS": "LipChain", "LIQ": "LIQ Protocol", @@ -8493,6 +8662,7 @@ "LIR": "Let it Ride", "LIS": "Realis Network", "LISA": "Lisa Simpson", + "LISAS": "Lisa Simpson", "LIST": "KList Protocol", "LISTA": "Lista DAO", "LISUSD": "lisUSD", @@ -8581,10 +8751,12 @@ "LOFIBUZZ": "LOFI", "LOG": "Wood Coin", "LOGO": "LOGOS", + "LOGOS": "LOGOSAI", "LOGX": "LogX Network", "LOIS": "Lois Token", "LOKA": "League of Kingdoms", "LOKR": "Polkalokr", + "LOKY": "Loky by Virtuals", "LOL": "EMOGI Network", "LOLA": "Lola", "LOLATHECAT": "Lola", @@ -8593,6 +8765,7 @@ "LOLO": "Lolo", "LON": "Tokenlon", "LONG": "Longdrink Finance", + "LONGEVITY": "longevity", "LONGFU": "LONGFU", "LONGM": "Long Mao", "LONGSHINE": "LongShine", @@ -8635,6 +8808,7 @@ "LOYAL": "Loyalty Labs", "LP": "Liquid Protocol", "LPC": "Little Phil", + "LPENGU": "Lil Pudgys", "LPI": "LPI DAO", "LPK": "Kripton", "LPL": "LinkPool", @@ -8719,6 +8893,7 @@ "LUCE": "Luce", "LUCHOW": "LunaChow", "LUCI": "LUCI", + "LUCIC": "Lucidum Coin", "LUCK": "Lucky Cat", "LUCKY": "Lucky Lion", "LUCKYB": "LuckyBlocks", @@ -8735,7 +8910,7 @@ "LUIGI": "Luigi Inu", "LUIS": "Tongue Cat", "LULU": "LULU", - "LUM": "Illuminates", + "LUM": "Luminous", "LUMA": "LUMA Token", "LUMI": "LUMI Credits", "LUMIA": "Lumia", @@ -8768,8 +8943,10 @@ "LVG": "Leverage Coin", "LVIP": "Limitless VIP", "LVL": "Level", + "LVLUSD": "Level USD", "LVM": "LakeViewMeta", "LVN": "LivenPay", + "LVVA": "Levva Protocol Token", "LVX": "Level01", "LWC": "Linework Coin", "LWF": "Local World Forwarders", @@ -8873,6 +9050,7 @@ "MALGO": "milkALGO", "MALL": "Metamall", "MALLY": "Malamute Finance", + "MALOU": "MALOU Token", "MAMAI": "MammothAI", "MAMBA": "Mamba", "MAN": "Matrix AI Network", @@ -8891,6 +9069,7 @@ "MANORUKA": "ManoRuka", "MANT": "Mantle USD", "MANTA": "Manta Network", + "MANTI": "Mantis", "MANTLE": "Mantle", "MANUSAI": "Manus AI Agent", "MANYU": "Little Manyu", @@ -8974,6 +9153,7 @@ "MAXCOIN": "MaxCoin", "MAXETH": "Max on ETH", "MAXI": "Maximus", + "MAXIMUSA": "Kekius Maximusa", "MAXL": "Maxi protocol", "MAXR": "Max Revive", "MAXX": "MAXX Finance", @@ -9032,7 +9212,7 @@ "MCAU": "Meld Gold", "MCB": "MCDEX", "MCC": "Magic Cube Coin", - "MCD": "CDbio", + "MCD": "McDonald's Job Application", "MCDAI": "Dai (Multichain)", "MCDULL": "McDull", "MCELO": "Moola Celo", @@ -9140,6 +9320,7 @@ "MEMD": "MemeDAO", "MEMDEX": "Memdex100", "MEME": "Memecoin", + "MEMEA": "MEME AI", "MEMEAI": "Meme Ai", "MEMECUP": "Meme Cup", "MEMEETF": "Meme ETF", @@ -9155,6 +9336,7 @@ "MEMESQUAD": "Meme Squad", "MEMET": "MEMETOON", "MEMETIC": "Memetic", + "MEMEX": "Meme Index", "MEMHASH": "Memhash", "MEMORYCOIN": "MemoryCoin", "MEN": "METAHUB FINANCE", @@ -9480,6 +9662,7 @@ "MNDE": "Marinade", "MNE": "Minereum", "MNEE": "MNEE USD Stablecoin ", + "MNEMO": "Mnemonics", "MNET": "MINE Network", "MNFT": "Mongol NFT", "MNFTS": "Marvelous NFTs", @@ -9491,6 +9674,7 @@ "MNRB": "MoneyRebel", "MNRCH": "Monarch", "MNS": "Monnos", + "MNSRY": "MANSORY", "MNST": "MoonStarter", "MNTA": "MantaDAO", "MNTC": "Manet Coin", @@ -9533,6 +9717,7 @@ "MODC": "Modclub", "MODE": "Mode", "MODEL": "Model Labs", + "MODERN": "bitcoin-modern", "MODEX": "Modex", "MODU": "Modular Wallet", "MODUM": "Modum", @@ -9659,7 +9844,9 @@ "MORPHO": "Morpho", "MORRA": "Morra", "MORSE": "Morse", + "MORTY": "Morty", "MOS": "MOS Coin", + "MOSS": "MOSS AI", "MOST": "MOST Global", "MOT": "Olympus Labs", "MOTA": "MotaCoin", @@ -9762,7 +9949,7 @@ "MSU": "MetaSoccer", "MSUSHI": "Sushi (Multichain)", "MSWAP": "MoneySwap", - "MT": "MyToken", + "MT": "Mint Token", "MTA": "Meta", "MTB": "MetaBridge", "MTBC": "Metabolic", @@ -9810,6 +9997,11 @@ "MTZ": "Monetizr", "MU": "Miracle Universe", "MUA": "MUA DAO", + "MUB": "Mubarak on Base", + "MUBA": "mubarak", + "MUBAR": "mubarak", + "MUBARAK": "mubarak", + "MUBARAKAH": "Mubarakah", "MUBI": "Multibit", "MUC": "Multi Universe Central", "MUDOL2": "Hero Blaze: Three Kingdoms", @@ -9912,6 +10104,7 @@ "MYT": "Mytrade", "MYTH": "Mythos", "MYTHTOKEN": "Myth Token", + "MYTOKEN": "MyToken", "MYTV": "MyTVchain", "MZC": "MazaCoin", "MZERO": "MetaZero", @@ -10154,6 +10347,7 @@ "NFN": "Nafen", "NFNT": "NFINITY AI", "NFP": "NFPrompt", + "NFPV1": "Token NFPrompt Token v1", "NFT": "APENFT", "NFT11": "NFT11", "NFTART": "NFT Art Finance", @@ -10208,6 +10402,7 @@ "NIIFI": "NiiFi", "NIK": "NIKPLACE", "NIKO": "NikolAI", + "NIL": "Nillion", "NILE": "Nile", "NIM": "Nimiq", "NIMBUS": "Nimbus AI", @@ -10280,6 +10475,7 @@ "NODIDDY": "NODIDDY", "NODIS": "Nodis", "NODL": "Nodle Network", + "NOEL": "AskNoel", "NOGS": "Noggles", "NOHAT": "DogWifNoHat", "NOIA": "Syntropy", @@ -10290,6 +10486,7 @@ "NOKUV1": "NOKU Master token v1", "NOLA": "Nola", "NOM": "Finom NOM Token", + "NOMAI": "nomAI by Virtuals", "NOMNOM": "nomnom", "NOMOX": "NOMOEX Token", "NONE": "None Trading", @@ -10412,6 +10609,7 @@ "NUUM": "MNet", "NUX": "Peanut", "NVA": "Neeva Defi", + "NVB": "NovaBank", "NVC": "NovaCoin", "NVDX": "Nodvix", "NVG": "NightVerse Game", @@ -10455,6 +10653,7 @@ "NYEX": "Nyerium", "NYM": "Nym Token", "NYN": "NYNJA", + "NYS": "node.sys", "NYX": "NYXCOIN", "NYXC": "Nyxia AI", "NYZO": "Nyzo", @@ -10531,6 +10730,7 @@ "ODMC": "ODMCoin", "ODN": "Obsidian", "ODNT": "Old Dogs New Tricks", + "ODOS": "Odos", "ODS": "Odesis", "ODX": "ODX Token", "ODYS": "OdysseyWallet", @@ -10544,6 +10744,7 @@ "OFFIC": "OFFICIAL SIMPSON", "OFFICI": "OFFICIAL BARRON", "OFFICIA": "Official Elon Coin", + "OFFICIALUSA": "Official USA Token", "OFN": "Openfabric AI", "OFT": "ONFA", "OG": "OG Fan Token", @@ -10609,6 +10810,7 @@ "OLY": "Olyseum", "OLYMP": "OlympCoin", "OLYMPE": "OLYMPÉ", + "OLYN": "Olyn by Virtuals", "OM": "MANTRA", "OMA": "OmegaCoin", "OMAX": "Omax", @@ -10697,6 +10899,7 @@ "OPENW": "OpenWorld", "OPENX": "OpenSwap Optimism Token", "OPEPE": "Optimism PEPE", + "OPERATOR": "OpenAI Agent", "OPES": "Opes", "OPET": "ÕpetFoundation", "OPEX": "Optherium Token", @@ -10886,6 +11089,8 @@ "PAK": "Pakcoin", "PAL": "PolicyPal Network", "PALAI": "PaladinAI", + "PALCOIN": "Palcoin Ventures", + "PALCOINV1": "PALCOIN Venture Capital v1", "PALE": "Palette", "PALET": "Palette", "PALG": "PalGold", @@ -10942,6 +11147,7 @@ "PARQ": "PARQ", "PARRY": "Parry Parrot", "PART": "Particl", + "PARTI": "PARTI Token", "PARTY": "Party", "PAS": "Passive Coin", "PASC": "Pascal Coin", @@ -10953,6 +11159,7 @@ "PATEK": "Silly Patek", "PATEX": "Patex", "PATH": "PathDAO", + "PATLU": "Patlu", "PATRIOT": "Patriot", "PATTON": "Patton", "PAUL": "Elephant Penguin", @@ -11036,6 +11243,7 @@ "PEA": "Pea Farm", "PEACH": "Based Peaches", "PEACHY": "Peachy", + "PEAGUY": "The Pea Guy by Virtuals", "PEAK": "PEAKDEFI", "PEAN": "Peanut the Squirrel (peanut-token.xyz)", "PEANIE": "Peanie", @@ -11074,6 +11282,7 @@ "PEKO": "Pepe Neko", "PEL": "Propel Token", "PELF": "PELFORT", + "PELL": "PELL Network Token", "PEM": "Pembrock", "PEME": "PEME", "PENC": "PenCoin", @@ -11119,6 +11328,7 @@ "PEPED": "PepeDAO Coin", "PEPEDAO": "PEPE DAO", "PEPEDERP": "PepeDerp", + "PEPEDNA": "PEPE DNA", "PEPEE": "Pepe the pepe", "PEPEF": "PEPEFLOKI", "PEPEFC": "Pepe FC", @@ -11167,6 +11377,7 @@ "PER": "Perproject", "PERA": "Pera Finance", "PERC": "Perion", + "PERCY": "Percy Verence", "PERI": "PERI Finance", "PERL": "PERL.eco", "PERMIAN": "Permian", @@ -11270,6 +11481,7 @@ "PIGEONC": "Pigeoncoin", "PIGGY": "Piggy", "PIGGYCOIN": "Piggy Coin", + "PIGLET": "PIGLET", "PIGONK": "PIGONK", "PIGS": "Elon Vitalik Pigs", "PIIN": "piin (Ordinals)", @@ -11430,6 +11642,7 @@ "PNC": "PlatiniumCoin", "PND": "PandaCoin", "PNDC": "Pond Coin", + "PNDN": "Pandana", "PNDR": "Pandora Finance", "PNFT": "Pawn My NFT", "PNG": "Pangolin", @@ -11485,6 +11698,7 @@ "POLK": "Polkamarkets", "POLKER": "Polker", "POLL": "Pollchain", + "POLLEN": "Beraborrow", "POLLUK": "Jasse Polluk", "POLLUX": "Pollux Coin", "POLLY": "Polynetica", @@ -11650,6 +11864,7 @@ "PROJECT89": "Project89", "PROLIFIC": "Prolific Game Studio", "PROM": "Prometeus", + "PROMPT": "Wayfinder", "PROOF": "PROVER", "PROP": "Propeller", "PROPC": "Propchain", @@ -11751,6 +11966,7 @@ "PUMBAA": "Pumbaa", "PUMLX": "PUMLx", "PUMP": "PUMP", + "PUMPB": "Pump", "PUMPBTC": "pumpBTC", "PUMPFUNBAN": "Pump Fun Ban", "PUMPIT": "BOGDANOFF", @@ -11758,6 +11974,7 @@ "PUMPY": "WOW MOON LAMBO PUMPPPPPPY", "PUN": "Punkko", "PUNCH": "PUNCHWORD", + "PUNDIAI": "Pundi AI", "PUNDIX": "Pundi X", "PUNDU": "Pundu", "PUNGU": "PUNGU", @@ -11920,6 +12137,7 @@ "QUA": "Quantum Tech", "QUAC": "QUACK", "QUACK": "Rich Quack", + "QUAI": "Quai Network", "QUAM": "Quam Network", "QUAN": "Quant AI", "QUANT": "Quant Finance", @@ -11946,8 +12164,10 @@ "QUIZ": "Quizando", "QUNT": "Quants", "QUO": "Quoll Finance", + "QUQ": "quq", "QUROZ": "Qfora", "QUSD": "QUSD", + "QUSDT": "Tether (Qom Bridge)", "QVT": "Qvolta", "QWAN": "The QWAN", "QWARK": "Qwark", @@ -12113,7 +12333,7 @@ "RECOM": "Recom", "RECORD": "Music Protocol", "RECT": "ReflectionAI", - "RED": "RED TOKEN", + "RED": "RedStone", "REDC": "RedCab", "REDCO": "Redcoin", "REDDIT": "Reddit", @@ -12129,6 +12349,8 @@ "REDP": "Red Ponzi Gud", "REDPEPE": "Red Pepe", "REDTH": "Red The Mal", + "REDTOKEN": "RED TOKEN", + "REDX": "REDX", "REDZILLA": "REDZILLA COIN", "REE": "ReeCoin", "REEE": "REEE", @@ -12166,6 +12388,7 @@ "REMILIA": " Remilia", "REMIT": "BlockRemit", "REMMETA": "Real Estate Metaverse", + "REMUS": "REMUS", "REN": "REN", "RENA": "Warena", "RENBTC": "renBTC", @@ -12192,6 +12415,7 @@ "RET": "Renewable Energy", "RETA": "Realital Metaverse", "RETAIL": "Retail.Global", + "RETAR": "Retard Finder Coin", "RETARDIA": "RETARDIA", "RETARDIO": "RETARDIO", "RETH": "Rocket Pool ETH", @@ -12200,6 +12424,7 @@ "RETIRE": "Retire Token", "REU": "REUCOIN", "REUNI": "Reunit Wallet", + "REUSDC": "Relend USDC", "REV": "Revain", "REV3L": "REV3AL", "REVA": "Revault Network", @@ -12332,6 +12557,7 @@ "RMS": "Resumeo Shares", "RMT": "SureRemit", "RMV": "Reality Metaverse", + "RNAPEPE": "RNA PEPE", "RNB": "Rentible", "RNBW": "Rainbow Token", "RNC": "ReturnCoin", @@ -12353,6 +12579,7 @@ "ROBIN": "Robin of Da Hood", "ROBINH": "ROBIN HOOD", "ROBO": "RoboHero", + "ROBOCOIN": "First Bitcoin ATM", "ROBOTA": "TAXI", "ROBOTAXI": "ROBOTAXI", "ROC": "Rasputin Online Coin", @@ -12412,6 +12639,7 @@ "ROUSH": "Roush Fenway Racing Fan Token", "ROUTE": "Router Protocol", "ROUTEV1": "Router Protocol v1", + "ROUTINE": "Morning Routine", "ROVI": "ROVI", "ROW": "Rage On Wheels", "ROWAN": "Sifchain", @@ -12522,6 +12750,7 @@ "RVT": "Rivetz", "RVX": "Rivex", "RWA": "Xend Finance", + "RWAECO": "RWA Ecosystem", "RWAS": "RWA Finance", "RWB": "RawBlock", "RWD": "Reward Vision", @@ -12529,6 +12758,7 @@ "RWN": "Rowan Token", "RWS": "Robonomics Web Services", "RWT": "RWT TOKEN", + "RX": "RealtyX", "RXCG": "RXCGames", "RXD": "Radiant", "RXO": "RocketXRP Official", @@ -12553,6 +12783,7 @@ "S4F": "S4FE", "S8C": "S88 Coin", "SA": "Superalgos", + "SAAD": "Saad Boi", "SAAS": "SaaSGo", "SABAI": "Sabai Protocol", "SABLE": "Sable Finance", @@ -12610,6 +12841,7 @@ "SAMA": "Moonsama", "SAMMY": "Samoyed", "SAMO": "Samoyedcoin", + "SAMS": "Samsara.Build", "SAN": "Santiment", "SANA": "Storage Area Network Anywhere", "SANCHO": "Sancho", @@ -12853,6 +13085,7 @@ "SEX": "SEX Odyssey", "SEXY": "EthXY", "SEXYP": "SEXY PEPE", + "SFAGRO": "SFAGRO", "SFARM": "SolFarm", "SFC": "Solarflarecoin", "SFCP": "SF Capital", @@ -12867,11 +13100,13 @@ "SFLOKI": "SuiFloki-Inu", "SFLR": "Sceptre Staked FLR", "SFM": "SafeMoon V2", + "SFMV2": "SafeMoon v2", "SFP": "SafePal", "SFR": "SaffronCoin", "SFRAX": "Staked FRAX", "SFRC": "Safari Crush", "SFRXETH": "Frax Staked Ether", + "SFRXUSD": "Staked Frax USD", "SFT": "SportsFix", "SFTMX": "Stader sFTMX", "SFTY": "Stella Fantasy", @@ -12910,6 +13145,7 @@ "SHARE": "Seigniorage Shares", "SHARECHAIN": "ShareChain", "SHARES": "shares.finance", + "SHAREV1": "Seigniorage Shares v1", "SHARK": "Sharky", "SHARKC": "Shark Cat", "SHARKI": "Sharki", @@ -13015,12 +13251,14 @@ "SHOGGOTHAI": "Shoggoth", "SHOKI": "Shoki", "SHON": "ShonToken", + "SHONG": "Shong Inu", "SHOOT": "Mars Battle", "SHOOTER": "Top Down Survival Shooter", "SHOP": "Shoppi Coin", "SHOPN": "ShopNEXT", "SHOPX": "Splyt", "SHORK": "shork", + "SHORT": "Bermuda Shorts", "SHORTY": "ShortyCoin", "SHOW": "ShowCoin", "SHPING": "Shping Coin", @@ -13028,12 +13266,15 @@ "SHRA": "Shrapnel", "SHRAP": "Shrapnel", "SHRED": "ShredN", - "SHREK": "ShrekCoin", + "SHREK": "Shrek", + "SHRI": "Shrimp Paste", "SHRIMP": "SHRIMP", "SHROO": "Shroomates", "SHROOM": "Shroom.Finance", "SHROOMFOX": "Magic Shroom", "SHRUB": "Shrub", + "SHRUBIUS": "Shrubius Maximus", + "SHRX": "Sherex", "SHS": "SHEESH", "SHU": "Shutter", "SHUB": "SimpleHub", @@ -13086,6 +13327,7 @@ "SIMPSO": "Simpson Neiro", "SIMPSON": "Homer", "SIMPSON6900": "Simpson6900 ", + "SIMPSONAI": "Simpson AI Agent", "SIMPSONF": "Simpson FUKU", "SIMPSONP": "Simpson Predictions", "SIMPSONSINU": "The Simpsons Inu", @@ -13170,6 +13412,7 @@ "SLAM": "Slam Token", "SLAP": "CatSlap", "SLAVI": "Slavi Coin", + "SLAYER": "ThreatSlayerAI by Virtuals", "SLB": "Solberg", "SLC": "Silencio", "SLCL": "Solcial", @@ -13208,6 +13451,7 @@ "SLT": "Salute", "SLUGDENG": "SLUG DENG", "SLUMBO": "SLUMBO", + "SLVLUSD": "Staked Level USD", "SLVX": "eToro Silver", "SLX": "Slate", "SMA": "Soma Network", @@ -13312,6 +13556,7 @@ "SNOLEX": "Snolex", "SNOOP": "SnoopDAO", "SNOOPY": "Snoopy", + "SNOR": "SNOR", "SNORK": "Snork", "SNORT": "SNORT", "SNOV": "Snovio", @@ -13393,6 +13638,7 @@ "SOLER": "Solerium", "SOLETF": "SOL ETF", "SOLEX": "Solex Launchpad", + "SOLEY": "Soley", "SOLFI": "SoliDefi", "SOLFUN": "SolFun", "SOLGOAT": "SOLGOAT", @@ -13428,6 +13674,7 @@ "SOLVBTCENA": "SolvBTC Ethena", "SOLVBTCJUP": "SolvBTC Jupiter", "SOLVE": "SOLVE", + "SOLVEX": "SOLVEX", "SOLWIF": "Solwif", "SOLX": "SolarX", "SOLXD": "Solxdex", @@ -13512,6 +13759,8 @@ "SPECT": "Spectral", "SPECTRE": "SPECTRE AI", "SPEE": "SpeedCash", + "SPEED": "IShowSpeed", + "SPEEDCOIN": "Speed Coin", "SPEEDY": "Speedy", "SPELL": "Spell Token", "SPELLFIRE": "Spellfire", @@ -13558,6 +13807,7 @@ "SPO": "Spores Network", "SPOK": "Spock", "SPOL": "Starterpool", + "SPONG": "Spongebob", "SPONGE": "Sponge", "SPONGEBOB": "Spongebob Squarepants", "SPOODY": "Spoody Man", @@ -13634,8 +13884,9 @@ "SSC": "SelfSell", "SSD": "Sonic Screw Driver Coin", "SSDX": "SpunkySDX", - "SSE": "Soroosh Smart Ecosystem", + "SSE": "Solana Social Explorer", "SSEV1": "Soroosh Smart Ecosystem v1", + "SSEV2": "Soroosh Smart Ecosystem", "SSG": "Surviving Soldiers", "SSGT": "Safeswap", "SSH": "StreamSpace", @@ -13692,6 +13943,7 @@ "STARSHIPONSOL": "Starship", "START": "StartCoin", "STARTA": "Starta", + "STARTER": "Starter.xyz", "STARWARS": "Star Wars", "STARX": "STARX TOKEN", "STASH": "BitStash", @@ -13740,6 +13992,7 @@ "STFX": "STFX", "STG": "Stargate Finance", "STHR": "Stakerush", + "STHYPE": "Staked HYPE", "STI": "Seek Tiger", "STIC": "StickMan", "STIK": "Staika", @@ -13815,6 +14068,7 @@ "STRUMP": "Super Trump", "STRX": "StrikeX", "STS": "SBank", + "STSHIP": "StarShip", "STSOL": "Lido Staked SOL", "STSOMM": "Stride Staked SOMM", "STSR": "SatelStar", @@ -14033,7 +14287,9 @@ "SYNTHSWAP": "Synthswap", "SYNX": "Syndicate", "SYPOOL": "Sypool", + "SYRAX": "Syrax AI", "SYRUP": "Syrup", + "SYRUPUSDC": "SyrupUSDC", "SYS": "Syscoin", "SZCB": "Zugacoin", "T": "Threshold Network Token", @@ -14111,6 +14367,7 @@ "TAXAD": "TAXAD", "TAXI": "Robotaxi", "TAXLESSTRUMP": "MAGA TAXLESS", + "TAXP": "Taxpad", "TBAC": "BlockAura", "TBANK": "TaoBank", "TBAR": "Titanium BAR", @@ -14189,6 +14446,7 @@ "TELOS": "Teloscoin", "TEM": "Temtum", "TEMCO": "TEMCO", + "TEMM": "TEM MARKET", "TEMP": "Tempus", "TEMPLE": "TempleDAO", "TEN": "Tokenomy", @@ -14279,6 +14537,7 @@ "THESTANDARD": "Standard Token", "THETA": "Theta Network", "THETAN": "Thetan Coin", + "THETRANSFERTOKEN": "The Transfer Token", "THETRIBE": "The Tribe", "THEX": "Thore Exchange", "THG": "Thetan Arena", @@ -14353,6 +14612,7 @@ "TITANO": "Titano", "TITANX": "TitanX", "TITC": "TitCoin", + "TITCOIN": "titcoin", "TITI": "TiTi Protocol", "TITS": "We Love Tits", "TITTY": "TamaKitty", @@ -14407,6 +14667,7 @@ "TNT": "Tierion", "TOA": "TOA Coin", "TOAD": "TOAD", + "TOADCOIN": "TOAD", "TOB": "Tom On Base", "TOBI": "MOTO DOG", "TOBY": "toby", @@ -14457,6 +14718,7 @@ "TOOLS": "TOOLS", "TOON": "Pontoon", "TOONF": "Toon Finance", + "TOOTHLESS": "Toothless", "TOPC": "Topchain", "TOPCA": "TOP CAT", "TOPCAT": "Topcat", @@ -14485,6 +14747,7 @@ "TOSHKIN": "Toshkin Coin", "TOT": "TotCoin", "TOTEM": "DragonMaster", + "TOTHEMOON": "To The Moon", "TOTM": "Totem", "TOTO": "TOTO", "TOUCHFAN": "TouchFan", @@ -14546,6 +14809,7 @@ "TRDL": "Strudel Finance", "TRDS": "Traders Token", "TRDT": "Trident", + "TRDX": "Trendix", "TREAT": "Treat", "TREB": "Treble", "TRECENTO": "Trecento Blockchain Capital", @@ -14569,6 +14833,7 @@ "TRINI": "Trinity Network Credit", "TRIO": "Tripio", "TRIPAD": "TripAdvisor, Inc.", + "TRIPPKI": "Trippki", "TRITON": "Triton", "TRIVIA": "Trivians", "TRIX": "TriumphX", @@ -14635,7 +14900,9 @@ "TRUMPEPE": "Trump Pepe", "TRUMPER": "Trump Era", "TRUMPF": "Trump Fight", + "TRUMPG": "TRUMP GROK", "TRUMPHAT": "Trump Hat", + "TRUMPI": "TRUMP IP", "TRUMPINU": "Trump Inu", "TRUMPJ": "TRUMPJR", "TRUMPJR": "OFFICIAL TRUMP JR", @@ -14687,6 +14954,7 @@ "TSL": "Energo", "TSLT": "Tamkin", "TSN": "Tsunami Exchange Token", + "TSO": "Thesirion", "TSR": "Tesra", "TST": "Test", "TSTAI": "Test AI", @@ -14700,9 +14968,9 @@ "TTC": "TTC PROTOCOL", "TTF": "TurboTrix Finance", "TTK": "The Three Kingdoms", - "TTM": "To The Moon", + "TTM": "Tradetomato", "TTN": "Titan Coin", - "TTT": "The Transfer Token", + "TTT": "TRUMPETTOKEN", "TTTU": "T-Project", "TTU": "TaTaTu", "TTV": "TV-TWO", @@ -14717,6 +14985,7 @@ "TUNA": "TUNACOIN", "TUNE": "Bitune", "TUP": "Tenup", + "TUPE": "Turtle Pepe", "TUR": "Turron", "TURB": "TurboX", "TURBO": "Turbo", @@ -14727,7 +14996,8 @@ "TUS": "Treasure Under Sea", "TUSD": "True USD", "TUSDV1": "True USD v1", - "TUT": "Tutellus", + "TUT": "Tutorial", + "TUTELLUS": "Tutellus", "TUTTER": "Tutter", "TUX": "Tux The Penguin", "TUZKI": "Tuzki", @@ -14901,6 +15171,7 @@ "UNFK": "UNFK", "UNI": "Uniswap Protocol Token", "UNIBOT": "Unibot", + "UNIBTC": "uniBTC", "UNIC": "Unicly", "UNICE": "UNICE", "UNICORN": "UNICORN Token", @@ -14961,6 +15232,7 @@ "UPR": "Upfire", "UPRO": "ULTRAPRO", "UPS": "UPFI Network", + "UPT": "Universal Protocol Token", "UPTOS": "UPTOS", "UPUNK": "Unicly CryptoPunks Collection", "UPUSD": "Universal US Dollar", @@ -14985,7 +15257,8 @@ "USD0": "Usual", "USD1": "USD1", "USD3": "Web 3 Dollar", - "USDA": "USDA", + "USDA": "USDa", + "USDACC": "USDA", "USDAP": "Bond Appetite USD", "USDB": "USD Bancor", "USDBC": "Bridged USDC", @@ -15006,7 +15279,10 @@ "USDEBT": "USDEBT", "USDEX": "eToro US Dollar", "USDFL": "USDFreeLiquidity", - "USDG": "USDG", + "USDG": "Global Dollar", + "USDGLOBI": "Globiance USD Stablecoin", + "USDGV1": "USDG v1", + "USDGV2": "USDG", "USDH": "HonestCoin", "USDI": "Interest Protocol USDi", "USDJ": "USDJ", @@ -15099,8 +15375,10 @@ "VAAVE": "Venus AAVE", "VAB": "Vabble", "VADA": "Venus Cardano", - "VADER": "Vader Protocol", + "VADER": "VaderAI", + "VADERPROTOCOL": "Vader Protocol", "VAI": "Vai", + "VAIN": "Vainguard by Virtuals", "VAIOT": "VAIOT", "VAIOTV1": "VAIOT v1", "VAL": "Validity", @@ -15367,6 +15645,7 @@ "VPR": "VaporWallet", "VPRC": "VapersCoin", "VPS": "VPS AI", + "VPT": "Veritas Protocol", "VR": "Victoria", "VRA": "Verasity", "VRC": "Virtual Coin", @@ -15412,6 +15691,7 @@ "VTRAD": "VTRADING", "VTRO": "Vitruveo DEX", "VTRUMP": "Vote Trump", + "VTRV": "VitraVerse", "VTRX": "Venus TRX", "VTS": "Veritise", "VTU": "Virtu", @@ -15475,7 +15755,7 @@ "WAIF": "Waifu Token", "WAIFU": "Waifu", "WAIT": "Hourglass", - "WAL": "The Wasted Lands", + "WAL": "WAL Token", "WALE": "Waletoken", "WALK": "Walk Token", "WALL": "Du Rove's Wall", @@ -15506,6 +15786,7 @@ "WASD": "WASD Studios", "WASH": "WashingtonCoin", "WASSIE": "WASSIE", + "WASTED": "WastedLands", "WASTR": "Wrapped Astar", "WAT": "Wat", "WATC": "WATCoin", @@ -15513,6 +15794,7 @@ "WATER": "doginwotah", "WAVAX": "Wrapped AVAX", "WAVES": "Waves", + "WAVESCOMM": "Waves Community Token", "WAVL": "Wrapped Aston Villa", "WAWA": "Wawa Cat", "WAXE": "WAXE", @@ -15561,8 +15843,9 @@ "WCRO": "Wrapped CRO", "WCS": "Weecoins", "WCSOV": "Wrapped CrownSterling", - "WCT": "Waves Community Token", + "WCT": "WalletConnect", "WCT1WCT1": "Wrapped Car Token 1", + "WCTH": "Wrapped CTH Token", "WCUSD": "Wrapped Celo Dollar", "WDAI": "Dai (Wormhole)", "WDC": "WorldCoin", @@ -15582,6 +15865,7 @@ "WEBAI": "Web Ai", "WEBC": "Webchain", "WEBD": "WebDollar", + "WEBSIM": "The Css God by Virtuals", "WEBSS": "Websser", "WEC": "Whole Earth Coin", "WECO": "WECOIN", @@ -15595,6 +15879,7 @@ "WEGI": "Wegie", "WEGLD": "Wrapped EGLD", "WEHMND": "Wrapped eHMND", + "WEHODL": "HODL", "WEIRDO": "Weirdo", "WEL": "Welsh Corgi", "WELA": "Wrapped Elastos", @@ -15636,6 +15921,7 @@ "WFLAMA": "WIFLAMA", "WFLOW": "Wrapped Flow", "WFO": "WoofOracle", + "WFRAGSOL": "Wrapped fragSOL", "WFT": "Windfall Token", "WFTM": "Wrapped Fantom", "WFTN": "Wrapped FTN", @@ -15780,6 +16066,7 @@ "WNEON": "Wrapped Neon EVM", "WNET": "Wavesnode.net", "WNK": "The Winkyverse", + "WNKV1": "The Winkyverse v1", "WNOW": "WalletNow", "WNRG": "Wrapped-Energi", "WNRZ": "WinPlay", @@ -15830,6 +16117,7 @@ "WOR": "Hollywood Capital Group WARRIOR", "WORK": "Work X", "WORKE": "Worken", + "WORKIE": "Workie", "WORL": "World Record Banana", "WORLD": "World Token", "WORM": "HealthyWorm", @@ -15892,6 +16180,7 @@ "WTC": "Waltonchain", "WTE": "Wonder Energy Technology", "WTF": "Waterfall Governance", + "WTFO": "WTF Opossum", "WTFT": "WTF Token", "WTFUEL": "Wrapped TFUEL", "WTG": "Watergate", @@ -15944,6 +16233,7 @@ "X": "X Empire", "X2": "X2Coin", "X2Y2": "X2Y2", + "X33": "Shadow Liquid Staking Token", "X42": "X42 Protocol", "X7": "X7", "X7C": "X7 Coin", @@ -16162,7 +16452,7 @@ "XOX": "XOX Labs", "XOXNO": "XOXNO", "XOXO": "XO Protocol", - "XP": "Experience Points", + "XP": "Xphere", "XPA": "XPA", "XPAT": "Bitnation Pangea", "XPAY": "Wallet Pay", @@ -16252,6 +16542,7 @@ "XTAL": "XTAL", "XTC": "TileCoin", "XTECH": "X-TECH", + "XTER": "Xterio", "XTK": "xToken", "XTM": "TORUM", "XTN": "Neutrino Index Token", @@ -16503,11 +16794,13 @@ "ZEBU": "ZEBU", "ZEC": "ZCash", "ZECD": "ZCashDarkCoin", - "ZED": "ZedCoins", + "ZED": "ZED Token", + "ZEDCOIN": "ZedCoin", "ZEDD": "ZedDex", "ZEDTOKEN": "Zed Token", - "ZEDX": "ZEDXION", + "ZEDX": "ZEDX Сoin", "ZEDXION": "Zedxion", + "ZEDXIONV1": "Zedxion v1", "ZEE": "ZeroSwap", "ZEFI": "ZCore Finance", "ZEFU": "Zenfuse", @@ -16587,6 +16880,7 @@ "ZKEVM": "zkEVMChain (BSC)", "ZKEX": "zkExchange", "ZKF": "ZKFair", + "ZKGPT": "ZKGPT", "ZKGROK": "ZKGROK", "ZKGUN": "zkGUN", "ZKHIVE": "zkHive", diff --git a/apps/api/src/services/cron.service.ts b/apps/api/src/services/cron.service.ts index 088348d85..3d4aff08b 100644 --- a/apps/api/src/services/cron.service.ts +++ b/apps/api/src/services/cron.service.ts @@ -1,8 +1,8 @@ import { UserService } from '@ghostfolio/api/app/user/user.service'; import { DATA_GATHERING_QUEUE_PRIORITY_LOW, - GATHER_ASSET_PROFILE_PROCESS, - GATHER_ASSET_PROFILE_PROCESS_OPTIONS, + GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, + GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS, PROPERTY_IS_DATA_GATHERING_ENABLED } from '@ghostfolio/common/config'; import { getAssetProfileIdentifier } from '@ghostfolio/common/helper'; @@ -66,9 +66,9 @@ export class CronService { dataSource, symbol }, - name: GATHER_ASSET_PROFILE_PROCESS, + name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, opts: { - ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, + ...GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS, jobId: getAssetProfileIdentifier({ dataSource, symbol }), priority: DATA_GATHERING_QUEUE_PRIORITY_LOW } diff --git a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts index 606e6b7fd..f9593f0d0 100644 --- a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts +++ b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts @@ -11,6 +11,7 @@ import { IDataProviderHistoricalResponse, IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces'; +import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DataProviderInfo, @@ -72,7 +73,9 @@ export class AlphaVantageService implements DataProviderInterface { const historicalData: { [symbol: string]: IAlphaVantageHistoricalResponse[]; } = await this.alphaVantage.crypto.daily( - symbol.substring(0, symbol.length - 3).toLowerCase(), + symbol + .substring(0, symbol.length - DEFAULT_CURRENCY.length) + .toLowerCase(), 'usd' ); diff --git a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts index d876b42ca..64bbeebb5 100644 --- a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts @@ -1,4 +1,5 @@ import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service'; +import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error'; import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface'; import { DEFAULT_CURRENCY, @@ -236,7 +237,13 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface { response.url = url; } } catch (error) { - Logger.error(error, 'YahooFinanceService'); + if (error.message === `Quote not found for symbol: ${aSymbol}`) { + throw new AssetProfileDelistedError( + `No data found, ${aSymbol} (${this.getName()}) may be delisted` + ); + } else { + Logger.error(error, 'YahooFinanceService'); + } } return response; diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 8bac6a95c..3d45308aa 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -19,6 +19,7 @@ import { DATE_FORMAT, getCurrencyFromSymbol, getStartOfUtcDate, + isCurrency, isDerivedCurrency } from '@ghostfolio/common/helper'; import { @@ -115,7 +116,13 @@ export class DataProviderService { } } - await Promise.all(promises); + try { + await Promise.all(promises); + } catch (error) { + Logger.error(error, 'DataProviderService'); + + throw error; + } return response; } @@ -464,17 +471,21 @@ export class DataProviderService { )) { const dataProvider = this.getDataProvider(DataSource[dataSource]); - if ( - dataProvider.getDataProviderInfo().isPremium && - this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && - user?.subscription.type === 'Basic' - ) { - continue; - } - const symbols = assetProfileIdentifiers .filter(({ symbol }) => { - return !isDerivedCurrency(getCurrencyFromSymbol(symbol)); + if (isCurrency(getCurrencyFromSymbol(symbol))) { + // Keep non-derived currencies + return !isDerivedCurrency(getCurrencyFromSymbol(symbol)); + } else if ( + dataProvider.getDataProviderInfo().isPremium && + this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && + user?.subscription.type === 'Basic' + ) { + // Skip symbols of Premium data providers for users without subscription + return false; + } + + return true; }) .map(({ symbol }) => { return symbol; diff --git a/apps/api/src/services/data-provider/errors/asset-profile-delisted.error.ts b/apps/api/src/services/data-provider/errors/asset-profile-delisted.error.ts new file mode 100644 index 000000000..dabe0aa5b --- /dev/null +++ b/apps/api/src/services/data-provider/errors/asset-profile-delisted.error.ts @@ -0,0 +1,7 @@ +export class AssetProfileDelistedError extends Error { + public constructor(message: string) { + super(message); + + this.name = 'AssetProfileDelistedError'; + } +} diff --git a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts index 119e8ea67..4e42201d0 100644 --- a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts +++ b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts @@ -12,8 +12,11 @@ import { IDataProviderHistoricalResponse, IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces'; -import { REPLACE_NAME_PARTS } from '@ghostfolio/common/config'; -import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; +import { + DEFAULT_CURRENCY, + REPLACE_NAME_PARTS +} from '@ghostfolio/common/config'; +import { DATE_FORMAT, isCurrency, parseDate } from '@ghostfolio/common/helper'; import { DataProviderInfo, LookupItem, @@ -67,7 +70,15 @@ export class FinancialModelingPrepService implements DataProviderInterface { }; try { - if (this.cryptocurrencyService.isCryptocurrency(symbol)) { + if ( + isCurrency(symbol.substring(0, symbol.length - DEFAULT_CURRENCY.length)) + ) { + response.assetClass = AssetClass.LIQUIDITY; + response.assetSubClass = AssetSubClass.CASH; + response.currency = symbol.substring( + symbol.length - DEFAULT_CURRENCY.length + ); + } else if (this.cryptocurrencyService.isCryptocurrency(symbol)) { const [quote] = await fetch( `${this.URL}/quote/${symbol}?apikey=${this.apiKey}`, { @@ -77,7 +88,9 @@ export class FinancialModelingPrepService implements DataProviderInterface { response.assetClass = AssetClass.LIQUIDITY; response.assetSubClass = AssetSubClass.CRYPTOCURRENCY; - response.currency = symbol.substring(symbol.length - 3); + response.currency = symbol.substring( + symbol.length - DEFAULT_CURRENCY.length + ); response.name = quote.name; } else { const [assetProfile] = await fetch( @@ -325,6 +338,10 @@ export class FinancialModelingPrepService implements DataProviderInterface { } } + public getMaxNumberOfSymbolsPerRequest() { + return 20; + } + public getName(): DataSource { return DataSource.FINANCIAL_MODELING_PREP; } @@ -340,18 +357,28 @@ export class FinancialModelingPrepService implements DataProviderInterface { } try { + const currencyBySymbolMap: { + [symbol: string]: Pick; + } = {}; + const quotes = await fetch( - `${this.URL}/quote/${symbols.join(',')}?apikey=${this.apiKey}`, + `${this.getUrl({ version: 'stable' })}/batch-quote-short?symbols=${symbols.join(',')}&apikey=${this.apiKey}`, { signal: AbortSignal.timeout(requestTimeout) } ).then((res) => res.json()); - for (const { price, symbol } of quotes) { - const { currency } = await this.getAssetProfile({ symbol }); + await Promise.all( + quotes.map(({ symbol }) => { + return this.getAssetProfile({ symbol }).then(({ currency }) => { + currencyBySymbolMap[symbol] = { currency }; + }); + }) + ); + for (const { price, symbol } of quotes) { response[symbol] = { - currency, + currency: currencyBySymbolMap[symbol]?.currency, dataProviderInfo: this.getDataProviderInfo(), dataSource: DataSource.FINANCIAL_MODELING_PREP, marketPrice: price, @@ -378,12 +405,15 @@ export class FinancialModelingPrepService implements DataProviderInterface { } public async search({ query }: GetSearchParams): Promise { + const assetProfileBySymbolMap: { + [symbol: string]: Partial; + } = {}; let items: LookupItem[] = []; try { - if (isISIN(query)) { + if (isISIN(query?.toUpperCase())) { const result = await fetch( - `${this.getUrl({ version: 4 })}/search/isin?isin=${query}&apikey=${this.apiKey}`, + `${this.getUrl({ version: 'stable' })}/search-isin?isin=${query.toUpperCase()}&apikey=${this.apiKey}`, { signal: AbortSignal.timeout( this.configurationService.get('REQUEST_TIMEOUT') @@ -391,15 +421,23 @@ export class FinancialModelingPrepService implements DataProviderInterface { } ).then((res) => res.json()); - items = result.map(({ companyName, currency, symbol }) => { + await Promise.all( + result.map(({ symbol }) => { + return this.getAssetProfile({ symbol }).then((assetProfile) => { + assetProfileBySymbolMap[symbol] = assetProfile; + }); + }) + ); + + items = result.map(({ assetClass, assetSubClass, name, symbol }) => { return { - currency, + assetClass, + assetSubClass, symbol, - assetClass: undefined, // TODO - assetSubClass: undefined, // TODO + currency: assetProfileBySymbolMap[symbol]?.currency, dataProviderInfo: this.getDataProviderInfo(), dataSource: this.getName(), - name: this.formatName({ name: companyName }) + name: this.formatName({ name }) }; }); } else { @@ -451,8 +489,14 @@ export class FinancialModelingPrepService implements DataProviderInterface { return name; } - private getUrl({ version }: { version: number }) { - return `https://financialmodelingprep.com/api/v${version}`; + private getUrl({ version }: { version: number | 'stable' }) { + const baseUrl = 'https://financialmodelingprep.com'; + + if (version === 'stable') { + return `${baseUrl}/stable`; + } + + return `${baseUrl}/api/v${version}`; } private parseAssetClass(profile: any): { @@ -462,15 +506,17 @@ export class FinancialModelingPrepService implements DataProviderInterface { let assetClass: AssetClass; let assetSubClass: AssetSubClass; - if (profile.isEtf) { - assetClass = AssetClass.EQUITY; - assetSubClass = AssetSubClass.ETF; - } else if (profile.isFund) { - assetClass = AssetClass.EQUITY; - assetSubClass = AssetSubClass.MUTUALFUND; - } else { - assetClass = AssetClass.EQUITY; - assetSubClass = AssetSubClass.STOCK; + if (profile) { + if (profile.isEtf) { + assetClass = AssetClass.EQUITY; + assetSubClass = AssetSubClass.ETF; + } else if (profile.isFund) { + assetClass = AssetClass.EQUITY; + assetSubClass = AssetSubClass.MUTUALFUND; + } else { + assetClass = AssetClass.EQUITY; + assetSubClass = AssetSubClass.STOCK; + } } return { assetClass, assetSubClass }; diff --git a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts index 72ae1ff97..6b42c9283 100644 --- a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts @@ -1,5 +1,6 @@ import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service'; import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service'; +import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error'; import { DataProviderInterface, GetAssetProfileParams, @@ -143,12 +144,18 @@ export class YahooFinanceService implements DataProviderInterface { return response; } catch (error) { - throw new Error( - `Could not get historical market data for ${symbol} (${this.getName()}) from ${format( - from, - DATE_FORMAT - )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` - ); + if (error.message === 'No data found, symbol may be delisted') { + throw new AssetProfileDelistedError( + `No data found, ${symbol} (${this.getName()}) may be delisted` + ); + } else { + throw new Error( + `Could not get historical market data for ${symbol} (${this.getName()}) from ${format( + from, + DATE_FORMAT + )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` + ); + } } } diff --git a/apps/api/src/services/market-data/market-data.service.ts b/apps/api/src/services/market-data/market-data.service.ts index d8722e3d9..6381039ad 100644 --- a/apps/api/src/services/market-data/market-data.service.ts +++ b/apps/api/src/services/market-data/market-data.service.ts @@ -63,12 +63,18 @@ export class MarketDataService { public async getRange({ assetProfileIdentifiers, - dateQuery + dateQuery, + skip, + take }: { assetProfileIdentifiers: AssetProfileIdentifier[]; dateQuery: DateQuery; + skip?: number; + take?: number; }): Promise { return this.prismaService.marketData.findMany({ + skip, + take, orderBy: [ { date: 'asc' @@ -78,17 +84,33 @@ export class MarketDataService { } ], where: { - dataSource: { - in: assetProfileIdentifiers.map(({ dataSource }) => { - return dataSource; - }) - }, date: dateQuery, - symbol: { - in: assetProfileIdentifiers.map(({ symbol }) => { - return symbol; - }) - } + OR: assetProfileIdentifiers.map(({ dataSource, symbol }) => { + return { + dataSource, + symbol + }; + }) + } + }); + } + + public async getRangeCount({ + assetProfileIdentifiers, + dateQuery + }: { + assetProfileIdentifiers: AssetProfileIdentifier[]; + dateQuery: DateQuery; + }): Promise { + return this.prismaService.marketData.count({ + where: { + date: dateQuery, + OR: assetProfileIdentifiers.map(({ dataSource, symbol }) => { + return { + dataSource, + symbol + }; + }) } }); } diff --git a/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts b/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts index 1f88375d5..d65d50fb7 100644 --- a/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts +++ b/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts @@ -1,14 +1,16 @@ import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; +import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error'; import { IDataGatheringItem, IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; +import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DATA_GATHERING_QUEUE, DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY, DEFAULT_PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY, - GATHER_ASSET_PROFILE_PROCESS, + GATHER_ASSET_PROFILE_PROCESS_JOB_NAME, GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME, GATHER_MISSING_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME } from '@ghostfolio/common/config'; @@ -40,7 +42,8 @@ export class DataGatheringProcessor { public constructor( private readonly dataGatheringService: DataGatheringService, private readonly dataProviderService: DataProviderService, - private readonly marketDataService: MarketDataService + private readonly marketDataService: MarketDataService, + private readonly symbolProfileService: SymbolProfileService ) {} @Process({ @@ -49,28 +52,49 @@ export class DataGatheringProcessor { DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY.toString(), 10 ), - name: GATHER_ASSET_PROFILE_PROCESS + name: GATHER_ASSET_PROFILE_PROCESS_JOB_NAME }) public async gatherAssetProfile(job: Job) { + const { dataSource, symbol } = job.data; + try { Logger.log( - `Asset profile data gathering has been started for ${job.data.symbol} (${job.data.dataSource})`, - `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})` + `Asset profile data gathering has been started for ${symbol} (${dataSource})`, + `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})` ); await this.dataGatheringService.gatherAssetProfiles([job.data]); Logger.log( - `Asset profile data gathering has been completed for ${job.data.symbol} (${job.data.dataSource})`, - `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})` + `Asset profile data gathering has been completed for ${symbol} (${dataSource})`, + `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})` ); } catch (error) { + if (error instanceof AssetProfileDelistedError) { + await this.symbolProfileService.updateSymbolProfile( + { + dataSource, + symbol + }, + { + isActive: false + } + ); + + Logger.log( + `Asset profile data gathering has been discarded for ${symbol} (${dataSource})`, + `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})` + ); + + return job.discard(); + } + Logger.error( error, - `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})` + `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS_JOB_NAME})` ); - throw new Error(error); + throw error; } } @@ -83,8 +107,9 @@ export class DataGatheringProcessor { name: GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME }) public async gatherHistoricalMarketData(job: Job) { + const { dataSource, date, symbol } = job.data; + try { - const { dataSource, date, symbol } = job.data; let currentDate = parseISO(date as unknown as string); Logger.log( @@ -149,12 +174,31 @@ export class DataGatheringProcessor { `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` ); } catch (error) { + if (error instanceof AssetProfileDelistedError) { + await this.symbolProfileService.updateSymbolProfile( + { + dataSource, + symbol + }, + { + isActive: false + } + ); + + Logger.log( + `Historical market data gathering has been discarded for ${symbol} (${dataSource})`, + `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` + ); + + return job.discard(); + } + Logger.error( error, `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` ); - throw new Error(error); + throw error; } } @Process({ @@ -166,9 +210,8 @@ export class DataGatheringProcessor { name: GATHER_MISSING_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME }) public async gatherMissingHistoricalMarketData(job: Job) { + const { dataSource, date, symbol } = job.data; try { - const { dataSource, date, symbol } = job.data; - Logger.log( `Historical market data gathering for missing values has been started for ${symbol} (${dataSource}) at ${format( date, @@ -237,12 +280,31 @@ export class DataGatheringProcessor { `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` ); } catch (error) { + if (error instanceof AssetProfileDelistedError) { + await this.symbolProfileService.updateSymbolProfile( + { + dataSource, + symbol + }, + { + isActive: false + } + ); + + Logger.log( + `Historical market data gathering has been discarded for ${symbol} (${dataSource})`, + `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` + ); + + return job.discard(); + } + Logger.error( error, `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` ); - throw new Error(error); + throw error; } } diff --git a/apps/api/src/services/queues/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts b/apps/api/src/services/queues/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts index 24948e211..b9f315c5d 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts @@ -1,6 +1,8 @@ import { Filter } from '@ghostfolio/common/interfaces'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; export interface IPortfolioSnapshotQueueJob { + calculationType: PerformanceCalculationType; filters: Filter[]; userCurrency: string; userId: string; diff --git a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts index 60c3cf695..6a2a3114e 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts @@ -1,9 +1,6 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { OrderService } from '@ghostfolio/api/app/order/order.service'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -68,7 +65,7 @@ export class PortfolioSnapshotProcessor { const portfolioCalculator = this.calculatorFactory.createCalculator({ accountBalanceItems, activities, - calculationType: PerformanceCalculationType.ROAI, + calculationType: job.data.calculationType, currency: job.data.userCurrency, filters: job.data.filters, userId: job.data.userId diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.ts index afb2283d5..4a2d54b17 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -44,14 +44,14 @@ export class SymbolProfileService { ? { some: { User: { - Subscription: { some: { expiresAt: { gt: new Date() } } } + subscriptions: { some: { expiresAt: { gt: new Date() } } } } } } : { every: { User: { - Subscription: { none: { expiresAt: { gt: new Date() } } } + subscriptions: { none: { expiresAt: { gt: new Date() } } } } } } diff --git a/apps/api/src/validators/is-currency-code.ts b/apps/api/src/validators/is-currency-code.ts index 34a82c481..d04da7808 100644 --- a/apps/api/src/validators/is-currency-code.ts +++ b/apps/api/src/validators/is-currency-code.ts @@ -25,19 +25,24 @@ export class IsExtendedCurrencyConstraint implements ValidatorConstraintInterface { public defaultMessage() { - return '$value must be a valid ISO4217 currency code'; + return '$property must be a valid ISO4217 currency code'; } public validate(currency: any) { // Return true if currency is a standard ISO 4217 code or a derived currency return ( - isISO4217CurrencyCode(currency) || - [ - ...DERIVED_CURRENCIES.map((derivedCurrency) => { - return derivedCurrency.currency; - }), - 'USX' - ].includes(currency) + this.isUpperCase(currency) && + (isISO4217CurrencyCode(currency) || + [ + ...DERIVED_CURRENCIES.map((derivedCurrency) => { + return derivedCurrency.currency; + }), + 'USX' + ].includes(currency)) ); } + + private isUpperCase(aString: string) { + return aString === aString?.toUpperCase(); + } } diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts index 4220208c0..38e48f139 100644 --- a/apps/client/src/app/app.component.ts +++ b/apps/client/src/app/app.component.ts @@ -143,8 +143,8 @@ export class AppComponent implements OnDestroy, OnInit { ); this.hasPromotion = - !!this.info?.subscriptionOffers?.default?.coupon || - !!this.info?.subscriptionOffers?.default?.durationExtension; + !!this.info?.subscriptionOffer?.coupon || + !!this.info?.subscriptionOffer?.durationExtension; this.impersonationStorageService .onChangeHasImpersonation() @@ -242,12 +242,8 @@ export class AppComponent implements OnDestroy, OnInit { this.canCreateAccount || !!this.user?.systemMessage; this.hasPromotion = - !!this.info?.subscriptionOffers?.[ - this.user?.subscription?.offer ?? 'default' - ]?.coupon || - !!this.info?.subscriptionOffers?.[ - this.user?.subscription?.offer ?? 'default' - ]?.durationExtension; + !!this.user?.subscription?.offer?.coupon || + !!this.user?.subscription?.offer?.durationExtension; this.initializeTheme(this.user?.settings.colorScheme); diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index c5e30644c..b56aff09b 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -137,6 +137,7 @@ export class AdminMarketDataComponent ); this.displayedColumns = [ + 'status', 'select', 'nameWithSymbol', 'dataSource', diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.html b/apps/client/src/app/components/admin-market-data/admin-market-data.html index aa7533156..9024998d6 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.html +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -20,6 +20,34 @@ matSortDirection="asc" [dataSource]="dataSource" > + + + + @if (!element.isActive) { +
+ +
+ } + + +
+ @@ -187,7 +215,11 @@ > - + @if (price) { diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.html b/apps/client/src/app/components/user-account-settings/user-account-settings.html index 8bd2efd1f..72d5aa678 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.html +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -2,25 +2,7 @@

Settings

-
-
-
Presenter View
-
- Protection for sensitive information like absolute performances and - quantity values -
-
-
- -
-
-
+
@@ -43,6 +25,32 @@
+ @if (user?.settings?.isExperimentalFeatures && !user?.subscription) { +
+
+ Performance Calculation +
+
+ + + Return on Average Investment (ROAI) + + +
+
+ }
Language
@@ -172,6 +180,24 @@
+
+
+
Presenter View
+
+ Protection for sensitive information like absolute performances and + quantity values +
+
+
+ +
+
Zen Mode
diff --git a/apps/client/src/app/pages/api/api-page.component.ts b/apps/client/src/app/pages/api/api-page.component.ts index 350650060..7b385ec2f 100644 --- a/apps/client/src/app/pages/api/api-page.component.ts +++ b/apps/client/src/app/pages/api/api-page.component.ts @@ -27,9 +27,10 @@ import { map, Observable, Subject, takeUntil } from 'rxjs'; export class GfApiPageComponent implements OnInit { public dividends$: Observable; public historicalData$: Observable; + public isinLookupItems$: Observable; + public lookupItems$: Observable; public quotes$: Observable; public status$: Observable; - public symbols$: Observable; private apiKey: string; private unsubscribeSubject = new Subject(); @@ -41,9 +42,10 @@ export class GfApiPageComponent implements OnInit { this.dividends$ = this.fetchDividends({ symbol: 'KO' }); this.historicalData$ = this.fetchHistoricalData({ symbol: 'AAPL' }); + this.isinLookupItems$ = this.fetchLookupItems({ query: 'US0378331005' }); + this.lookupItems$ = this.fetchLookupItems({ query: 'apple' }); this.quotes$ = this.fetchQuotes({ symbols: ['AAPL', 'VOO.US'] }); this.status$ = this.fetchStatus(); - this.symbols$ = this.fetchSymbols({ query: 'apple' }); } public ngOnDestroy() { @@ -93,32 +95,7 @@ export class GfApiPageComponent implements OnInit { ); } - private fetchQuotes({ symbols }: { symbols: string[] }) { - const params = new HttpParams().set('symbols', symbols.join(',')); - - return this.http - .get('/api/v2/data-providers/ghostfolio/quotes', { - params, - headers: this.getHeaders() - }) - .pipe( - map(({ quotes }) => { - return quotes; - }), - takeUntil(this.unsubscribeSubject) - ); - } - - private fetchStatus() { - return this.http - .get( - '/api/v2/data-providers/ghostfolio/status', - { headers: this.getHeaders() } - ) - .pipe(takeUntil(this.unsubscribeSubject)); - } - - private fetchSymbols({ + private fetchLookupItems({ includeIndices = false, query }: { @@ -144,6 +121,31 @@ export class GfApiPageComponent implements OnInit { ); } + private fetchQuotes({ symbols }: { symbols: string[] }) { + const params = new HttpParams().set('symbols', symbols.join(',')); + + return this.http + .get('/api/v2/data-providers/ghostfolio/quotes', { + params, + headers: this.getHeaders() + }) + .pipe( + map(({ quotes }) => { + return quotes; + }), + takeUntil(this.unsubscribeSubject) + ); + } + + private fetchStatus() { + return this.http + .get( + '/api/v2/data-providers/ghostfolio/status', + { headers: this.getHeaders() } + ) + .pipe(takeUntil(this.unsubscribeSubject)); + } + private getHeaders() { return new HttpHeaders({ [HEADER_KEY_SKIP_INTERCEPTOR]: 'true', diff --git a/apps/client/src/app/pages/api/api-page.html b/apps/client/src/app/pages/api/api-page.html index a1f286c07..d8bfc75d7 100644 --- a/apps/client/src/app/pages/api/api-page.html +++ b/apps/client/src/app/pages/api/api-page.html @@ -3,10 +3,21 @@

Status

{{ status$ | async | json }}
-
+

Lookup

- @if (symbols$) { - @let symbols = symbols$ | async; + @if (lookupItems$) { + @let symbols = lookupItems$ | async; +
    + @for (item of symbols; track item.symbol) { +
  • {{ item.name }} ({{ item.symbol }})
  • + } +
+ } +
+
+

Lookup (ISIN)

+ @if (isinLookupItems$) { + @let symbols = isinLookupItems$ | async;
    @for (item of symbols; track item.symbol) {
  • {{ item.name }} ({{ item.symbol }})
  • diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index a0aca4605..819bc78fb 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -15,7 +15,7 @@ import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { AssetClass, AssetSubClass, Tag, Type } from '@prisma/client'; import { isAfter, isToday } from 'date-fns'; -import { EMPTY, Subject, lastValueFrom } from 'rxjs'; +import { EMPTY, Subject } from 'rxjs'; import { catchError, delay, takeUntil } from 'rxjs/operators'; import { DataService } from '../../../../services/data.service'; @@ -102,7 +102,8 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { Validators.required ], currencyOfUnitPrice: [ - this.data.activity?.SymbolProfile?.currency, + this.data.activity?.currency ?? + this.data.activity?.SymbolProfile?.currency, Validators.required ], dataSource: [ @@ -111,7 +112,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { ], date: [this.data.activity?.date, Validators.required], fee: [this.data.activity?.fee, Validators.required], - feeInCustomCurrency: [this.data.activity?.fee, Validators.required], name: [this.data.activity?.SymbolProfile?.name, Validators.required], quantity: [this.data.activity?.quantity, Validators.required], searchSymbol: [ @@ -133,10 +133,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { ], type: [undefined, Validators.required], // Set after value changes subscription unitPrice: [this.data.activity?.unitPrice, Validators.required], - unitPriceInCustomCurrency: [ - this.data.activity?.unitPrice, - Validators.required - ], updateAccountBalance: [false] }); @@ -148,57 +144,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { takeUntil(this.unsubscribeSubject) ) .subscribe(async () => { - let exchangeRateOfUnitPrice = 1; - - this.activityForm.get('feeInCustomCurrency').setErrors(null); - this.activityForm.get('unitPriceInCustomCurrency').setErrors(null); - - const currency = this.activityForm.get('currency').value; - const currencyOfUnitPrice = this.activityForm.get( - 'currencyOfUnitPrice' - ).value; - const date = this.activityForm.get('date').value; - - if ( - currency && - currencyOfUnitPrice && - currency !== currencyOfUnitPrice && - date - ) { - try { - const { marketPrice } = await lastValueFrom( - this.dataService - .fetchExchangeRateForDate({ - date, - symbol: `${currencyOfUnitPrice}-${currency}` - }) - .pipe(takeUntil(this.unsubscribeSubject)) - ); - - exchangeRateOfUnitPrice = marketPrice; - } catch { - this.activityForm.get('unitPriceInCustomCurrency').setErrors({ - invalid: true - }); - } - } - - const feeInCustomCurrency = - this.activityForm.get('feeInCustomCurrency').value * - exchangeRateOfUnitPrice; - - const unitPriceInCustomCurrency = - this.activityForm.get('unitPriceInCustomCurrency').value * - exchangeRateOfUnitPrice; - - this.activityForm.get('fee').setValue(feeInCustomCurrency, { - emitEvent: false - }); - - this.activityForm.get('unitPrice').setValue(unitPriceInCustomCurrency, { - emitEvent: false - }); - if ( this.activityForm.get('type').value === 'BUY' || this.activityForm.get('type').value === 'FEE' || @@ -269,10 +214,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.activityForm.get('type').value ) ) { - this.activityForm - .get('dataSource') - .setValue(this.activityForm.get('searchSymbol').value.dataSource); - this.updateSymbol(); } @@ -301,7 +242,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { .get('dataSource') .removeValidators(Validators.required); this.activityForm.get('dataSource').updateValueAndValidity(); - this.activityForm.get('feeInCustomCurrency').reset(); + this.activityForm.get('fee').reset(); this.activityForm.get('name').setValidators(Validators.required); this.activityForm.get('name').updateValueAndValidity(); this.activityForm.get('quantity').setValue(1); @@ -335,12 +276,11 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.activityForm.get('dataSource').updateValueAndValidity(); if ( - (type === 'FEE' && - this.activityForm.get('feeInCustomCurrency').value === 0) || + (type === 'FEE' && this.activityForm.get('fee').value === 0) || type === 'INTEREST' || type === 'LIABILITY' ) { - this.activityForm.get('feeInCustomCurrency').reset(); + this.activityForm.get('fee').reset(); } this.activityForm.get('name').setValidators(Validators.required); @@ -358,7 +298,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.activityForm.get('searchSymbol').updateValueAndValidity(); if (type === 'FEE') { - this.activityForm.get('unitPriceInCustomCurrency').setValue(0); + this.activityForm.get('unitPrice').setValue(0); } if ( @@ -414,7 +354,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { public applyCurrentMarketPrice() { this.activityForm.patchValue({ currencyOfUnitPrice: this.activityForm.get('currency').value, - unitPriceInCustomCurrency: this.currentMarketPrice + unitPrice: this.currentMarketPrice }); } @@ -500,7 +440,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.dataService .fetchSymbolItem({ - dataSource: this.activityForm.get('dataSource').value, + dataSource: this.activityForm.get('searchSymbol').value.dataSource, symbol: this.activityForm.get('searchSymbol').value.symbol }) .pipe( @@ -516,9 +456,11 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { takeUntil(this.unsubscribeSubject) ) .subscribe(({ currency, dataSource, marketPrice }) => { - this.activityForm.get('currency').setValue(currency); - this.activityForm.get('currencyOfUnitPrice').setValue(currency); - this.activityForm.get('dataSource').setValue(dataSource); + if (this.mode === 'create') { + this.activityForm.get('currency').setValue(currency); + this.activityForm.get('currencyOfUnitPrice').setValue(currency); + this.activityForm.get('dataSource').setValue(dataSource); + } this.currentMarketPrice = marketPrice; diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html index ec6c66358..b47d83a4c 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -225,11 +225,7 @@ } } - +
    - @if ( - activityForm.get('unitPriceInCustomCurrency').hasError('invalid') - ) { - Oops! Could not get the historical exchange rate - from - {{ - activityForm.get('date')?.value | date: defaultDateFormat - }} - } @if ( currentMarketPrice && @@ -274,36 +257,6 @@ }
-
- - - @switch (activityForm.get('type')?.value) { - @case ('DIVIDEND') { - Dividend - } - @case ('FEE') { - Value - } - @case ('INTEREST') { - Value - } - @case ('ITEM') { - Value - } - @case ('LIABILITY') { - Value - } - @default { - Unit Price - } - } - - - {{ - activityForm.get('currency').value - }} - -
Fee - +
{{ activityForm.get('currencyOfUnitPrice').value }}
- @if (activityForm.get('feeInCustomCurrency').hasError('invalid')) { - Oops! Could not get the historical exchange rate - from - {{ - activityForm.get('date')?.value | date: defaultDateFormat - }} - } - -
-
- - Fee - - {{ - activityForm.get('currency').value - }}
@@ -403,7 +336,8 @@ [isCurrency]="true" [locale]="data.user?.settings?.locale" [unit]=" - activityForm.get('currency')?.value ?? data.user?.settings?.baseCurrency + activityForm.get('currencyOfUnitPrice')?.value ?? + data.user?.settings?.baseCurrency " [value]="total" /> diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts index 82e78a180..20f135801 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -247,9 +247,10 @@ export class ImportActivitiesDialog implements OnDestroy { reader.onload = async (readerEvent) => { const fileContent = readerEvent.target.result as string; + const fileExtension = file.name.split('.').pop()?.toLowerCase(); try { - if (file.name.endsWith('.json')) { + if (fileExtension === 'json') { const content = JSON.parse(fileContent); this.accounts = content.accounts; @@ -294,7 +295,7 @@ export class ImportActivitiesDialog implements OnDestroy { } return; - } else if (file.name.endsWith('.csv')) { + } else if (fileExtension === 'csv') { const content = fileContent.split('\n').slice(1); try { diff --git a/apps/client/src/app/pages/pricing/pricing-page.component.ts b/apps/client/src/app/pages/pricing/pricing-page.component.ts index 62e2bec0b..cadc3a48c 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.component.ts +++ b/apps/client/src/app/pages/pricing/pricing-page.component.ts @@ -55,13 +55,13 @@ export class PricingPageComponent implements OnDestroy, OnInit { ) {} public ngOnInit() { - const { baseCurrency, subscriptionOffers } = this.dataService.fetchInfo(); + const { baseCurrency, subscriptionOffer } = this.dataService.fetchInfo(); this.baseCurrency = baseCurrency; - this.coupon = subscriptionOffers?.default?.coupon; - this.durationExtension = subscriptionOffers?.default?.durationExtension; - this.label = subscriptionOffers?.default?.label; - this.price = subscriptionOffers?.default?.price; + this.coupon = subscriptionOffer?.coupon; + this.durationExtension = subscriptionOffer?.durationExtension; + this.label = subscriptionOffer?.label; + this.price = subscriptionOffer?.price; this.userService.stateChanged .pipe(takeUntil(this.unsubscribeSubject)) @@ -74,20 +74,13 @@ export class PricingPageComponent implements OnDestroy, OnInit { permissions.updateUserSettings ); - this.coupon = - subscriptionOffers?.[this.user?.subscription?.offer]?.coupon; - this.couponId = - subscriptionOffers?.[this.user.subscription.offer]?.couponId; + this.coupon = this.user?.subscription?.offer?.coupon; + this.couponId = this.user?.subscription?.offer?.couponId; this.durationExtension = - subscriptionOffers?.[ - this.user?.subscription?.offer - ]?.durationExtension; - this.label = - subscriptionOffers?.[this.user?.subscription?.offer]?.label; - this.price = - subscriptionOffers?.[this.user?.subscription?.offer]?.price; - this.priceId = - subscriptionOffers?.[this.user.subscription.offer]?.priceId; + this.user?.subscription?.offer?.durationExtension; + this.label = this.user?.subscription?.offer?.label; + this.price = this.user?.subscription?.offer?.price; + this.priceId = this.user?.subscription?.offer?.priceId; this.changeDetectorRef.markForCheck(); } diff --git a/apps/client/src/app/pages/pricing/pricing-page.html b/apps/client/src/app/pages/pricing/pricing-page.html index b165d5c23..d26a2e11e 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.html +++ b/apps/client/src/app/pages/pricing/pricing-page.html @@ -306,14 +306,10 @@ mat-flat-button (click)="onCheckout()" > - @if (user.subscription.offer === 'default') { - Upgrade Plan - } @else if ( - user.subscription.offer === 'renewal' || - user.subscription.offer === 'renewal-early-bird-2023' || - user.subscription.offer === 'renewal-early-bird-2024' - ) { + @if (user.subscription.offer.isRenewal) { Renew Plan + } @else { + Upgrade Plan }

diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts index 6a8543e71..bee5cb642 100644 --- a/apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts +++ b/apps/client/src/app/pages/resources/personal-finance-tools/product-page.component.ts @@ -33,9 +33,9 @@ export class GfProductPageComponent implements OnInit { ) {} public ngOnInit() { - const { subscriptionOffers } = this.dataService.fetchInfo(); + const { subscriptionOffer } = this.dataService.fetchInfo(); - this.price = subscriptionOffers?.default?.price; + this.price = subscriptionOffer?.price; this.product1 = { founded: 2021, diff --git a/apps/client/src/app/services/import-activities.service.ts b/apps/client/src/app/services/import-activities.service.ts index 241fa50ab..1d48085a2 100644 --- a/apps/client/src/app/services/import-activities.service.ts +++ b/apps/client/src/app/services/import-activities.service.ts @@ -126,6 +126,7 @@ export class ImportActivitiesService { private convertToCreateOrderDto({ accountId, comment, + currency, date, fee, quantity, @@ -142,7 +143,7 @@ export class ImportActivitiesService { type, unitPrice, updateAccountBalance, - currency: SymbolProfile.currency, + currency: currency ?? SymbolProfile.currency, dataSource: SymbolProfile.dataSource, date: date.toString(), symbol: SymbolProfile.symbol diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index 39ff2331f..456e15790 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -74,7 +74,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -98,7 +98,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -118,7 +118,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -238,7 +238,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -282,11 +282,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -314,43 +314,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -719,6 +719,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -943,7 +947,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -999,7 +1003,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -1031,11 +1035,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1095,11 +1099,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1145,22 +1149,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -1195,7 +1183,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1219,11 +1207,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1289,6 +1277,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + Symbol @@ -1299,11 +1291,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1323,11 +1315,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -1447,7 +1439,7 @@ Preu de Mercat apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1463,11 +1455,11 @@ Cancel·lar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1495,7 +1487,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1511,7 +1503,7 @@ Guardar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1539,7 +1531,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -1583,7 +1575,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -1591,15 +1583,15 @@ Classe d’Actiu apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1607,11 +1599,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -1619,15 +1611,15 @@ Subclasse d’Actiu apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1635,7 +1627,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -1643,11 +1635,11 @@ Primera Activitat apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1663,7 +1655,7 @@ Nombre d’Activitats apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -1671,7 +1663,7 @@ Dades Històriques apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -1683,7 +1675,7 @@ Nombre de Sectors apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -1691,7 +1683,7 @@ Nombre de Països apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -1699,11 +1691,11 @@ Recopilar Dades del Perfil apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -1711,7 +1703,7 @@ Eliminar Perfils apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -1783,7 +1775,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1795,7 +1787,7 @@ País apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -1811,11 +1803,11 @@ Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1831,11 +1823,11 @@ Països apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1847,7 +1839,7 @@ Referència apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -1855,7 +1847,7 @@ Mapatge de Símbols apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -1863,7 +1855,7 @@ Configuració del Proveïdor de Dades apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -1871,7 +1863,7 @@ Prova apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -1879,11 +1871,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1899,7 +1891,7 @@ Notes apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1907,7 +1899,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -1939,7 +1931,7 @@ Nom, símbol o ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2043,7 +2035,7 @@ Recollida de Dades apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -2127,7 +2119,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2343,7 +2335,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -2355,7 +2347,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -2367,7 +2359,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -2375,7 +2367,7 @@ Millora la teva Subscripció apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -2383,11 +2375,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -2395,15 +2387,15 @@ Renova la teva Subscripció apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -2411,7 +2403,7 @@ Tu apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -2423,7 +2415,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -2431,7 +2423,7 @@ El meu Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -2439,7 +2431,7 @@ Sobre Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -2451,7 +2443,7 @@ Iniciar Sessió apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -2463,7 +2455,7 @@ Primers Passos apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2557,10 +2549,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Dividend Yield @@ -2791,7 +2779,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -3267,7 +3255,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -3283,7 +3271,7 @@ Please enter your coupon code. apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -3291,7 +3279,7 @@ Could not redeem coupon code apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -3299,7 +3287,7 @@ Coupon code has been redeemed apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -3307,7 +3295,7 @@ Reload apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -3315,7 +3303,7 @@ per year apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -3327,7 +3315,7 @@ Try Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -3335,7 +3323,7 @@ Redeem Coupon apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -3383,7 +3371,7 @@ Presenter View apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -3391,7 +3379,7 @@ Protection for sensitive information like absolute performances and quantity values apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3399,7 +3387,7 @@ Base Currency apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -3407,7 +3395,7 @@ Language apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -3415,7 +3403,7 @@ If a translation is missing, kindly support us in extending it here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -3423,11 +3411,11 @@ Locale apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -3435,7 +3423,7 @@ Date and number format apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -3443,7 +3431,7 @@ Appearance apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3451,7 +3439,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -3459,7 +3447,7 @@ Light apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -3467,7 +3455,7 @@ Dark apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3475,7 +3463,7 @@ Zen Mode apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -3487,7 +3475,7 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3495,7 +3483,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -3503,7 +3491,7 @@ Sign in with fingerprint apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -3511,7 +3499,7 @@ Experimental Features apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -3519,7 +3507,7 @@ Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3527,7 +3515,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -3535,7 +3523,7 @@ Danger Zone apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -3543,7 +3531,7 @@ Close Account apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -3595,7 +3583,7 @@ Okay apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -4183,7 +4171,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -4651,7 +4639,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -4669,47 +4657,23 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 - - Oops! Could not get the historical exchange rate from - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Fee Fee apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html 234 - - Oops! Could not get the historical exchange rate from - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Import Activities Import Activities @@ -4775,7 +4739,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -5411,7 +5375,7 @@ One-time payment, no auto-renewal. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -5419,7 +5383,7 @@ It’s free. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -6071,11 +6035,11 @@ No entries... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6091,7 +6055,7 @@ Date Range libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6099,7 +6063,7 @@ Reset Filters libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6107,7 +6071,7 @@ Apply Filters libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -7099,7 +7063,7 @@ No auto-renewal. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7445,7 +7409,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7477,7 +7441,7 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7485,7 +7449,7 @@ Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7493,7 +7457,7 @@ Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7501,7 +7465,7 @@ Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7509,7 +7473,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7637,7 +7601,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7645,7 +7609,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7653,7 +7617,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7661,7 +7625,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7914,7 +7878,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7930,7 +7894,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7938,15 +7902,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index aca6af395..10f26cddb 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -98,7 +98,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -130,11 +130,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -212,22 +212,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -262,7 +246,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -286,11 +270,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -338,11 +322,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -362,11 +346,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -420,6 +404,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + View Data @@ -478,7 +466,7 @@ Marktpreis apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -494,11 +482,11 @@ Abbrechen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -526,7 +514,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -542,7 +530,7 @@ Speichern apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -570,7 +558,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -582,11 +570,11 @@ Erste Aktivität apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -610,7 +598,7 @@ Historische Daten apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -662,7 +650,7 @@ Letzte historische Marktdaten synchronisieren apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -670,7 +658,7 @@ Alle historischen Marktdaten synchronisieren apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 @@ -678,11 +666,11 @@ Profildaten synchronisieren apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -770,7 +758,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -814,7 +802,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -826,7 +814,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -846,7 +834,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -866,7 +854,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -882,7 +870,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -902,11 +890,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -926,7 +914,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -934,7 +922,7 @@ Ich apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -942,7 +930,7 @@ Mein Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -950,7 +938,7 @@ Über Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -966,7 +954,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -982,7 +970,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -1062,7 +1050,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1134,7 +1122,7 @@ Einloggen apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1276,10 +1264,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -1294,11 +1278,11 @@ Sektoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1314,11 +1298,11 @@ Länder apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1450,7 +1434,7 @@ Okay apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -1634,7 +1618,7 @@ Bitte gebe deinen Gutscheincode ein. apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -1642,7 +1626,7 @@ Gutscheincode konnte nicht eingelöst werden apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -1650,7 +1634,7 @@ Gutscheincode wurde eingelöst apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -1658,7 +1642,7 @@ Neu laden apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -1682,7 +1666,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -1698,7 +1682,7 @@ pro Jahr apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -1710,7 +1694,7 @@ Premium ausprobieren apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -1718,7 +1702,7 @@ Gutschein einlösen apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -1726,7 +1710,7 @@ Präsentationsansicht apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -1734,7 +1718,7 @@ Basiswährung apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -1742,11 +1726,11 @@ Lokalität apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -1754,7 +1738,7 @@ Datums- und Zahlenformat apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -1762,7 +1746,7 @@ Zen Modus apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -1774,7 +1758,7 @@ Einloggen mit Fingerabdruck apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -1786,7 +1770,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -1854,11 +1838,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2202,7 +2186,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -2238,7 +2222,7 @@ Name, Symbol oder ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2272,10 +2256,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 @@ -2286,11 +2266,7 @@ Gebühr apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2302,7 +2278,7 @@ Kommentar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2310,7 +2286,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -2318,15 +2294,15 @@ Anlageklasse apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2334,11 +2310,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -2590,7 +2566,7 @@ Sprache apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -2598,7 +2574,7 @@ Registrieren apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2674,15 +2650,15 @@ Anlageunterklasse apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2690,7 +2666,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -2698,7 +2674,7 @@ Sektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2710,7 +2686,7 @@ Land apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -2806,7 +2782,7 @@ Anzahl Länder apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -2814,7 +2790,7 @@ Anzahl Sektoren apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -2846,7 +2822,7 @@ Filtern nach... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -2874,7 +2850,7 @@ Experimentelle Funktionen apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -2922,7 +2898,7 @@ Aussehen apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2930,7 +2906,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -2938,7 +2914,7 @@ Hell apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -2946,7 +2922,7 @@ Dunkel apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3210,43 +3186,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -3258,7 +3234,7 @@ Anzahl Aktivitäten apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -3274,7 +3250,7 @@ Symbol Zuordnung apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -3382,7 +3358,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -3474,7 +3450,7 @@ Ausblenden von sensiblen Informationen wie absoluter Performance und Stückzahl apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3482,7 +3458,7 @@ Unbeschwertes Erlebnis für turbulente Zeiten apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3490,7 +3466,7 @@ Vorschau auf kommende Funktionalität apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3578,7 +3554,7 @@ Abonnement abschliessen apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -3586,11 +3562,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3702,7 +3678,7 @@ Einmalige Zahlung, keine automatische Erneuerung. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -3718,7 +3694,7 @@ Es ist kostenlos. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -3829,14 +3805,6 @@ 2 - - Oops! Could not get the historical exchange rate from - Ups! Der historische Wechselkurs konnte nicht abgerufen werden vom - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Retirement Date Pensionierungsdatum @@ -3845,12 +3813,12 @@ 32 - - Gather Historical Market Dataa + + Gather Historical Market Data Historische Marktdaten synchronisieren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 @@ -3878,15 +3846,15 @@ Abonnement erneuern apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -3950,11 +3918,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4342,7 +4310,7 @@ Scraper Konfiguration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -4734,7 +4702,7 @@ Biometrische Authentifizierung apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -4818,7 +4786,7 @@ Daten exportieren apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -4918,7 +4886,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -5535,6 +5503,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -5822,14 +5794,6 @@ 41 - - Oops! Could not get the historical exchange rate from - Ups! Der historische Wechselkurs konnte nicht abgerufen werden vom - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee Gebühr @@ -5919,7 +5883,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -5999,11 +5963,11 @@ Keine Einträge vorhanden... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6195,7 +6159,7 @@ Wenn eine Übersetzung fehlt, unterstütze uns bitte dabei, sie hier zu ergänzen. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6211,7 +6175,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6219,7 +6183,7 @@ Zeitraum libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6419,7 +6383,7 @@ Filter zurücksetzen libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6443,7 +6407,7 @@ Filter anwenden libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6451,7 +6415,7 @@ Finanzmarktdaten synchronisieren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6635,7 +6599,7 @@ Gefahrenzone apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6643,7 +6607,7 @@ Konto schliessen apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6699,7 +6663,7 @@ Profile löschen apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7123,7 +7087,7 @@ Keine automatische Erneuerung. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7469,7 +7433,7 @@ Bitte gib den API-Schlüssel ein: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7501,7 +7465,7 @@ API-Schlüssel konnte nicht erstellt werden apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7509,7 +7473,7 @@ Setze diesen API-Schlüssel in deiner selbst gehosteten Umgebung: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7517,7 +7481,7 @@ API-Schlüssel für den Ghostfolio Premium Datenanbieter apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7525,7 +7489,7 @@ Möchtest du wirklich einen neuen API-Schlüssel erstellen? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7533,7 +7497,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7661,7 +7625,7 @@ Standardmarktpreis apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7669,7 +7633,7 @@ Modus apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7677,7 +7641,7 @@ Selektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7685,7 +7649,7 @@ HTTP Request-Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7938,7 +7902,7 @@ Übernehmen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7949,6 +7913,22 @@ 266 + + Data Gathering is off + Finanzmarktdaten synchronisieren ist deaktiviert + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Berechnung + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 + + diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index d9712b3f6..8ba704729 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -99,7 +99,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -131,11 +131,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -213,22 +213,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -263,7 +247,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -287,11 +271,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -339,11 +323,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -363,11 +347,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -421,6 +405,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + View Data @@ -479,7 +467,7 @@ Precio de mercado apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -495,11 +483,11 @@ Cancela apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -527,7 +515,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -543,7 +531,7 @@ Guarda apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -571,7 +559,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -583,11 +571,11 @@ Primera actividad apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -611,7 +599,7 @@ Datos históricos apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -663,11 +651,11 @@ Recoger los datos del perfil apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -755,7 +743,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -799,7 +787,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -811,7 +799,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -831,7 +819,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -851,7 +839,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -867,7 +855,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -887,11 +875,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -911,7 +899,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -919,7 +907,7 @@ apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -927,7 +915,7 @@ Mi Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -935,7 +923,7 @@ Sobre Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -951,7 +939,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -967,7 +955,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -1047,7 +1035,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1119,7 +1107,7 @@ Iniciar sesión apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1261,10 +1249,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -1279,11 +1263,11 @@ Sectores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1299,11 +1283,11 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1435,7 +1419,7 @@ De acuerdo apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -1619,7 +1603,7 @@ Por favor, ingresa tu código de cupón: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -1627,7 +1611,7 @@ No se puede canjear este código de cupón apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -1635,7 +1619,7 @@ El codigo de cupón ha sido canjeado apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -1643,7 +1627,7 @@ Refrescar apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -1667,7 +1651,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -1683,7 +1667,7 @@ por año apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -1695,7 +1679,7 @@ Prueba Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -1703,7 +1687,7 @@ Canjea el cupón apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -1711,7 +1695,7 @@ Vista del presentador apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -1719,7 +1703,7 @@ Divisa base apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -1727,11 +1711,11 @@ Ubicación apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -1739,7 +1723,7 @@ Formato de fecha y número apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -1747,7 +1731,7 @@ Modo Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -1759,7 +1743,7 @@ Iniciar sesión con huella digital apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -1771,7 +1755,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -1839,11 +1823,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2187,7 +2171,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -2223,7 +2207,7 @@ Nombre, símbolo o ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2257,10 +2241,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 @@ -2271,11 +2251,7 @@ Comisión apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2287,7 +2263,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2295,7 +2271,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -2303,15 +2279,15 @@ Tipo de activo apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2319,11 +2295,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -2575,7 +2551,7 @@ Idioma apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -2583,7 +2559,7 @@ Comenzar apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2647,15 +2623,15 @@ Subtipo de activo apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2663,7 +2639,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -2711,7 +2687,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2723,7 +2699,7 @@ País apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -2791,7 +2767,7 @@ Número de sectores apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -2799,7 +2775,7 @@ Número de países apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -2831,7 +2807,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -2859,7 +2835,7 @@ Funcionalidades experimentales apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -2907,7 +2883,7 @@ Apariencia apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2915,7 +2891,7 @@ Automático apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -2923,7 +2899,7 @@ Claro apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -2931,7 +2907,7 @@ Oscuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3195,43 +3171,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -3243,7 +3219,7 @@ Recuento de actividades apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -3259,7 +3235,7 @@ Mapeo de símbolos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -3367,7 +3343,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -3459,7 +3435,7 @@ Protección de información confidencial como rendimientos absolutos y valores cuantitativos apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3467,7 +3443,7 @@ Experiencia sin distracciones para tiempos turbulentos apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3475,7 +3451,7 @@ Un adelanto de las próximas funciones apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3563,7 +3539,7 @@ Mejorar plan apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -3571,11 +3547,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3687,7 +3663,7 @@ Pago único, sin renovación automática. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -3703,7 +3679,7 @@ Es gratis. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -3814,14 +3790,6 @@ 2 - - Oops! Could not get the historical exchange rate from - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Retirement Date Retirement Date @@ -3855,15 +3823,15 @@ Renovar Plan apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -3927,11 +3895,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4319,7 +4287,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -4711,7 +4679,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -4795,7 +4763,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -4895,7 +4863,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -5512,6 +5480,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -5799,14 +5771,6 @@ 41 - - Oops! Could not get the historical exchange rate from - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee Fee @@ -5896,7 +5860,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -5976,11 +5940,11 @@ No entries... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6172,7 +6136,7 @@ If a translation is missing, kindly support us in extending it here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6188,7 +6152,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6196,7 +6160,7 @@ Date Range libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6396,7 +6360,7 @@ Reiniciar filtros libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6420,7 +6384,7 @@ Aplicar filtros libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6428,7 +6392,7 @@ Data Gathering apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6612,7 +6576,7 @@ Zona peligrosa apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6620,7 +6584,7 @@ Eliminar cuenta apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6676,7 +6640,7 @@ Borrar Perfiles apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7100,7 +7064,7 @@ No auto-renewal. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7446,7 +7410,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7478,7 +7442,7 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7486,7 +7450,7 @@ Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7494,7 +7458,7 @@ Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7502,7 +7466,7 @@ Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7510,7 +7474,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7638,7 +7602,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7646,7 +7610,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7654,7 +7618,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7662,7 +7626,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7915,7 +7879,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7931,7 +7895,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7939,15 +7903,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index e4203f7dd..78893b590 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -138,11 +138,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -202,11 +202,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -268,22 +268,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -318,7 +302,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -342,11 +326,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -386,11 +370,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -410,11 +394,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -476,6 +460,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + View Data @@ -534,7 +522,7 @@ Prix du Marché apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -550,11 +538,11 @@ Annuler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -582,7 +570,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -598,7 +586,7 @@ Sauvegarder apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -626,7 +614,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -638,7 +626,7 @@ Filtrer par... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -646,15 +634,15 @@ Classe d’Actifs apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -662,11 +650,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -674,15 +662,15 @@ Sous-classe d’Actifs apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -690,7 +678,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -698,11 +686,11 @@ Première Activité apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -718,7 +706,7 @@ Nombre d’Activités apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -726,7 +714,7 @@ Données Historiques apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -738,7 +726,7 @@ Nombre de Secteurs apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -746,7 +734,7 @@ Nombre de Pays apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -754,11 +742,11 @@ Obtenir les Données du Profil apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -774,7 +762,7 @@ Secteur apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -786,7 +774,7 @@ Pays apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -802,11 +790,11 @@ Secteurs apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -822,11 +810,11 @@ Pays apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -838,7 +826,7 @@ Équivalence de Symboles apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -846,7 +834,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -854,7 +842,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -1014,7 +1002,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -1042,7 +1030,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1130,7 +1118,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -1142,7 +1130,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -1154,7 +1142,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -1170,7 +1158,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -1190,11 +1178,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -1214,7 +1202,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -1222,7 +1210,7 @@ Moi apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -1230,7 +1218,7 @@ Mon Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -1238,7 +1226,7 @@ À propos de Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -1254,7 +1242,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -1270,7 +1258,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -1286,7 +1274,7 @@ Se connecter apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1298,7 +1286,7 @@ Démarrer apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -1398,7 +1386,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1608,10 +1596,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -1778,7 +1762,7 @@ D’accord apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -1874,7 +1858,7 @@ Veuillez entrer votre code promotionnel. apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -1882,7 +1866,7 @@ Le code promotionnel n’a pas pu être appliqué apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -1890,7 +1874,7 @@ Le code promotionnel a été appliqué apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -1898,7 +1882,7 @@ Rafraîchir apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -1922,7 +1906,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -1938,7 +1922,7 @@ par an apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -1950,7 +1934,7 @@ Essayer Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -1958,7 +1942,7 @@ Utiliser un Code Promotionnel apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -1966,7 +1950,7 @@ Vue de Présentation apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -1974,7 +1958,7 @@ Devise de Base apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -1982,7 +1966,7 @@ Langue apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -1994,43 +1978,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -2042,11 +2026,11 @@ Paramètres régionaux apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -2054,7 +2038,7 @@ Format de date et d’heure apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -2062,7 +2046,7 @@ Apparence apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2070,7 +2054,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -2078,7 +2062,7 @@ Clair apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -2086,7 +2070,7 @@ Sombre apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -2094,7 +2078,7 @@ Mode Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -2106,7 +2090,7 @@ Se connecter avec empreinte apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -2114,7 +2098,7 @@ Fonctionnalités expérimentales apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -2126,7 +2110,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -2458,7 +2442,7 @@ Nom, symbole, ou ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2476,10 +2460,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 @@ -2490,11 +2470,7 @@ Frais apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2822,7 +2798,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -3366,7 +3342,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -3458,7 +3434,7 @@ Protection pour les informations sensibles telles que la performance absolue et les montants apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3466,7 +3442,7 @@ Expérience sans distraction pour les périodes tumultueuses apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3474,7 +3450,7 @@ Avant-première de fonctionnalités futures apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3562,7 +3538,7 @@ Mettre à niveau l’Abonnement apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -3570,11 +3546,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3686,7 +3662,7 @@ Paiement unique, sans auto-renouvellement. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -3702,7 +3678,7 @@ C’est gratuit. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -3813,14 +3789,6 @@ 2 - - Oops! Could not get the historical exchange rate from - Oups ! Nous n’avons pas pu obtenir le taux de change historique à partir de - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Retirement Date Date de Retraite @@ -3854,15 +3822,15 @@ Renouveler l’Abonnement apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -3926,11 +3894,11 @@ Lien apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4318,7 +4286,7 @@ Configuration du Scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -4710,7 +4678,7 @@ Authentication biométrique apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -4794,7 +4762,7 @@ Exporter les Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -4894,7 +4862,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -5511,6 +5479,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -5798,14 +5770,6 @@ 41 - - Oops! Could not get the historical exchange rate from - Oops! Echec de la récupération des données historiques depuis - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee Frais @@ -5895,7 +5859,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -5975,11 +5939,11 @@ Pas d’entrées ... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6171,7 +6135,7 @@ Si une traduction est manquante, veuillez nous aider à compléter la traduction here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6187,7 +6151,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6195,7 +6159,7 @@ Intervalle de Date libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6395,7 +6359,7 @@ Réinitialiser les Filtres libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6419,7 +6383,7 @@ Appliquer les Filtres libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6427,7 +6391,7 @@ Collecter les données apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6611,7 +6575,7 @@ Zone de danger apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6619,7 +6583,7 @@ Supprimer le compte apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6675,7 +6639,7 @@ Supprimer des Profils apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7099,7 +7063,7 @@ Pas de renouvellement automatique. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7445,7 +7409,7 @@ Veuillez saisir votre clé API Ghostfolio : apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7477,7 +7441,7 @@ Impossible de générer une clé API apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7485,7 +7449,7 @@ Définissez cette clé API dans votre environnement auto-hébergé : apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7493,7 +7457,7 @@ Clé API du fournisseur de données Ghostfolio Premium apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7501,7 +7465,7 @@ Voulez-vous vraiment générer une nouvelle clé API ? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7509,7 +7473,7 @@ Étiquette libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7637,7 +7601,7 @@ Prix du marché par défaut apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7645,7 +7609,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7653,7 +7617,7 @@ Selecteur apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7661,7 +7625,7 @@ En-têtes de requête HTTP apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7914,7 +7878,7 @@ Appliquer apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7930,7 +7894,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7938,15 +7902,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index ce6b7771a..bc72bfa8d 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -99,7 +99,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -131,11 +131,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -213,22 +213,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -263,7 +247,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -287,11 +271,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -339,11 +323,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -363,11 +347,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -421,6 +405,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + View Data @@ -479,7 +467,7 @@ Prezzo di mercato apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -495,11 +483,11 @@ Annulla apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -527,7 +515,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -543,7 +531,7 @@ Salva apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -571,7 +559,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -583,11 +571,11 @@ Prima attività apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -611,7 +599,7 @@ Dati storici apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -663,11 +651,11 @@ Raccogli i dati del profilo apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -755,7 +743,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -799,7 +787,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -811,7 +799,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -831,7 +819,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -851,7 +839,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -867,7 +855,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -887,11 +875,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -911,7 +899,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -919,7 +907,7 @@ Io apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -927,7 +915,7 @@ Il mio Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -935,7 +923,7 @@ Informazioni su Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -951,7 +939,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -967,7 +955,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -1047,7 +1035,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1119,7 +1107,7 @@ Accedi apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1261,10 +1249,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -1279,11 +1263,11 @@ Settori apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1299,11 +1283,11 @@ Paesi apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1435,7 +1419,7 @@ Bene apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -1619,7 +1603,7 @@ Inserisci il tuo codice del buono: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -1627,7 +1611,7 @@ Impossibile riscattare il codice del buono apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -1635,7 +1619,7 @@ Il codice del buono è stato riscattato apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -1643,7 +1627,7 @@ Ricarica apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -1667,7 +1651,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -1683,7 +1667,7 @@ per anno apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -1695,7 +1679,7 @@ Prova Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -1703,7 +1687,7 @@ Riscatta il buono apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -1711,7 +1695,7 @@ Vista presentatore apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -1719,7 +1703,7 @@ Valuta base apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -1727,11 +1711,11 @@ Locale apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -1739,7 +1723,7 @@ Formato data e numero apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -1747,7 +1731,7 @@ Modalità Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -1759,7 +1743,7 @@ Accesso con impronta digitale apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -1771,7 +1755,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -1839,11 +1823,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2187,7 +2171,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -2223,7 +2207,7 @@ Nome, simbolo o ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2257,10 +2241,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 @@ -2271,11 +2251,7 @@ Commissione apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2287,7 +2263,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2295,7 +2271,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -2303,15 +2279,15 @@ Classe asset apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2319,11 +2295,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -2575,7 +2551,7 @@ Lingua apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -2583,7 +2559,7 @@ Inizia apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2647,15 +2623,15 @@ Sottoclasse asset apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2663,7 +2639,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -2711,7 +2687,7 @@ Settore apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2723,7 +2699,7 @@ Paese apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -2791,7 +2767,7 @@ Numero di settori apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -2799,7 +2775,7 @@ Numero di paesi apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -2831,7 +2807,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -2859,7 +2835,7 @@ Funzionalità sperimentali apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -2907,7 +2883,7 @@ Aspetto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2915,7 +2891,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -2923,7 +2899,7 @@ Chiaro apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -2931,7 +2907,7 @@ Scuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3195,43 +3171,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -3243,7 +3219,7 @@ Conteggio attività apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -3259,7 +3235,7 @@ Mappatura dei simboli apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -3367,7 +3343,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -3459,7 +3435,7 @@ Protezione delle informazioni sensibili come le prestazioni assolute e i valori quantitativi apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3467,7 +3443,7 @@ Esperienza priva di distrazioni per i periodi più turbolenti apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3475,7 +3451,7 @@ Un’anteprima delle funzionalità in arrivo apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3563,7 +3539,7 @@ Aggiorna il piano apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -3571,11 +3547,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3687,7 +3663,7 @@ Pagamento una tantum, senza rinnovo automatico. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -3703,7 +3679,7 @@ È gratuito. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -3814,14 +3790,6 @@ 2 - - Oops! Could not get the historical exchange rate from - Ops! Impossibile ottenere il tasso di cambio storico da - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Retirement Date Data di pensionamento @@ -3855,15 +3823,15 @@ Rinnova il piano apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -3927,11 +3895,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4319,7 +4287,7 @@ Configurazione dello scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -4711,7 +4679,7 @@ Autenticazione biometrica apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -4795,7 +4763,7 @@ Esporta dati apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -4895,7 +4863,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -5512,6 +5480,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -5799,14 +5771,6 @@ 41 - - Oops! Could not get the historical exchange rate from - Ops! Impossibile ottenere il tasso di cambio storico da - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee Commissione @@ -5896,7 +5860,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -5976,11 +5940,11 @@ Nessun risultato... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6172,7 +6136,7 @@ Se manca una traduzione, puoi aiutarci modificando questo file: here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6188,7 +6152,7 @@ Prova apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6196,7 +6160,7 @@ Intervallo di date libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6396,7 +6360,7 @@ Reset Filtri libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6420,7 +6384,7 @@ Applica i Filtri libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6428,7 +6392,7 @@ Raccolta Dati apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6612,7 +6576,7 @@ Zona di Pericolo apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6620,7 +6584,7 @@ Chiudi l’account apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6676,7 +6640,7 @@ Elimina i profili apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7100,7 +7064,7 @@ No rinnovo automatico. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7446,7 +7410,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7478,7 +7442,7 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7486,7 +7450,7 @@ Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7494,7 +7458,7 @@ Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7502,7 +7466,7 @@ Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7510,7 +7474,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7638,7 +7602,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7646,7 +7610,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7654,7 +7618,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7662,7 +7626,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7915,7 +7879,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7931,7 +7895,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7939,15 +7903,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index f58aa6349..7c5066ad6 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -98,7 +98,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -130,11 +130,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -212,22 +212,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -262,7 +246,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -286,11 +270,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -338,11 +322,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -362,11 +346,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -420,6 +404,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + View Data @@ -478,7 +466,7 @@ Marktprijs apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -494,11 +482,11 @@ Annuleren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -526,7 +514,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -542,7 +530,7 @@ Opslaan apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -570,7 +558,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -582,11 +570,11 @@ Eerste activiteit apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -610,7 +598,7 @@ Historische gegevens apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -662,11 +650,11 @@ Verzamel profielgegevens apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -754,7 +742,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -798,7 +786,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -810,7 +798,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -830,7 +818,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -850,7 +838,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -866,7 +854,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -886,11 +874,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -910,7 +898,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -918,7 +906,7 @@ Ik apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -926,7 +914,7 @@ Mijn Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -934,7 +922,7 @@ Over Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -950,7 +938,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -966,7 +954,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -1046,7 +1034,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1118,7 +1106,7 @@ Aanmelden apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1260,10 +1248,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -1278,11 +1262,11 @@ Sectoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1298,11 +1282,11 @@ Landen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1434,7 +1418,7 @@ Oké apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -1618,7 +1602,7 @@ Voer je couponcode in: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -1626,7 +1610,7 @@ Kon je kortingscode niet inwisselen apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -1634,7 +1618,7 @@ Je couponcode is ingewisseld apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -1642,7 +1626,7 @@ Herladen apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -1666,7 +1650,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -1682,7 +1666,7 @@ per jaar apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -1694,7 +1678,7 @@ Probeer Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -1702,7 +1686,7 @@ Coupon inwisselen apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -1710,7 +1694,7 @@ Presentatie weergave apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -1718,7 +1702,7 @@ Basisvaluta apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -1726,11 +1710,11 @@ Locatie apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -1738,7 +1722,7 @@ Datum- en getalnotatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -1746,7 +1730,7 @@ Zen-modus apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -1758,7 +1742,7 @@ Aanmelden met vingerafdruk apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -1770,7 +1754,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -1838,11 +1822,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2186,7 +2170,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -2222,7 +2206,7 @@ Naam, symbool of ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2256,10 +2240,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 @@ -2270,11 +2250,7 @@ Transactiekosten apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2286,7 +2262,7 @@ Opmerking apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2294,7 +2270,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -2302,15 +2278,15 @@ Asset klasse apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2318,11 +2294,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -2574,7 +2550,7 @@ Taal apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -2582,7 +2558,7 @@ Aan de slag apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2646,15 +2622,15 @@ Asset subklasse apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2662,7 +2638,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -2710,7 +2686,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2722,7 +2698,7 @@ Land apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -2790,7 +2766,7 @@ Aantal sectoren apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -2798,7 +2774,7 @@ Aantal landen apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -2830,7 +2806,7 @@ Filter op... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -2858,7 +2834,7 @@ Experimentele functies apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -2906,7 +2882,7 @@ Weergave apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2914,7 +2890,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -2922,7 +2898,7 @@ Licht apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -2930,7 +2906,7 @@ Donker apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3194,43 +3170,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -3242,7 +3218,7 @@ Aantal activiteiten apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -3258,7 +3234,7 @@ Symbool toewijzen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -3366,7 +3342,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -3458,7 +3434,7 @@ Bescherming voor gevoelige informatie zoals absoluut rendement en hoeveelheden apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3466,7 +3442,7 @@ Afleidingsvrije ervaring voor roerige tijden apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3474,7 +3450,7 @@ Voorproefje van nieuwe functionaliteit apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3562,7 +3538,7 @@ Abonnement uitbreiden apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -3570,11 +3546,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3686,7 +3662,7 @@ Eenmalige betaling, geen automatische verlenging. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -3702,7 +3678,7 @@ Het is gratis. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -3813,14 +3789,6 @@ 2 - - Oops! Could not get the historical exchange rate from - Oeps! Kon de historische wisselkoers niet krijgen van - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Retirement Date Pensioen Datum @@ -3854,15 +3822,15 @@ Abonnement Vernieuwen apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -3926,11 +3894,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4318,7 +4286,7 @@ Scraper instellingen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -4710,7 +4678,7 @@ Biometrische authenticatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -4794,7 +4762,7 @@ Exporteer Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -4894,7 +4862,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -5511,6 +5479,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -5798,14 +5770,6 @@ 41 - - Oops! Could not get the historical exchange rate from - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee Fee @@ -5895,7 +5859,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -5975,11 +5939,11 @@ No entries... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6171,7 +6135,7 @@ If a translation is missing, kindly support us in extending it here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6187,7 +6151,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6195,7 +6159,7 @@ Date Range libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6395,7 +6359,7 @@ Reset Filters libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6419,7 +6383,7 @@ Apply Filters libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6427,7 +6391,7 @@ Data Gathering apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6611,7 +6575,7 @@ Danger Zone apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6619,7 +6583,7 @@ Close Account apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6675,7 +6639,7 @@ Delete Profiles apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7099,7 +7063,7 @@ No auto-renewal. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7445,7 +7409,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7477,7 +7441,7 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7485,7 +7449,7 @@ Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7493,7 +7457,7 @@ Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7501,7 +7465,7 @@ Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7509,7 +7473,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7637,7 +7601,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7645,7 +7609,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7653,7 +7617,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7661,7 +7625,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7914,7 +7878,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7930,7 +7894,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7938,15 +7902,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 0a3164ffc..4970c3d53 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -338,6 +338,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + privacy-policy @@ -503,7 +507,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -527,7 +531,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -547,7 +551,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -667,7 +671,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -711,11 +715,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -743,43 +747,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -899,7 +903,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -959,11 +963,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1023,11 +1027,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1073,22 +1077,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -1123,7 +1111,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1147,11 +1135,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1197,6 +1185,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + Symbol @@ -1207,11 +1199,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1231,11 +1223,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -1339,7 +1331,7 @@ Cena Rynkowa apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1355,11 +1347,11 @@ Anuluj apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1387,7 +1379,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1403,7 +1395,7 @@ Zapisz apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1431,7 +1423,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -1475,7 +1467,7 @@ Filtruj według... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -1483,15 +1475,15 @@ Klasa Aktywów apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1499,11 +1491,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -1511,15 +1503,15 @@ Podklasa Aktywów apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1527,7 +1519,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -1535,11 +1527,11 @@ Pierwsza Aktywność apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1555,7 +1547,7 @@ Liczba Aktywności apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -1563,7 +1555,7 @@ Dane Historyczne apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -1575,7 +1567,7 @@ Liczba Sektorów apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -1583,7 +1575,7 @@ Liczba Krajów apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -1591,11 +1583,11 @@ Zbierz Dane Profilu apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -1635,7 +1627,7 @@ Sektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1647,7 +1639,7 @@ Kraj apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -1663,11 +1655,11 @@ Sektory apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1683,11 +1675,11 @@ Kraje apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1699,7 +1691,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -1707,7 +1699,7 @@ Mapowanie Symboli apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -1715,7 +1707,7 @@ Konfiguracja Scrapera apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -1723,7 +1715,7 @@ Notatka apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1731,7 +1723,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -1763,7 +1755,7 @@ Nazwa, symbol lub ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1927,11 +1919,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1959,7 +1951,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2175,7 +2167,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -2187,7 +2179,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -2199,7 +2191,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -2207,7 +2199,7 @@ Ja apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -2219,7 +2211,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -2227,7 +2219,7 @@ Moje Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -2235,7 +2227,7 @@ O Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -2247,7 +2239,7 @@ Zaloguj się apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -2259,7 +2251,7 @@ Rozpocznij apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2443,7 +2435,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2705,10 +2697,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -2907,7 +2895,7 @@ Ulepsz Plan apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -2915,11 +2903,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3011,7 +2999,7 @@ Wpisz kod kuponu: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -3019,7 +3007,7 @@ Nie udało się zrealizować kodu kuponu apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -3027,7 +3015,7 @@ Kupon został zrealizowany apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -3035,7 +3023,7 @@ Odśwież apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -3043,7 +3031,7 @@ rocznie apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -3055,7 +3043,7 @@ Wypróbuj Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -3063,7 +3051,7 @@ Wykorzystaj kupon apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -3095,7 +3083,7 @@ Widok Prezentera apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -3103,7 +3091,7 @@ Ochrona dla wrażliwych informacji takich jak wyniki i wartości ilościowe apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3111,7 +3099,7 @@ Waluta Bazowa apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -3119,7 +3107,7 @@ Język apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -3127,11 +3115,11 @@ Ustawienia Regionalne apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -3139,7 +3127,7 @@ Format daty i liczb apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -3147,7 +3135,7 @@ Wygląd (tryb) apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3155,7 +3143,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -3163,7 +3151,7 @@ Jasny apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -3171,7 +3159,7 @@ Ciemny apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3179,7 +3167,7 @@ Tryb Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -3191,7 +3179,7 @@ Doświadczenie bez zakłóceń w niespokojnych czasach apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3199,7 +3187,7 @@ Uwierzytelnianie Biometryczne apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -3207,7 +3195,7 @@ Logowanie za pomocą linii papilarnych apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -3215,7 +3203,7 @@ Funkcje Eksperymentalne apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -3223,7 +3211,7 @@ Podgląd nadchodzących funkcjonalności apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3235,7 +3223,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -3243,7 +3231,7 @@ Eksportuj Dane apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -3287,7 +3275,7 @@ Okej apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -3803,7 +3791,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -4263,7 +4251,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -4281,47 +4269,23 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 - - Oops! Could not get the historical exchange rate from - Ups! Nie udało się uzyskać historycznego kursu wymiany z - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee Opłata apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html 234 - - Oops! Could not get the historical exchange rate from - Ups! Nie udało się uzyskać historycznego kursu wymiany z - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Import Activities Importuj Aktywności @@ -4387,7 +4351,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -4787,7 +4751,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -4963,15 +4927,15 @@ Odnów Plan apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -4979,7 +4943,7 @@ Płatność jednorazowa, bez automatycznego odnawiania. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -4995,7 +4959,7 @@ Jest bezpłatny. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -5535,11 +5499,11 @@ Brak wpisów... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6171,7 +6135,7 @@ Jeżeli brakuje jakiegoś tłumaczenia, uprzejmie prosimy o wsparcie w jego uzupełnieniu tutaj. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6187,7 +6151,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6195,7 +6159,7 @@ Zakres Dat libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6395,7 +6359,7 @@ Resetuj Filtry libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6419,7 +6383,7 @@ Zastosuj Filtry libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6427,7 +6391,7 @@ Gromadzenie Danych apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6611,7 +6575,7 @@ Strefa Zagrożenia apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6619,7 +6583,7 @@ Zamknij Konto apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6675,7 +6639,7 @@ Usuń Profile apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7099,7 +7063,7 @@ Bez automatycznego odnawiania. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7445,7 +7409,7 @@ Wprowadź swój klucz API konta Ghostfolio: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7477,7 +7441,7 @@ Nie udało się wygenerować klucza API apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7485,7 +7449,7 @@ Ustaw ten klucz API w samodzielnie hostowanym środowisku: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7493,7 +7457,7 @@ Klucz API dostawcy danych Premium Ghostfolio apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7501,7 +7465,7 @@ Czy na pewno chcesz wygenerować nowy klucz API? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7509,7 +7473,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7637,7 +7601,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7645,7 +7609,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7653,7 +7617,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7661,7 +7625,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7914,7 +7878,7 @@ Zatwierdź apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7930,7 +7894,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7938,15 +7902,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index f5f61a4b2..84a3a0061 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -138,11 +138,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -202,11 +202,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -268,22 +268,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -318,7 +302,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -342,11 +326,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -386,11 +370,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -410,11 +394,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -476,6 +460,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + View Data @@ -534,7 +522,7 @@ Preço de Mercado apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -550,11 +538,11 @@ Cancelar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -582,7 +570,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -598,7 +586,7 @@ Guardar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -626,7 +614,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -638,7 +626,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -646,15 +634,15 @@ Classe do Ativo apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -662,11 +650,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -674,15 +662,15 @@ Subclasse do ativo apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -690,7 +678,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -698,11 +686,11 @@ Primeira Atividade apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -726,7 +714,7 @@ Dados Históricos apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -738,7 +726,7 @@ Contagem de Países apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -746,7 +734,7 @@ Contagem de Setores apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -754,11 +742,11 @@ Recolher Dados de Perfíl apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -886,7 +874,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -914,7 +902,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1002,7 +990,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -1014,7 +1002,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -1026,7 +1014,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -1042,7 +1030,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -1062,11 +1050,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -1086,7 +1074,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -1094,7 +1082,7 @@ Eu apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -1102,7 +1090,7 @@ O meu Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -1110,7 +1098,7 @@ Sobre o Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -1126,7 +1114,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -1142,7 +1130,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -1158,7 +1146,7 @@ Iniciar sessão apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -1170,7 +1158,7 @@ Começar apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -1278,7 +1266,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1488,10 +1476,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -1554,7 +1538,7 @@ Setor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1566,7 +1550,7 @@ País apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -1582,11 +1566,11 @@ Setores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1602,11 +1586,11 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1762,7 +1746,7 @@ OK apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -1858,7 +1842,7 @@ Por favor, insira o seu código de cupão: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -1866,7 +1850,7 @@ Não foi possível resgatar o código de cupão apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -1874,7 +1858,7 @@ Código de cupão foi resgatado apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -1882,7 +1866,7 @@ Atualizar apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -1906,7 +1890,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -1922,7 +1906,7 @@ por ano apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -1934,7 +1918,7 @@ Experimentar Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -1942,7 +1926,7 @@ Resgatar Cupão apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -1950,7 +1934,7 @@ Vista do Apresentador apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -1958,7 +1942,7 @@ Moeda Base apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -1966,7 +1950,7 @@ Língua apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -1986,11 +1970,11 @@ Localidade apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -1998,7 +1982,7 @@ Formato de números e datas apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -2006,7 +1990,7 @@ Modo Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -2018,7 +2002,7 @@ Aparência apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2026,7 +2010,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -2034,7 +2018,7 @@ Claro apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -2042,7 +2026,7 @@ Escuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -2050,7 +2034,7 @@ Iniciar sessão com impressão digital apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -2058,7 +2042,7 @@ Funcionalidades Experimentais apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -2070,7 +2054,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -2370,7 +2354,7 @@ Nome, símbolo or ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2388,10 +2372,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 @@ -2402,11 +2382,7 @@ Comissão apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2418,7 +2394,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2426,7 +2402,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -2718,7 +2694,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -3202,7 +3178,7 @@ Nº de Atividades apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -3218,7 +3194,7 @@ Mapeamento de Símbolo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -3238,43 +3214,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -3366,7 +3342,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -3458,7 +3434,7 @@ Proteção para informações sensíveis, como desempenhos absolutos e valores quantitativos apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3466,7 +3442,7 @@ Experiência sem distrações para tempos turbulentos apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3474,7 +3450,7 @@ Acesso antecipado a funcionalidades futuras apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3562,7 +3538,7 @@ Atualizar Plano apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -3570,11 +3546,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3686,7 +3662,7 @@ Pagamento único, sem renovação automática. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -3702,7 +3678,7 @@ É gratuito. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -3813,14 +3789,6 @@ 2 - - Oops! Could not get the historical exchange rate from - Oops! Não foi possível obter a taxa de câmbio histórica de - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Retirement Date Data da Reforma @@ -3854,15 +3822,15 @@ Renovar Plano apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -3926,11 +3894,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4318,7 +4286,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -4710,7 +4678,7 @@ Autenticação biométrica apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -4794,7 +4762,7 @@ Exportar dados apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -4894,7 +4862,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -5511,6 +5479,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -5798,14 +5770,6 @@ 41 - - Oops! Could not get the historical exchange rate from - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee Fee @@ -5895,7 +5859,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -5975,11 +5939,11 @@ No entries... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6171,7 +6135,7 @@ If a translation is missing, kindly support us in extending it here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6187,7 +6151,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6195,7 +6159,7 @@ Date Range libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6395,7 +6359,7 @@ Reset Filters libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6419,7 +6383,7 @@ Apply Filters libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6427,7 +6391,7 @@ Data Gathering apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6611,7 +6575,7 @@ Danger Zone apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6619,7 +6583,7 @@ Close Account apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6675,7 +6639,7 @@ Delete Profiles apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7099,7 +7063,7 @@ No auto-renewal. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7445,7 +7409,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7477,7 +7441,7 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7485,7 +7449,7 @@ Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7493,7 +7457,7 @@ Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7501,7 +7465,7 @@ Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7509,7 +7473,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7637,7 +7601,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7645,7 +7609,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7653,7 +7617,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7661,7 +7625,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7914,7 +7878,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7930,7 +7894,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7938,15 +7902,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index b576d5ac2..97457c7a0 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -338,6 +338,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + privacy-policy @@ -475,7 +479,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -499,7 +503,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -519,7 +523,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -639,7 +643,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -683,11 +687,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -715,43 +719,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -887,7 +891,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -919,11 +923,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -983,11 +987,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1033,22 +1037,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -1083,7 +1071,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1107,11 +1095,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1151,11 +1139,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1175,11 +1163,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -1241,6 +1229,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + View Data @@ -1299,7 +1291,7 @@ Piyasa Fiyatı apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1315,11 +1307,11 @@ İptal apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1347,7 +1339,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1363,7 +1355,7 @@ Kaydet apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1391,7 +1383,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -1427,7 +1419,7 @@ Filtrele... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -1435,15 +1427,15 @@ Varlık Sınıfı apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1451,11 +1443,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -1463,15 +1455,15 @@ Varlık Alt Sınıfı apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1479,7 +1471,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -1487,11 +1479,11 @@ İlk İşlem apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1507,7 +1499,7 @@ İşlem Sayısı apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -1515,7 +1507,7 @@ Tarihsel Veri apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -1527,7 +1519,7 @@ Sektör Sayısı apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -1535,7 +1527,7 @@ Ülke Sayısı apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -1543,11 +1535,11 @@ Profil Verisini Getir apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -1563,7 +1555,7 @@ Sektör apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1575,7 +1567,7 @@ Ülke apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -1591,11 +1583,11 @@ Sektörler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1611,11 +1603,11 @@ Ülkeler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1627,7 +1619,7 @@ Sembol Eşleştirme apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -1635,7 +1627,7 @@ Veri Toplayıcı Yapılandırması apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -1643,7 +1635,7 @@ Not apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1651,7 +1643,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -1667,7 +1659,7 @@ Ad, sembol ya da ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1831,11 +1823,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1863,7 +1855,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1923,7 +1915,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -2035,7 +2027,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -2047,7 +2039,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -2059,7 +2051,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -2067,7 +2059,7 @@ Ben apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -2075,7 +2067,7 @@ Ghostfolio’m apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -2083,7 +2075,7 @@ Ghostfolio Hakkında apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -2095,7 +2087,7 @@ Giriş apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -2107,7 +2099,7 @@ Haydi Başlayalım apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2291,7 +2283,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2529,10 +2521,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -2747,7 +2735,7 @@ Üyeliğinizi Yükseltin apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -2755,11 +2743,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -2863,7 +2851,7 @@ Tamam apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -3203,7 +3191,7 @@ Zen Modu apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -3335,7 +3323,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -3743,7 +3731,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -3761,33 +3749,17 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 - - Oops! Could not get the historical exchange rate from - Hay Allah! Geçmiş döviz kuru alınamadı: - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Fee Komisyon apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3859,7 +3831,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -4251,7 +4223,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -4427,15 +4399,15 @@ Aboneliği Yenile apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -4443,7 +4415,7 @@ Tek seferlik ödeme, otomatik yenileme yok. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -4459,7 +4431,7 @@ Ücretsiz. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -4899,7 +4871,7 @@ Lütfen kupon kodunuzu girin: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -4907,7 +4879,7 @@ Kupon kodu kullanılamadı apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -4915,7 +4887,7 @@ Kupon kodu kullanıldı apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -4923,7 +4895,7 @@ Yeniden Yükle apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -4959,7 +4931,7 @@ yıllık apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -4971,7 +4943,7 @@ Premium’u Deneyin apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -4979,7 +4951,7 @@ Kupon Kullan apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -4987,7 +4959,7 @@ Sunum Görünümü apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -4995,7 +4967,7 @@ Gerçek performans ve miktar değerleri gibi hassas bilgilerin saklanması için apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -5003,7 +4975,7 @@ Temel Para Birimi apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -5011,7 +4983,7 @@ Dil apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -5019,11 +4991,11 @@ Yerel Ayarlar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -5031,7 +5003,7 @@ Tarih ve Sayı Formatları apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -5039,7 +5011,7 @@ Görünüm apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -5047,7 +5019,7 @@ Otomatik apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -5055,7 +5027,7 @@ Açık apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -5063,7 +5035,7 @@ Koyu apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -5071,7 +5043,7 @@ Çalkantılı zamanlar için dikkat dağıtmayan bir deneyim apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -5079,7 +5051,7 @@ Biyometrik Kimlik Doğrulama apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -5087,7 +5059,7 @@ Parmak iziyle oturum aç apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -5095,7 +5067,7 @@ Deneysel Özellikler apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -5103,7 +5075,7 @@ Gelecek özelliklere göz atın apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -5115,7 +5087,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -5123,7 +5095,7 @@ Verileri Dışa Aktar apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -5806,14 +5778,6 @@ 49 - - Oops! Could not get the historical exchange rate from - Hay Allah! Tarihsel kur verisi elde edilemedi - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Choose or drop a file here Dosya seçin ya da sürükleyin @@ -5895,7 +5859,7 @@ Kıyaslama apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -5975,11 +5939,11 @@ Girdi yok... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6171,7 +6135,7 @@ If a translation is missing, kindly support us in extending it here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6187,7 +6151,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6195,7 +6159,7 @@ Date Range libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6395,7 +6359,7 @@ Reset Filters libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6419,7 +6383,7 @@ Apply Filters libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6427,7 +6391,7 @@ Data Gathering apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6611,7 +6575,7 @@ Danger Zone apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6619,7 +6583,7 @@ Close Account apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6675,7 +6639,7 @@ Delete Profiles apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7099,7 +7063,7 @@ No auto-renewal. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7445,7 +7409,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7477,7 +7441,7 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7485,7 +7449,7 @@ Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7493,7 +7457,7 @@ Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7501,7 +7465,7 @@ Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7509,7 +7473,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7637,7 +7601,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7645,7 +7609,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7653,7 +7617,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7661,7 +7625,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7914,7 +7878,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7930,7 +7894,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7938,15 +7902,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index ee488966d..dae661112 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -74,7 +74,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -98,7 +98,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -118,7 +118,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -238,7 +238,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -282,11 +282,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -314,43 +314,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -719,6 +719,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + register @@ -959,7 +963,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1015,7 +1019,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -1047,11 +1051,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1111,11 +1115,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1161,22 +1165,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -1211,7 +1199,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1235,11 +1223,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1305,6 +1293,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + Portfolio Snapshot @@ -1323,11 +1315,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1347,11 +1339,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -1475,7 +1467,7 @@ Фільтрувати за... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -1483,15 +1475,15 @@ Клас активу apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1499,11 +1491,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -1511,15 +1503,15 @@ Підклас активу apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1527,7 +1519,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -1535,7 +1527,7 @@ Ринкова ціна apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1551,11 +1543,11 @@ Перша активність apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1571,7 +1563,7 @@ Кількість активностей apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -1579,7 +1571,7 @@ Історичні дані apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -1591,7 +1583,7 @@ Кількість секторів apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -1599,7 +1591,7 @@ Кількість країн apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -1607,11 +1599,11 @@ Зібрати дані профілю apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -1619,7 +1611,7 @@ Видалити профілі apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -1675,7 +1667,7 @@ Сектор apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1687,7 +1679,7 @@ Країна apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -1703,11 +1695,11 @@ Сектори apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1723,11 +1715,11 @@ Країни apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1739,7 +1731,7 @@ Порівняльний показник apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -1747,7 +1739,7 @@ Зіставлення символів apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -1755,7 +1747,7 @@ Конфігурація скребка apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -1763,7 +1755,7 @@ Тест apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -1771,11 +1763,11 @@ URL apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1791,7 +1783,7 @@ Примітка apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1799,7 +1791,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -1807,11 +1799,11 @@ Скасувати apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1839,7 +1831,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1855,7 +1847,7 @@ Зберегти apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1883,7 +1875,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -1927,7 +1919,7 @@ Назва, символ або ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2031,7 +2023,7 @@ Збір даних apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -2115,7 +2107,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2315,7 +2307,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -2475,7 +2467,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -2487,7 +2479,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -2499,7 +2491,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -2507,7 +2499,7 @@ Оновити план apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -2515,11 +2507,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -2527,15 +2519,15 @@ Поновити план apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -2543,7 +2535,7 @@ Я apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -2551,7 +2543,7 @@ Мій Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -2559,7 +2551,7 @@ Про Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -2571,7 +2563,7 @@ Увійти apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -2583,7 +2575,7 @@ Почати apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2685,10 +2677,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Dividend Yield @@ -2919,7 +2907,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -3443,7 +3431,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -3475,7 +3463,7 @@ Не вдалося згенерувати ключ API apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -3483,7 +3471,7 @@ ОК apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -3499,7 +3487,7 @@ Встановіть цей ключ API у вашому self-hosted середовищі: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -3507,7 +3495,7 @@ Ключ API Ghostfolio Premium Data Provider apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -3515,7 +3503,7 @@ Ви дійсно хочете згенерувати новий ключ API? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -3523,7 +3511,7 @@ Не вдалося обміняти код купона apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -3531,7 +3519,7 @@ Код купона був обміняний apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -3539,7 +3527,7 @@ Перезавантажити apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -3547,7 +3535,7 @@ Будь ласка, введіть ваш код купона. apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -3555,7 +3543,7 @@ на рік apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -3567,7 +3555,7 @@ Спробуйте Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -3575,7 +3563,7 @@ Обміняти купон apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -3583,7 +3571,7 @@ Без автоматичного поновлення. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -3631,7 +3619,7 @@ Режим доповідача apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -3639,7 +3627,7 @@ Захист конфіденційної інформації, такої як абсолютні показники та кількісні значення apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3647,7 +3635,7 @@ Базова валюта apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -3655,7 +3643,7 @@ Мова apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -3663,7 +3651,7 @@ Якщо переклад відсутній, будь ласка, підтримайте нас у його розширенні тут. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -3671,11 +3659,11 @@ Локалізація apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -3683,7 +3671,7 @@ Формат дати та чисел apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -3691,7 +3679,7 @@ Зовнішній вигляд apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3699,7 +3687,7 @@ Автоматичний apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -3707,7 +3695,7 @@ Світлий apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -3715,7 +3703,7 @@ Темний apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3723,7 +3711,7 @@ Режим дзен apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -3735,7 +3723,7 @@ Досвід без відволікань для неспокійних часів apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3743,7 +3731,7 @@ Біометрична аутентифікація apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -3751,7 +3739,7 @@ Увійти з відбитком пальця apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -3759,7 +3747,7 @@ Експериментальні функції apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -3767,7 +3755,7 @@ Попередній перегляд майбутніх функцій apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3775,7 +3763,7 @@ Експортувати дані apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -3783,7 +3771,7 @@ Зона небезпеки apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -3791,7 +3779,7 @@ Закрити обліковий запис apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -4079,7 +4067,7 @@ Будь ласка, введіть ваш ключ API Ghostfolio: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -4423,7 +4411,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -4891,7 +4879,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -4929,47 +4917,23 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 - - Oops! Could not get the historical exchange rate from - Упс! Не вдалося отримати історичний обмінний курс від - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Fee Комісія apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html 234 - - Oops! Could not get the historical exchange rate from - Упс! Не вдалося отримати історичний обмінний курс від - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Import Activities Імпортувати активності @@ -5035,7 +4999,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -5735,7 +5699,7 @@ Разова оплата, без автоматичного поновлення. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -5743,7 +5707,7 @@ Це безкоштовно. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -6717,11 +6681,11 @@ Немає записів... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6737,7 +6701,7 @@ Діапазон дат libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6745,7 +6709,7 @@ Тег libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -6753,7 +6717,7 @@ Скинути фільтри libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6761,7 +6725,7 @@ Застосувати фільтри libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -7637,7 +7601,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7645,7 +7609,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7653,7 +7617,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7661,7 +7625,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7914,7 +7878,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7930,7 +7894,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7938,15 +7902,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 0817ab4c9..d8a7b552c 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -333,6 +333,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + privacy-policy @@ -491,7 +495,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -514,7 +518,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -533,7 +537,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -650,7 +654,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -691,11 +695,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -721,43 +725,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -867,7 +871,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -931,11 +935,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -993,11 +997,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1042,22 +1046,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -1091,7 +1079,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1114,11 +1102,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1161,6 +1149,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + Symbol @@ -1170,11 +1162,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1193,11 +1185,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -1290,7 +1282,7 @@ Market Price apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1305,11 +1297,11 @@ Cancel apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1337,7 +1329,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1352,7 +1344,7 @@ Save apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1380,7 +1372,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -1419,22 +1411,22 @@ Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 Asset Class apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1442,26 +1434,26 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 Asset Sub Class apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1469,18 +1461,18 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 First Activity apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1495,14 +1487,14 @@ Activities Count apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 Historical Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -1513,39 +1505,39 @@ Sectors Count apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 Countries Count apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 Gather Profile Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -1562,11 +1554,11 @@ 17 - - Gather Historical Market Dataa + + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 @@ -1588,7 +1580,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1599,7 +1591,7 @@ Country apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -1614,11 +1606,11 @@ Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1633,11 +1625,11 @@ Countries apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1648,28 +1640,28 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1677,7 +1669,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -1705,7 +1697,7 @@ Name, symbol or ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1850,11 +1842,11 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1881,7 +1873,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2074,7 +2066,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -2085,7 +2077,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -2096,14 +2088,14 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 Me apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -2114,21 +2106,21 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 My Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 About Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -2139,7 +2131,7 @@ Sign in apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -2150,7 +2142,7 @@ Get started apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2314,7 +2306,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2552,10 +2544,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -2736,7 +2724,7 @@ Upgrade Plan apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -2744,11 +2732,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -2831,35 +2819,35 @@ Please enter your coupon code. apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 Could not redeem coupon code apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 Coupon code has been redeemed apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 Reload apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 per year apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -2870,14 +2858,14 @@ Try Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 Redeem Coupon apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -2905,81 +2893,81 @@ Presenter View apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 Protection for sensitive information like absolute performances and quantity values apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 Base Currency apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 Language apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 Locale apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 Date and number format apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 Appearance apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 Light apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 Dark apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 Zen Mode apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -2990,35 +2978,35 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 Sign in with fingerprint apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 Experimental Features apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3029,14 +3017,14 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -3076,7 +3064,7 @@ Okay apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -3542,7 +3530,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -3949,7 +3937,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -3965,44 +3953,22 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 - - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html 234 - - Oops! Could not get the historical exchange rate from - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Import Activities @@ -4060,7 +4026,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -4417,7 +4383,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -4576,22 +4542,22 @@ Renew Plan apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 One-time payment, no auto-renewal. apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -4605,7 +4571,7 @@ It’s free. apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -5118,11 +5084,11 @@ No entries... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -5643,14 +5609,14 @@ If a translation is missing, kindly support us in extending it here. apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 Date Range libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -5664,7 +5630,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -5835,7 +5801,7 @@ Reset Filters libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -5863,7 +5829,7 @@ Apply Filters libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -5899,7 +5865,7 @@ Data Gathering apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6026,7 +5992,7 @@ Close Account apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6040,7 +6006,7 @@ Danger Zone apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6089,7 +6055,7 @@ Delete Profiles apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -6460,7 +6426,7 @@ No auto-renewal. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -6737,7 +6703,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -6800,7 +6766,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -6814,28 +6780,28 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -6919,21 +6885,21 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -6954,7 +6920,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7178,7 +7144,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7188,6 +7154,20 @@ 266 + + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 + + diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 5312c3731..6305867a3 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -339,6 +339,10 @@ libs/ui/src/lib/membership-card/membership-card.component.ts 30 + + libs/ui/src/lib/premium-indicator/premium-indicator.component.ts + 21 + privacy-policy @@ -504,7 +508,7 @@ apps/client/src/app/components/header/header.component.html - 398 + 394 apps/client/src/app/components/home-market/home-market.html @@ -528,7 +532,7 @@ apps/client/src/app/components/header/header.component.html - 291 + 287 apps/client/src/app/pages/resources/overview/resources-overview.component.html @@ -548,7 +552,7 @@ apps/client/src/app/components/header/header.component.html - 364 + 360 @@ -668,7 +672,7 @@ apps/client/src/app/components/header/header.component.html - 351 + 347 apps/client/src/app/pages/features/features-page.html @@ -712,11 +716,11 @@ apps/client/src/app/components/header/header.component.html - 303 + 299 apps/client/src/app/components/header/header.component.html - 379 + 375 apps/client/src/app/pages/resources/personal-finance-tools/product-page.html @@ -744,43 +748,43 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 77 + 85 apps/client/src/app/components/user-account-settings/user-account-settings.html - 83 + 91 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 96 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 100 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 104 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 108 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 112 apps/client/src/app/components/user-account-settings/user-account-settings.html - 108 + 116 apps/client/src/app/components/user-account-settings/user-account-settings.html - 112 + 120 apps/client/src/app/components/user-account-settings/user-account-settings.html - 117 + 125 apps/client/src/app/pages/features/features-page.html @@ -900,7 +904,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 189 + 205 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -968,11 +972,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 60 + 88 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 271 + 287 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1032,11 +1036,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 169 + 185 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 278 + 294 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1082,22 +1086,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 210 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 274 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 277 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 280 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 283 - libs/ui/src/lib/account-balances/account-balances.component.html 34 @@ -1132,7 +1120,7 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 235 + 267 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1156,11 +1144,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 257 + 289 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 60 + 64 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1206,6 +1194,10 @@ apps/client/src/app/components/admin-jobs/admin-jobs.html 37 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 85 + Symbol @@ -1216,11 +1208,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 46 + 74 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 137 + 153 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1240,11 +1232,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 77 + 105 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 147 + 163 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -1348,7 +1340,7 @@ 市场价 apps/client/src/app/components/admin-market-data/admin-market-data.html - 104 + 132 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1364,11 +1356,11 @@ 取消 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 130 + 146 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 526 + 544 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1396,7 +1388,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 400 + 334 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -1412,7 +1404,7 @@ 保存 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 533 + 551 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1440,7 +1432,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 407 + 341 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor-dialog/historical-market-data-editor-dialog.html @@ -1484,7 +1476,7 @@ 过滤... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 329 + 330 @@ -1492,15 +1484,15 @@ 资产类别 apps/client/src/app/components/admin-market-data/admin-market-data.html - 86 + 114 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 198 + 214 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 304 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1508,11 +1500,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 287 libs/ui/src/lib/assistant/assistant.html - 166 + 168 @@ -1520,15 +1512,15 @@ 资产子类别 apps/client/src/app/components/admin-market-data/admin-market-data.html - 95 + 123 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 207 + 223 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 301 + 317 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1536,7 +1528,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 370 + 303 @@ -1544,11 +1536,11 @@ 第一个活动 apps/client/src/app/components/admin-market-data/admin-market-data.html - 119 + 147 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 180 + 196 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1564,7 +1556,7 @@ 活动计数 apps/client/src/app/components/admin-market-data/admin-market-data.html - 128 + 156 @@ -1572,7 +1564,7 @@ 历史数据 apps/client/src/app/components/admin-market-data/admin-market-data.html - 137 + 165 libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html @@ -1584,7 +1576,7 @@ 行业数 apps/client/src/app/components/admin-market-data/admin-market-data.html - 146 + 174 @@ -1592,7 +1584,7 @@ 国家数 apps/client/src/app/components/admin-market-data/admin-market-data.html - 155 + 183 @@ -1600,11 +1592,11 @@ 收集个人资料数据 apps/client/src/app/components/admin-market-data/admin-market-data.html - 202 + 234 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 40 + 44 @@ -1644,7 +1636,7 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 224 + 240 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1656,7 +1648,7 @@ 国家 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 235 + 251 apps/client/src/app/components/admin-users/admin-users.html @@ -1672,11 +1664,11 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 241 + 257 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 466 + 484 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1692,11 +1684,11 @@ 国家 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 251 + 267 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 477 + 495 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -1708,7 +1700,7 @@ 基准 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 346 @@ -1716,7 +1708,7 @@ 符号映射 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 336 + 352 @@ -1724,7 +1716,7 @@ 刮削配置 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 377 @@ -1732,7 +1724,7 @@ 笔记 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 502 + 520 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1740,7 +1732,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 339 + 272 @@ -1772,7 +1764,7 @@ 名称、符号或 ISIN apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 101 + 117 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1936,11 +1928,11 @@ 网址 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 437 + 455 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 489 + 507 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1968,7 +1960,7 @@ apps/client/src/app/components/header/header.component.html - 263 + 259 apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -2184,7 +2176,7 @@ apps/client/src/app/components/header/header.component.html - 245 + 241 @@ -2196,7 +2188,7 @@ apps/client/src/app/components/header/header.component.html - 255 + 251 @@ -2208,7 +2200,7 @@ apps/client/src/app/components/header/header.component.html - 279 + 275 @@ -2216,7 +2208,7 @@ apps/client/src/app/components/header/header.component.html - 211 + 207 @@ -2228,7 +2220,7 @@ apps/client/src/app/components/header/header.component.html - 229 + 225 @@ -2236,7 +2228,7 @@ 我的 Ghostfolio apps/client/src/app/components/header/header.component.html - 270 + 266 @@ -2244,7 +2236,7 @@ 关于 Ghostfolio apps/client/src/app/components/header/header.component.html - 316 + 312 apps/client/src/app/pages/about/overview/about-overview-page.html @@ -2256,7 +2248,7 @@ 登入 apps/client/src/app/components/header/header.component.html - 412 + 408 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -2268,7 +2260,7 @@ 开始使用 apps/client/src/app/components/header/header.component.html - 422 + 418 @@ -2452,7 +2444,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 255 + 281 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2714,10 +2706,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 271 - Please set the amount of your emergency fund. @@ -2916,7 +2904,7 @@ 升级计划 apps/client/src/app/components/header/header.component.html - 185 + 187 apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html @@ -2924,11 +2912,11 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 21 + 20 apps/client/src/app/pages/pricing/pricing-page.html - 310 + 312 @@ -3020,7 +3008,7 @@ 请输入您的优惠券代码: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 208 + 201 @@ -3028,7 +3016,7 @@ 无法兑换优惠券代码 apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 172 + 165 @@ -3036,7 +3024,7 @@ 优惠券代码已兑换 apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 185 + 178 @@ -3044,7 +3032,7 @@ 重新加载 apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 186 + 179 @@ -3052,7 +3040,7 @@ 每年 apps/client/src/app/components/user-account-membership/user-account-membership.html - 39 + 32 apps/client/src/app/pages/pricing/pricing-page.html @@ -3064,7 +3052,7 @@ 尝试高级版 apps/client/src/app/components/user-account-membership/user-account-membership.html - 56 + 49 @@ -3072,7 +3060,7 @@ 兑换优惠券 apps/client/src/app/components/user-account-membership/user-account-membership.html - 70 + 63 @@ -3104,7 +3092,7 @@ 演示者视图 apps/client/src/app/components/user-account-settings/user-account-settings.html - 7 + 185 @@ -3112,7 +3100,7 @@ 保护绝对性能和数量值等敏感信息 apps/client/src/app/components/user-account-settings/user-account-settings.html - 8 + 186 @@ -3120,7 +3108,7 @@ 基础货币 apps/client/src/app/components/user-account-settings/user-account-settings.html - 27 + 9 @@ -3128,7 +3116,7 @@ 语言 apps/client/src/app/components/user-account-settings/user-account-settings.html - 48 + 56 @@ -3136,11 +3124,11 @@ 语言环境 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 396 + 414 apps/client/src/app/components/user-account-settings/user-account-settings.html - 127 + 135 @@ -3148,7 +3136,7 @@ 日期和数字格式 apps/client/src/app/components/user-account-settings/user-account-settings.html - 129 + 137 @@ -3156,7 +3144,7 @@ 外貌 apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3164,7 +3152,7 @@ 自动 apps/client/src/app/components/user-account-settings/user-account-settings.html - 166 + 174 @@ -3172,7 +3160,7 @@ 明亮 apps/client/src/app/components/user-account-settings/user-account-settings.html - 167 + 175 @@ -3180,7 +3168,7 @@ 黑暗 apps/client/src/app/components/user-account-settings/user-account-settings.html - 168 + 176 @@ -3188,7 +3176,7 @@ 极简模式 apps/client/src/app/components/user-account-settings/user-account-settings.html - 177 + 203 apps/client/src/app/pages/features/features-page.html @@ -3200,7 +3188,7 @@ 动荡时期的无干扰体验 apps/client/src/app/components/user-account-settings/user-account-settings.html - 178 + 204 @@ -3208,7 +3196,7 @@ 生物识别认证 apps/client/src/app/components/user-account-settings/user-account-settings.html - 194 + 220 @@ -3216,7 +3204,7 @@ 使用指纹登录 apps/client/src/app/components/user-account-settings/user-account-settings.html - 195 + 221 @@ -3224,7 +3212,7 @@ 实验性功能 apps/client/src/app/components/user-account-settings/user-account-settings.html - 211 + 237 @@ -3232,7 +3220,7 @@ 预览即将推出的功能 apps/client/src/app/components/user-account-settings/user-account-settings.html - 212 + 238 @@ -3244,7 +3232,7 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 228 + 254 @@ -3252,7 +3240,7 @@ 导出数据 apps/client/src/app/components/user-account-settings/user-account-settings.html - 236 + 262 @@ -3296,7 +3284,7 @@ 好的 apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 147 + 140 apps/client/src/app/core/http-response.interceptor.ts @@ -3812,7 +3800,7 @@ apps/client/src/app/pages/pricing/pricing-page.html - 346 + 342 @@ -4272,7 +4260,7 @@ libs/ui/src/lib/assistant/assistant.html - 107 + 109 @@ -4290,47 +4278,23 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 213 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 - libs/ui/src/lib/activities-table/activities-table.component.html 210 - - Oops! Could not get the historical exchange rate from - 哎呀!无法从以下来源获取历史汇率 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 318 - - Fee 费用 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 306 - - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 330 + 259 libs/ui/src/lib/activities-table/activities-table.component.html 234 - - Oops! Could not get the historical exchange rate from - 哎呀!无法获取历史汇率 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 240 - - Import Activities 导入活动 @@ -4396,7 +4360,7 @@ libs/ui/src/lib/assistant/assistant.html - 127 + 129 @@ -4796,7 +4760,7 @@ libs/ui/src/lib/assistant/assistant.html - 46 + 44 @@ -4972,15 +4936,15 @@ 更新计划 apps/client/src/app/components/header/header.component.html - 191 + 185 apps/client/src/app/components/user-account-membership/user-account-membership.html - 27 + 18 apps/client/src/app/pages/pricing/pricing-page.html - 316 + 310 @@ -4988,7 +4952,7 @@ 一次性付款,无自动续订。 apps/client/src/app/pages/pricing/pricing-page.html - 320 + 316 @@ -5004,7 +4968,7 @@ 免费。 apps/client/src/app/pages/pricing/pricing-page.html - 349 + 345 @@ -5576,11 +5540,11 @@ 没有条目... libs/ui/src/lib/assistant/assistant.html - 63 + 62 libs/ui/src/lib/assistant/assistant.html - 84 + 85 @@ -6172,7 +6136,7 @@ 如果翻译缺失,请支持我们进行扩展这里 apps/client/src/app/components/user-account-settings/user-account-settings.html - 50 + 58 @@ -6180,7 +6144,7 @@ 日期范围 libs/ui/src/lib/assistant/assistant.html - 93 + 95 @@ -6196,7 +6160,7 @@ 测试 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 455 + 473 @@ -6388,7 +6352,7 @@ 重置过滤器 libs/ui/src/lib/assistant/assistant.html - 185 + 187 @@ -6420,7 +6384,7 @@ 应用过滤器 libs/ui/src/lib/assistant/assistant.html - 195 + 197 @@ -6460,7 +6424,7 @@ 数据收集 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 523 + 541 apps/client/src/app/components/admin-overview/admin-overview.html @@ -6612,7 +6576,7 @@ Danger Zone apps/client/src/app/components/user-account-settings/user-account-settings.html - 248 + 274 @@ -6620,7 +6584,7 @@ Close Account apps/client/src/app/components/user-account-settings/user-account-settings.html - 283 + 309 @@ -6676,7 +6640,7 @@ Delete Profiles apps/client/src/app/components/admin-market-data/admin-market-data.html - 210 + 242 @@ -7100,7 +7064,7 @@ No auto-renewal. apps/client/src/app/components/user-account-membership/user-account-membership.html - 77 + 70 @@ -7446,7 +7410,7 @@ Please enter your Ghostfolio API key: apps/client/src/app/pages/api/api-page.component.ts - 40 + 41 @@ -7478,7 +7442,7 @@ Could not generate an API key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 134 + 127 @@ -7486,7 +7450,7 @@ Set this API key in your self-hosted environment: apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 149 + 142 @@ -7494,7 +7458,7 @@ Ghostfolio Premium Data Provider API Key apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 152 + 145 @@ -7502,7 +7466,7 @@ Do you really want to generate a new API key? apps/client/src/app/components/user-account-membership/user-account-membership.component.ts - 157 + 150 @@ -7510,7 +7474,7 @@ Tag libs/ui/src/lib/assistant/assistant.html - 155 + 157 @@ -7638,7 +7602,7 @@ Default Market Price apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 368 + 386 @@ -7646,7 +7610,7 @@ Mode apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 405 + 423 @@ -7654,7 +7618,7 @@ Selector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 421 + 439 @@ -7662,7 +7626,7 @@ HTTP Request Headers apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 381 + 399 @@ -7915,7 +7879,7 @@ Apply apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 138 @@ -7931,7 +7895,7 @@ Gather Recent Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 193 + 225 @@ -7939,15 +7903,31 @@ Gather All Historical Market Data apps/client/src/app/components/admin-market-data/admin-market-data.html - 198 + 230 - - Gather Historical Market Dataa - Gather Historical Market Dataa + + Gather Historical Market Data + Gather Historical Market Data apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 27 + 29 + + + + Data Gathering is off + Data Gathering is off + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + + Performance Calculation + Performance Calculation + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 31 diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index df556dad0..c8f42a0f7 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -78,8 +78,8 @@ export const DERIVED_CURRENCIES = [ export const EMERGENCY_FUND_TAG_ID = '4452656d-9fa4-4bd0-ba38-70492e31d180'; -export const GATHER_ASSET_PROFILE_PROCESS = 'GATHER_ASSET_PROFILE'; -export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = { +export const GATHER_ASSET_PROFILE_PROCESS_JOB_NAME = 'GATHER_ASSET_PROFILE'; +export const GATHER_ASSET_PROFILE_PROCESS_JOB_OPTIONS: JobOptions = { attempts: 12, backoff: { delay: ms('1 minute'), diff --git a/libs/common/src/lib/interfaces/admin-market-data.interface.ts b/libs/common/src/lib/interfaces/admin-market-data.interface.ts index b2517c73d..1a7eec117 100644 --- a/libs/common/src/lib/interfaces/admin-market-data.interface.ts +++ b/libs/common/src/lib/interfaces/admin-market-data.interface.ts @@ -14,6 +14,7 @@ export interface AdminMarketDataItem { dataSource: DataSource; date: Date; id: string; + isActive: boolean; isBenchmark?: boolean; isUsedByUsersWithSubscription?: boolean; lastMarketPrice: number; diff --git a/libs/common/src/lib/interfaces/info-item.interface.ts b/libs/common/src/lib/interfaces/info-item.interface.ts index bd3eb1f94..fe4101197 100644 --- a/libs/common/src/lib/interfaces/info-item.interface.ts +++ b/libs/common/src/lib/interfaces/info-item.interface.ts @@ -1,5 +1,3 @@ -import { SubscriptionOfferKey } from '@ghostfolio/common/types'; - import { Platform, SymbolProfile } from '@prisma/client'; import { Statistics } from './statistics.interface'; @@ -18,5 +16,5 @@ export interface InfoItem { platforms: Platform[]; statistics: Statistics; stripePublicKey?: string; - subscriptionOffers: { [offer in SubscriptionOfferKey]: SubscriptionOffer }; + subscriptionOffer?: SubscriptionOffer; } diff --git a/libs/common/src/lib/interfaces/subscription-offer.interface.ts b/libs/common/src/lib/interfaces/subscription-offer.interface.ts index 9ffe96a58..a9ebb54f4 100644 --- a/libs/common/src/lib/interfaces/subscription-offer.interface.ts +++ b/libs/common/src/lib/interfaces/subscription-offer.interface.ts @@ -4,6 +4,7 @@ export interface SubscriptionOffer { coupon?: number; couponId?: string; durationExtension?: StringValue; + isRenewal?: boolean; label?: string; price: number; priceId: string; diff --git a/libs/common/src/lib/interfaces/user-settings.interface.ts b/libs/common/src/lib/interfaces/user-settings.interface.ts index d72be7c7c..942f6e616 100644 --- a/libs/common/src/lib/interfaces/user-settings.interface.ts +++ b/libs/common/src/lib/interfaces/user-settings.interface.ts @@ -5,6 +5,7 @@ import { HoldingsViewMode, ViewMode } from '@ghostfolio/common/types'; +import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; export interface UserSettings { annualInterestRate?: number; @@ -22,6 +23,7 @@ export interface UserSettings { isRestrictedView?: boolean; language?: string; locale?: string; + performanceCalculationType?: PerformanceCalculationType; projectedTotalAmount?: number; retirementDate?: string; savingsRate?: number; diff --git a/libs/common/src/lib/interfaces/user.interface.ts b/libs/common/src/lib/interfaces/user.interface.ts index 84f48d1dc..a48317fad 100644 --- a/libs/common/src/lib/interfaces/user.interface.ts +++ b/libs/common/src/lib/interfaces/user.interface.ts @@ -1,8 +1,8 @@ -import { SubscriptionOfferKey } from '@ghostfolio/common/types'; import { SubscriptionType } from '@ghostfolio/common/types/subscription-type.type'; import { Access, Account, Tag } from '@prisma/client'; +import { SubscriptionOffer } from './subscription-offer.interface'; import { SystemMessage } from './system-message.interface'; import { UserSettings } from './user-settings.interface'; @@ -18,7 +18,7 @@ export interface User { systemMessage?: SystemMessage; subscription: { expiresAt?: Date; - offer: SubscriptionOfferKey; + offer: SubscriptionOffer; type: SubscriptionType; }; tags: (Tag & { isUsed: boolean })[]; diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 1c79720f5..592167562 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -17,15 +17,17 @@ export const permissions = { createPlatform: 'createPlatform', createTag: 'createTag', createUserAccount: 'createUserAccount', + createWatchlistItem: 'createWatchlistItem', deleteAccess: 'deleteAccess', - deleteAccount: 'deleteAcccount', - deleteAccountBalance: 'deleteAcccountBalance', + deleteAccount: 'deleteAccount', + deleteAccountBalance: 'deleteAccountBalance', deleteAuthDevice: 'deleteAuthDevice', deleteOrder: 'deleteOrder', deleteOwnUser: 'deleteOwnUser', deletePlatform: 'deletePlatform', deleteTag: 'deleteTag', deleteUser: 'deleteUser', + deleteWatchlistItem: 'deleteWatchlistItem', enableDataProviderGhostfolio: 'enableDataProviderGhostfolio', enableFearAndGreedIndex: 'enableFearAndGreedIndex', enableImport: 'enableImport', @@ -41,6 +43,7 @@ export const permissions = { readMarketDataOfOwnAssetProfile: 'readMarketDataOfOwnAssetProfile', readPlatforms: 'readPlatforms', readTags: 'readTags', + readWatchlist: 'readWatchlist', reportDataGlitch: 'reportDataGlitch', toggleReadOnlyMode: 'toggleReadOnlyMode', updateAccount: 'updateAccount', @@ -64,7 +67,9 @@ export function getPermissions(aRole: Role): string[] { permissions.createAccess, permissions.createAccount, permissions.createAccountBalance, + permissions.createWatchlistItem, permissions.deleteAccountBalance, + permissions.deleteWatchlistItem, permissions.createMarketData, permissions.createMarketDataOfOwnAssetProfile, permissions.createOrder, @@ -84,6 +89,7 @@ export function getPermissions(aRole: Role): string[] { permissions.readMarketDataOfOwnAssetProfile, permissions.readPlatforms, permissions.readTags, + permissions.readWatchlist, permissions.updateAccount, permissions.updateAuthDevice, permissions.updateMarketData, @@ -100,7 +106,8 @@ export function getPermissions(aRole: Role): string[] { permissions.accessAssistant, permissions.accessHoldingsChart, permissions.createUserAccount, - permissions.readAiPrompt + permissions.readAiPrompt, + permissions.readWatchlist ]; case 'USER': @@ -113,14 +120,17 @@ export function getPermissions(aRole: Role): string[] { permissions.createMarketDataOfOwnAssetProfile, permissions.createOrder, permissions.createOwnTag, + permissions.createWatchlistItem, permissions.deleteAccess, permissions.deleteAccount, permissions.deleteAccountBalance, permissions.deleteAuthDevice, permissions.deleteOrder, permissions.deleteOwnUser, + permissions.deleteWatchlistItem, permissions.readAiPrompt, permissions.readMarketDataOfOwnAssetProfile, + permissions.readWatchlist, permissions.updateAccount, permissions.updateAuthDevice, permissions.updateMarketDataOfOwnAssetProfile, diff --git a/libs/common/src/lib/personal-finance-tools.ts b/libs/common/src/lib/personal-finance-tools.ts index 3f15c80a2..bcbfd09ec 100644 --- a/libs/common/src/lib/personal-finance-tools.ts +++ b/libs/common/src/lib/personal-finance-tools.ts @@ -287,6 +287,14 @@ export const personalFinanceTools: Product[] = [ origin: 'British Virgin Islands', slogan: 'Easy-to-use Portfolio Tracker' }, + { + founded: 2021, + hasSelfHostingAbility: false, + key: 'finvest', + name: 'Finvest', + origin: 'United States', + slogan: 'Grow your wealth in a stress-free way' + }, { founded: 2023, hasFreePlan: true, @@ -331,8 +339,10 @@ export const personalFinanceTools: Product[] = [ { hasFreePlan: true, hasSelfHostingAbility: false, + isArchived: true, key: 'gospatz', name: 'goSPATZ', + note: 'Renamed to Money Peak', origin: 'Germany', slogan: 'Volle Kontrolle über deine Investitionen' }, @@ -495,6 +505,15 @@ export const personalFinanceTools: Product[] = [ pricingPerYear: '$100', slogan: 'Personal Finance Manager for Mac, Windows, and Linux' }, + { + hasFreePlan: true, + hasSelfHostingAbility: false, + key: 'moneypeak', + name: 'Money Peak', + note: 'Originally named as goSPATZ', + origin: 'Germany', + slogan: 'Dein smarter Finance Assistant' + }, { hasFreePlan: false, hasSelfHostingAbility: false, @@ -545,6 +564,13 @@ export const personalFinanceTools: Product[] = [ regions: ['Austria', 'Germany', 'Switzerland'], slogan: 'Dein Vermögen immer im Blick' }, + { + hasSelfHostingAbility: false, + key: 'peek', + name: 'Peek', + origin: 'Singapore', + slogan: 'Feel in control of your money without spreadsheets or shame' + }, { founded: 2023, hasFreePlan: true, @@ -780,6 +806,18 @@ export const personalFinanceTools: Product[] = [ pricingPerYear: '$360', slogan: 'The Trading Journal to Improve Your Trading Performance' }, + { + founded: 2020, + hasSelfHostingAbility: false, + hasFreePlan: true, + isArchived: true, + key: 'tresor-one', + name: 'Tresor One', + note: 'Renamed to Parqet', + origin: 'Germany', + regions: ['Austria', 'Germany', 'Switzerland'], + slogan: 'Dein Vermögen immer im Blick' + }, { hasFreePlan: true, hasSelfHostingAbility: false, diff --git a/libs/common/src/lib/types/index.ts b/libs/common/src/lib/types/index.ts index 668486a94..8ffd345db 100644 --- a/libs/common/src/lib/types/index.ts +++ b/libs/common/src/lib/types/index.ts @@ -17,6 +17,7 @@ import type { Market } from './market.type'; import type { OrderWithAccount } from './order-with-account.type'; import type { RequestWithUser } from './request-with-user.type'; import type { SubscriptionOfferKey } from './subscription-offer-key.type'; +import type { SubscriptionType } from './subscription-type.type'; import type { UserWithSettings } from './user-with-settings.type'; import type { ViewMode } from './view-mode.type'; @@ -40,6 +41,7 @@ export type { OrderWithAccount, RequestWithUser, SubscriptionOfferKey, + SubscriptionType, UserWithSettings, ViewMode }; diff --git a/libs/common/src/lib/types/performance-calculation-type.type.ts b/libs/common/src/lib/types/performance-calculation-type.type.ts new file mode 100644 index 000000000..a970636b6 --- /dev/null +++ b/libs/common/src/lib/types/performance-calculation-type.type.ts @@ -0,0 +1,6 @@ +export enum PerformanceCalculationType { + MWR = 'MWR', // Money-Weighted Rate of Return + ROAI = 'ROAI', // Return on Average Investment + ROI = 'ROI', // Return on Investment + TWR = 'TWR' // Time-Weighted Rate of Return +} diff --git a/libs/common/src/lib/types/user-with-settings.type.ts b/libs/common/src/lib/types/user-with-settings.type.ts index 5f9835176..5fb25a664 100644 --- a/libs/common/src/lib/types/user-with-settings.type.ts +++ b/libs/common/src/lib/types/user-with-settings.type.ts @@ -1,6 +1,5 @@ -import { UserSettings } from '@ghostfolio/common/interfaces'; -import { SubscriptionOfferKey } from '@ghostfolio/common/types'; -import { SubscriptionType } from '@ghostfolio/common/types/subscription-type.type'; +import { SubscriptionOffer, UserSettings } from '@ghostfolio/common/interfaces'; +import { SubscriptionType } from '@ghostfolio/common/types'; import { Access, Account, Settings, User } from '@prisma/client'; @@ -14,7 +13,7 @@ export type UserWithSettings = User & { Settings: Settings & { settings: UserSettings }; subscription?: { expiresAt?: Date; - offer: SubscriptionOfferKey; + offer: SubscriptionOffer; type: SubscriptionType; }; }; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.html b/libs/ui/src/lib/activities-table/activities-table.component.html index e5b33efd2..79a7d3417 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.html +++ b/libs/ui/src/lib/activities-table/activities-table.component.html @@ -280,7 +280,7 @@ class="d-none d-lg-table-cell px-1" mat-cell > - {{ element.SymbolProfile?.currency }} + {{ element.currency ?? element.SymbolProfile?.currency }} diff --git a/libs/ui/src/lib/assistant/assistant.html b/libs/ui/src/lib/assistant/assistant.html index 69fa4c9b2..46afba27b 100644 --- a/libs/ui/src/lib/assistant/assistant.html +++ b/libs/ui/src/lib/assistant/assistant.html @@ -15,28 +15,26 @@ [formControl]="searchFormControl" [placeholder]="placeholder" /> -

- / -
- - + @if (deviceType !== 'mobile' && !searchFormControl.value) { +
/
+ } + @if (searchFormControl.value) { + + } @else { + + }
- -
No entries...
+ @if (isLoading) { + + } @else { +
No entries...
+ }
@@ -72,16 +72,18 @@ (clicked)="onCloseAssistant()" /> - -
No entries...
+ @if (isLoading) { + + } @else { +
No entries...
+ }
diff --git a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts index 96dc6800e..ff309a47a 100644 --- a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts +++ b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.component.ts @@ -7,6 +7,7 @@ import { LineChartItem } from '@ghostfolio/common/interfaces'; import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CUSTOM_ELEMENTS_SCHEMA, @@ -35,6 +36,7 @@ import { BenchmarkDetailDialogParams } from './interfaces/interfaces'; GfDialogFooterModule, GfDialogHeaderModule, GfLineChartComponent, + GfValueComponent, MatDialogModule ], schemas: [CUSTOM_ELEMENTS_SCHEMA], @@ -45,6 +47,7 @@ import { BenchmarkDetailDialogParams } from './interfaces/interfaces'; export class GfBenchmarkDetailDialogComponent implements OnDestroy, OnInit { public assetProfile: AdminMarketDataDetails['assetProfile']; public historicalDataItems: LineChartItem[]; + public value: number; private unsubscribeSubject = new Subject(); @@ -65,9 +68,18 @@ export class GfBenchmarkDetailDialogComponent implements OnDestroy, OnInit { .subscribe(({ assetProfile, marketData }) => { this.assetProfile = assetProfile; - this.historicalDataItems = marketData.map(({ date, marketPrice }) => { - return { date: format(date, DATE_FORMAT), value: marketPrice }; - }); + this.historicalDataItems = marketData.map( + ({ date, marketPrice }, index) => { + if (marketData.length - 1 === index) { + this.value = marketPrice; + } + + return { + date: format(date, DATE_FORMAT), + value: marketPrice + }; + } + ); this.changeDetectorRef.markForCheck(); }); diff --git a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.html b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.html index 23196f162..032663355 100644 --- a/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.html +++ b/libs/ui/src/lib/benchmark/benchmark-detail-dialog/benchmark-detail-dialog.html @@ -8,6 +8,17 @@
+
+
+ +
+
+ @for (itemByMonth of marketDataByMonth | keyvalue; track itemByMonth) {
-
{{ itemByMonth.key }}
+
{{ itemByMonth.key }}
@for (dayItem of days; track dayItem; let i = $index) {
diff --git a/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts b/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts index 17b0f94dd..b4e871342 100644 --- a/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts +++ b/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts @@ -17,4 +17,6 @@ import { RouterModule } from '@angular/router'; }) export class GfPremiumIndicatorComponent { @Input() enableLink = true; + + public routerLinkPricing = ['/' + $localize`:snake-case:pricing`]; } diff --git a/libs/ui/src/lib/value/value.component.html b/libs/ui/src/lib/value/value.component.html index 0ead7497e..e252ef8a2 100644 --- a/libs/ui/src/lib/value/value.component.html +++ b/libs/ui/src/lib/value/value.component.html @@ -13,42 +13,45 @@
+
-
-
- @if (value === null) { - *****% - } @else { - {{ formattedValue }}% - } -
-
- @if (value === null) { - ***** - } @else { - {{ formattedValue }} - } -
- - {{ unit }} - -
- {{ unit }} -
+ @if (isPercent) { +
+ @if (value === null) { + *****% + } @else { + {{ formattedValue }}% + } +
+ } @else { +
+ @if (value === null) { + ***** + } @else { + {{ formattedValue }} + } +
+ } + @if (unit) { + + {{ unit }} + +
+ {{ unit }} +
+ } - + @if (isString) {
+ @if (value === undefined) { + + }
diff --git a/package-lock.json b/package-lock.json index c9e83be12..d1adff321 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.150.0", + "version": "2.155.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.150.0", + "version": "2.155.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { @@ -41,7 +41,7 @@ "@nestjs/platform-express": "10.4.15", "@nestjs/schedule": "4.1.2", "@nestjs/serve-static": "4.0.2", - "@prisma/client": "6.5.0", + "@prisma/client": "6.6.0", "@simplewebauthn/browser": "13.1.0", "@simplewebauthn/server": "13.1.1", "@stripe/stripe-js": "5.4.0", @@ -52,7 +52,7 @@ "bull": "4.16.5", "cache-manager": "5.7.6", "cache-manager-redis-yet": "5.1.4", - "chart.js": "4.4.7", + "chart.js": "4.4.9", "chartjs-adapter-date-fns": "3.0.0", "chartjs-chart-treemap": "3.1.0", "chartjs-plugin-annotation": "3.1.0", @@ -90,7 +90,7 @@ "stripe": "17.3.0", "svgmap": "2.12.2", "twitter-api-v2": "1.14.2", - "uuid": "11.0.5", + "uuid": "11.1.0", "yahoo-finance2": "2.11.3", "zone.js": "0.15.0" }, @@ -110,22 +110,22 @@ "@eslint/js": "9.24.0", "@nestjs/schematics": "10.2.3", "@nestjs/testing": "10.4.15", - "@nx/angular": "20.6.4", - "@nx/cypress": "20.6.4", - "@nx/eslint-plugin": "20.6.4", - "@nx/jest": "20.6.4", - "@nx/js": "20.6.4", - "@nx/module-federation": "20.6.4", - "@nx/nest": "20.6.4", - "@nx/node": "20.6.4", - "@nx/storybook": "20.6.4", - "@nx/web": "20.6.4", - "@nx/workspace": "20.6.4", + "@nx/angular": "20.8.0", + "@nx/cypress": "20.8.0", + "@nx/eslint-plugin": "20.8.0", + "@nx/jest": "20.8.0", + "@nx/js": "20.8.0", + "@nx/module-federation": "20.8.0", + "@nx/nest": "20.8.0", + "@nx/node": "20.8.0", + "@nx/storybook": "20.8.0", + "@nx/web": "20.8.0", + "@nx/workspace": "20.8.0", "@schematics/angular": "19.2.1", - "@storybook/addon-essentials": "8.4.7", - "@storybook/addon-interactions": "8.4.7", - "@storybook/angular": "8.4.7", - "@storybook/core-server": "8.4.7", + "@storybook/addon-essentials": "8.6.12", + "@storybook/addon-interactions": "8.6.12", + "@storybook/angular": "8.6.12", + "@storybook/core-server": "8.6.12", "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/big.js": "6.2.2", "@types/cache-manager": "4.0.6", @@ -140,7 +140,7 @@ "codelyzer": "6.0.1", "cypress": "6.2.1", "eslint": "9.24.0", - "eslint-config-prettier": "9.1.0", + "eslint-config-prettier": "10.1.1", "eslint-plugin-cypress": "4.2.0", "eslint-plugin-import": "2.31.0", "eslint-plugin-storybook": "0.12.0", @@ -148,15 +148,15 @@ "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "jest-preset-angular": "14.4.2", - "nx": "20.6.4", + "nx": "20.8.0", "prettier": "3.5.3", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "6.5.0", + "prisma": "6.6.0", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "8.3.0", "shx": "0.3.4", - "storybook": "8.4.7", + "storybook": "8.6.12", "ts-jest": "29.1.0", "ts-node": "10.9.2", "tslib": "2.8.1", @@ -3203,9 +3203,9 @@ } }, "node_modules/@emnapi/core": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.0.tgz", - "integrity": "sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.1.tgz", + "integrity": "sha512-4JFstCTaToCFrPqrGzgkF8N2NHjtsaY4uRh6brZQ5L9e4wbMieX8oDT8N7qfVFTQecHFEtkj4ve49VIZ3mKVqw==", "dev": true, "dependencies": { "@emnapi/wasi-threads": "1.0.1", @@ -3213,9 +3213,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz", - "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.1.tgz", + "integrity": "sha512-LMshMVP0ZhACNjQNYXiU1iZJ6QCcv0lUdPDPugqGvCGXt5xtRVBPdtA0qU12pEXZzpWAhWlZYptfdAFq10DOVQ==", "dev": true, "dependencies": { "tslib": "^2.4.0" @@ -5548,14 +5548,14 @@ } }, "node_modules/@module-federation/cli": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/cli/-/cli-0.11.3.tgz", - "integrity": "sha512-TQAmEoJBaNpXNZf+dY9mJkIFrwkODp7qbNu9sL6sJ+bLUhoUHoTSoOTKMqdhLTSVJKulf4k8GfYPvKoCKX/FaA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/cli/-/cli-0.11.4.tgz", + "integrity": "sha512-ARl++lw29Ne12P2WFNRpD4dwnZW0aodMDay3/tTOE9Nx4BdBVfHf5HyCZIph589STy+dIy/ih/ebHbue1glL3Q==", "dev": true, "dependencies": { "@modern-js/node-bundle-require": "2.65.1", - "@module-federation/dts-plugin": "0.11.3", - "@module-federation/sdk": "0.11.3", + "@module-federation/dts-plugin": "0.11.4", + "@module-federation/sdk": "0.11.4", "chalk": "3.0.0", "commander": "11.1.0" }, @@ -5567,15 +5567,15 @@ } }, "node_modules/@module-federation/cli/node_modules/@module-federation/dts-plugin": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.11.3.tgz", - "integrity": "sha512-C43yJySmcwGhmVqisZomlz/OETEUXE7pybfEcrpInKc5FI4o6upLYV4P65jKRS0N+I/U3y6bAsHX4gtIq7XdbA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.11.4.tgz", + "integrity": "sha512-QkHbW/ZOyqNI2Oz7ZqAAiTWc3vTejoimS3nfRy947rvX3xaFEavmgJNJLBEJntos2eAF3gw5TCEuKL08zVI7BQ==", "dev": true, "dependencies": { - "@module-federation/error-codes": "0.11.3", - "@module-federation/managers": "0.11.3", - "@module-federation/sdk": "0.11.3", - "@module-federation/third-party-dts-extractor": "0.11.3", + "@module-federation/error-codes": "0.11.4", + "@module-federation/managers": "0.11.4", + "@module-federation/sdk": "0.11.4", + "@module-federation/third-party-dts-extractor": "0.11.4", "adm-zip": "^0.5.10", "ansi-colors": "^4.1.3", "axios": "^1.8.2", @@ -5600,32 +5600,34 @@ } }, "node_modules/@module-federation/cli/node_modules/@module-federation/error-codes": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.11.3.tgz", - "integrity": "sha512-RG5cZAJUtlcJLoJiFXevdNRnBxrEye5aDHrDHY7szbO3hBK+XLqKTd0OOVHiGE5tpSy3TMy8qR9xHH4a1Q8bWg==", - "dev": true + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.11.4.tgz", + "integrity": "sha512-WugZdcNbNVTKuxuArGfnRW1R+siNgMBhad451HniyCG+SjlS0HEO9zIDuVP12l3xJsiTHgLqyutYEvunQ5O1aQ==", + "dev": true, + "license": "MIT" }, "node_modules/@module-federation/cli/node_modules/@module-federation/managers": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.11.3.tgz", - "integrity": "sha512-9mhP2gCblG5oWA3YRxlfkIZbl9VuQjCATczs+VnS+sgykNZBUhTDj9K//sIN5Zrrd60IBz9HW7xjj8760ERwFw==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.11.4.tgz", + "integrity": "sha512-BCoIKCo7QBvqBgwXjMUPlUKYIPXieHDvQhXp24oQIQk4WhEcaMw3BByTPKOje9V6GKZqkmzQwO00e3Ca2lnHxQ==", "dev": true, "dependencies": { - "@module-federation/sdk": "0.11.3", + "@module-federation/sdk": "0.11.4", "find-pkg": "2.0.0", "fs-extra": "9.1.0" } }, "node_modules/@module-federation/cli/node_modules/@module-federation/sdk": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.3.tgz", - "integrity": "sha512-XzohSaFNbLbEoiwPtYOuoDeInx7vOSYHngfcQqJ356LRzNIPdCMjmtA0WM1YhRkpBchmQ1LXg6HVXy7R7AEKsg==", - "dev": true + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.4.tgz", + "integrity": "sha512-23Poajva/+wye8+66NvEiL/dJDUahOjEgxljLvzmxQXi9x5hdrfJvBDIwLtzyewZ+vA5Nzpwz35sSzEOyPJUqg==", + "dev": true, + "license": "MIT" }, "node_modules/@module-federation/cli/node_modules/@module-federation/third-party-dts-extractor": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.11.3.tgz", - "integrity": "sha512-c/Lpo2Ve33g5gQW62tcVe8O8NmPdt7gifT4Lu+IgWZpsxdnzTZcS4ujuyu19VCTjevNPxYc2aTtfkYjNtvvbpQ==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.11.4.tgz", + "integrity": "sha512-hgqi7K1BTBAxW2NAqguwFvQfbQrEAHfb7CBwx+w9jKm77koKrS3+uHoAHD1mh34eWnkK2kVBktcbBPoxA0df3Q==", "dev": true, "dependencies": { "find-pkg": "2.0.0", @@ -5823,15 +5825,15 @@ } }, "node_modules/@module-federation/node": { - "version": "2.6.32", - "resolved": "https://registry.npmjs.org/@module-federation/node/-/node-2.6.32.tgz", - "integrity": "sha512-0tGz84UfmvDOWZJTRLo4vk9i7czd+MHz+WsvqkLRHVxGBaiOkUXlQd0Wabig2uTwBftvm3DrTnpz5uxzLkDt4g==", + "version": "2.6.33", + "resolved": "https://registry.npmjs.org/@module-federation/node/-/node-2.6.33.tgz", + "integrity": "sha512-wuoh3bQ95aBzEXkRHOvuDd1kd5RPAck84SUYRnN+xsJAYe3syGtY2zUx6/XPYhEjCvBDVNVv2jznn4qILSerNQ==", "dev": true, "dependencies": { - "@module-federation/enhanced": "0.11.3", - "@module-federation/runtime": "0.11.3", - "@module-federation/sdk": "0.11.3", - "@module-federation/utilities": "3.1.50", + "@module-federation/enhanced": "0.11.4", + "@module-federation/runtime": "0.11.4", + "@module-federation/sdk": "0.11.4", + "@module-federation/utilities": "3.1.51", "btoa": "1.2.1", "encoding": "^0.1.13", "node-fetch": "2.7.0" @@ -5854,24 +5856,24 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/bridge-react-webpack-plugin": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.11.3.tgz", - "integrity": "sha512-uaIWbKqs98vROrgG6DJE54ArxTFyVAvjg0JMDjP6s+lp7hXrjATVhnvpsVOyDBCw4ezhrLVVtuThNTpxfIiOrw==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/bridge-react-webpack-plugin/-/bridge-react-webpack-plugin-0.11.4.tgz", + "integrity": "sha512-oagMRwPuMBOJ+0fggNlwgp/5LxxKyWmXBjfJmJGlJQtADxcWp3odlGXTZuAxDO2sh0S8toDnJFNt5bqruSszwg==", "dev": true, "dependencies": { - "@module-federation/sdk": "0.11.3", + "@module-federation/sdk": "0.11.4", "@types/semver": "7.5.8", "semver": "7.6.3" } }, "node_modules/@module-federation/node/node_modules/@module-federation/data-prefetch": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-0.11.3.tgz", - "integrity": "sha512-m0Iyl2xclAhIX4mVvPaEgytBx+hwQVJQqghKcN7HJR7UF7tvjO+xoJQmNIlxAl5+QOgPyYlJrmWtNTfzQHbcsw==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/data-prefetch/-/data-prefetch-0.11.4.tgz", + "integrity": "sha512-wRUJ8E4QJBwMp/vejH5M1rR0EbuxrwQyHUHW0Ec5C5NQludqDbXJVf+f01fdPnJI+hVt5hL4GPltZwwuUWzdIw==", "dev": true, "dependencies": { - "@module-federation/runtime": "0.11.3", - "@module-federation/sdk": "0.11.3", + "@module-federation/runtime": "0.11.4", + "@module-federation/sdk": "0.11.4", "fs-extra": "9.1.0" }, "peerDependencies": { @@ -5880,15 +5882,15 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/dts-plugin": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.11.3.tgz", - "integrity": "sha512-C43yJySmcwGhmVqisZomlz/OETEUXE7pybfEcrpInKc5FI4o6upLYV4P65jKRS0N+I/U3y6bAsHX4gtIq7XdbA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/dts-plugin/-/dts-plugin-0.11.4.tgz", + "integrity": "sha512-QkHbW/ZOyqNI2Oz7ZqAAiTWc3vTejoimS3nfRy947rvX3xaFEavmgJNJLBEJntos2eAF3gw5TCEuKL08zVI7BQ==", "dev": true, "dependencies": { - "@module-federation/error-codes": "0.11.3", - "@module-federation/managers": "0.11.3", - "@module-federation/sdk": "0.11.3", - "@module-federation/third-party-dts-extractor": "0.11.3", + "@module-federation/error-codes": "0.11.4", + "@module-federation/managers": "0.11.4", + "@module-federation/sdk": "0.11.4", + "@module-federation/third-party-dts-extractor": "0.11.4", "adm-zip": "^0.5.10", "ansi-colors": "^4.1.3", "axios": "^1.8.2", @@ -5913,22 +5915,22 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/enhanced": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-0.11.3.tgz", - "integrity": "sha512-ySRp2tsJFXjw9wOkWPKV0Jmy6GPJfrWDEfEpJIDc5h75dk4Y0sPX3vrdQtZsNz/ofYJN1z3XJRLNzAZdRdYuIg==", - "dev": true, - "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "0.11.3", - "@module-federation/cli": "0.11.3", - "@module-federation/data-prefetch": "0.11.3", - "@module-federation/dts-plugin": "0.11.3", - "@module-federation/error-codes": "0.11.3", - "@module-federation/inject-external-runtime-core-plugin": "0.11.3", - "@module-federation/managers": "0.11.3", - "@module-federation/manifest": "0.11.3", - "@module-federation/rspack": "0.11.3", - "@module-federation/runtime-tools": "0.11.3", - "@module-federation/sdk": "0.11.3", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/enhanced/-/enhanced-0.11.4.tgz", + "integrity": "sha512-WFmJsTMUSdXxNEBPhvVJRszFecHPnTbNg/LhwT1i631v7AqzLE8R/lE/CsAoMaxuuPtQqEmZgU9wwjRLW80DfA==", + "dev": true, + "dependencies": { + "@module-federation/bridge-react-webpack-plugin": "0.11.4", + "@module-federation/cli": "0.11.4", + "@module-federation/data-prefetch": "0.11.4", + "@module-federation/dts-plugin": "0.11.4", + "@module-federation/error-codes": "0.11.4", + "@module-federation/inject-external-runtime-core-plugin": "0.11.4", + "@module-federation/managers": "0.11.4", + "@module-federation/manifest": "0.11.4", + "@module-federation/rspack": "0.11.4", + "@module-federation/runtime-tools": "0.11.4", + "@module-federation/sdk": "0.11.4", "btoa": "^1.2.1", "upath": "2.0.1" }, @@ -5953,57 +5955,58 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/error-codes": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.11.3.tgz", - "integrity": "sha512-RG5cZAJUtlcJLoJiFXevdNRnBxrEye5aDHrDHY7szbO3hBK+XLqKTd0OOVHiGE5tpSy3TMy8qR9xHH4a1Q8bWg==", - "dev": true + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.11.4.tgz", + "integrity": "sha512-WugZdcNbNVTKuxuArGfnRW1R+siNgMBhad451HniyCG+SjlS0HEO9zIDuVP12l3xJsiTHgLqyutYEvunQ5O1aQ==", + "dev": true, + "license": "MIT" }, "node_modules/@module-federation/node/node_modules/@module-federation/inject-external-runtime-core-plugin": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/inject-external-runtime-core-plugin/-/inject-external-runtime-core-plugin-0.11.3.tgz", - "integrity": "sha512-l7MUjXlV6O7h8BSlMC9FlJ0bi9wFz0+PIkn6r7vaE0IuepJ7SuZDzJxtErzTz5OggPOFLygS2r7q+60dNVwh7A==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/inject-external-runtime-core-plugin/-/inject-external-runtime-core-plugin-0.11.4.tgz", + "integrity": "sha512-VHPD8NpAZ9m+EgvojX/1+CDp0eR4Jx/SbWsCVJm1qijh9BU5JSrVnRe+pVJPHHkNfkN70mzqWRexr4oC7qMC4Q==", "dev": true, "peerDependencies": { - "@module-federation/runtime-tools": "0.11.3" + "@module-federation/runtime-tools": "0.11.4" } }, "node_modules/@module-federation/node/node_modules/@module-federation/managers": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.11.3.tgz", - "integrity": "sha512-9mhP2gCblG5oWA3YRxlfkIZbl9VuQjCATczs+VnS+sgykNZBUhTDj9K//sIN5Zrrd60IBz9HW7xjj8760ERwFw==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/managers/-/managers-0.11.4.tgz", + "integrity": "sha512-BCoIKCo7QBvqBgwXjMUPlUKYIPXieHDvQhXp24oQIQk4WhEcaMw3BByTPKOje9V6GKZqkmzQwO00e3Ca2lnHxQ==", "dev": true, "dependencies": { - "@module-federation/sdk": "0.11.3", + "@module-federation/sdk": "0.11.4", "find-pkg": "2.0.0", "fs-extra": "9.1.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/manifest": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-0.11.3.tgz", - "integrity": "sha512-UHODiU4g2mogYbud9/RZk73jDPSJtP4GiRSVtZo1OUW9J4qiy16N4FNw47M2OlGsHlgOzQ3igoo2NX7AQudAjA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/manifest/-/manifest-0.11.4.tgz", + "integrity": "sha512-5dLyQNezlSfZeWtpDcKs6TnSr7JaJXcLggFAk0WhFan4WXdi+aEQtDMVCBdbdQ3hpEq3OYz9T1Ez4q6CVimZZA==", "dev": true, "dependencies": { - "@module-federation/dts-plugin": "0.11.3", - "@module-federation/managers": "0.11.3", - "@module-federation/sdk": "0.11.3", + "@module-federation/dts-plugin": "0.11.4", + "@module-federation/managers": "0.11.4", + "@module-federation/sdk": "0.11.4", "chalk": "3.0.0", "find-pkg": "2.0.0" } }, "node_modules/@module-federation/node/node_modules/@module-federation/rspack": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-0.11.3.tgz", - "integrity": "sha512-1Mhy3L4jL1z+xFCLny5PBL6Fyu6i2eJB/n7sPTqyu/vfO0cgOfxwBxxcEneq0oAJ1er+n6WWcug8IrJ5hIzkTw==", - "dev": true, - "dependencies": { - "@module-federation/bridge-react-webpack-plugin": "0.11.3", - "@module-federation/dts-plugin": "0.11.3", - "@module-federation/inject-external-runtime-core-plugin": "0.11.3", - "@module-federation/managers": "0.11.3", - "@module-federation/manifest": "0.11.3", - "@module-federation/runtime-tools": "0.11.3", - "@module-federation/sdk": "0.11.3", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/rspack/-/rspack-0.11.4.tgz", + "integrity": "sha512-NbNPvzbnlSoNf2BsRywX6jnKLCzMA7cHGqn7m9+xyCjLrUVt3+AAUhxSW4+HdiHgfm/T2e4G1By9OtwVdX0L1Q==", + "dev": true, + "dependencies": { + "@module-federation/bridge-react-webpack-plugin": "0.11.4", + "@module-federation/dts-plugin": "0.11.4", + "@module-federation/inject-external-runtime-core-plugin": "0.11.4", + "@module-federation/managers": "0.11.4", + "@module-federation/manifest": "0.11.4", + "@module-federation/runtime-tools": "0.11.4", + "@module-federation/sdk": "0.11.4", "btoa": "1.2.1" }, "peerDependencies": { @@ -6021,46 +6024,47 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.11.3.tgz", - "integrity": "sha512-lGCrWQclRVLP6ryYwdwvmphxRJi1thchO5Q4BbK4MsRxYUMlHGkPi0ygAXwedl6Kaa2ZqhbvlMrUhB+n5PnwNQ==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.11.4.tgz", + "integrity": "sha512-pUfhsa3iYoXBV3CsUfBJN04Cvckj9gBbs8+sLsYiWxxU+cJYNiJpco0iKxRX1/60O+RAH8fAaNq5ilz2qc204A==", "dev": true, "dependencies": { - "@module-federation/error-codes": "0.11.3", - "@module-federation/runtime-core": "0.11.3", - "@module-federation/sdk": "0.11.3" + "@module-federation/error-codes": "0.11.4", + "@module-federation/runtime-core": "0.11.4", + "@module-federation/sdk": "0.11.4" } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime-core": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.11.3.tgz", - "integrity": "sha512-xz9++7Z0JXpOepknl2YmIQXzG8hmvLJLRtg7XYHuA1JRXW4vBKaUvvUAqLHvxS9+6FZTb8AAjQ9+8eeAOz5RYg==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.11.4.tgz", + "integrity": "sha512-+n2fWUPj6cCeHXmChZ35RFyNONfBEcNgQ3o7KEmxOBJ6bRh1vr3AO2OPRPYr5WHcvAyjny+l/xhi+sZPNV3uOQ==", "dev": true, "dependencies": { - "@module-federation/error-codes": "0.11.3", - "@module-federation/sdk": "0.11.3" + "@module-federation/error-codes": "0.11.4", + "@module-federation/sdk": "0.11.4" } }, "node_modules/@module-federation/node/node_modules/@module-federation/runtime-tools": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.11.3.tgz", - "integrity": "sha512-mN1Ft2O4Khz8PEwNZT7ujWKjVyCKhkInHoMn2n8U8DmOShOlbSQaBR48ZvLP2NTUcbkZbMmWls4q9Ou2UampOw==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.11.4.tgz", + "integrity": "sha512-rNtaY1Eo9PJ9kn6Z9wp+OsPOA6dbJa4zyDVC1Bo+dnKkjoJ+YwGYpBw88vb0btwCtc5gJkK14ZvnYtDyPVrPWQ==", "dev": true, "dependencies": { - "@module-federation/runtime": "0.11.3", - "@module-federation/webpack-bundler-runtime": "0.11.3" + "@module-federation/runtime": "0.11.4", + "@module-federation/webpack-bundler-runtime": "0.11.4" } }, "node_modules/@module-federation/node/node_modules/@module-federation/sdk": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.3.tgz", - "integrity": "sha512-XzohSaFNbLbEoiwPtYOuoDeInx7vOSYHngfcQqJ356LRzNIPdCMjmtA0WM1YhRkpBchmQ1LXg6HVXy7R7AEKsg==", - "dev": true + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.4.tgz", + "integrity": "sha512-23Poajva/+wye8+66NvEiL/dJDUahOjEgxljLvzmxQXi9x5hdrfJvBDIwLtzyewZ+vA5Nzpwz35sSzEOyPJUqg==", + "dev": true, + "license": "MIT" }, "node_modules/@module-federation/node/node_modules/@module-federation/third-party-dts-extractor": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.11.3.tgz", - "integrity": "sha512-c/Lpo2Ve33g5gQW62tcVe8O8NmPdt7gifT4Lu+IgWZpsxdnzTZcS4ujuyu19VCTjevNPxYc2aTtfkYjNtvvbpQ==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/third-party-dts-extractor/-/third-party-dts-extractor-0.11.4.tgz", + "integrity": "sha512-hgqi7K1BTBAxW2NAqguwFvQfbQrEAHfb7CBwx+w9jKm77koKrS3+uHoAHD1mh34eWnkK2kVBktcbBPoxA0df3Q==", "dev": true, "dependencies": { "find-pkg": "2.0.0", @@ -6069,13 +6073,13 @@ } }, "node_modules/@module-federation/node/node_modules/@module-federation/webpack-bundler-runtime": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.11.3.tgz", - "integrity": "sha512-SyLDwwzvR/UxcJi3vcSevcL0/NmbiSZkaVXDOK5z/Xts+uANNzi0OSth1JKfTqT0nUUm4tTkkD6fufPWqg1NZA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.11.4.tgz", + "integrity": "sha512-lhY0RGkirPTC5AIdXjyCe4uNYtKQA7A2Oo08sa0XIAhzZUeBzVIAes1jWGS3nvPV5/SZ+ldzoMmTvlrEpgz5vQ==", "dev": true, "dependencies": { - "@module-federation/runtime": "0.11.3", - "@module-federation/sdk": "0.11.3" + "@module-federation/runtime": "0.11.4", + "@module-federation/sdk": "0.11.4" } }, "node_modules/@module-federation/node/node_modules/chalk": { @@ -6218,12 +6222,12 @@ } }, "node_modules/@module-federation/utilities": { - "version": "3.1.50", - "resolved": "https://registry.npmjs.org/@module-federation/utilities/-/utilities-3.1.50.tgz", - "integrity": "sha512-vDarbdRCryGMzt1mGfh3oXrEAEXytrZd1NfdnLDRDn5K6YR+wdfklJBIG28pFP80Kc0dDjZc+03EqR+yYToPpQ==", + "version": "3.1.51", + "resolved": "https://registry.npmjs.org/@module-federation/utilities/-/utilities-3.1.51.tgz", + "integrity": "sha512-TccjlRDiNMg/VsAoiUqvqvzKkAsFwj3mtbjnbZ+fLvlmr1BhouzYIjyBFxvSZBrXdEKkzLKDKGRABWF8D79AOg==", "dev": true, "dependencies": { - "@module-federation/sdk": "0.11.3" + "@module-federation/sdk": "0.11.4" }, "peerDependencies": { "react": "^16 || ^17 || ^18", @@ -6243,10 +6247,11 @@ } }, "node_modules/@module-federation/utilities/node_modules/@module-federation/sdk": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.3.tgz", - "integrity": "sha512-XzohSaFNbLbEoiwPtYOuoDeInx7vOSYHngfcQqJ356LRzNIPdCMjmtA0WM1YhRkpBchmQ1LXg6HVXy7R7AEKsg==", - "dev": true + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.11.4.tgz", + "integrity": "sha512-23Poajva/+wye8+66NvEiL/dJDUahOjEgxljLvzmxQXi9x5hdrfJvBDIwLtzyewZ+vA5Nzpwz35sSzEOyPJUqg==", + "dev": true, + "license": "MIT" }, "node_modules/@module-federation/webpack-bundler-runtime": { "version": "0.9.1", @@ -7473,19 +7478,19 @@ } }, "node_modules/@nx/angular": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/angular/-/angular-20.6.4.tgz", - "integrity": "sha512-DDuPDtot6gaU9wZCW3WKGHAWY3oITW2I9KlCqba8qRuWiZK67/q4Y1OVVVlJLLaNT+qjkt0cPWbmIcKImaYuxA==", - "dev": true, - "dependencies": { - "@nx/devkit": "20.6.4", - "@nx/eslint": "20.6.4", - "@nx/js": "20.6.4", - "@nx/module-federation": "20.6.4", - "@nx/rspack": "20.6.4", - "@nx/web": "20.6.4", - "@nx/webpack": "20.6.4", - "@nx/workspace": "20.6.4", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/angular/-/angular-20.8.0.tgz", + "integrity": "sha512-v69G+3v+ZdwN/d0cBNqwx+QTa0WH+2hvLL7QAfE1g3gpUjVFCzwuvPmsrMq67OC5MGhaWknNUL0jN+pCKekhIA==", + "dev": true, + "dependencies": { + "@nx/devkit": "20.8.0", + "@nx/eslint": "20.8.0", + "@nx/js": "20.8.0", + "@nx/module-federation": "20.8.0", + "@nx/rspack": "20.8.0", + "@nx/web": "20.8.0", + "@nx/webpack": "20.8.0", + "@nx/workspace": "20.8.0", "@phenomnomnominal/tsquery": "~5.0.1", "@typescript-eslint/type-utils": "^8.0.0", "enquirer": "~2.3.6", @@ -7521,20 +7526,21 @@ } }, "node_modules/@nx/cypress": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/cypress/-/cypress-20.6.4.tgz", - "integrity": "sha512-1cEI9AEYNDBLKbIM78nvfN4QXgYzo9Kyc+XdL403pUbCoFeqc7gznN3TvtdxsA0O+W2Cs9hIppga8qj6F4CEvA==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/cypress/-/cypress-20.8.0.tgz", + "integrity": "sha512-tiS9R3X//9ZVeNU9d5uV5voDmrp0Sh+B25EuZoeFtah7RNgQcnNXqc488dmCYhCK5Tl58K44eDNyyXvIwOlyCw==", "dev": true, "dependencies": { - "@nx/devkit": "20.6.4", - "@nx/eslint": "20.6.4", - "@nx/js": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/eslint": "20.8.0", + "@nx/js": "20.8.0", "@phenomnomnominal/tsquery": "~5.0.1", "detect-port": "^1.5.1", + "semver": "^7.6.3", "tslib": "^2.3.0" }, "peerDependencies": { - "cypress": ">= 3 < 14" + "cypress": ">= 3 < 15" }, "peerDependenciesMeta": { "cypress": { @@ -7543,9 +7549,9 @@ } }, "node_modules/@nx/devkit": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-20.6.4.tgz", - "integrity": "sha512-lyEidfyPhTuHt1X6EsskugBREazS5VOKSPIcreQ8Qt0MaULxn0bQ9o0N6C+BQaw5Zu6RTaMRMWKGW0I0Qni0UA==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-20.8.0.tgz", + "integrity": "sha512-0616zW0Krwb5frNZ7C0HUItonCDiAHY9UYSTyJm6hnal0Xc6XkJuEAFNjbx2sEOopO85CEAMNeYEHkRyWsSxCQ==", "dev": true, "dependencies": { "ejs": "^3.1.7", @@ -7586,13 +7592,13 @@ } }, "node_modules/@nx/eslint": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/eslint/-/eslint-20.6.4.tgz", - "integrity": "sha512-/DKHPid+QDSkvZP19qoAnjAveuu8l7WaapOhErChYVQmZetLAvS8WUwtwcHExYCYSsUWGJcMpYh9eQDOCyJYUg==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/eslint/-/eslint-20.8.0.tgz", + "integrity": "sha512-FPpw/RHgg08gkhntf/d7xh8GtNKOjTzLrwh7/YUO5UTi26lCjglM0nsFJJEQS988STElgjBEeDh78wcMuXeQ7g==", "dev": true, "dependencies": { - "@nx/devkit": "20.6.4", - "@nx/js": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/js": "20.8.0", "semver": "^7.5.3", "tslib": "^2.3.0", "typescript": "~5.7.2" @@ -7608,13 +7614,13 @@ } }, "node_modules/@nx/eslint-plugin": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/eslint-plugin/-/eslint-plugin-20.6.4.tgz", - "integrity": "sha512-05ltU1i6UDecehnleRwi3Y4ZU0QmaEAkO/etB3Ncve3oduyJUe2QAxzeInYMPC51+W798ah8tDqE9i8npUoUkw==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/eslint-plugin/-/eslint-plugin-20.8.0.tgz", + "integrity": "sha512-qcwvSI8MKdEinJ0XX01SIlVkTo2+Vi2ZvDbGccIdrej287hjaipphTvfesPnvnb7TSGZf0JG64P/yukmSFLxEw==", "dev": true, "dependencies": { - "@nx/devkit": "20.6.4", - "@nx/js": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/js": "20.8.0", "@typescript-eslint/type-utils": "^8.0.0", "@typescript-eslint/utils": "^8.0.0", "chalk": "^4.1.0", @@ -7626,7 +7632,7 @@ }, "peerDependencies": { "@typescript-eslint/parser": "^6.13.2 || ^7.0.0 || ^8.0.0", - "eslint-config-prettier": "^9.0.0" + "eslint-config-prettier": "^10.0.0" }, "peerDependenciesMeta": { "eslint-config-prettier": { @@ -7648,15 +7654,15 @@ } }, "node_modules/@nx/jest": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/jest/-/jest-20.6.4.tgz", - "integrity": "sha512-/GRvhs4DMDUd347jM55Ft1k8VnO7bvjHjQ6MakQalVk60l2GbF172c1EaAWZPgQhpMY2NlYHVr0FnjpfUjQ7jw==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/jest/-/jest-20.8.0.tgz", + "integrity": "sha512-Nrch28OhUnofnIrT+V5+uHWdNVFDHc0G9yF83dPLMipne8NJ9731xxAglL9H7lw73AMTeHaxin2I4UE0Vf1/HA==", "dev": true, "dependencies": { "@jest/reporters": "^29.4.1", "@jest/test-result": "^29.4.1", - "@nx/devkit": "20.6.4", - "@nx/js": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/js": "20.8.0", "@phenomnomnominal/tsquery": "~5.0.1", "identity-obj-proxy": "3.0.0", "jest-config": "^29.4.1", @@ -7697,9 +7703,9 @@ } }, "node_modules/@nx/js": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/js/-/js-20.6.4.tgz", - "integrity": "sha512-GHYpqLi9pjdPrMZqgYjDat+WhL9k350/+g+hQiAoueEwQ1PbG3d/NwcA2dffX47VLXF1BhoQMtn0C3LPPx3Z/g==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/js/-/js-20.8.0.tgz", + "integrity": "sha512-JqQ94l0njkoCCIeqRzFsajMoSV5WodfGGG3giipBe9+cmqsMCZJxh7DiSTGCZ2vnUo3zoX8hodumlk8r+HtMZQ==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", @@ -7709,8 +7715,8 @@ "@babel/preset-env": "^7.23.2", "@babel/preset-typescript": "^7.22.5", "@babel/runtime": "^7.22.6", - "@nx/devkit": "20.6.4", - "@nx/workspace": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/workspace": "20.8.0", "@zkochan/js-yaml": "0.0.7", "babel-plugin-const-enum": "^1.0.1", "babel-plugin-macros": "^3.1.0", @@ -7883,38 +7889,36 @@ } }, "node_modules/@nx/module-federation": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/module-federation/-/module-federation-20.6.4.tgz", - "integrity": "sha512-SaCfOny3dxA20MEHI4KskRsDa8wGvwwClTGcpWu+wZZbAPey4Cvd1TxPrXGgvCqXyGkSS0XwjIsrPBGl+EWnFQ==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/module-federation/-/module-federation-20.8.0.tgz", + "integrity": "sha512-dybk1+2svR+mV3V/d4F9ZUMHhE0q7t1Go8qHC98sRVrRX0xQMDt51s5WETJlBbN230euKfcYBkPNL+l5AdIlLg==", "dev": true, "dependencies": { "@module-federation/enhanced": "^0.9.0", "@module-federation/node": "^2.6.26", "@module-federation/sdk": "^0.9.0", - "@nx/devkit": "20.6.4", - "@nx/js": "20.6.4", - "@nx/web": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/js": "20.8.0", + "@nx/web": "20.8.0", + "@rspack/core": "^1.1.5", "express": "^4.21.2", "http-proxy-middleware": "^3.0.3", "picocolors": "^1.1.0", "tslib": "^2.3.0", "webpack": "^5.88.0" - }, - "peerDependencies": { - "@rspack/core": "^1.1.5" } }, "node_modules/@nx/nest": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nest/-/nest-20.6.4.tgz", - "integrity": "sha512-XG6p1whmUr4YaGurnEWoAH+AHaoEXQZ++ugcY/d370F4K2C3pOJbWjy6Sa8u6ll9GviRz9VdFbElVypkYpa/dA==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nest/-/nest-20.8.0.tgz", + "integrity": "sha512-24XTwHlb/Ur+AHRAabsUHgC0cjOIQrz4Ec4IArv0y66nq+8MjTTJYWMmUMHCiYojyoL+W7EshTyViBedFPOJCg==", "dev": true, "dependencies": { "@nestjs/schematics": "^9.1.0", - "@nx/devkit": "20.6.4", - "@nx/eslint": "20.6.4", - "@nx/js": "20.6.4", - "@nx/node": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/eslint": "20.8.0", + "@nx/js": "20.8.0", + "@nx/node": "20.8.0", "tslib": "^2.3.0" } }, @@ -8108,22 +8112,22 @@ } }, "node_modules/@nx/node": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/node/-/node-20.6.4.tgz", - "integrity": "sha512-rD/86V+HOh4SmGq5ONCSXRdZspGP5imCPATZeQFnbuvL3fM643X0NDkbQboZM6n6AvkOz1lfs1cyfRkuVhi25Q==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/node/-/node-20.8.0.tgz", + "integrity": "sha512-lvywGoWAx2yV7Y4QHzl1petGumUrGvpk9pZYW+xaXPi3Arv5thMeycZCC2Oj28kws5Kf9wbaq90jyu4JSI3xgA==", "dev": true, "dependencies": { - "@nx/devkit": "20.6.4", - "@nx/eslint": "20.6.4", - "@nx/jest": "20.6.4", - "@nx/js": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/eslint": "20.8.0", + "@nx/jest": "20.8.0", + "@nx/js": "20.8.0", "tslib": "^2.3.0" } }, "node_modules/@nx/nx-darwin-arm64": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-20.6.4.tgz", - "integrity": "sha512-urdLFCY0c2X11FBuokSgCktKTma7kjZKWJi8mVO8PbTJh0h2Qtp4l9/px8tv9EHeHuusA18p2Wq3ZM6c95qcBg==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-20.8.0.tgz", + "integrity": "sha512-A6Te2KlINtcOo/depXJzPyjbk9E0cmgbom/sm/49XdQ8G94aDfyIIY1RIdwmDCK5NVd74KFG3JIByTk5+VnAhA==", "cpu": [ "arm64" ], @@ -8137,9 +8141,9 @@ } }, "node_modules/@nx/nx-darwin-x64": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-20.6.4.tgz", - "integrity": "sha512-nNOXc9ccdsdmylC/InRud/F977ldat2zQuSWfhoI5+9exHIjMo0TNU8gZdT53t3S1OTQKOEbNXZcoEaURb6STA==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-20.8.0.tgz", + "integrity": "sha512-UpqayUjgalArXaDvOoshqSelTrEp42cGDsZGy0sqpxwBpm3oPQ8wE1d7oBAmRo208rAxOuFP0LZRFUqRrwGvLA==", "cpu": [ "x64" ], @@ -8153,9 +8157,9 @@ } }, "node_modules/@nx/nx-freebsd-x64": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-20.6.4.tgz", - "integrity": "sha512-jPGzjdB9biMu8N4038qBe0VBfrQ+HDjXfxBhETqrVIJPBfgdxN1I8CXIhCqMPG2CHBAM6kDQCU6QCTMWADJcEw==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-20.8.0.tgz", + "integrity": "sha512-dUR2fsLyKZYMHByvjy2zvmdMbsdXAiP+6uTlIAuu8eHMZ2FPQCAtt7lPYLwOFUxUXChbek2AJ+uCI0gRAgK/eg==", "cpu": [ "x64" ], @@ -8169,9 +8173,9 @@ } }, "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-20.6.4.tgz", - "integrity": "sha512-j4ekxzZPc5lj+VbaLBpKJl6w2VyFXycLrT65CWQYAj9yqV5dUuDtTR33r50ddLtqQt3PVV5hJAj8+g7sGPXUWQ==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-20.8.0.tgz", + "integrity": "sha512-GuZ7t0SzSX5ksLYva7koKZovQ5h/Kr1pFbOsQcBf3VLREBqFPSz6t7CVYpsIsMhiu/I3EKq6FZI3wDOJbee5uw==", "cpu": [ "arm" ], @@ -8185,9 +8189,9 @@ } }, "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-20.6.4.tgz", - "integrity": "sha512-nYMB4Sh5yI7WbunizZ/mgR21MQgrs77frnAChs+6aPF5HA7N1VGEn3FMKX+ypd3DjTl14zuwB/R5ilwNgKzL+A==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-20.8.0.tgz", + "integrity": "sha512-CiI955Q+XZmBBZ7cQqQg0MhGEFwZIgSpJnjPfWBt3iOYP8aE6nZpNOkmD7O8XcN/nEwwyeCOF8euXqEStwsk8w==", "cpu": [ "arm64" ], @@ -8201,9 +8205,9 @@ } }, "node_modules/@nx/nx-linux-arm64-musl": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-20.6.4.tgz", - "integrity": "sha512-ukjB1pmBvtinT0zeYJ1lWi7BAw6cDnPQnfXMbyV+afYnNRcgdDFzQaUpo3UUeai69Fo3TTr0SWx6DjMVifxJZw==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-20.8.0.tgz", + "integrity": "sha512-Iy9DpvVisxsfNh4gOinmMQ4cLWdBlgvt1wmry1UwvcXg479p1oJQ1Kp1wksUZoWYqrAG8VPZUmkE0f7gjyHTGg==", "cpu": [ "arm64" ], @@ -8217,9 +8221,9 @@ } }, "node_modules/@nx/nx-linux-x64-gnu": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-20.6.4.tgz", - "integrity": "sha512-+6DloqqB8ZzuZOY4A1PryuPD5hGoxbSafRN++sXUFvKx6mRYNyLGrn5APT3Kiq1qPBxkAxcsreexcu/wsTcrcw==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-20.8.0.tgz", + "integrity": "sha512-kZrrXXzVSbqwmdTmQ9xL4Jhi0/FSLrePSxYCL9oOM3Rsj0lmo/aC9kz4NBv1ZzuqT7fumpBOnhqiL1QyhOWOeQ==", "cpu": [ "x64" ], @@ -8233,9 +8237,9 @@ } }, "node_modules/@nx/nx-linux-x64-musl": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-20.6.4.tgz", - "integrity": "sha512-+ZuF6dobfGo5EN55syuUEdbYs9qxbLmTkGPMq66X7dZ/jm7kKTsVzDYnf9v3ynQCOq4DMFtdACneL32Ks22+NQ==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-20.8.0.tgz", + "integrity": "sha512-0l9jEMN8NhULKYCFiDF7QVpMMNG40duya+OF8dH0OzFj52N0zTsvsgLY72TIhslCB/cC74oAzsmWEIiFslscnA==", "cpu": [ "x64" ], @@ -8249,9 +8253,9 @@ } }, "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-20.6.4.tgz", - "integrity": "sha512-z+Y8iwEPZ8L8SISh/tcyqEtAy9Ju6aB5kLe8E/E1Wwzy5DU/jNvqM9Wq4HRPMY0r1S4jzwC6x7W3/fkxeFjZ7A==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-20.8.0.tgz", + "integrity": "sha512-5miZJmRSwx1jybBsiB3NGocXL9TxGdT2D+dOqR2fsLklpGz0ItEWm8+i8lhDjgOdAr2nFcuQUfQMY57f9FOHrA==", "cpu": [ "arm64" ], @@ -8265,9 +8269,9 @@ } }, "node_modules/@nx/nx-win32-x64-msvc": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-20.6.4.tgz", - "integrity": "sha512-9LMVHZQqc1m2Fulvfz1nPZFHUKvFjmU7igxoWJXj/m+q+DyYWEbE710ARK9JtMibLg+xSRfERKOcIy11k6Ro1A==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-20.8.0.tgz", + "integrity": "sha512-0P5r+bDuSNvoWys+6C1/KqGpYlqwSHpigCcyRzR62iZpT3OooZv+nWO06RlURkxMR8LNvYXTSSLvoLkjxqM8uQ==", "cpu": [ "x64" ], @@ -8281,15 +8285,15 @@ } }, "node_modules/@nx/rspack": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/rspack/-/rspack-20.6.4.tgz", - "integrity": "sha512-c1weD9bDtflf47pp9B+7RNIkHoJnc0oA4epK4SLNZjNzmu40O4hE9kWEVazFSId7UqczO0QWvqhvgbzSxZDtcg==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/rspack/-/rspack-20.8.0.tgz", + "integrity": "sha512-lxascsF4XygCICchwcGWP1RQkKxEZAPqiLGLYJMxTj6ewXv9RsjJMIJftd3PO4UVhRU+BhvDZD5W9OX+NX23jQ==", "dev": true, "dependencies": { - "@nx/devkit": "20.6.4", - "@nx/js": "20.6.4", - "@nx/module-federation": "20.6.4", - "@nx/web": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/js": "20.8.0", + "@nx/module-federation": "20.8.0", + "@nx/web": "20.8.0", "@phenomnomnominal/tsquery": "~5.0.1", "@rspack/core": "^1.1.5", "@rspack/dev-server": "^1.0.9", @@ -8401,28 +8405,28 @@ } }, "node_modules/@nx/storybook": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/storybook/-/storybook-20.6.4.tgz", - "integrity": "sha512-YvBLMbBI8SSpHDVmrsmd3UToMxhpOFPVwo4Jzld93Vgw5FaHNUtnOvIFUHg37nvFah1KyfYdH9O8LPXT65Nfqg==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/storybook/-/storybook-20.8.0.tgz", + "integrity": "sha512-czGPlYdukeR4ThhwuUSWQI889aVJrW/bxhAY7BInBJGK56UFnBt1Galnw2um2TzQErN21eS2pRELwyyFeP6/OA==", "dev": true, "dependencies": { - "@nx/cypress": "20.6.4", - "@nx/devkit": "20.6.4", - "@nx/eslint": "20.6.4", - "@nx/js": "20.6.4", + "@nx/cypress": "20.8.0", + "@nx/devkit": "20.8.0", + "@nx/eslint": "20.8.0", + "@nx/js": "20.8.0", "@phenomnomnominal/tsquery": "~5.0.1", "semver": "^7.5.3", "tslib": "^2.3.0" } }, "node_modules/@nx/web": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/web/-/web-20.6.4.tgz", - "integrity": "sha512-YqbSAa/3ynQVUIjrFAZV23UGcX14xRKC5z/kMm3LnM6w8DQxaKquz+3IH+KMPi4xfbxujujh8h5/1qwfDJJ0Sw==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/web/-/web-20.8.0.tgz", + "integrity": "sha512-jbK3+ZrVygYHMGCbp7NO1/G+ejH6Z74PcWwEKSZDPm7io6fxieO9j+GSzucvUWrY4cfJNC+S//X4tENwVj0g2w==", "dev": true, "dependencies": { - "@nx/devkit": "20.6.4", - "@nx/js": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/js": "20.8.0", "detect-port": "^1.5.1", "http-server": "^14.1.0", "picocolors": "^1.1.0", @@ -8430,14 +8434,14 @@ } }, "node_modules/@nx/webpack": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/webpack/-/webpack-20.6.4.tgz", - "integrity": "sha512-XEcyuI1McupN9bMj8Jy21cJJJdPGKlFyzMqvFDTh5w/IIEIsy8PHZpqVwoQJME4sC+16R7EVGWq2a6Kyy4EONg==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/webpack/-/webpack-20.8.0.tgz", + "integrity": "sha512-zqboigPhlPNMzOIFECkLzkCOfpvOR1BnE7zu2Vyzok18s3dhb1UErar6MuSb6Dh5Mwfe2HELa8iD60bM8PBSQg==", "dev": true, "dependencies": { "@babel/core": "^7.23.2", - "@nx/devkit": "20.6.4", - "@nx/js": "20.6.4", + "@nx/devkit": "20.8.0", + "@nx/js": "20.8.0", "@phenomnomnominal/tsquery": "~5.0.1", "ajv": "^8.12.0", "autoprefixer": "^10.4.9", @@ -8469,12 +8473,25 @@ "ts-loader": "^9.3.1", "tsconfig-paths-webpack-plugin": "4.0.0", "tslib": "^2.3.0", - "webpack": "^5.80.0", - "webpack-dev-server": "^5.0.4", + "webpack": "5.98.0", + "webpack-dev-server": "^5.2.1", "webpack-node-externals": "^3.0.0", "webpack-subresource-integrity": "^5.1.0" } }, + "node_modules/@nx/webpack/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@nx/webpack/node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -8484,6 +8501,44 @@ "node": "*" } }, + "node_modules/@nx/webpack/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@nx/webpack/node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@nx/webpack/node_modules/copy-webpack-plugin": { "version": "10.2.4", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz", @@ -8543,6 +8598,62 @@ } } }, + "node_modules/@nx/webpack/node_modules/globby": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", + "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^3.0.1", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.7", + "ignore": "^5.1.9", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nx/webpack/node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/@nx/webpack/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/@nx/webpack/node_modules/less": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", @@ -8650,7 +8761,21 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@nx/webpack/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, "node_modules/@nx/webpack/node_modules/pify": { "version": "4.0.1", @@ -8684,6 +8809,32 @@ "webpack": "^5.0.0" } }, + "node_modules/@nx/webpack/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/@nx/webpack/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@nx/webpack/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8694,17 +8845,76 @@ "node": ">=0.10.0" } }, + "node_modules/@nx/webpack/node_modules/webpack-dev-server": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.1.tgz", + "integrity": "sha512-ml/0HIj9NLpVKOMq+SuBPLHcmbG+TGIjXRHsYfZwocUBIqEvws8NnS/V9AFQ5FKP+tgn5adwVwRrTEpGL33QFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.7", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, "node_modules/@nx/workspace": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-20.6.4.tgz", - "integrity": "sha512-HZK0XTJ1flx9NpAFW8ZVeMRrsAEOc4Bj5ZtBR1aVUSC/IzAGQH4dkVZMXX1oG3vBzhuz+4Ery2mfst1YsJNuxQ==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-20.8.0.tgz", + "integrity": "sha512-FdaHA5ISHSN+RyHswAAx+2A9HC77kWeFgeucdX2NSBs2QK2Lzg2Et639RzR1sYk2gYTP6tOkQXHHGKcg3jmiYQ==", "dev": true, + "license": "MIT", "dependencies": { - "@nx/devkit": "20.6.4", + "@nx/devkit": "20.8.0", "@zkochan/js-yaml": "0.0.7", "chalk": "^4.1.0", "enquirer": "~2.3.6", - "nx": "20.6.4", + "nx": "20.8.0", "picomatch": "4.0.2", "tslib": "^2.3.0", "yargs-parser": "21.1.1" @@ -9144,9 +9354,9 @@ "license": "MIT" }, "node_modules/@prisma/client": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.5.0.tgz", - "integrity": "sha512-M6w1Ql/BeiGoZmhMdAZUXHu5sz5HubyVcKukbLs3l0ELcQb8hTUJxtGEChhv4SVJ0QJlwtLnwOLgIRQhpsm9dw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.6.0.tgz", + "integrity": "sha512-vfp73YT/BHsWWOAuthKQ/1lBgESSqYqAWZEYyTdGXyFAHpmewwWL2Iz6ErIzkj4aHbuc6/cGSsE6ZY+pBO04Cg==", "hasInstallScript": true, "license": "Apache-2.0", "engines": { @@ -9166,9 +9376,9 @@ } }, "node_modules/@prisma/config": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.5.0.tgz", - "integrity": "sha512-sOH/2Go9Zer67DNFLZk6pYOHj+rumSb0VILgltkoxOjYnlLqUpHPAN826vnx8HigqnOCxj9LRhT6U7uLiIIWgw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.6.0.tgz", + "integrity": "sha512-d8FlXRHsx72RbN8nA2QCRORNv5AcUnPXgtPvwhXmYkQSMF/j9cKaJg+9VcUzBRXGy9QBckNzEQDEJZdEOZ+ubA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { @@ -9177,53 +9387,53 @@ } }, "node_modules/@prisma/debug": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.5.0.tgz", - "integrity": "sha512-fc/nusYBlJMzDmDepdUtH9aBsJrda2JNErP9AzuHbgUEQY0/9zQYZdNlXmKoIWENtio+qarPNe/+DQtrX5kMcQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.6.0.tgz", + "integrity": "sha512-DL6n4IKlW5k2LEXzpN60SQ1kP/F6fqaCgU/McgaYsxSf43GZ8lwtmXLke9efS+L1uGmrhtBUP4npV/QKF8s2ZQ==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.5.0.tgz", - "integrity": "sha512-FVPQYHgOllJklN9DUyujXvh3hFJCY0NX86sDmBErLvoZjy2OXGiZ5FNf3J/C4/RZZmCypZBYpBKEhx7b7rEsdw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.6.0.tgz", + "integrity": "sha512-nC0IV4NHh7500cozD1fBoTwTD1ydJERndreIjpZr/S3mno3P6tm8qnXmIND5SwUkibNeSJMpgl4gAnlqJ/gVlg==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.5.0", - "@prisma/engines-version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60", - "@prisma/fetch-engine": "6.5.0", - "@prisma/get-platform": "6.5.0" + "@prisma/debug": "6.6.0", + "@prisma/engines-version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a", + "@prisma/fetch-engine": "6.6.0", + "@prisma/get-platform": "6.6.0" } }, "node_modules/@prisma/engines-version": { - "version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60.tgz", - "integrity": "sha512-iK3EmiVGFDCmXjSpdsKGNqy9hOdLnvYBrJB61far/oP03hlIxrb04OWmDjNTwtmZ3UZdA5MCvI+f+3k2jPTflQ==", + "version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a.tgz", + "integrity": "sha512-JzRaQ5Em1fuEcbR3nUsMNYaIYrOT1iMheenjCvzZblJcjv/3JIuxXN7RCNT5i6lRkLodW5ojCGhR7n5yvnNKrw==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.5.0.tgz", - "integrity": "sha512-3LhYA+FXP6pqY8FLHCjewyE8pGXXJ7BxZw2rhPq+CZAhvflVzq4K8Qly3OrmOkn6wGlz79nyLQdknyCG2HBTuA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.6.0.tgz", + "integrity": "sha512-Ohfo8gKp05LFLZaBlPUApM0M7k43a0jmo86YY35u1/4t+vuQH9mRGU7jGwVzGFY3v+9edeb/cowb1oG4buM1yw==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.5.0", - "@prisma/engines-version": "6.5.0-73.173f8d54f8d52e692c7e27e72a88314ec7aeff60", - "@prisma/get-platform": "6.5.0" + "@prisma/debug": "6.6.0", + "@prisma/engines-version": "6.6.0-53.f676762280b54cd07c770017ed3711ddde35f37a", + "@prisma/get-platform": "6.6.0" } }, "node_modules/@prisma/get-platform": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.5.0.tgz", - "integrity": "sha512-xYcvyJwNMg2eDptBYFqFLUCfgi+wZLcj6HDMsj0Qw0irvauG4IKmkbywnqwok0B+k+W+p+jThM2DKTSmoPCkzw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.6.0.tgz", + "integrity": "sha512-3qCwmnT4Jh5WCGUrkWcc6VZaw0JY7eWN175/pcb5Z6FiLZZ3ygY93UX0WuV41bG51a6JN/oBH0uywJ90Y+V5eA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.5.0" + "@prisma/debug": "6.6.0" } }, "node_modules/@redis/bloom": { @@ -9764,20 +9974,20 @@ } }, "node_modules/@rspack/dev-server": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rspack/dev-server/-/dev-server-1.1.0.tgz", - "integrity": "sha512-/IMfxE5SWhZ0+6xrlJzsJwJV7a0FpsY51gDBmsjGTCCa+V8ucXNxS2233V4YG/ESAM4URJEKaHzNLAGtwCSW1g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@rspack/dev-server/-/dev-server-1.1.1.tgz", + "integrity": "sha512-9r7vOml2SrFA8cvbcJdSan9wHEo1TPXezF22+s5jvdyAAywg8w7HqDol6TPVv64NUonP1DOdyLxZ+6UW6WZiwg==", "dev": true, "license": "MIT", "dependencies": { "chokidar": "^3.6.0", - "express": "^4.19.2", - "http-proxy-middleware": "^2.0.6", + "express": "^4.21.2", + "http-proxy-middleware": "^2.0.7", "mime-types": "^2.1.35", "p-retry": "^6.2.0", "webpack-dev-middleware": "^7.4.2", "webpack-dev-server": "5.2.0", - "ws": "^8.16.0" + "ws": "^8.18.0" }, "engines": { "node": ">= 18.12.0" @@ -9825,9 +10035,9 @@ } }, "node_modules/@rspack/dev-server/node_modules/http-proxy-middleware": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", - "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", "dev": true, "license": "MIT", "dependencies": { @@ -9886,20 +10096,21 @@ } }, "node_modules/@rspack/plugin-react-refresh": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.0.1.tgz", - "integrity": "sha512-KSBc3bsr3mrAPViv7w9MpE9KEWm6q87EyRXyHlRfJ9PpQ56NbX9KZ7AXo7jPeECb0q5sfpM2PSEf+syBiMgLSw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.2.0.tgz", + "integrity": "sha512-DTsbtggCfsiXE5QQtYMS8rKfEF8GIjwPDbgIT6Kg8BlAjpJY4jT5IisyhfIi7YOT3d5RIvu60iFB6Kr9sSMsnA==", "dev": true, "license": "MIT", "dependencies": { "error-stack-parser": "^2.1.4", - "html-entities": "^2.5.2" + "html-entities": "^2.6.0" }, "peerDependencies": { - "react-refresh": ">=0.10.0 <1.0.0" + "react-refresh": ">=0.10.0 <1.0.0", + "webpack-hot-middleware": "2.x" }, "peerDependenciesMeta": { - "react-refresh": { + "webpack-hot-middleware": { "optional": true } } @@ -10108,9 +10319,9 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.4.7.tgz", - "integrity": "sha512-mjtD5JxcPuW74T6h7nqMxWTvDneFtokg88p6kQ5OnC1M259iAXb//yiSZgu/quunMHPCXSiqn4FNOSgASTSbsA==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.12.tgz", + "integrity": "sha512-B5kfiRvi35oJ0NIo53CGH66H471A3XTzrfaa6SxXEJsgxxSeKScG5YeXcCvLiZfvANRQ7QDsmzPUgg0o3hdMXw==", "dev": true, "license": "MIT", "dependencies": { @@ -10125,7 +10336,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-actions/node_modules/uuid": { @@ -10143,9 +10354,9 @@ } }, "node_modules/@storybook/addon-backgrounds": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.4.7.tgz", - "integrity": "sha512-I4/aErqtFiazcoWyKafOAm3bLpxTj6eQuH/woSbk1Yx+EzN+Dbrgx1Updy8//bsNtKkcrXETITreqHC+a57DHQ==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.12.tgz", + "integrity": "sha512-lmIAma9BiiCTbJ8YfdZkXjpnAIrOUcgboLkt1f6XJ78vNEMnLNzD9gnh7Tssz1qrqvm34v9daDjIb+ggdiKp3Q==", "dev": true, "license": "MIT", "dependencies": { @@ -10158,13 +10369,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-controls": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.4.7.tgz", - "integrity": "sha512-377uo5IsJgXLnQLJixa47+11V+7Wn9KcDEw+96aGCBCfLbWNH8S08tJHHnSu+jXg9zoqCAC23MetntVp6LetHA==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.12.tgz", + "integrity": "sha512-9VSRPJWQVb9wLp21uvpxDGNctYptyUX0gbvxIWOHMH3R2DslSoq41lsC/oQ4l4zSHVdL+nq8sCTkhBxIsjKqdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10177,22 +10388,22 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-docs": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.4.7.tgz", - "integrity": "sha512-NwWaiTDT5puCBSUOVuf6ME7Zsbwz7Y79WF5tMZBx/sLQ60vpmJVQsap6NSjvK1Ravhc21EsIXqemAcBjAWu80w==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.12.tgz", + "integrity": "sha512-kEezQjAf/p3SpDzLABgg4fbT48B6dkT2LiZCKTRmCrJVtuReaAr4R9MMM6Jsph6XjbIj/SvOWf3CMeOPXOs9sg==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.4.7", - "@storybook/csf-plugin": "8.4.7", - "@storybook/react-dom-shim": "8.4.7", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "@storybook/blocks": "8.6.12", + "@storybook/csf-plugin": "8.6.12", + "@storybook/react-dom-shim": "8.6.12", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" }, "funding": { @@ -10200,25 +10411,25 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-essentials": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.4.7.tgz", - "integrity": "sha512-+BtZHCBrYtQKILtejKxh0CDRGIgTl9PumfBOKRaihYb4FX1IjSAxoV/oo/IfEjlkF5f87vouShWsRa8EUauFDw==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.12.tgz", + "integrity": "sha512-Y/7e8KFlttaNfv7q2zoHMPdX6hPXHdsuQMAjYl5NG9HOAJREu4XBy4KZpbcozRe4ApZ78rYsN/MO1EuA+bNMIA==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/addon-actions": "8.4.7", - "@storybook/addon-backgrounds": "8.4.7", - "@storybook/addon-controls": "8.4.7", - "@storybook/addon-docs": "8.4.7", - "@storybook/addon-highlight": "8.4.7", - "@storybook/addon-measure": "8.4.7", - "@storybook/addon-outline": "8.4.7", - "@storybook/addon-toolbars": "8.4.7", - "@storybook/addon-viewport": "8.4.7", + "@storybook/addon-actions": "8.6.12", + "@storybook/addon-backgrounds": "8.6.12", + "@storybook/addon-controls": "8.6.12", + "@storybook/addon-docs": "8.6.12", + "@storybook/addon-highlight": "8.6.12", + "@storybook/addon-measure": "8.6.12", + "@storybook/addon-outline": "8.6.12", + "@storybook/addon-toolbars": "8.6.12", + "@storybook/addon-viewport": "8.6.12", "ts-dedent": "^2.0.0" }, "funding": { @@ -10226,13 +10437,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-highlight": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.4.7.tgz", - "integrity": "sha512-whQIDBd3PfVwcUCrRXvCUHWClXe9mQ7XkTPCdPo4B/tZ6Z9c6zD8JUHT76ddyHivixFLowMnA8PxMU6kCMAiNw==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.12.tgz", + "integrity": "sha512-9FITVxdoycZ+eXuAZL9ElWyML/0fPPn9UgnnAkrU7zkMi+Segq/Tx7y+WWanC5zfWZrXAuG6WTOYEXeWQdm//w==", "dev": true, "license": "MIT", "dependencies": { @@ -10243,19 +10454,19 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-interactions": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.4.7.tgz", - "integrity": "sha512-fnufT3ym8ht3HHUIRVXAH47iOJW/QOb0VSM+j269gDuvyDcY03D1civCu1v+eZLGaXPKJ8vtjr0L8zKQ/4P0JQ==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.12.tgz", + "integrity": "sha512-cTAJlTq6uVZBEbtwdXkXoPQ4jHOAGKQnYSezBT4pfNkdjn/FnEeaQhMBDzf14h2wr5OgBnJa6Lmd8LD9ficz4A==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.4.7", - "@storybook/test": "8.4.7", + "@storybook/instrumenter": "8.6.12", + "@storybook/test": "8.6.12", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -10264,13 +10475,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-measure": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.4.7.tgz", - "integrity": "sha512-QfvqYWDSI5F68mKvafEmZic3SMiK7zZM8VA0kTXx55hF/+vx61Mm0HccApUT96xCXIgmwQwDvn9gS4TkX81Dmw==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.12.tgz", + "integrity": "sha512-tACmwqqOvutaQSduw8SMb62wICaT1rWaHtMN3vtWXuxgDPSdJQxLP+wdVyRYMAgpxhLyIO7YRf++Hfha9RHgFg==", "dev": true, "license": "MIT", "dependencies": { @@ -10282,13 +10493,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-outline": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.4.7.tgz", - "integrity": "sha512-6LYRqUZxSodmAIl8icr585Oi8pmzbZ90aloZJIpve+dBAzo7ydYrSQxxoQEVltXbKf3VeVcrs64ouAYqjisMYA==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.12.tgz", + "integrity": "sha512-1ylwm+n1s40S91No0v9T4tCjZORu3GbnjINlyjYTDLLhQHyBQd3nWR1Y1eewU4xH4cW9SnSLcMQFS/82xHqU6A==", "dev": true, "license": "MIT", "dependencies": { @@ -10300,13 +10511,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-toolbars": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.4.7.tgz", - "integrity": "sha512-OSfdv5UZs+NdGB+nZmbafGUWimiweJ/56gShlw8Neo/4jOJl1R3rnRqqY7MYx8E4GwoX+i3GF5C3iWFNQqlDcw==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.12.tgz", + "integrity": "sha512-HEcSzo1DyFtIu5/ikVOmh5h85C1IvK9iFKSzBR6ice33zBOaehVJK+Z5f487MOXxPsZ63uvWUytwPyViGInj+g==", "dev": true, "license": "MIT", "funding": { @@ -10314,13 +10525,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/addon-viewport": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.4.7.tgz", - "integrity": "sha512-hvczh/jjuXXcOogih09a663sRDDSATXwbE866al1DXgbDFraYD/LxX/QDb38W9hdjU9+Qhx8VFIcNWoMQns5HQ==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.12.tgz", + "integrity": "sha512-EXK2LArAnABsPP0leJKy78L/lbMWow+EIJfytEP5fHaW4EhMR6h7Hzaqzre6U0IMMr/jVFa1ci+m0PJ0eQc2bw==", "dev": true, "license": "MIT", "dependencies": { @@ -10331,24 +10542,23 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/angular": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/angular/-/angular-8.4.7.tgz", - "integrity": "sha512-PYWWEvoe+sT8riprSQVCyGnQbifbuzT9YNYPi22YBxB8ZGVuIVwjshKjSZvC99ULQbMvJ/g2OPCcBA8hhc3aTg==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/angular/-/angular-8.6.12.tgz", + "integrity": "sha512-hYbx+CaftAWuomGQ+wXpheodM5C7dTK2m/dpJ0JiWMxhMBt5Jh0SerW7KiFvODHwctXy0KZ8ZUT1PMhqPIldwg==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/builder-webpack5": "8.4.7", - "@storybook/components": "8.4.7", - "@storybook/core-webpack": "8.4.7", + "@storybook/builder-webpack5": "8.6.12", + "@storybook/components": "8.6.12", + "@storybook/core-webpack": "8.6.12", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "8.4.7", - "@storybook/preview-api": "8.4.7", - "@storybook/theming": "8.4.7", - "@types/node": "^22.0.0", + "@storybook/manager-api": "8.6.12", + "@storybook/preview-api": "8.6.12", + "@storybook/theming": "8.6.12", "@types/react": "^18.0.37", "@types/react-dom": "^18.0.11", "@types/semver": "^7.3.4", @@ -10373,6 +10583,7 @@ "@angular-devkit/architect": ">=0.1500.0 < 0.2000.0", "@angular-devkit/build-angular": ">=15.0.0 < 20.0.0", "@angular-devkit/core": ">=15.0.0 < 20.0.0", + "@angular/animations": ">=15.0.0 < 20.0.0", "@angular/cli": ">=15.0.0 < 20.0.0", "@angular/common": ">=15.0.0 < 20.0.0", "@angular/compiler": ">=15.0.0 < 20.0.0", @@ -10382,26 +10593,22 @@ "@angular/platform-browser": ">=15.0.0 < 20.0.0", "@angular/platform-browser-dynamic": ">=15.0.0 < 20.0.0", "rxjs": "^6.0.0 || ^7.4.0", - "storybook": "^8.4.7", + "storybook": "^8.6.12", "typescript": "^4.0.0 || ^5.0.0", "zone.js": ">= 0.11.1 < 1.0.0" }, "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + }, "@angular/cli": { "optional": true + }, + "zone.js": { + "optional": true } } }, - "node_modules/@storybook/angular/node_modules/@types/node": { - "version": "22.13.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", - "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.20.0" - } - }, "node_modules/@storybook/angular/node_modules/tsconfig-paths-webpack-plugin": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz", @@ -10418,21 +10625,13 @@ "node": ">=10.13.0" } }, - "node_modules/@storybook/angular/node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true, - "license": "MIT" - }, "node_modules/@storybook/blocks": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.4.7.tgz", - "integrity": "sha512-+QH7+JwXXXIyP3fRCxz/7E2VZepAanXJM7G8nbR3wWsqWgrRp4Wra6MvybxAYCxU7aNfJX5c+RW84SNikFpcIA==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.12.tgz", + "integrity": "sha512-DohlTq6HM1jDbHYiXL4ZvZ00VkhpUp5uftzj/CZDLY1fYHRjqtaTwWm2/OpceivMA8zDitLcq5atEZN+f+siTg==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf": "^0.1.11", "@storybook/icons": "^1.2.12", "ts-dedent": "^2.0.0" }, @@ -10441,9 +10640,9 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.4.7" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^8.6.12" }, "peerDependenciesMeta": { "react": { @@ -10455,14 +10654,13 @@ } }, "node_modules/@storybook/builder-webpack5": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.4.7.tgz", - "integrity": "sha512-O8LpsQ+4g2x5kh7rI9+jEUdX8k1a5egBQU1lbudmHchqsV0IKiVqBD9LL5Gj3wpit4vB8coSW4ZWTFBw8FQb4Q==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.6.12.tgz", + "integrity": "sha512-Z7RsQ/1+HbxdbM69JrEFcTL+pnVKUTMmeURMn5/eOvYTGjBtM18vbQTj0LjCUDIjC+v9U+uX8ZJEUVxFbGcxBw==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core-webpack": "8.4.7", - "@types/node": "^22.0.0", + "@storybook/core-webpack": "8.6.12", "@types/semver": "^7.3.4", "browser-assert": "^1.2.1", "case-sensitive-paths-webpack-plugin": "^2.4.0", @@ -10492,7 +10690,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" }, "peerDependenciesMeta": { "typescript": { @@ -10500,16 +10698,6 @@ } } }, - "node_modules/@storybook/builder-webpack5/node_modules/@types/node": { - "version": "22.13.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", - "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.20.0" - } - }, "node_modules/@storybook/builder-webpack5/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -10658,650 +10846,159 @@ "universalify": "^2.0.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@storybook/builder-webpack5/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/@storybook/builder-webpack5/node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@storybook/builder-webpack5/node_modules/webpack-dev-middleware": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", - "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.12", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "node_modules/@storybook/components": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.4.7.tgz", - "integrity": "sha512-uyJIcoyeMWKAvjrG9tJBUCKxr2WZk+PomgrgrUwejkIfXMO76i6jw9BwLa0NZjYdlthDv30r9FfbYZyeNPmF0g==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" - } - }, - "node_modules/@storybook/core": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.4.7.tgz", - "integrity": "sha512-7Z8Z0A+1YnhrrSXoKKwFFI4gnsLbWzr8fnDCU6+6HlDukFYh8GHRcZ9zKfqmy6U3hw2h8H5DrHsxWfyaYUUOoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/csf": "^0.1.11", - "better-opn": "^3.0.2", - "browser-assert": "^1.2.1", - "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0", - "esbuild-register": "^3.5.0", - "jsdoc-type-pratt-parser": "^4.0.0", - "process": "^0.11.10", - "recast": "^0.23.5", - "semver": "^7.6.2", - "util": "^0.12.5", - "ws": "^8.2.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "prettier": "^2 || ^3" - }, - "peerDependenciesMeta": { - "prettier": { - "optional": true - } - } - }, - "node_modules/@storybook/core-server": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-8.4.7.tgz", - "integrity": "sha512-RW5R+kqRmcP+7QNTmhcrh46qWYkVpxaRlN8MmkHV52m2H5nbBrvgwc3/sb3wdgm1PEU0K5wxT0cmAMIwtnHC9Q==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" - } - }, - "node_modules/@storybook/core-webpack": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.4.7.tgz", - "integrity": "sha512-Tj+CjQLpFyBJxhhMms+vbPT3+gTRAiQlrhY3L1IEVwBa3wtRMS0qjozH26d1hK4G6mUIEdwu13L54HMU/w33Sg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "^22.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.4.7" - } - }, - "node_modules/@storybook/core-webpack/node_modules/@types/node": { - "version": "22.13.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", - "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.20.0" - } - }, - "node_modules/@storybook/core-webpack/node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@storybook/core/node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@storybook/core/node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" + "node": ">=12" } }, - "node_modules/@storybook/core/node_modules/@esbuild/netbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", - "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", - "cpu": [ - "arm64" - ], + "node_modules/@storybook/builder-webpack5/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=18" + "node": ">= 6" } }, - "node_modules/@storybook/core/node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", - "cpu": [ - "x64" - ], + "node_modules/@storybook/builder-webpack5/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } + "license": "MIT" }, - "node_modules/@storybook/core/node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", - "cpu": [ - "arm64" - ], + "node_modules/@storybook/builder-webpack5/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], "engines": { - "node": ">=18" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@storybook/core/node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", - "cpu": [ - "x64" - ], + "node_modules/@storybook/builder-webpack5/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">=18" + "node": ">=8.10.0" } }, - "node_modules/@storybook/core/node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", - "cpu": [ - "x64" - ], + "node_modules/@storybook/builder-webpack5/node_modules/webpack-dev-middleware": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", + "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.12", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, "engines": { - "node": ">=18" + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } } }, - "node_modules/@storybook/core/node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", - "cpu": [ - "arm64" - ], + "node_modules/@storybook/components": { + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.12.tgz", + "integrity": "sha512-FiaE8xvCdvKC2arYusgtlDNZ77b8ysr8njAYQZwwaIHjy27TbR2tEpLDCmUwSbANNmivtc/xGEiDDwcNppMWlQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" } }, - "node_modules/@storybook/core/node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", - "cpu": [ - "ia32" - ], + "node_modules/@storybook/core": { + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.12.tgz", + "integrity": "sha512-t+ZuDzAlsXKa6tLxNZT81gEAt4GNwsKP/Id2wluhmUWD/lwYW0uum1JiPUuanw8xD6TdakCW/7ULZc7aQUBLCQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@storybook/theming": "8.6.12", + "better-opn": "^3.0.2", + "browser-assert": "^1.2.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", + "esbuild-register": "^3.5.0", + "jsdoc-type-pratt-parser": "^4.0.0", + "process": "^0.11.10", + "recast": "^0.23.5", + "semver": "^7.6.2", + "util": "^0.12.5", + "ws": "^8.2.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } } }, - "node_modules/@storybook/core/node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", - "cpu": [ - "x64" - ], + "node_modules/@storybook/core-server": { + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-8.6.12.tgz", + "integrity": "sha512-y6x5jbx2BsverwQIv5msIYRAxQzOXsHLv+6tNtt2hvcp5w9jvRVtsRO93yQl1st+IZ9BUIhhV5EJQkiCTKbdmg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" } }, - "node_modules/@storybook/core/node_modules/esbuild": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "node_modules/@storybook/core-webpack": { + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.6.12.tgz", + "integrity": "sha512-TiE+KOm0hxb/p0JxeGHKxqTNX+xnTOFsBh6uloCSuvodutJ5pR/XpxKVxwo1gtSc0Uq3qpgbMhW6qYlYQetnKA==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "ts-dedent": "^2.0.0" }, - "engines": { - "node": ">=18" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" + "peerDependencies": { + "storybook": "^8.6.12" } }, "node_modules/@storybook/csf": { @@ -11315,9 +11012,9 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.4.7.tgz", - "integrity": "sha512-Fgogplu4HImgC+AYDcdGm1rmL6OR1rVdNX1Be9C/NEXwOCpbbBwi0BxTf/2ZxHRk9fCeaPEcOdP5S8QHfltc1g==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.12.tgz", + "integrity": "sha512-6s8CnP1aoKPb3XtC0jRLUp8M5vTA8RhGAwQDKUsFpCC7g89JR9CaKs9FY2ZSzsNbjR15uASi7b3K8BzeYumYQg==", "dev": true, "license": "MIT", "dependencies": { @@ -11328,7 +11025,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/global": { @@ -11353,9 +11050,9 @@ } }, "node_modules/@storybook/instrumenter": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.4.7.tgz", - "integrity": "sha512-k6NSD3jaRCCHAFtqXZ7tw8jAzD/yTEWXGya+REgZqq5RCkmJ+9S4Ytp/6OhQMPtPFX23gAuJJzTQVLcCr+gjRg==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.12.tgz", + "integrity": "sha512-VK5fYAF8jMwWP/u3YsmSwKGh+FeSY8WZn78flzRUwirp2Eg1WWjsqPRubAk7yTpcqcC/km9YMF3KbqfzRv2s/A==", "dev": true, "license": "MIT", "dependencies": { @@ -11367,13 +11064,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/manager-api": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.4.7.tgz", - "integrity": "sha512-ELqemTviCxAsZ5tqUz39sDmQkvhVAvAgiplYy9Uf15kO0SP2+HKsCMzlrm2ue2FfkUNyqbDayCPPCB0Cdn/mpQ==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.12.tgz", + "integrity": "sha512-O0SpISeJLNTQvhSBOsWzzkCgs8vCjOq1578rwqHlC6jWWm4QmtfdyXqnv7rR1Hk08kQ+Dzqh0uhwHx0nfwy4nQ==", "dev": true, "license": "MIT", "funding": { @@ -11385,9 +11082,9 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.4.7.tgz", - "integrity": "sha512-0QVQwHw+OyZGHAJEXo6Knx+6/4er7n2rTDE5RYJ9F2E2Lg42E19pfdLlq2Jhoods2Xrclo3wj6GWR//Ahi39Eg==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.12.tgz", + "integrity": "sha512-84FE3Hrs0AYKHqpDZOwx1S/ffOfxBdL65lhCoeI8GoWwCkzwa9zEP3kvXBo/BnEDO7nAfxvMhjASTZXbKRJh5Q==", "dev": true, "license": "MIT", "funding": { @@ -11399,9 +11096,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.4.7.tgz", - "integrity": "sha512-6bkG2jvKTmWrmVzCgwpTxwIugd7Lu+2btsLAqhQSzDyIj2/uhMNp8xIMr/NBDtLgq3nomt9gefNa9xxLwk/OMg==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.12.tgz", + "integrity": "sha512-51QvoimkBzYs8s3rCYnY5h0cFqLz/Mh0vRcughwYaXckWzDBV8l67WBO5Xf5nBsukCbWyqBVPpEQLww8s7mrLA==", "dev": true, "license": "MIT", "funding": { @@ -11411,19 +11108,18 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/test": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.4.7.tgz", - "integrity": "sha512-AhvJsu5zl3uG40itSQVuSy5WByp3UVhS6xAnme4FWRwgSxhvZjATJ3AZkkHWOYjnnk+P2/sbz/XuPli1FVCWoQ==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.12.tgz", + "integrity": "sha512-0BK1Eg+VD0lNMB1BtxqHE3tP9FdkUmohtvWG7cq6lWvMrbCmAmh3VWai3RMCCDOukPFpjabOr8BBRLVvhNpv2w==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf": "^0.1.11", "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.4.7", + "@storybook/instrumenter": "8.6.12", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.5.0", "@testing-library/user-event": "14.5.2", @@ -11435,13 +11131,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.4.7" + "storybook": "^8.6.12" } }, "node_modules/@storybook/theming": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.4.7.tgz", - "integrity": "sha512-99rgLEjf7iwfSEmdqlHkSG3AyLcK0sfExcr0jnc6rLiAkBhzuIsvcHjjUwkR210SOCgXqBPW0ZA6uhnuyppHLw==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.12.tgz", + "integrity": "sha512-6VjZg8HJ2Op7+KV7ihJpYrDnFtd9D1jrQnUS8LckcpuBXrIEbaut5+34ObY8ssQnSqkk2GwIZBBBQYQBCVvkOw==", "dev": true, "license": "MIT", "funding": { @@ -13535,6 +13231,18 @@ "dev": true, "license": "MIT" }, + "node_modules/array-union": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", + "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/array.prototype.findlastindex": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", @@ -14979,9 +14687,9 @@ "license": "MIT" }, "node_modules/chart.js": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.7.tgz", - "integrity": "sha512-pwkcKfdzTMAU/+jNosKhNL2bHtJc/sSmYgVbuGTEDhzkrhmyihmP7vUc/5ZK9WopidMDHNe3Wm7jOd/WhuHWuw==", + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.9.tgz", + "integrity": "sha512-EyZ9wWKgpAU0fLJ43YAEIF8sr5F2W3LqbS40ZJyHIner2lY14ufqv2VMp69MAiZ2rpwxEUxEhIH/0U3xyRynxg==", "license": "MIT", "dependencies": { "@kurkle/color": "^0.3.0" @@ -17542,6 +17250,18 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", @@ -18340,9 +18060,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz", + "integrity": "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==", "dev": true, "license": "MIT", "bin": { @@ -20107,61 +19827,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", - "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", - "dev": true, - "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.3", - "path-type": "^6.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", - "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/globby/node_modules/path-type": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/good-listener": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", @@ -20581,9 +20246,9 @@ } }, "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", "dev": true, "funding": [ { @@ -26387,9 +26052,9 @@ "license": "MIT" }, "node_modules/nx": { - "version": "20.6.4", - "resolved": "https://registry.npmjs.org/nx/-/nx-20.6.4.tgz", - "integrity": "sha512-mkRgGvPSZpezn65upZ9psuyywr03XTirHDsqlnRYp90qqDQqMH/I1FsHqqUG5qdy4gbm5qFkZ5Vvc8Z3RkN/jg==", + "version": "20.8.0", + "resolved": "https://registry.npmjs.org/nx/-/nx-20.8.0.tgz", + "integrity": "sha512-+BN5B5DFBB5WswD8flDDTnr4/bf1VTySXOv60aUAllHqR+KS6deT0p70TTMZF4/A2n/L2UCWDaDro37MGaYozA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -26433,16 +26098,16 @@ "nx-cloud": "bin/nx-cloud.js" }, "optionalDependencies": { - "@nx/nx-darwin-arm64": "20.6.4", - "@nx/nx-darwin-x64": "20.6.4", - "@nx/nx-freebsd-x64": "20.6.4", - "@nx/nx-linux-arm-gnueabihf": "20.6.4", - "@nx/nx-linux-arm64-gnu": "20.6.4", - "@nx/nx-linux-arm64-musl": "20.6.4", - "@nx/nx-linux-x64-gnu": "20.6.4", - "@nx/nx-linux-x64-musl": "20.6.4", - "@nx/nx-win32-arm64-msvc": "20.6.4", - "@nx/nx-win32-x64-msvc": "20.6.4" + "@nx/nx-darwin-arm64": "20.8.0", + "@nx/nx-darwin-x64": "20.8.0", + "@nx/nx-freebsd-x64": "20.8.0", + "@nx/nx-linux-arm-gnueabihf": "20.8.0", + "@nx/nx-linux-arm64-gnu": "20.8.0", + "@nx/nx-linux-arm64-musl": "20.8.0", + "@nx/nx-linux-x64-gnu": "20.8.0", + "@nx/nx-linux-x64-musl": "20.8.0", + "@nx/nx-win32-arm64-msvc": "20.8.0", + "@nx/nx-win32-x64-msvc": "20.8.0" }, "peerDependencies": { "@swc-node/register": "^1.8.0", @@ -28380,15 +28045,15 @@ } }, "node_modules/prisma": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.5.0.tgz", - "integrity": "sha512-yUGXmWqv5F4PByMSNbYFxke/WbnyTLjnJ5bKr8fLkcnY7U5rU9rUTh/+Fja+gOrRxEgtCbCtca94IeITj4j/pg==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.6.0.tgz", + "integrity": "sha512-SYCUykz+1cnl6Ugd8VUvtTQq5+j1Q7C0CtzKPjQ8JyA2ALh0EEJkMCS+KgdnvKW1lrxjtjCyJSHOOT236mENYg==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/config": "6.5.0", - "@prisma/engines": "6.5.0" + "@prisma/config": "6.6.0", + "@prisma/engines": "6.6.0" }, "bin": { "prisma": "build/index.js" @@ -28712,6 +28377,17 @@ "dev": true, "license": "MIT" }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -31061,13 +30737,13 @@ } }, "node_modules/storybook": { - "version": "8.4.7", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.4.7.tgz", - "integrity": "sha512-RP/nMJxiWyFc8EVMH5gp20ID032Wvk+Yr3lmKidoegto5Iy+2dVQnUoElZb2zpbVXNHWakGuAkfI0dY1Hfp/vw==", + "version": "8.6.12", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.12.tgz", + "integrity": "sha512-Z/nWYEHBTLK1ZBtAWdhxC0l5zf7ioJ7G4+zYqtTdYeb67gTnxNj80gehf8o8QY9L2zA2+eyMRGLC2V5fI7Z3Tw==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core": "8.4.7" + "@storybook/core": "8.6.12" }, "bin": { "getstorybook": "bin/index.cjs", @@ -33054,9 +32730,9 @@ } }, "node_modules/uuid": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz", - "integrity": "sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" diff --git a/package.json b/package.json index cb9f14a4c..70cb2917d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.150.0", + "version": "2.155.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", @@ -88,7 +88,7 @@ "@nestjs/platform-express": "10.4.15", "@nestjs/schedule": "4.1.2", "@nestjs/serve-static": "4.0.2", - "@prisma/client": "6.5.0", + "@prisma/client": "6.6.0", "@simplewebauthn/browser": "13.1.0", "@simplewebauthn/server": "13.1.1", "@stripe/stripe-js": "5.4.0", @@ -99,7 +99,7 @@ "bull": "4.16.5", "cache-manager": "5.7.6", "cache-manager-redis-yet": "5.1.4", - "chart.js": "4.4.7", + "chart.js": "4.4.9", "chartjs-adapter-date-fns": "3.0.0", "chartjs-chart-treemap": "3.1.0", "chartjs-plugin-annotation": "3.1.0", @@ -137,7 +137,7 @@ "stripe": "17.3.0", "svgmap": "2.12.2", "twitter-api-v2": "1.14.2", - "uuid": "11.0.5", + "uuid": "11.1.0", "yahoo-finance2": "2.11.3", "zone.js": "0.15.0" }, @@ -157,22 +157,22 @@ "@eslint/js": "9.24.0", "@nestjs/schematics": "10.2.3", "@nestjs/testing": "10.4.15", - "@nx/angular": "20.6.4", - "@nx/cypress": "20.6.4", - "@nx/eslint-plugin": "20.6.4", - "@nx/jest": "20.6.4", - "@nx/js": "20.6.4", - "@nx/module-federation": "20.6.4", - "@nx/nest": "20.6.4", - "@nx/node": "20.6.4", - "@nx/storybook": "20.6.4", - "@nx/web": "20.6.4", - "@nx/workspace": "20.6.4", + "@nx/angular": "20.8.0", + "@nx/cypress": "20.8.0", + "@nx/eslint-plugin": "20.8.0", + "@nx/jest": "20.8.0", + "@nx/js": "20.8.0", + "@nx/module-federation": "20.8.0", + "@nx/nest": "20.8.0", + "@nx/node": "20.8.0", + "@nx/storybook": "20.8.0", + "@nx/web": "20.8.0", + "@nx/workspace": "20.8.0", "@schematics/angular": "19.2.1", - "@storybook/addon-essentials": "8.4.7", - "@storybook/addon-interactions": "8.4.7", - "@storybook/angular": "8.4.7", - "@storybook/core-server": "8.4.7", + "@storybook/addon-essentials": "8.6.12", + "@storybook/addon-interactions": "8.6.12", + "@storybook/angular": "8.6.12", + "@storybook/core-server": "8.6.12", "@trivago/prettier-plugin-sort-imports": "5.2.2", "@types/big.js": "6.2.2", "@types/cache-manager": "4.0.6", @@ -187,7 +187,7 @@ "codelyzer": "6.0.1", "cypress": "6.2.1", "eslint": "9.24.0", - "eslint-config-prettier": "9.1.0", + "eslint-config-prettier": "10.1.1", "eslint-plugin-cypress": "4.2.0", "eslint-plugin-import": "2.31.0", "eslint-plugin-storybook": "0.12.0", @@ -195,15 +195,15 @@ "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "jest-preset-angular": "14.4.2", - "nx": "20.6.4", + "nx": "20.8.0", "prettier": "3.5.3", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "6.5.0", + "prisma": "6.6.0", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "8.3.0", "shx": "0.3.4", - "storybook": "8.4.7", + "storybook": "8.6.12", "ts-jest": "29.1.0", "ts-node": "10.9.2", "tslib": "2.8.1", diff --git a/prisma/migrations/20250401084916_set_value_of_currency_to_null_in_order/migration.sql b/prisma/migrations/20250401084916_set_value_of_currency_to_null_in_order/migration.sql new file mode 100644 index 000000000..03a4e7178 --- /dev/null +++ b/prisma/migrations/20250401084916_set_value_of_currency_to_null_in_order/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +UPDATE "Order" SET "currency" = NULL; diff --git a/prisma/migrations/20250418123137_added_watchlist_to_user/migration.sql b/prisma/migrations/20250418123137_added_watchlist_to_user/migration.sql new file mode 100644 index 000000000..25fd35041 --- /dev/null +++ b/prisma/migrations/20250418123137_added_watchlist_to_user/migration.sql @@ -0,0 +1,16 @@ +-- CreateTable +CREATE TABLE "_UserWatchlist" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_UserWatchlist_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_UserWatchlist_B_index" ON "_UserWatchlist"("B"); + +-- AddForeignKey +ALTER TABLE "_UserWatchlist" ADD CONSTRAINT "_UserWatchlist_A_fkey" FOREIGN KEY ("A") REFERENCES "SymbolProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_UserWatchlist" ADD CONSTRAINT "_UserWatchlist_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml index 648c57fd5..044d57cdb 100644 --- a/prisma/migrations/migration_lock.toml +++ b/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually # It should be added in your version-control system (e.g., Git) -provider = "postgresql" \ No newline at end of file +provider = "postgresql" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7e37ecde0..e9220ecef 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -191,6 +191,7 @@ model SymbolProfile { symbolMapping Json? url String? userId String? + watchedBy User[] @relation("UserWatchlist") Order Order[] tags Tag[] SymbolProfileOverrides SymbolProfileOverrides? @@ -226,8 +227,8 @@ model Subscription { id String @id @default(uuid()) price Float? updatedAt DateTime @updatedAt + user User @relation(fields: [userId], onDelete: Cascade, references: [id]) userId String - User User @relation(fields: [userId], onDelete: Cascade, references: [id]) @@index([userId]) } @@ -251,8 +252,10 @@ model User { id String @id @default(uuid()) provider Provider @default(ANONYMOUS) role Role @default(USER) + subscriptions Subscription[] thirdPartyId String? updatedAt DateTime @updatedAt + watchlist SymbolProfile[] @relation("UserWatchlist") Access Access[] @relation("accessGet") AccessGive Access[] @relation("accessGive") Account Account[] @@ -261,7 +264,6 @@ model User { AuthDevice AuthDevice[] Order Order[] Settings Settings? - Subscription Subscription[] SymbolProfile SymbolProfile[] Tag Tag[] diff --git a/test/import/invalid-data-source.json b/test/import/invalid-data-source.json new file mode 100644 index 000000000..472e295ee --- /dev/null +++ b/test/import/invalid-data-source.json @@ -0,0 +1,18 @@ +{ + "meta": { + "date": "2021-01-01T00:00:00.000Z", + "version": "dev" + }, + "activities": [ + { + "currency": "USD", + "dataSource": "", + "date": "2021-01-01T00:00:00.000Z", + "fee": 0, + "quantity": 20, + "symbol": "AAPL", + "type": "BUY", + "unitPrice": 100.0 + } + ] +} diff --git a/test/import/ok-btceur.json b/test/import/ok-btceur.json new file mode 100644 index 000000000..b370682f9 --- /dev/null +++ b/test/import/ok-btceur.json @@ -0,0 +1,29 @@ +{ + "meta": { + "date": "2021-12-12T00:00:00.000Z", + "version": "dev" + }, + "accounts": [], + "platforms": [], + "tags": [], + "activities": [ + { + "accountId": null, + "comment": null, + "fee": 3.94, + "quantity": 1, + "type": "BUY", + "unitPrice": 39378.5, + "currency": "EUR", + "dataSource": "YAHOO", + "date": "2021-12-12T00:00:00.000Z", + "symbol": "BTCUSD", + "tags": [] + } + ], + "user": { + "settings": { + "currency": "USD" + } + } +} diff --git a/test/import/ok-btcusd.json b/test/import/ok-btcusd.json new file mode 100644 index 000000000..fc2e1f66e --- /dev/null +++ b/test/import/ok-btcusd.json @@ -0,0 +1,29 @@ +{ + "meta": { + "date": "2021-12-12T00:00:00.000Z", + "version": "dev" + }, + "accounts": [], + "platforms": [], + "tags": [], + "activities": [ + { + "accountId": null, + "comment": null, + "fee": 4.46, + "quantity": 1, + "type": "BUY", + "unitPrice": 44558.42, + "currency": "USD", + "dataSource": "YAHOO", + "date": "2021-12-12T00:00:00.000Z", + "symbol": "BTCUSD", + "tags": [] + } + ], + "user": { + "settings": { + "currency": "USD" + } + } +}