Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
d9c07456cd | |||
0a53df4293 | |||
4416ba0c88 | |||
486de968a2 | |||
a5833566a8 | |||
261f5844dd | |||
2173c418a7 | |||
4efd5cefd8 | |||
d735e4db75 | |||
e10707fde4 | |||
ac953df809 | |||
bb4ee50738 | |||
4f41bac328 | |||
cd07802400 | |||
b692b7432c | |||
a4efbc0131 | |||
55b0fe232c | |||
46432edce9 | |||
990028316e | |||
37871fbabc | |||
0fdeef7953 | |||
cdbe6eedeb |
44
CHANGELOG.md
44
CHANGELOG.md
@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 2.78.0 - 2024-05-02
|
||||
|
||||
### Added
|
||||
|
||||
- Added a form validation against the DTO in the create or update access dialog
|
||||
- Added a form validation against the DTO in the asset profile details dialog of the admin control
|
||||
- Added a form validation against the DTO in the platform management of the admin control panel
|
||||
- Added a form validation against the DTO in the tag management of the admin control panel
|
||||
|
||||
### Changed
|
||||
|
||||
- Set the performance column of the holdings table to stick at the end
|
||||
- Skipped the caching in the portfolio calculator if there are active filters (experimental)
|
||||
- Improved the `INACTIVE` user role
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an issue in the calculation of the portfolio summary caused by future liabilities
|
||||
- Fixed a division by zero error in the dividend yield calculation (experimental)
|
||||
|
||||
## 2.77.1 - 2024-04-27
|
||||
|
||||
### Added
|
||||
|
||||
- Extended the content of the _Self-Hosting_ section by the custom asset instructions on the Frequently Asked Questions (FAQ) page
|
||||
- Added the caching to the portfolio calculator (experimental)
|
||||
|
||||
### Changed
|
||||
|
||||
- Migrated the `@ghostfolio/ui` components to control flow
|
||||
- Updated the browserslist database
|
||||
- Upgraded `prisma` from version `5.12.1` to `5.13.0`
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed the form submit in the asset profile details dialog of the admin control due to the `url` validation
|
||||
- Fixed the historical market data gathering for asset profiles with `MANUAL` data source
|
||||
|
||||
## 2.76.0 - 2024-04-23
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed `CASH` to `LIQUIDITY` in the asset class enum
|
||||
|
||||
## 2.75.1 - 2024-04-21
|
||||
|
||||
### Added
|
||||
|
34
README.md
34
README.md
@ -85,23 +85,23 @@ We provide official container images hosted on [Docker Hub](https://hub.docker.c
|
||||
|
||||
### Supported Environment Variables
|
||||
|
||||
| Name | Default Value | Description |
|
||||
| ------------------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ACCESS_TOKEN_SALT` | | A random string used as salt for access tokens |
|
||||
| `API_KEY_COINGECKO_DEMO` | | The _CoinGecko_ Demo API key |
|
||||
| `API_KEY_COINGECKO_PRO` | | The _CoinGecko_ Pro API |
|
||||
| `DATABASE_URL` | | The database connection URL, e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?sslmode=prefer` |
|
||||
| `HOST` | `0.0.0.0` | The host where the Ghostfolio application will run on |
|
||||
| `JWT_SECRET_KEY` | | A random string used for _JSON Web Tokens_ (JWT) |
|
||||
| `PORT` | `3333` | The port where the Ghostfolio application will run on |
|
||||
| `POSTGRES_DB` | | The name of the _PostgreSQL_ database |
|
||||
| `POSTGRES_PASSWORD` | | The password of the _PostgreSQL_ database |
|
||||
| `POSTGRES_USER` | | The user of the _PostgreSQL_ database |
|
||||
| `REDIS_DB` | `0` | The database index of _Redis_ |
|
||||
| `REDIS_HOST` | | The host where _Redis_ is running |
|
||||
| `REDIS_PASSWORD` | | The password of _Redis_ |
|
||||
| `REDIS_PORT` | | The port where _Redis_ is running |
|
||||
| `REQUEST_TIMEOUT` | `2000` | The timeout of network requests to data providers in milliseconds |
|
||||
| Name | Type | Default Value | Description |
|
||||
| ------------------------ | ------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ACCESS_TOKEN_SALT` | string | | A random string used as salt for access tokens |
|
||||
| `API_KEY_COINGECKO_DEMO` | string (`optional`) | | The _CoinGecko_ Demo API key |
|
||||
| `API_KEY_COINGECKO_PRO` | string (`optional`) | | The _CoinGecko_ Pro API |
|
||||
| `DATABASE_URL` | string | | The database connection URL, e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?sslmode=prefer` |
|
||||
| `HOST` | string (`optional`) | `0.0.0.0` | The host where the Ghostfolio application will run on |
|
||||
| `JWT_SECRET_KEY` | string | | A random string used for _JSON Web Tokens_ (JWT) |
|
||||
| `PORT` | number (`optional`) | `3333` | The port where the Ghostfolio application will run on |
|
||||
| `POSTGRES_DB` | string | | The name of the _PostgreSQL_ database |
|
||||
| `POSTGRES_PASSWORD` | string | | The password of the _PostgreSQL_ database |
|
||||
| `POSTGRES_USER` | string | | The user of the _PostgreSQL_ database |
|
||||
| `REDIS_DB` | number (`optional`) | `0` | The database index of _Redis_ |
|
||||
| `REDIS_HOST` | string | | The host where _Redis_ is running |
|
||||
| `REDIS_PASSWORD` | string | | The password of _Redis_ |
|
||||
| `REDIS_PORT` | number | | The port where _Redis_ is running |
|
||||
| `REQUEST_TIMEOUT` | number (`optional`) | `2000` | The timeout of network requests to data providers in milliseconds |
|
||||
|
||||
### Run with Docker Compose
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { AccountService } from '@ghostfolio/api/app/account/account.service';
|
||||
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator';
|
||||
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
|
||||
import { resetHours } from '@ghostfolio/common/helper';
|
||||
import { permissions } from '@ghostfolio/common/permissions';
|
||||
import type { RequestWithUser } from '@ghostfolio/common/types';
|
||||
|
||||
@ -18,7 +17,6 @@ import {
|
||||
import { REQUEST } from '@nestjs/core';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { AccountBalance } from '@prisma/client';
|
||||
import { parseISO } from 'date-fns';
|
||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||
|
||||
import { AccountBalanceService } from './account-balance.service';
|
||||
@ -67,10 +65,11 @@ export class AccountBalanceController {
|
||||
@Param('id') id: string
|
||||
): Promise<AccountBalance> {
|
||||
const accountBalance = await this.accountBalanceService.accountBalance({
|
||||
id
|
||||
id,
|
||||
userId: this.request.user.id
|
||||
});
|
||||
|
||||
if (!accountBalance || accountBalance.userId !== this.request.user.id) {
|
||||
if (!accountBalance) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||
StatusCodes.FORBIDDEN
|
||||
@ -78,7 +77,8 @@ export class AccountBalanceController {
|
||||
}
|
||||
|
||||
return this.accountBalanceService.deleteAccountBalance({
|
||||
id
|
||||
id: accountBalance.id,
|
||||
userId: accountBalance.userId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
|
||||
import { resetHours } from '@ghostfolio/common/helper';
|
||||
@ -5,6 +6,7 @@ import { AccountBalancesResponse, Filter } from '@ghostfolio/common/interfaces';
|
||||
import { UserWithSettings } from '@ghostfolio/common/types';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { AccountBalance, Prisma } from '@prisma/client';
|
||||
import { parseISO } from 'date-fns';
|
||||
|
||||
@ -13,6 +15,7 @@ import { CreateAccountBalanceDto } from './create-account-balance.dto';
|
||||
@Injectable()
|
||||
export class AccountBalanceService {
|
||||
public constructor(
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||
private readonly prismaService: PrismaService
|
||||
) {}
|
||||
@ -36,7 +39,7 @@ export class AccountBalanceService {
|
||||
}: CreateAccountBalanceDto & {
|
||||
userId: string;
|
||||
}): Promise<AccountBalance> {
|
||||
return this.prismaService.accountBalance.upsert({
|
||||
const accountBalance = await this.prismaService.accountBalance.upsert({
|
||||
create: {
|
||||
Account: {
|
||||
connect: {
|
||||
@ -59,14 +62,32 @@ export class AccountBalanceService {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId
|
||||
})
|
||||
);
|
||||
|
||||
return accountBalance;
|
||||
}
|
||||
|
||||
public async deleteAccountBalance(
|
||||
where: Prisma.AccountBalanceWhereUniqueInput
|
||||
): Promise<AccountBalance> {
|
||||
return this.prismaService.accountBalance.delete({
|
||||
const accountBalance = await this.prismaService.accountBalance.delete({
|
||||
where
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: <string>where.userId
|
||||
})
|
||||
);
|
||||
|
||||
return accountBalance;
|
||||
}
|
||||
|
||||
public async getAccountBalances({
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service';
|
||||
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
|
||||
import { DATE_FORMAT } from '@ghostfolio/common/helper';
|
||||
import { Filter } from '@ghostfolio/common/interfaces';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { Account, Order, Platform, Prisma } from '@prisma/client';
|
||||
import { Big } from 'big.js';
|
||||
import { format } from 'date-fns';
|
||||
@ -16,6 +18,7 @@ import { CashDetails } from './interfaces/cash-details.interface';
|
||||
export class AccountService {
|
||||
public constructor(
|
||||
private readonly accountBalanceService: AccountBalanceService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||
private readonly prismaService: PrismaService
|
||||
) {}
|
||||
@ -94,6 +97,13 @@ export class AccountService {
|
||||
userId: aUserId
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: account.userId
|
||||
})
|
||||
);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
@ -101,9 +111,18 @@ export class AccountService {
|
||||
where: Prisma.AccountWhereUniqueInput,
|
||||
aUserId: string
|
||||
): Promise<Account> {
|
||||
return this.prismaService.account.delete({
|
||||
const account = await this.prismaService.account.delete({
|
||||
where
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: account.userId
|
||||
})
|
||||
);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
public async getAccounts(aUserId: string): Promise<Account[]> {
|
||||
@ -201,10 +220,19 @@ export class AccountService {
|
||||
userId: aUserId
|
||||
});
|
||||
|
||||
return this.prismaService.account.update({
|
||||
const account = await this.prismaService.account.update({
|
||||
data,
|
||||
where
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: account.userId
|
||||
})
|
||||
);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
public async updateAccountBalance({
|
||||
|
@ -416,7 +416,7 @@ export class AdminService {
|
||||
dataSource,
|
||||
marketDataItemCount,
|
||||
symbol,
|
||||
assetClass: 'CASH',
|
||||
assetClass: AssetClass.LIQUIDITY,
|
||||
countriesCount: 0,
|
||||
currency: symbol.replace(DEFAULT_CURRENCY, ''),
|
||||
id: undefined,
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { EventsModule } from '@ghostfolio/api/events/events.module';
|
||||
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
|
||||
import { CronService } from '@ghostfolio/api/services/cron.service';
|
||||
import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering/data-gathering.module';
|
||||
@ -14,6 +15,7 @@ import {
|
||||
import { BullModule } from '@nestjs/bull';
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||
import { StatusCodes } from 'http-status-codes';
|
||||
@ -44,6 +46,7 @@ import { TagModule } from './tag/tag.module';
|
||||
import { UserModule } from './user/user.module';
|
||||
|
||||
@Module({
|
||||
controllers: [AppController],
|
||||
imports: [
|
||||
AdminModule,
|
||||
AccessModule,
|
||||
@ -64,6 +67,8 @@ import { UserModule } from './user/user.module';
|
||||
ConfigurationModule,
|
||||
DataGatheringModule,
|
||||
DataProviderModule,
|
||||
EventEmitterModule.forRoot(),
|
||||
EventsModule,
|
||||
ExchangeRateModule,
|
||||
ExchangeRateDataModule,
|
||||
ExportModule,
|
||||
@ -109,7 +114,6 @@ import { UserModule } from './user/user.module';
|
||||
TwitterBotModule,
|
||||
UserModule
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [CronService]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
@ -2,10 +2,12 @@ import { UserService } from '@ghostfolio/api/app/user/user.service';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
|
||||
import { HEADER_KEY_TIMEZONE } from '@ghostfolio/common/config';
|
||||
import { hasRole } from '@ghostfolio/common/permissions';
|
||||
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { HttpException, Injectable } from '@nestjs/common';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import * as countriesAndTimezones from 'countries-and-timezones';
|
||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||
|
||||
@Injectable()
|
||||
@ -29,6 +31,13 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
|
||||
if (user) {
|
||||
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
|
||||
if (hasRole(user, 'INACTIVE')) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.TOO_MANY_REQUESTS),
|
||||
StatusCodes.TOO_MANY_REQUESTS
|
||||
);
|
||||
}
|
||||
|
||||
const country =
|
||||
countriesAndTimezones.getCountryForTimezone(timezone)?.id;
|
||||
|
||||
@ -45,10 +54,20 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
|
||||
return user;
|
||||
} else {
|
||||
throw '';
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.NOT_FOUND),
|
||||
StatusCodes.NOT_FOUND
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error?.getStatus() === StatusCodes.TOO_MANY_REQUESTS) {
|
||||
throw error;
|
||||
} else {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.UNAUTHORIZED),
|
||||
StatusCodes.UNAUTHORIZED
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
throw new UnauthorizedException('unauthorized', err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -416,6 +416,11 @@ export class ImportService {
|
||||
User: { connect: { id: user.id } },
|
||||
userId: user.id
|
||||
});
|
||||
|
||||
if (order.SymbolProfile?.symbol) {
|
||||
// Update symbol that may have been assigned in createOrder()
|
||||
assetProfile.symbol = order.SymbolProfile.symbol;
|
||||
}
|
||||
}
|
||||
|
||||
const value = new Big(quantity).mul(unitPrice).toNumber();
|
||||
|
@ -60,15 +60,15 @@ export class OrderController {
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@HasPermission(permissions.deleteOrder)
|
||||
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
||||
public async deleteOrder(@Param('id') id: string): Promise<OrderModel> {
|
||||
const order = await this.orderService.order({ id });
|
||||
const order = await this.orderService.order({
|
||||
id,
|
||||
userId: this.request.user.id
|
||||
});
|
||||
|
||||
if (
|
||||
!hasPermission(this.request.user.permissions, permissions.deleteOrder) ||
|
||||
!order ||
|
||||
order.userId !== this.request.user.id
|
||||
) {
|
||||
if (!order) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||
StatusCodes.FORBIDDEN
|
||||
@ -88,21 +88,26 @@ export class OrderController {
|
||||
@Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId,
|
||||
@Query('accounts') filterByAccounts?: string,
|
||||
@Query('assetClasses') filterByAssetClasses?: string,
|
||||
@Query('range') dateRange: DateRange = 'max',
|
||||
@Query('range') dateRange?: DateRange,
|
||||
@Query('skip') skip?: number,
|
||||
@Query('sortColumn') sortColumn?: string,
|
||||
@Query('sortDirection') sortDirection?: Prisma.SortOrder,
|
||||
@Query('tags') filterByTags?: string,
|
||||
@Query('take') take?: number
|
||||
): Promise<Activities> {
|
||||
let endDate: Date;
|
||||
let startDate: Date;
|
||||
|
||||
if (dateRange) {
|
||||
({ endDate, startDate } = getInterval(dateRange));
|
||||
}
|
||||
|
||||
const filters = this.apiService.buildFiltersFromQueryParams({
|
||||
filterByAccounts,
|
||||
filterByAssetClasses,
|
||||
filterByTags
|
||||
});
|
||||
|
||||
const { endDate, startDate } = getInterval(dateRange);
|
||||
|
||||
const impersonationUserId =
|
||||
await this.impersonationService.validateImpersonationId(impersonationId);
|
||||
const userCurrency = this.request.user.Settings.settings.baseCurrency;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { AccountService } from '@ghostfolio/api/app/account/account.service';
|
||||
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
|
||||
import { DataGatheringService } from '@ghostfolio/api/services/data-gathering/data-gathering.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
|
||||
@ -13,6 +14,7 @@ import { Filter, UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||
import { OrderWithAccount } from '@ghostfolio/common/types';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import {
|
||||
AssetClass,
|
||||
AssetSubClass,
|
||||
@ -27,7 +29,6 @@ import { endOfToday, isAfter } from 'date-fns';
|
||||
import { groupBy, uniqBy } from 'lodash';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { CreateOrderDto } from './create-order.dto';
|
||||
import { Activities } from './interfaces/activities.interface';
|
||||
|
||||
@Injectable()
|
||||
@ -35,6 +36,7 @@ export class OrderService {
|
||||
public constructor(
|
||||
private readonly accountService: AccountService,
|
||||
private readonly dataGatheringService: DataGatheringService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||
private readonly prismaService: PrismaService,
|
||||
private readonly symbolProfileService: SymbolProfileService
|
||||
@ -138,7 +140,8 @@ export class OrderService {
|
||||
return { id };
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
include: { SymbolProfile: true }
|
||||
});
|
||||
|
||||
if (updateAccountBalance === true) {
|
||||
@ -160,6 +163,13 @@ export class OrderService {
|
||||
});
|
||||
}
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: order.userId
|
||||
})
|
||||
);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
@ -174,6 +184,13 @@ export class OrderService {
|
||||
await this.symbolProfileService.deleteById(order.symbolProfileId);
|
||||
}
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: order.userId
|
||||
})
|
||||
);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
@ -182,6 +199,13 @@ export class OrderService {
|
||||
where
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: <string>where.userId
|
||||
})
|
||||
);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -455,7 +479,7 @@ export class OrderService {
|
||||
where
|
||||
});
|
||||
|
||||
return this.prismaService.order.update({
|
||||
const order = await this.prismaService.order.update({
|
||||
data: {
|
||||
...data,
|
||||
isDraft,
|
||||
@ -467,6 +491,15 @@ export class OrderService {
|
||||
},
|
||||
where
|
||||
});
|
||||
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId: order.userId
|
||||
})
|
||||
);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
private async orders(params: {
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
|
||||
import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface';
|
||||
import {
|
||||
SymbolMetrics,
|
||||
TimelinePosition,
|
||||
UniqueAsset
|
||||
} from '@ghostfolio/common/interfaces';
|
||||
import { SymbolMetrics, UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||
import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models';
|
||||
|
||||
export class MWRPortfolioCalculator extends PortfolioCalculator {
|
||||
protected calculateOverallPerformance(
|
||||
|
@ -24,3 +24,7 @@ export const symbolProfileDummyData = {
|
||||
sectors: [],
|
||||
updatedAt: undefined
|
||||
};
|
||||
|
||||
export const userDummyData = {
|
||||
id: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||
};
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service';
|
||||
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
|
||||
import { DateRange } from '@ghostfolio/common/types';
|
||||
import { DateRange, UserWithSettings } from '@ghostfolio/common/types';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
@ -18,8 +20,10 @@ export enum PerformanceCalculationType {
|
||||
@Injectable()
|
||||
export class PortfolioCalculatorFactory {
|
||||
public constructor(
|
||||
private readonly configurationService: ConfigurationService,
|
||||
private readonly currentRateService: CurrentRateService,
|
||||
private readonly exchangeRateDataService: ExchangeRateDataService
|
||||
private readonly exchangeRateDataService: ExchangeRateDataService,
|
||||
private readonly redisCacheService: RedisCacheService
|
||||
) {}
|
||||
|
||||
public createCalculator({
|
||||
@ -27,14 +31,22 @@ export class PortfolioCalculatorFactory {
|
||||
activities,
|
||||
calculationType,
|
||||
currency,
|
||||
dateRange = 'max'
|
||||
dateRange = 'max',
|
||||
hasFilters,
|
||||
isExperimentalFeatures = false,
|
||||
userId
|
||||
}: {
|
||||
accountBalanceItems?: HistoricalDataItem[];
|
||||
activities: Activity[];
|
||||
calculationType: PerformanceCalculationType;
|
||||
currency: string;
|
||||
dateRange?: DateRange;
|
||||
hasFilters: boolean;
|
||||
isExperimentalFeatures?: boolean;
|
||||
userId: string;
|
||||
}): PortfolioCalculator {
|
||||
const useCache = !hasFilters && isExperimentalFeatures;
|
||||
|
||||
switch (calculationType) {
|
||||
case PerformanceCalculationType.MWR:
|
||||
return new MWRPortfolioCalculator({
|
||||
@ -42,8 +54,12 @@ export class PortfolioCalculatorFactory {
|
||||
activities,
|
||||
currency,
|
||||
dateRange,
|
||||
useCache,
|
||||
userId,
|
||||
configurationService: this.configurationService,
|
||||
currentRateService: this.currentRateService,
|
||||
exchangeRateDataService: this.exchangeRateDataService
|
||||
exchangeRateDataService: this.exchangeRateDataService,
|
||||
redisCacheService: this.redisCacheService
|
||||
});
|
||||
case PerformanceCalculationType.TWR:
|
||||
return new TWRPortfolioCalculator({
|
||||
@ -52,7 +68,11 @@ export class PortfolioCalculatorFactory {
|
||||
currency,
|
||||
currentRateService: this.currentRateService,
|
||||
dateRange,
|
||||
exchangeRateDataService: this.exchangeRateDataService
|
||||
useCache,
|
||||
userId,
|
||||
configurationService: this.configurationService,
|
||||
exchangeRateDataService: this.exchangeRateDataService,
|
||||
redisCacheService: this.redisCacheService
|
||||
});
|
||||
default:
|
||||
throw new Error('Invalid calculation type');
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service';
|
||||
import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface';
|
||||
import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface';
|
||||
import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface';
|
||||
import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface';
|
||||
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
|
||||
import {
|
||||
getFactor,
|
||||
getInterval
|
||||
} from '@ghostfolio/api/helper/portfolio.helper';
|
||||
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 { MAX_CHART_ITEMS } from '@ghostfolio/common/config';
|
||||
@ -23,17 +24,20 @@ import {
|
||||
InvestmentItem,
|
||||
ResponseError,
|
||||
SymbolMetrics,
|
||||
TimelinePosition,
|
||||
UniqueAsset
|
||||
} from '@ghostfolio/common/interfaces';
|
||||
import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models';
|
||||
import { DateRange, GroupBy } from '@ghostfolio/common/types';
|
||||
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { Big } from 'big.js';
|
||||
import { plainToClass } from 'class-transformer';
|
||||
import {
|
||||
differenceInDays,
|
||||
eachDayOfInterval,
|
||||
endOfDay,
|
||||
format,
|
||||
isAfter,
|
||||
isBefore,
|
||||
isSameDay,
|
||||
max,
|
||||
@ -46,54 +50,88 @@ export abstract class PortfolioCalculator {
|
||||
protected static readonly ENABLE_LOGGING = false;
|
||||
|
||||
protected accountBalanceItems: HistoricalDataItem[];
|
||||
protected orders: PortfolioOrder[];
|
||||
protected activities: PortfolioOrder[];
|
||||
|
||||
private configurationService: ConfigurationService;
|
||||
private currency: string;
|
||||
private currentRateService: CurrentRateService;
|
||||
private dataProviderInfos: DataProviderInfo[];
|
||||
private dateRange: DateRange;
|
||||
private endDate: Date;
|
||||
private exchangeRateDataService: ExchangeRateDataService;
|
||||
private redisCacheService: RedisCacheService;
|
||||
private snapshot: PortfolioSnapshot;
|
||||
private snapshotPromise: Promise<void>;
|
||||
private startDate: Date;
|
||||
private transactionPoints: TransactionPoint[];
|
||||
private useCache: boolean;
|
||||
private userId: string;
|
||||
|
||||
public constructor({
|
||||
accountBalanceItems,
|
||||
activities,
|
||||
configurationService,
|
||||
currency,
|
||||
currentRateService,
|
||||
dateRange,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService,
|
||||
useCache,
|
||||
userId
|
||||
}: {
|
||||
accountBalanceItems: HistoricalDataItem[];
|
||||
activities: Activity[];
|
||||
configurationService: ConfigurationService;
|
||||
currency: string;
|
||||
currentRateService: CurrentRateService;
|
||||
dateRange: DateRange;
|
||||
exchangeRateDataService: ExchangeRateDataService;
|
||||
redisCacheService: RedisCacheService;
|
||||
useCache: boolean;
|
||||
userId: string;
|
||||
}) {
|
||||
this.accountBalanceItems = accountBalanceItems;
|
||||
this.configurationService = configurationService;
|
||||
this.currency = currency;
|
||||
this.currentRateService = currentRateService;
|
||||
this.dateRange = dateRange;
|
||||
this.exchangeRateDataService = exchangeRateDataService;
|
||||
this.orders = activities.map(
|
||||
({ date, fee, quantity, SymbolProfile, tags = [], type, unitPrice }) => {
|
||||
return {
|
||||
SymbolProfile,
|
||||
tags,
|
||||
type,
|
||||
date: format(date, DATE_FORMAT),
|
||||
fee: new Big(fee),
|
||||
quantity: new Big(quantity),
|
||||
unitPrice: new Big(unitPrice)
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
this.orders.sort((a, b) => {
|
||||
return a.date?.localeCompare(b.date);
|
||||
});
|
||||
this.activities = 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);
|
||||
});
|
||||
|
||||
this.redisCacheService = redisCacheService;
|
||||
this.useCache = useCache;
|
||||
this.userId = userId;
|
||||
|
||||
const { endDate, startDate } = getInterval(dateRange);
|
||||
|
||||
@ -887,7 +925,7 @@ export abstract class PortfolioCalculator {
|
||||
tags,
|
||||
type,
|
||||
unitPrice
|
||||
} of this.orders) {
|
||||
} of this.activities) {
|
||||
let currentTransactionPointItem: TransactionPointSymbol;
|
||||
const oldAccumulatedSymbol = symbols[SymbolProfile.symbol];
|
||||
|
||||
@ -1011,6 +1049,52 @@ export abstract class PortfolioCalculator {
|
||||
}
|
||||
|
||||
private async initialize() {
|
||||
this.snapshot = await this.computeSnapshot(this.startDate, this.endDate);
|
||||
if (this.useCache) {
|
||||
const startTimeTotal = performance.now();
|
||||
|
||||
const cachedSnapshot = await this.redisCacheService.get(
|
||||
this.redisCacheService.getPortfolioSnapshotKey({
|
||||
userId: this.userId
|
||||
})
|
||||
);
|
||||
|
||||
if (cachedSnapshot) {
|
||||
this.snapshot = plainToClass(
|
||||
PortfolioSnapshot,
|
||||
JSON.parse(cachedSnapshot)
|
||||
);
|
||||
|
||||
Logger.debug(
|
||||
`Fetched portfolio snapshot from cache in ${(
|
||||
(performance.now() - startTimeTotal) /
|
||||
1000
|
||||
).toFixed(3)} seconds`,
|
||||
'PortfolioCalculator'
|
||||
);
|
||||
} else {
|
||||
this.snapshot = await this.computeSnapshot(
|
||||
this.startDate,
|
||||
this.endDate
|
||||
);
|
||||
|
||||
this.redisCacheService.set(
|
||||
this.redisCacheService.getPortfolioSnapshotKey({
|
||||
userId: this.userId
|
||||
}),
|
||||
JSON.stringify(this.snapshot),
|
||||
this.configurationService.get('CACHE_QUOTES_TTL')
|
||||
);
|
||||
|
||||
Logger.debug(
|
||||
`Computed portfolio snapshot in ${(
|
||||
(performance.now() - startTimeTotal) /
|
||||
1000
|
||||
).toFixed(3)} seconds`,
|
||||
'PortfolioCalculator'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.snapshot = await this.computeSnapshot(this.startDate, this.endDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PortfolioCalculatorFactory,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -101,7 +122,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const chartData = await portfolioCalculator.getChartData({
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PerformanceCalculationType,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -86,7 +107,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const chartData = await portfolioCalculator.getChartData({
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PortfolioCalculatorFactory,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -71,7 +92,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const chartData = await portfolioCalculator.getChartData({
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PortfolioCalculatorFactory,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service.mock';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
@ -24,6 +28,15 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock(
|
||||
'@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service',
|
||||
() => {
|
||||
@ -37,11 +50,15 @@ jest.mock(
|
||||
);
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -51,9 +68,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -99,7 +120,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const chartData = await portfolioCalculator.getChartData({
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PortfolioCalculatorFactory,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -71,7 +92,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'USD'
|
||||
currency: 'USD',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const portfolioSnapshot = await portfolioCalculator.computeSnapshot(
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PortfolioCalculatorFactory,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service.mock';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
@ -24,6 +28,15 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock(
|
||||
'@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service',
|
||||
() => {
|
||||
@ -37,11 +50,15 @@ jest.mock(
|
||||
);
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -51,9 +68,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -84,7 +105,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const chartData = await portfolioCalculator.getChartData({
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PortfolioCalculatorFactory,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -71,7 +92,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'USD'
|
||||
currency: 'USD',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const portfolioSnapshot = await portfolioCalculator.computeSnapshot(
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PortfolioCalculatorFactory,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -53,7 +74,7 @@ describe('PortfolioCalculator', () => {
|
||||
const activities: Activity[] = [
|
||||
{
|
||||
...activityDummyData,
|
||||
date: new Date('2022-01-01'),
|
||||
date: new Date('2023-01-01'), // Date in future
|
||||
fee: 0,
|
||||
quantity: 1,
|
||||
SymbolProfile: {
|
||||
@ -71,64 +92,17 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'USD'
|
||||
currency: 'USD',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const portfolioSnapshot = await portfolioCalculator.computeSnapshot(
|
||||
parseDate('2022-01-01')
|
||||
);
|
||||
|
||||
spy.mockRestore();
|
||||
|
||||
expect(portfolioSnapshot).toEqual({
|
||||
currentValueInBaseCurrency: new Big('0'),
|
||||
errors: [],
|
||||
grossPerformance: new Big('0'),
|
||||
grossPerformancePercentage: new Big('0'),
|
||||
grossPerformancePercentageWithCurrencyEffect: new Big('0'),
|
||||
grossPerformanceWithCurrencyEffect: new Big('0'),
|
||||
hasErrors: true,
|
||||
netPerformance: new Big('0'),
|
||||
netPerformancePercentage: new Big('0'),
|
||||
netPerformancePercentageWithCurrencyEffect: new Big('0'),
|
||||
netPerformanceWithCurrencyEffect: new Big('0'),
|
||||
positions: [
|
||||
{
|
||||
averagePrice: new Big('3000'),
|
||||
currency: 'USD',
|
||||
dataSource: 'MANUAL',
|
||||
dividend: new Big('0'),
|
||||
dividendInBaseCurrency: new Big('0'),
|
||||
fee: new Big('0'),
|
||||
firstBuyDate: '2022-01-01',
|
||||
grossPerformance: null,
|
||||
grossPerformancePercentage: null,
|
||||
grossPerformancePercentageWithCurrencyEffect: null,
|
||||
grossPerformanceWithCurrencyEffect: null,
|
||||
investment: new Big('0'),
|
||||
investmentWithCurrencyEffect: new Big('0'),
|
||||
marketPrice: null,
|
||||
marketPriceInBaseCurrency: 3000,
|
||||
netPerformance: null,
|
||||
netPerformancePercentage: null,
|
||||
netPerformancePercentageWithCurrencyEffect: null,
|
||||
netPerformanceWithCurrencyEffect: null,
|
||||
quantity: new Big('0'),
|
||||
symbol: '55196015-1365-4560-aa60-8751ae6d18f8',
|
||||
tags: [],
|
||||
timeWeightedInvestment: new Big('0'),
|
||||
timeWeightedInvestmentWithCurrencyEffect: new Big('0'),
|
||||
transactionCount: 1,
|
||||
valueInBaseCurrency: new Big('0')
|
||||
}
|
||||
],
|
||||
totalFeesWithCurrencyEffect: new Big('0'),
|
||||
totalInterestWithCurrencyEffect: new Big('0'),
|
||||
totalInvestment: new Big('0'),
|
||||
totalInvestmentWithCurrencyEffect: new Big('0'),
|
||||
totalLiabilitiesWithCurrencyEffect: new Big('0'),
|
||||
totalValuablesWithCurrencyEffect: new Big('0')
|
||||
});
|
||||
const liabilitiesInBaseCurrency =
|
||||
await portfolioCalculator.getLiabilitiesInBaseCurrency();
|
||||
|
||||
expect(liabilitiesInBaseCurrency).toEqual(new Big(3000));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PerformanceCalculationType,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service.mock';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
@ -24,6 +28,15 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock(
|
||||
'@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service',
|
||||
() => {
|
||||
@ -37,11 +50,15 @@ jest.mock(
|
||||
);
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -51,9 +68,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -99,7 +120,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'USD'
|
||||
currency: 'USD',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const portfolioSnapshot = await portfolioCalculator.computeSnapshot(
|
||||
|
@ -1,9 +1,13 @@
|
||||
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 { 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -19,12 +23,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -34,9 +51,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -49,7 +70,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities: [],
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const start = subDays(new Date(Date.now()), 10);
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PerformanceCalculationType,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -86,7 +107,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const chartData = await portfolioCalculator.getChartData({
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface';
|
||||
import {
|
||||
activityDummyData,
|
||||
symbolProfileDummyData
|
||||
symbolProfileDummyData,
|
||||
userDummyData
|
||||
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils';
|
||||
import {
|
||||
PerformanceCalculationType,
|
||||
@ -9,6 +10,9 @@ import {
|
||||
} 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';
|
||||
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { parseDate } from '@ghostfolio/common/helper';
|
||||
|
||||
@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => {
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
RedisCacheService: jest.fn().mockImplementation(() => {
|
||||
return RedisCacheServiceMock;
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
@ -86,7 +107,9 @@ describe('PortfolioCalculator', () => {
|
||||
const portfolioCalculator = factory.createCalculator({
|
||||
activities,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: 'CHF'
|
||||
currency: 'CHF',
|
||||
hasFilters: false,
|
||||
userId: userDummyData.id
|
||||
});
|
||||
|
||||
const chartData = await portfolioCalculator.getChartData({
|
||||
|
@ -1,13 +1,19 @@
|
||||
import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory';
|
||||
import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service';
|
||||
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
|
||||
describe('PortfolioCalculator', () => {
|
||||
let configurationService: ConfigurationService;
|
||||
let currentRateService: CurrentRateService;
|
||||
let exchangeRateDataService: ExchangeRateDataService;
|
||||
let factory: PortfolioCalculatorFactory;
|
||||
let redisCacheService: RedisCacheService;
|
||||
|
||||
beforeEach(() => {
|
||||
configurationService = new ConfigurationService();
|
||||
|
||||
currentRateService = new CurrentRateService(null, null, null, null);
|
||||
|
||||
exchangeRateDataService = new ExchangeRateDataService(
|
||||
@ -17,9 +23,13 @@ describe('PortfolioCalculator', () => {
|
||||
null
|
||||
);
|
||||
|
||||
redisCacheService = new RedisCacheService(null, null);
|
||||
|
||||
factory = new PortfolioCalculatorFactory(
|
||||
configurationService,
|
||||
currentRateService,
|
||||
exchangeRateDataService
|
||||
exchangeRateDataService,
|
||||
redisCacheService
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
|
||||
import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order-item.interface';
|
||||
import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface';
|
||||
import { getFactor } from '@ghostfolio/api/helper/portfolio.helper';
|
||||
import { DATE_FORMAT } from '@ghostfolio/common/helper';
|
||||
import {
|
||||
SymbolMetrics,
|
||||
TimelinePosition,
|
||||
UniqueAsset
|
||||
} from '@ghostfolio/common/interfaces';
|
||||
import { SymbolMetrics, UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||
import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models';
|
||||
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { Big } from 'big.js';
|
||||
@ -207,7 +203,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
let valueAtStartDateWithCurrencyEffect: Big;
|
||||
|
||||
// Clone orders to keep the original values in this.orders
|
||||
let orders: PortfolioOrderItem[] = cloneDeep(this.orders).filter(
|
||||
let orders: PortfolioOrderItem[] = cloneDeep(this.activities).filter(
|
||||
({ SymbolProfile }) => {
|
||||
return SymbolProfile.symbol === symbol;
|
||||
}
|
||||
|
@ -8,6 +8,13 @@ import { GetValuesParams } from './interfaces/get-values-params.interface';
|
||||
|
||||
function mockGetValue(symbol: string, date: Date) {
|
||||
switch (symbol) {
|
||||
case '55196015-1365-4560-aa60-8751ae6d18f8':
|
||||
if (isSameDay(parseDate('2022-01-31'), date)) {
|
||||
return { marketPrice: 3000 };
|
||||
}
|
||||
|
||||
return { marketPrice: 0 };
|
||||
|
||||
case 'BALN.SW':
|
||||
if (isSameDay(parseDate('2021-11-12'), date)) {
|
||||
return { marketPrice: 146 };
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces';
|
||||
|
||||
import { Big } from 'big.js';
|
||||
|
||||
export interface PortfolioSnapshot extends ResponseError {
|
||||
currentValueInBaseCurrency: Big;
|
||||
grossPerformance: Big;
|
||||
grossPerformanceWithCurrencyEffect: Big;
|
||||
grossPerformancePercentage: Big;
|
||||
grossPerformancePercentageWithCurrencyEffect: Big;
|
||||
netAnnualizedPerformance?: Big;
|
||||
netAnnualizedPerformanceWithCurrencyEffect?: Big;
|
||||
netPerformance: Big;
|
||||
netPerformanceWithCurrencyEffect: Big;
|
||||
netPerformancePercentage: Big;
|
||||
netPerformancePercentageWithCurrencyEffect: Big;
|
||||
positions: TimelinePosition[];
|
||||
totalFeesWithCurrencyEffect: Big;
|
||||
totalInterestWithCurrencyEffect: Big;
|
||||
totalInvestment: Big;
|
||||
totalInvestmentWithCurrencyEffect: Big;
|
||||
totalLiabilitiesWithCurrencyEffect: Big;
|
||||
totalValuablesWithCurrencyEffect: Big;
|
||||
}
|
@ -47,6 +47,7 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { REQUEST } from '@nestjs/core';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { AssetClass, AssetSubClass } from '@prisma/client';
|
||||
import { Big } from 'big.js';
|
||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||
|
||||
@ -128,14 +129,19 @@ export class PortfolioController {
|
||||
|
||||
const totalValue = Object.values(holdings)
|
||||
.filter(({ assetClass, assetSubClass }) => {
|
||||
return assetClass !== 'CASH' && assetSubClass !== 'CASH';
|
||||
return (
|
||||
assetClass !== AssetClass.LIQUIDITY &&
|
||||
assetSubClass !== AssetSubClass.CASH
|
||||
);
|
||||
})
|
||||
.map(({ valueInBaseCurrency }) => {
|
||||
return valueInBaseCurrency;
|
||||
})
|
||||
.reduce((a, b) => a + b, 0);
|
||||
.reduce((a, b) => {
|
||||
return a + b;
|
||||
}, 0);
|
||||
|
||||
for (const [symbol, portfolioPosition] of Object.entries(holdings)) {
|
||||
for (const [, portfolioPosition] of Object.entries(holdings)) {
|
||||
portfolioPosition.investment =
|
||||
portfolioPosition.investment / totalInvestment;
|
||||
portfolioPosition.valueInPercentage =
|
||||
@ -185,11 +191,11 @@ export class PortfolioController {
|
||||
holdings[symbol] = {
|
||||
...portfolioPosition,
|
||||
assetClass:
|
||||
hasDetails || portfolioPosition.assetClass === 'CASH'
|
||||
hasDetails || portfolioPosition.assetClass === AssetClass.LIQUIDITY
|
||||
? portfolioPosition.assetClass
|
||||
: undefined,
|
||||
assetSubClass:
|
||||
hasDetails || portfolioPosition.assetSubClass === 'CASH'
|
||||
hasDetails || portfolioPosition.assetSubClass === AssetSubClass.CASH
|
||||
? portfolioPosition.assetSubClass
|
||||
: undefined,
|
||||
countries: hasDetails ? portfolioPosition.countries : [],
|
||||
|
@ -2,6 +2,7 @@ import { AccessModule } from '@ghostfolio/api/app/access/access.module';
|
||||
import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service';
|
||||
import { AccountService } from '@ghostfolio/api/app/account/account.service';
|
||||
import { OrderModule } from '@ghostfolio/api/app/order/order.module';
|
||||
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
|
||||
import { UserModule } from '@ghostfolio/api/app/user/user.module';
|
||||
import { ApiModule } from '@ghostfolio/api/services/api/api.module';
|
||||
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
|
||||
@ -35,6 +36,7 @@ import { RulesService } from './rules.service';
|
||||
MarketDataModule,
|
||||
OrderModule,
|
||||
PrismaModule,
|
||||
RedisCacheModule,
|
||||
SymbolProfileModule,
|
||||
UserModule
|
||||
],
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
EnhancedSymbolProfile,
|
||||
Filter,
|
||||
HistoricalDataItem,
|
||||
InvestmentItem,
|
||||
PortfolioDetails,
|
||||
PortfolioInvestments,
|
||||
PortfolioPerformanceResponse,
|
||||
@ -36,10 +37,9 @@ import {
|
||||
PortfolioReport,
|
||||
PortfolioSummary,
|
||||
Position,
|
||||
TimelinePosition,
|
||||
UserSettings
|
||||
} from '@ghostfolio/common/interfaces';
|
||||
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface';
|
||||
import { TimelinePosition } from '@ghostfolio/common/models';
|
||||
import type {
|
||||
AccountWithValue,
|
||||
DateRange,
|
||||
@ -54,6 +54,7 @@ import {
|
||||
Account,
|
||||
Type as ActivityType,
|
||||
AssetClass,
|
||||
AssetSubClass,
|
||||
DataSource,
|
||||
Order,
|
||||
Platform,
|
||||
@ -276,8 +277,13 @@ export class PortfolioService {
|
||||
|
||||
const portfolioCalculator = this.calculatorFactory.createCalculator({
|
||||
activities,
|
||||
dateRange,
|
||||
userId,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: this.request.user.Settings.settings.baseCurrency
|
||||
currency: this.request.user.Settings.settings.baseCurrency,
|
||||
hasFilters: filters?.length > 0,
|
||||
isExperimentalFeatures:
|
||||
this.request.user.Settings.settings.isExperimentalFeatures
|
||||
});
|
||||
|
||||
const items = await portfolioCalculator.getChart({
|
||||
@ -351,8 +357,12 @@ export class PortfolioService {
|
||||
const portfolioCalculator = this.calculatorFactory.createCalculator({
|
||||
activities,
|
||||
dateRange,
|
||||
userId,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: userCurrency
|
||||
currency: userCurrency,
|
||||
hasFilters: filters?.length > 0,
|
||||
isExperimentalFeatures:
|
||||
this.request.user?.Settings.settings.isExperimentalFeatures
|
||||
});
|
||||
|
||||
const { currentValueInBaseCurrency, hasErrors, positions } =
|
||||
@ -376,7 +386,7 @@ export class PortfolioService {
|
||||
}) ?? false;
|
||||
|
||||
const isFilteredByCash = filters?.some(({ id, type }) => {
|
||||
return id === 'CASH' && type === 'ASSET_CLASS';
|
||||
return id === AssetClass.LIQUIDITY && type === 'ASSET_CLASS';
|
||||
});
|
||||
|
||||
const isFilteredByClosedHoldings =
|
||||
@ -391,8 +401,8 @@ export class PortfolioService {
|
||||
if (
|
||||
filters?.length === 0 ||
|
||||
(filters?.length === 1 &&
|
||||
filters[0].type === 'ASSET_CLASS' &&
|
||||
filters[0].id === 'CASH')
|
||||
filters[0].id === AssetClass.LIQUIDITY &&
|
||||
filters[0].type === 'ASSET_CLASS')
|
||||
) {
|
||||
filteredValueInBaseCurrency = filteredValueInBaseCurrency.plus(
|
||||
cashDetails.balanceInBaseCurrency
|
||||
@ -647,11 +657,15 @@ export class PortfolioService {
|
||||
]);
|
||||
|
||||
const portfolioCalculator = this.calculatorFactory.createCalculator({
|
||||
userId,
|
||||
activities: orders.filter((order) => {
|
||||
return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type);
|
||||
}),
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: userCurrency
|
||||
currency: userCurrency,
|
||||
hasFilters: true,
|
||||
isExperimentalFeatures:
|
||||
this.request.user.Settings.settings.isExperimentalFeatures
|
||||
});
|
||||
|
||||
const portfolioStart = portfolioCalculator.getStartDate();
|
||||
@ -690,17 +704,19 @@ export class PortfolioService {
|
||||
|
||||
const dividendYieldPercent = this.getAnnualizedPerformancePercent({
|
||||
daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)),
|
||||
netPerformancePercent: dividendInBaseCurrency.div(
|
||||
timeWeightedInvestment
|
||||
)
|
||||
netPerformancePercent: timeWeightedInvestment.eq(0)
|
||||
? new Big(0)
|
||||
: dividendInBaseCurrency.div(timeWeightedInvestment)
|
||||
});
|
||||
|
||||
const dividendYieldPercentWithCurrencyEffect =
|
||||
this.getAnnualizedPerformancePercent({
|
||||
daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)),
|
||||
netPerformancePercent: dividendInBaseCurrency.div(
|
||||
timeWeightedInvestmentWithCurrencyEffect
|
||||
)
|
||||
netPerformancePercent: timeWeightedInvestmentWithCurrencyEffect.eq(0)
|
||||
? new Big(0)
|
||||
: dividendInBaseCurrency.div(
|
||||
timeWeightedInvestmentWithCurrencyEffect
|
||||
)
|
||||
});
|
||||
|
||||
const historicalData = await this.dataProviderService.getHistorical(
|
||||
@ -918,8 +934,12 @@ export class PortfolioService {
|
||||
const portfolioCalculator = this.calculatorFactory.createCalculator({
|
||||
activities,
|
||||
dateRange,
|
||||
userId,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: this.request.user.Settings.settings.baseCurrency
|
||||
currency: this.request.user.Settings.settings.baseCurrency,
|
||||
hasFilters: filters?.length > 0,
|
||||
isExperimentalFeatures:
|
||||
this.request.user.Settings.settings.isExperimentalFeatures
|
||||
});
|
||||
|
||||
let { hasErrors, positions } = await portfolioCalculator.getSnapshot();
|
||||
@ -1072,7 +1092,7 @@ export class PortfolioService {
|
||||
)
|
||||
);
|
||||
|
||||
const { endDate, startDate } = getInterval(dateRange);
|
||||
const { endDate } = getInterval(dateRange);
|
||||
|
||||
const { activities } = await this.orderService.getOrders({
|
||||
endDate,
|
||||
@ -1107,8 +1127,12 @@ export class PortfolioService {
|
||||
accountBalanceItems,
|
||||
activities,
|
||||
dateRange,
|
||||
userId,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: userCurrency
|
||||
currency: userCurrency,
|
||||
hasFilters: filters?.length > 0,
|
||||
isExperimentalFeatures:
|
||||
this.request.user.Settings.settings.isExperimentalFeatures
|
||||
});
|
||||
|
||||
const {
|
||||
@ -1201,8 +1225,12 @@ export class PortfolioService {
|
||||
|
||||
const portfolioCalculator = this.calculatorFactory.createCalculator({
|
||||
activities,
|
||||
userId,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: this.request.user.Settings.settings.baseCurrency
|
||||
currency: this.request.user.Settings.settings.baseCurrency,
|
||||
hasFilters: false,
|
||||
isExperimentalFeatures:
|
||||
this.request.user.Settings.settings.isExperimentalFeatures
|
||||
});
|
||||
|
||||
let { totalFeesWithCurrencyEffect, positions, totalInvestment } =
|
||||
@ -1425,8 +1453,8 @@ export class PortfolioService {
|
||||
return {
|
||||
currency,
|
||||
allocationInPercentage: 0,
|
||||
assetClass: AssetClass.CASH,
|
||||
assetSubClass: AssetClass.CASH,
|
||||
assetClass: AssetClass.LIQUIDITY,
|
||||
assetSubClass: AssetSubClass.CASH,
|
||||
countries: [],
|
||||
dataSource: undefined,
|
||||
dateOfFirstActivity: undefined,
|
||||
|
13
apps/api/src/app/redis-cache/redis-cache.service.mock.ts
Normal file
13
apps/api/src/app/redis-cache/redis-cache.service.mock.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { RedisCacheService } from './redis-cache.service';
|
||||
|
||||
export const RedisCacheServiceMock = {
|
||||
get: (key: string): Promise<string> => {
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
getPortfolioSnapshotKey: (userId: string): string => {
|
||||
return `portfolio-snapshot-${userId}`;
|
||||
},
|
||||
set: (key: string, value: string, ttlInSeconds?: number): Promise<string> => {
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
};
|
@ -24,6 +24,10 @@ export class RedisCacheService {
|
||||
return this.cache.get(key);
|
||||
}
|
||||
|
||||
public getPortfolioSnapshotKey({ userId }: { userId: string }) {
|
||||
return `portfolio-snapshot-${userId}`;
|
||||
}
|
||||
|
||||
public getQuoteKey({ dataSource, symbol }: UniqueAsset) {
|
||||
return `quote-${getAssetProfileIdentifier({ dataSource, symbol })}`;
|
||||
}
|
||||
|
@ -2,11 +2,7 @@ import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorat
|
||||
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
|
||||
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
|
||||
import { User, UserSettings } from '@ghostfolio/common/interfaces';
|
||||
import {
|
||||
hasPermission,
|
||||
hasRole,
|
||||
permissions
|
||||
} from '@ghostfolio/common/permissions';
|
||||
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
||||
import type { RequestWithUser } from '@ghostfolio/common/types';
|
||||
|
||||
import {
|
||||
@ -63,13 +59,6 @@ export class UserController {
|
||||
public async getUser(
|
||||
@Headers('accept-language') acceptLanguage: string
|
||||
): Promise<User> {
|
||||
if (hasRole(this.request.user, 'INACTIVE')) {
|
||||
throw new HttpException(
|
||||
getReasonPhrase(StatusCodes.TOO_MANY_REQUESTS),
|
||||
StatusCodes.TOO_MANY_REQUESTS
|
||||
);
|
||||
}
|
||||
|
||||
return this.userService.getUser(
|
||||
this.request.user,
|
||||
acceptLanguage?.split(',')?.[0]
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
|
||||
import { environment } from '@ghostfolio/api/environments/environment';
|
||||
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
|
||||
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
|
||||
@ -25,6 +26,7 @@ import {
|
||||
import { UserWithSettings } from '@ghostfolio/common/types';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { Prisma, Role, User } from '@prisma/client';
|
||||
import { differenceInDays } from 'date-fns';
|
||||
import { sortBy, without } from 'lodash';
|
||||
@ -37,6 +39,7 @@ export class UserService {
|
||||
|
||||
public constructor(
|
||||
private readonly configurationService: ConfigurationService,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly prismaService: PrismaService,
|
||||
private readonly propertyService: PropertyService,
|
||||
private readonly subscriptionService: SubscriptionService,
|
||||
@ -437,11 +440,9 @@ export class UserService {
|
||||
userId: string;
|
||||
userSettings: UserSettings;
|
||||
}) {
|
||||
const settings = userSettings as unknown as Prisma.JsonObject;
|
||||
|
||||
await this.prismaService.settings.upsert({
|
||||
const { settings } = await this.prismaService.settings.upsert({
|
||||
create: {
|
||||
settings,
|
||||
settings: userSettings as unknown as Prisma.JsonObject,
|
||||
User: {
|
||||
connect: {
|
||||
id: userId
|
||||
@ -449,14 +450,21 @@ export class UserService {
|
||||
}
|
||||
},
|
||||
update: {
|
||||
settings
|
||||
settings: userSettings as unknown as Prisma.JsonObject
|
||||
},
|
||||
where: {
|
||||
userId
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
this.eventEmitter.emit(
|
||||
PortfolioChangedEvent.getName(),
|
||||
new PortfolioChangedEvent({
|
||||
userId
|
||||
})
|
||||
);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
private getRandomString(length: number) {
|
||||
|
11
apps/api/src/events/events.module.ts
Normal file
11
apps/api/src/events/events.module.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
|
||||
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { PortfolioChangedListener } from './portfolio-changed.listener';
|
||||
|
||||
@Module({
|
||||
imports: [RedisCacheModule],
|
||||
providers: [PortfolioChangedListener]
|
||||
})
|
||||
export class EventsModule {}
|
15
apps/api/src/events/portfolio-changed.event.ts
Normal file
15
apps/api/src/events/portfolio-changed.event.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export class PortfolioChangedEvent {
|
||||
private userId: string;
|
||||
|
||||
public constructor({ userId }: { userId: string }) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public static getName() {
|
||||
return 'portfolio.changed';
|
||||
}
|
||||
|
||||
public getUserId() {
|
||||
return this.userId;
|
||||
}
|
||||
}
|
25
apps/api/src/events/portfolio-changed.listener.ts
Normal file
25
apps/api/src/events/portfolio-changed.listener.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
|
||||
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { OnEvent } from '@nestjs/event-emitter';
|
||||
|
||||
import { PortfolioChangedEvent } from './portfolio-changed.event';
|
||||
|
||||
@Injectable()
|
||||
export class PortfolioChangedListener {
|
||||
public constructor(private readonly redisCacheService: RedisCacheService) {}
|
||||
|
||||
@OnEvent(PortfolioChangedEvent.getName())
|
||||
handlePortfolioChangedEvent(event: PortfolioChangedEvent) {
|
||||
Logger.log(
|
||||
`Portfolio of user with id ${event.getUserId()} has changed`,
|
||||
'PortfolioChangedListener'
|
||||
);
|
||||
|
||||
this.redisCacheService.remove(
|
||||
this.redisCacheService.getPortfolioSnapshotKey({
|
||||
userId: event.getUserId()
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { groupBy } from '@ghostfolio/common/helper';
|
||||
import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces';
|
||||
import { UserSettings } from '@ghostfolio/common/interfaces';
|
||||
import { TimelinePosition } from '@ghostfolio/common/models';
|
||||
|
||||
import { EvaluationResult } from './interfaces/evaluation-result.interface';
|
||||
import { RuleInterface } from './interfaces/rule.interface';
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
|
||||
import { Rule } from '@ghostfolio/api/models/rule';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces';
|
||||
import { UserSettings } from '@ghostfolio/common/interfaces';
|
||||
import { TimelinePosition } from '@ghostfolio/common/models';
|
||||
|
||||
export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule<Settings> {
|
||||
private positions: TimelinePosition[];
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
|
||||
import { Rule } from '@ghostfolio/api/models/rule';
|
||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
|
||||
import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces';
|
||||
import { UserSettings } from '@ghostfolio/common/interfaces';
|
||||
import { TimelinePosition } from '@ghostfolio/common/models';
|
||||
|
||||
export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> {
|
||||
private positions: TimelinePosition[];
|
||||
|
@ -59,7 +59,7 @@ export class CoinGeckoService implements DataProviderInterface {
|
||||
}): Promise<Partial<SymbolProfile>> {
|
||||
const response: Partial<SymbolProfile> = {
|
||||
symbol,
|
||||
assetClass: AssetClass.CASH,
|
||||
assetClass: AssetClass.LIQUIDITY,
|
||||
assetSubClass: AssetSubClass.CRYPTOCURRENCY,
|
||||
currency: DEFAULT_CURRENCY,
|
||||
dataSource: this.getName()
|
||||
@ -243,7 +243,7 @@ export class CoinGeckoService implements DataProviderInterface {
|
||||
return {
|
||||
name,
|
||||
symbol,
|
||||
assetClass: AssetClass.CASH,
|
||||
assetClass: AssetClass.LIQUIDITY,
|
||||
assetSubClass: AssetSubClass.CRYPTOCURRENCY,
|
||||
currency: DEFAULT_CURRENCY,
|
||||
dataProviderInfo: this.getDataProviderInfo(),
|
||||
|
@ -266,7 +266,7 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface {
|
||||
|
||||
switch (quoteType?.toLowerCase()) {
|
||||
case 'cryptocurrency':
|
||||
assetClass = AssetClass.CASH;
|
||||
assetClass = AssetClass.LIQUIDITY;
|
||||
assetSubClass = AssetSubClass.CRYPTOCURRENCY;
|
||||
break;
|
||||
case 'equity':
|
||||
|
@ -399,7 +399,8 @@ export class DataProviderService {
|
||||
numberOfItemsInCache > 1 ? 's' : ''
|
||||
} from cache in ${((performance.now() - startTimeTotal) / 1000).toFixed(
|
||||
3
|
||||
)} seconds`
|
||||
)} seconds`,
|
||||
'DataProviderService'
|
||||
);
|
||||
}
|
||||
|
||||
@ -505,7 +506,8 @@ export class DataProviderService {
|
||||
} from ${dataSource} in ${(
|
||||
(performance.now() - startTimeDataSource) /
|
||||
1000
|
||||
).toFixed(3)} seconds`
|
||||
).toFixed(3)} seconds`,
|
||||
'DataProviderService'
|
||||
);
|
||||
|
||||
try {
|
||||
@ -535,14 +537,15 @@ export class DataProviderService {
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
Logger.debug('------------------------------------------------');
|
||||
Logger.debug('--------------------------------------------------------');
|
||||
Logger.debug(
|
||||
`Fetched ${items.length} quote${items.length > 1 ? 's' : ''} in ${(
|
||||
(performance.now() - startTimeTotal) /
|
||||
1000
|
||||
).toFixed(3)} seconds`
|
||||
).toFixed(3)} seconds`,
|
||||
'DataProviderService'
|
||||
);
|
||||
Logger.debug('================================================');
|
||||
Logger.debug('========================================================');
|
||||
|
||||
return response;
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
|
||||
assetSubClass = AssetSubClass.STOCK;
|
||||
break;
|
||||
case 'currency':
|
||||
assetClass = AssetClass.CASH;
|
||||
assetClass = AssetClass.LIQUIDITY;
|
||||
|
||||
if (Exchange?.toLowerCase() === 'cc') {
|
||||
assetSubClass = AssetSubClass.CRYPTOCURRENCY;
|
||||
|
@ -91,7 +91,7 @@ export class ManualService implements DataProviderInterface {
|
||||
headers = {},
|
||||
selector,
|
||||
url
|
||||
} = symbolProfile.scraperConfiguration ?? {};
|
||||
} = symbolProfile?.scraperConfiguration ?? {};
|
||||
|
||||
if (defaultMarketPrice) {
|
||||
const historical: {
|
||||
|
@ -3,6 +3,7 @@ import { UpdateMarketDataDto } from '@ghostfolio/api/app/admin/update-market-dat
|
||||
import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service';
|
||||
import { AdminService } from '@ghostfolio/client/services/admin.service';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { validateObjectForForm } from '@ghostfolio/client/util/form.util';
|
||||
import { ghostfolioScraperApiSymbolPrefix } from '@ghostfolio/common/config';
|
||||
import { DATE_FORMAT } from '@ghostfolio/common/helper';
|
||||
import {
|
||||
@ -258,29 +259,29 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
public onSubmit() {
|
||||
public async onSubmit() {
|
||||
let countries = [];
|
||||
let scraperConfiguration = {};
|
||||
let sectors = [];
|
||||
let symbolMapping = {};
|
||||
|
||||
try {
|
||||
countries = JSON.parse(this.assetProfileForm.controls['countries'].value);
|
||||
countries = JSON.parse(this.assetProfileForm.get('countries').value);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
scraperConfiguration = JSON.parse(
|
||||
this.assetProfileForm.controls['scraperConfiguration'].value
|
||||
this.assetProfileForm.get('scraperConfiguration').value
|
||||
);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
sectors = JSON.parse(this.assetProfileForm.controls['sectors'].value);
|
||||
sectors = JSON.parse(this.assetProfileForm.get('sectors').value);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
symbolMapping = JSON.parse(
|
||||
this.assetProfileForm.controls['symbolMapping'].value
|
||||
this.assetProfileForm.get('symbolMapping').value
|
||||
);
|
||||
} catch {}
|
||||
|
||||
@ -289,16 +290,27 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
scraperConfiguration,
|
||||
sectors,
|
||||
symbolMapping,
|
||||
assetClass: this.assetProfileForm.controls['assetClass'].value,
|
||||
assetSubClass: this.assetProfileForm.controls['assetSubClass'].value,
|
||||
comment: this.assetProfileForm.controls['comment'].value ?? null,
|
||||
assetClass: this.assetProfileForm.get('assetClass').value,
|
||||
assetSubClass: this.assetProfileForm.get('assetSubClass').value,
|
||||
comment: this.assetProfileForm.get('comment').value || null,
|
||||
currency: (<Currency>(
|
||||
(<unknown>this.assetProfileForm.controls['currency'].value)
|
||||
(<unknown>this.assetProfileForm.get('currency').value)
|
||||
))?.value,
|
||||
name: this.assetProfileForm.controls['name'].value,
|
||||
url: this.assetProfileForm.controls['url'].value
|
||||
name: this.assetProfileForm.get('name').value,
|
||||
url: this.assetProfileForm.get('url').value || null
|
||||
};
|
||||
|
||||
try {
|
||||
await validateObjectForForm({
|
||||
classDto: UpdateAssetProfileDto,
|
||||
form: this.assetProfileForm,
|
||||
object: assetProfileData
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
|
||||
this.adminService
|
||||
.patchAssetProfile({
|
||||
...assetProfileData,
|
||||
@ -314,8 +326,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
this.adminService
|
||||
.testMarketData({
|
||||
dataSource: this.data.dataSource,
|
||||
scraperConfiguration:
|
||||
this.assetProfileForm.controls['scraperConfiguration'].value,
|
||||
scraperConfiguration: this.assetProfileForm.get('scraperConfiguration')
|
||||
.value,
|
||||
symbol: this.data.symbol
|
||||
})
|
||||
.pipe(
|
||||
@ -331,9 +343,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
||||
' ' +
|
||||
price +
|
||||
' ' +
|
||||
(<Currency>(
|
||||
(<unknown>this.assetProfileForm.controls['currency'].value)
|
||||
))?.value
|
||||
(<Currency>(<unknown>this.assetProfileForm.get('currency').value))
|
||||
?.value
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -302,7 +302,7 @@
|
||||
mat-flat-button
|
||||
type="button"
|
||||
[disabled]="
|
||||
assetProfileForm.controls['scraperConfiguration'].value === '{}'
|
||||
assetProfileForm.get('scraperConfiguration').value === '{}'
|
||||
"
|
||||
(click)="onTestMarketData()"
|
||||
>
|
||||
@ -338,11 +338,11 @@
|
||||
<mat-form-field appearance="outline" class="w-100 without-hint">
|
||||
<mat-label i18n>Url</mat-label>
|
||||
<input formControlName="url" matInput type="text" />
|
||||
@if (assetProfileForm.controls['url'].value) {
|
||||
@if (assetProfileForm.get('url').value) {
|
||||
<gf-asset-profile-icon
|
||||
class="mr-3"
|
||||
matSuffix
|
||||
[url]="assetProfileForm.controls['url'].value"
|
||||
[url]="assetProfileForm.get('url').value"
|
||||
/>
|
||||
}
|
||||
</mat-form-field>
|
||||
|
@ -59,14 +59,12 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy {
|
||||
this.mode === 'auto'
|
||||
? this.dialogRef.close({
|
||||
dataSource:
|
||||
this.createAssetProfileForm.controls['searchSymbol'].value
|
||||
.dataSource,
|
||||
symbol:
|
||||
this.createAssetProfileForm.controls['searchSymbol'].value.symbol
|
||||
this.createAssetProfileForm.get('searchSymbol').value.dataSource,
|
||||
symbol: this.createAssetProfileForm.get('searchSymbol').value.symbol
|
||||
})
|
||||
: this.dialogRef.close({
|
||||
dataSource: 'MANUAL',
|
||||
symbol: this.createAssetProfileForm.controls['addSymbol'].value
|
||||
symbol: this.createAssetProfileForm.get('addSymbol').value
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -143,9 +143,7 @@ export class AdminPlatformComponent implements OnInit, OnDestroy {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data) => {
|
||||
const platform: CreatePlatformDto = data?.platform;
|
||||
|
||||
.subscribe((platform: CreatePlatformDto | null) => {
|
||||
if (platform) {
|
||||
this.adminService
|
||||
.postPlatform(platform)
|
||||
@ -182,9 +180,7 @@ export class AdminPlatformComponent implements OnInit, OnDestroy {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data) => {
|
||||
const platform: UpdatePlatformDto = data?.platform;
|
||||
|
||||
.subscribe((platform: UpdatePlatformDto | null) => {
|
||||
if (platform) {
|
||||
this.adminService
|
||||
.putPlatform(platform)
|
||||
|
@ -1,4 +1,14 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto';
|
||||
import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto';
|
||||
import { validateObjectForForm } from '@ghostfolio/client/util/form.util';
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Inject,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@ -11,18 +21,54 @@ import { CreateOrUpdatePlatformDialogParams } from './interfaces/interfaces';
|
||||
styleUrls: ['./create-or-update-platform-dialog.scss'],
|
||||
templateUrl: 'create-or-update-platform-dialog.html'
|
||||
})
|
||||
export class CreateOrUpdatePlatformDialog {
|
||||
export class CreateOrUpdatePlatformDialog implements OnDestroy {
|
||||
public platformForm: FormGroup;
|
||||
|
||||
private unsubscribeSubject = new Subject<void>();
|
||||
|
||||
public constructor(
|
||||
@Inject(MAT_DIALOG_DATA) public data: CreateOrUpdatePlatformDialogParams,
|
||||
public dialogRef: MatDialogRef<CreateOrUpdatePlatformDialog>
|
||||
) {}
|
||||
public dialogRef: MatDialogRef<CreateOrUpdatePlatformDialog>,
|
||||
private formBuilder: FormBuilder
|
||||
) {
|
||||
this.platformForm = this.formBuilder.group({
|
||||
name: [this.data.platform.name, Validators.required],
|
||||
url: [this.data.platform.url, Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
public onCancel() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
public async onSubmit() {
|
||||
try {
|
||||
const platform: CreatePlatformDto | UpdatePlatformDto = {
|
||||
name: this.platformForm.get('name')?.value,
|
||||
url: this.platformForm.get('url')?.value
|
||||
};
|
||||
|
||||
if (this.data.platform.id) {
|
||||
(platform as UpdatePlatformDto).id = this.data.platform.id;
|
||||
await validateObjectForForm({
|
||||
classDto: UpdatePlatformDto,
|
||||
form: this.platformForm,
|
||||
object: platform
|
||||
});
|
||||
} else {
|
||||
await validateObjectForForm({
|
||||
classDto: CreatePlatformDto,
|
||||
form: this.platformForm,
|
||||
object: platform
|
||||
});
|
||||
}
|
||||
|
||||
this.dialogRef.close(platform);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.unsubscribeSubject.next();
|
||||
this.unsubscribeSubject.complete();
|
||||
|
@ -1,17 +1,30 @@
|
||||
<form #addPlatformForm="ngForm" class="d-flex flex-column h-100">
|
||||
<form
|
||||
class="d-flex flex-column h-100"
|
||||
[formGroup]="platformForm"
|
||||
(keyup.enter)="platformForm.valid && onSubmit()"
|
||||
(ngSubmit)="onSubmit()"
|
||||
>
|
||||
<h1 *ngIf="data.platform.id" i18n mat-dialog-title>Update platform</h1>
|
||||
<h1 *ngIf="!data.platform.id" i18n mat-dialog-title>Add platform</h1>
|
||||
<div class="flex-grow-1 py-3" mat-dialog-content>
|
||||
<div>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Name</mat-label>
|
||||
<input matInput name="name" required [(ngModel)]="data.platform.name" />
|
||||
<input
|
||||
formControlName="name"
|
||||
matInput
|
||||
(keydown.enter)="$event.stopPropagation()"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Url</mat-label>
|
||||
<input matInput name="url" required [(ngModel)]="data.platform.url" />
|
||||
<input
|
||||
formControlName="url"
|
||||
matInput
|
||||
(keydown.enter)="$event.stopPropagation()"
|
||||
/>
|
||||
@if (data.platform.url) {
|
||||
<gf-asset-profile-icon
|
||||
class="mr-3"
|
||||
@ -23,12 +36,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="justify-content-end" mat-dialog-actions>
|
||||
<button i18n mat-button (click)="onCancel()">Cancel</button>
|
||||
<button i18n mat-button type="button" (click)="onCancel()">Cancel</button>
|
||||
<button
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
[disabled]="!addPlatformForm.form.valid"
|
||||
[mat-dialog-close]="data"
|
||||
type="submit"
|
||||
[disabled]="!platformForm.valid"
|
||||
>
|
||||
<ng-container i18n>Save</ng-container>
|
||||
</button>
|
||||
|
@ -142,9 +142,7 @@ export class AdminTagComponent implements OnInit, OnDestroy {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data) => {
|
||||
const tag: CreateTagDto = data?.tag;
|
||||
|
||||
.subscribe((tag: CreateTagDto | null) => {
|
||||
if (tag) {
|
||||
this.adminService
|
||||
.postTag(tag)
|
||||
@ -180,9 +178,7 @@ export class AdminTagComponent implements OnInit, OnDestroy {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data) => {
|
||||
const tag: UpdateTagDto = data?.tag;
|
||||
|
||||
.subscribe((tag: UpdateTagDto | null) => {
|
||||
if (tag) {
|
||||
this.adminService
|
||||
.putTag(tag)
|
||||
|
@ -1,4 +1,14 @@
|
||||
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
|
||||
import { CreateTagDto } from '@ghostfolio/api/app/tag/create-tag.dto';
|
||||
import { UpdateTagDto } from '@ghostfolio/api/app/tag/update-tag.dto';
|
||||
import { validateObjectForForm } from '@ghostfolio/client/util/form.util';
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Inject,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
@ -11,18 +21,52 @@ import { CreateOrUpdateTagDialogParams } from './interfaces/interfaces';
|
||||
styleUrls: ['./create-or-update-tag-dialog.scss'],
|
||||
templateUrl: 'create-or-update-tag-dialog.html'
|
||||
})
|
||||
export class CreateOrUpdateTagDialog {
|
||||
export class CreateOrUpdateTagDialog implements OnDestroy {
|
||||
public tagForm: FormGroup;
|
||||
|
||||
private unsubscribeSubject = new Subject<void>();
|
||||
|
||||
public constructor(
|
||||
@Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateTagDialogParams,
|
||||
public dialogRef: MatDialogRef<CreateOrUpdateTagDialog>
|
||||
) {}
|
||||
public dialogRef: MatDialogRef<CreateOrUpdateTagDialog>,
|
||||
private formBuilder: FormBuilder
|
||||
) {
|
||||
this.tagForm = this.formBuilder.group({
|
||||
name: [this.data.tag.name]
|
||||
});
|
||||
}
|
||||
|
||||
public onCancel() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
public async onSubmit() {
|
||||
try {
|
||||
const tag: CreateTagDto | UpdateTagDto = {
|
||||
name: this.tagForm.get('name')?.value
|
||||
};
|
||||
|
||||
if (this.data.tag.id) {
|
||||
(tag as UpdateTagDto).id = this.data.tag.id;
|
||||
await validateObjectForForm({
|
||||
classDto: UpdateTagDto,
|
||||
form: this.tagForm,
|
||||
object: tag
|
||||
});
|
||||
} else {
|
||||
await validateObjectForForm({
|
||||
classDto: CreateTagDto,
|
||||
form: this.tagForm,
|
||||
object: tag
|
||||
});
|
||||
}
|
||||
|
||||
this.dialogRef.close(tag);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.unsubscribeSubject.next();
|
||||
this.unsubscribeSubject.complete();
|
||||
|
@ -1,21 +1,30 @@
|
||||
<form #addTagForm="ngForm" class="d-flex flex-column h-100">
|
||||
<form
|
||||
class="d-flex flex-column h-100"
|
||||
[formGroup]="tagForm"
|
||||
(keyup.enter)="tagForm.valid && onSubmit()"
|
||||
(ngSubmit)="onSubmit()"
|
||||
>
|
||||
<h1 *ngIf="data.tag.id" i18n mat-dialog-title>Update tag</h1>
|
||||
<h1 *ngIf="!data.tag.id" i18n mat-dialog-title>Add tag</h1>
|
||||
<div class="flex-grow-1 py-3" mat-dialog-content>
|
||||
<div>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Name</mat-label>
|
||||
<input matInput name="name" required [(ngModel)]="data.tag.name" />
|
||||
<input
|
||||
formControlName="name"
|
||||
matInput
|
||||
(keydown.enter)="$event.stopPropagation()"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="justify-content-end" mat-dialog-actions>
|
||||
<button i18n mat-button (click)="onCancel()">Cancel</button>
|
||||
<button i18n mat-button type="button" (click)="onCancel()">Cancel</button>
|
||||
<button
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
[disabled]="!addTagForm.form.valid"
|
||||
[mat-dialog-close]="data"
|
||||
type="submit"
|
||||
[disabled]="!tagForm.valid"
|
||||
>
|
||||
<ng-container i18n>Save</ng-container>
|
||||
</button>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { validateObjectForForm } from '@ghostfolio/client/util/form.util';
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
@ -40,22 +41,22 @@ export class CreateOrUpdateAccessDialog implements OnDestroy {
|
||||
alias: [this.data.access.alias],
|
||||
permissions: [this.data.access.permissions[0], Validators.required],
|
||||
type: [this.data.access.type, Validators.required],
|
||||
userId: [this.data.access.grantee, Validators.required]
|
||||
granteeUserId: [this.data.access.grantee, Validators.required]
|
||||
});
|
||||
|
||||
this.accessForm.get('type').valueChanges.subscribe((accessType) => {
|
||||
const granteeUserIdControl = this.accessForm.get('granteeUserId');
|
||||
const permissionsControl = this.accessForm.get('permissions');
|
||||
const userIdControl = this.accessForm.get('userId');
|
||||
|
||||
if (accessType === 'PRIVATE') {
|
||||
granteeUserIdControl.setValidators(Validators.required);
|
||||
permissionsControl.setValidators(Validators.required);
|
||||
userIdControl.setValidators(Validators.required);
|
||||
} else {
|
||||
userIdControl.clearValidators();
|
||||
granteeUserIdControl.clearValidators();
|
||||
}
|
||||
|
||||
granteeUserIdControl.updateValueAndValidity();
|
||||
permissionsControl.updateValueAndValidity();
|
||||
userIdControl.updateValueAndValidity();
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
@ -65,28 +66,38 @@ export class CreateOrUpdateAccessDialog implements OnDestroy {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
public onSubmit() {
|
||||
public async onSubmit() {
|
||||
const access: CreateAccessDto = {
|
||||
alias: this.accessForm.controls['alias'].value,
|
||||
granteeUserId: this.accessForm.controls['userId'].value,
|
||||
permissions: [this.accessForm.controls['permissions'].value]
|
||||
alias: this.accessForm.get('alias').value,
|
||||
granteeUserId: this.accessForm.get('granteeUserId').value,
|
||||
permissions: [this.accessForm.get('permissions').value]
|
||||
};
|
||||
|
||||
this.dataService
|
||||
.postAccess(access)
|
||||
.pipe(
|
||||
catchError((error) => {
|
||||
if (error.status === StatusCodes.BAD_REQUEST) {
|
||||
alert($localize`Oops! Could not grant access.`);
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
}),
|
||||
takeUntil(this.unsubscribeSubject)
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.dialogRef.close({ access });
|
||||
try {
|
||||
await validateObjectForForm({
|
||||
classDto: CreateAccessDto,
|
||||
form: this.accessForm,
|
||||
object: access
|
||||
});
|
||||
|
||||
this.dataService
|
||||
.postAccess(access)
|
||||
.pipe(
|
||||
catchError((error) => {
|
||||
if (error.status === StatusCodes.BAD_REQUEST) {
|
||||
alert($localize`Oops! Could not grant access.`);
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
}),
|
||||
takeUntil(this.unsubscribeSubject)
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.dialogRef.close(access);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
|
@ -27,7 +27,7 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
@if (accessForm.controls['type'].value === 'PRIVATE') {
|
||||
@if (accessForm.get('type').value === 'PRIVATE') {
|
||||
<div>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Permission</mat-label>
|
||||
@ -45,7 +45,7 @@
|
||||
Ghostfolio <ng-container i18n>User ID</ng-container>
|
||||
</mat-label>
|
||||
<input
|
||||
formControlName="userId"
|
||||
formControlName="granteeUserId"
|
||||
matInput
|
||||
type="text"
|
||||
(keydown.enter)="$event.stopPropagation()"
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto';
|
||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||
import { UserService } from '@ghostfolio/client/services/user/user.service';
|
||||
import { Access, User } from '@ghostfolio/common/interfaces';
|
||||
@ -113,7 +114,7 @@ export class UserAccountAccessComponent implements OnDestroy, OnInit {
|
||||
width: this.deviceType === 'mobile' ? '100vw' : '50rem'
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((access) => {
|
||||
dialogRef.afterClosed().subscribe((access: CreateAccessDto | null) => {
|
||||
if (access) {
|
||||
this.update();
|
||||
}
|
||||
|
@ -54,9 +54,10 @@ export class AuthGuard {
|
||||
this.router.navigate(['/' + $localize`register`]);
|
||||
resolve(false);
|
||||
} else if (
|
||||
AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) =>
|
||||
state.url.startsWith(publicPageRoute)
|
||||
)?.length > 0
|
||||
AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) => {
|
||||
const [, url] = state.url.split('/');
|
||||
return `/${url}` === publicPageRoute;
|
||||
})?.length > 0
|
||||
) {
|
||||
resolve(true);
|
||||
return EMPTY;
|
||||
|
@ -189,9 +189,7 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data: any) => {
|
||||
const account: UpdateAccountDto = data?.account;
|
||||
|
||||
.subscribe((account: UpdateAccountDto | null) => {
|
||||
if (account) {
|
||||
this.dataService
|
||||
.putAccount(account)
|
||||
@ -258,9 +256,7 @@ export class AccountsPageComponent implements OnDestroy, OnInit {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data: any) => {
|
||||
const account: CreateAccountDto = data?.account;
|
||||
|
||||
.subscribe((account: CreateAccountDto | null) => {
|
||||
if (account) {
|
||||
this.dataService
|
||||
.postAccount(account)
|
||||
|
@ -82,7 +82,7 @@ export class CreateOrUpdateAccountDialog implements OnDestroy {
|
||||
}
|
||||
|
||||
public autoCompleteCheck() {
|
||||
const inputValue = this.accountForm.controls['platformId'].value;
|
||||
const inputValue = this.accountForm.get('platformId').value;
|
||||
|
||||
if (typeof inputValue === 'string') {
|
||||
const matchingEntry = this.platforms.find(({ name }) => {
|
||||
@ -90,7 +90,7 @@ export class CreateOrUpdateAccountDialog implements OnDestroy {
|
||||
});
|
||||
|
||||
if (matchingEntry) {
|
||||
this.accountForm.controls['platformId'].setValue(matchingEntry);
|
||||
this.accountForm.get('platformId').setValue(matchingEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,13 +105,13 @@ export class CreateOrUpdateAccountDialog implements OnDestroy {
|
||||
|
||||
public async onSubmit() {
|
||||
const account: CreateAccountDto | UpdateAccountDto = {
|
||||
balance: this.accountForm.controls['balance'].value,
|
||||
comment: this.accountForm.controls['comment'].value,
|
||||
currency: this.accountForm.controls['currency'].value?.value,
|
||||
id: this.accountForm.controls['accountId'].value,
|
||||
isExcluded: this.accountForm.controls['isExcluded'].value,
|
||||
name: this.accountForm.controls['name'].value,
|
||||
platformId: this.accountForm.controls['platformId'].value?.id ?? null
|
||||
balance: this.accountForm.get('balance').value,
|
||||
comment: this.accountForm.get('comment').value || null,
|
||||
currency: this.accountForm.get('currency').value?.value,
|
||||
id: this.accountForm.get('accountId').value,
|
||||
isExcluded: this.accountForm.get('isExcluded').value,
|
||||
name: this.accountForm.get('name').value,
|
||||
platformId: this.accountForm.get('platformId').value?.id || null
|
||||
};
|
||||
|
||||
try {
|
||||
@ -123,6 +123,8 @@ export class CreateOrUpdateAccountDialog implements OnDestroy {
|
||||
form: this.accountForm,
|
||||
object: account
|
||||
});
|
||||
|
||||
this.dialogRef.close(account as UpdateAccountDto);
|
||||
} else {
|
||||
delete (account as CreateAccountDto).id;
|
||||
|
||||
@ -131,9 +133,9 @@ export class CreateOrUpdateAccountDialog implements OnDestroy {
|
||||
form: this.accountForm,
|
||||
object: account
|
||||
});
|
||||
}
|
||||
|
||||
this.dialogRef.close({ account });
|
||||
this.dialogRef.close(account as CreateAccountDto);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
(keydown.enter)="$event.stopPropagation()"
|
||||
/>
|
||||
<span class="ml-2" matTextSuffix>{{
|
||||
accountForm.controls['currency']?.value?.value
|
||||
accountForm.get('currency')?.value?.value
|
||||
}}</span>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
@ -66,9 +66,9 @@ export class TransferBalanceDialog implements OnDestroy {
|
||||
|
||||
public onSubmit() {
|
||||
const account: TransferBalanceDto = {
|
||||
accountIdFrom: this.transferBalanceForm.controls['fromAccount'].value,
|
||||
accountIdTo: this.transferBalanceForm.controls['toAccount'].value,
|
||||
balance: this.transferBalanceForm.controls['balance'].value
|
||||
accountIdFrom: this.transferBalanceForm.get('fromAccount').value,
|
||||
accountIdTo: this.transferBalanceForm.get('toAccount').value,
|
||||
balance: this.transferBalanceForm.get('balance').value
|
||||
};
|
||||
|
||||
this.dialogRef.close({ account });
|
||||
|
@ -118,6 +118,25 @@
|
||||
providers are considered experimental.</mat-card-content
|
||||
>
|
||||
</mat-card>
|
||||
<mat-card appearance="outlined" class="mb-3">
|
||||
<mat-card-header>
|
||||
<mat-card-title>How do I add a custom asset?</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>
|
||||
If you want to track an asset that is not available from any data
|
||||
provider, you can create a custom asset as follows.
|
||||
</p>
|
||||
<ol>
|
||||
<li>Go to the <i>Admin Control</i> panel</li>
|
||||
<li>Go to the <i>Market Data</i> section</li>
|
||||
<li>Create an asset profile</li>
|
||||
<li>Select <i>Add Manually</i> and enter a unique symbol</li>
|
||||
<li>Edit your asset profile</li>
|
||||
<li>Add a new activity by searching for the symbol</li>
|
||||
</ol>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<mat-card appearance="outlined" class="mb-3">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Which devices are supported?</mat-card-title>
|
||||
|
@ -287,9 +287,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data: any) => {
|
||||
const transaction: UpdateOrderDto = data?.activity;
|
||||
|
||||
.subscribe((transaction: UpdateOrderDto | null) => {
|
||||
if (transaction) {
|
||||
this.dataService
|
||||
.putOrder(transaction)
|
||||
@ -338,9 +336,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit {
|
||||
dialogRef
|
||||
.afterClosed()
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((data: any) => {
|
||||
const transaction: CreateOrderDto = data?.activity;
|
||||
|
||||
.subscribe((transaction: CreateOrderDto | null) => {
|
||||
if (transaction) {
|
||||
this.dataService.postOrder(transaction).subscribe({
|
||||
next: () => {
|
||||
|
@ -148,13 +148,14 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
.subscribe(async () => {
|
||||
let exchangeRateOfUnitPrice = 1;
|
||||
|
||||
this.activityForm.controls['feeInCustomCurrency'].setErrors(null);
|
||||
this.activityForm.controls['unitPriceInCustomCurrency'].setErrors(null);
|
||||
this.activityForm.get('feeInCustomCurrency').setErrors(null);
|
||||
this.activityForm.get('unitPriceInCustomCurrency').setErrors(null);
|
||||
|
||||
const currency = this.activityForm.controls['currency'].value;
|
||||
const currencyOfUnitPrice =
|
||||
this.activityForm.controls['currencyOfUnitPrice'].value;
|
||||
const date = this.activityForm.controls['date'].value;
|
||||
const currency = this.activityForm.get('currency').value;
|
||||
const currencyOfUnitPrice = this.activityForm.get(
|
||||
'currencyOfUnitPrice'
|
||||
).value;
|
||||
const date = this.activityForm.get('date').value;
|
||||
|
||||
if (
|
||||
currency &&
|
||||
@ -174,104 +175,97 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
|
||||
exchangeRateOfUnitPrice = marketPrice;
|
||||
} catch {
|
||||
this.activityForm.controls['unitPriceInCustomCurrency'].setErrors({
|
||||
this.activityForm.get('unitPriceInCustomCurrency').setErrors({
|
||||
invalid: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const feeInCustomCurrency =
|
||||
this.activityForm.controls['feeInCustomCurrency'].value *
|
||||
this.activityForm.get('feeInCustomCurrency').value *
|
||||
exchangeRateOfUnitPrice;
|
||||
|
||||
const unitPriceInCustomCurrency =
|
||||
this.activityForm.controls['unitPriceInCustomCurrency'].value *
|
||||
this.activityForm.get('unitPriceInCustomCurrency').value *
|
||||
exchangeRateOfUnitPrice;
|
||||
|
||||
this.activityForm.controls['fee'].setValue(feeInCustomCurrency, {
|
||||
this.activityForm.get('fee').setValue(feeInCustomCurrency, {
|
||||
emitEvent: false
|
||||
});
|
||||
|
||||
this.activityForm.controls['unitPrice'].setValue(
|
||||
unitPriceInCustomCurrency,
|
||||
{
|
||||
emitEvent: false
|
||||
}
|
||||
);
|
||||
this.activityForm.get('unitPrice').setValue(unitPriceInCustomCurrency, {
|
||||
emitEvent: false
|
||||
});
|
||||
|
||||
if (
|
||||
this.activityForm.controls['type'].value === 'BUY' ||
|
||||
this.activityForm.controls['type'].value === 'FEE' ||
|
||||
this.activityForm.controls['type'].value === 'ITEM'
|
||||
this.activityForm.get('type').value === 'BUY' ||
|
||||
this.activityForm.get('type').value === 'FEE' ||
|
||||
this.activityForm.get('type').value === 'ITEM'
|
||||
) {
|
||||
this.total =
|
||||
this.activityForm.controls['quantity'].value *
|
||||
this.activityForm.controls['unitPrice'].value +
|
||||
this.activityForm.controls['fee'].value ?? 0;
|
||||
this.activityForm.get('quantity').value *
|
||||
this.activityForm.get('unitPrice').value +
|
||||
this.activityForm.get('fee').value ?? 0;
|
||||
} else {
|
||||
this.total =
|
||||
this.activityForm.controls['quantity'].value *
|
||||
this.activityForm.controls['unitPrice'].value -
|
||||
this.activityForm.controls['fee'].value ?? 0;
|
||||
this.activityForm.get('quantity').value *
|
||||
this.activityForm.get('unitPrice').value -
|
||||
this.activityForm.get('fee').value ?? 0;
|
||||
}
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
||||
this.activityForm.controls['accountId'].valueChanges.subscribe(
|
||||
(accountId) => {
|
||||
const type = this.activityForm.controls['type'].value;
|
||||
this.activityForm.get('accountId').valueChanges.subscribe((accountId) => {
|
||||
const type = this.activityForm.get('type').value;
|
||||
|
||||
if (
|
||||
type === 'FEE' ||
|
||||
type === 'INTEREST' ||
|
||||
type === 'ITEM' ||
|
||||
type === 'LIABILITY'
|
||||
) {
|
||||
const currency =
|
||||
this.data.accounts.find(({ id }) => {
|
||||
return id === accountId;
|
||||
})?.currency ?? this.data.user.settings.baseCurrency;
|
||||
if (
|
||||
type === 'FEE' ||
|
||||
type === 'INTEREST' ||
|
||||
type === 'ITEM' ||
|
||||
type === 'LIABILITY'
|
||||
) {
|
||||
const currency =
|
||||
this.data.accounts.find(({ id }) => {
|
||||
return id === accountId;
|
||||
})?.currency ?? this.data.user.settings.baseCurrency;
|
||||
|
||||
this.activityForm.controls['currency'].setValue(currency);
|
||||
this.activityForm.controls['currencyOfUnitPrice'].setValue(currency);
|
||||
this.activityForm.get('currency').setValue(currency);
|
||||
this.activityForm.get('currencyOfUnitPrice').setValue(currency);
|
||||
|
||||
if (['FEE', 'INTEREST'].includes(type)) {
|
||||
if (this.activityForm.controls['accountId'].value) {
|
||||
this.activityForm.controls['updateAccountBalance'].enable();
|
||||
} else {
|
||||
this.activityForm.controls['updateAccountBalance'].disable();
|
||||
this.activityForm.controls['updateAccountBalance'].setValue(
|
||||
false
|
||||
);
|
||||
}
|
||||
if (['FEE', 'INTEREST'].includes(type)) {
|
||||
if (this.activityForm.get('accountId').value) {
|
||||
this.activityForm.get('updateAccountBalance').enable();
|
||||
} else {
|
||||
this.activityForm.get('updateAccountBalance').disable();
|
||||
this.activityForm.get('updateAccountBalance').setValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
this.activityForm.controls['date'].valueChanges.subscribe(() => {
|
||||
if (isToday(this.activityForm.controls['date'].value)) {
|
||||
this.activityForm.controls['updateAccountBalance'].enable();
|
||||
this.activityForm.get('date').valueChanges.subscribe(() => {
|
||||
if (isToday(this.activityForm.get('date').value)) {
|
||||
this.activityForm.get('updateAccountBalance').enable();
|
||||
} else {
|
||||
this.activityForm.controls['updateAccountBalance'].disable();
|
||||
this.activityForm.controls['updateAccountBalance'].setValue(false);
|
||||
this.activityForm.get('updateAccountBalance').disable();
|
||||
this.activityForm.get('updateAccountBalance').setValue(false);
|
||||
}
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
||||
this.activityForm.controls['searchSymbol'].valueChanges.subscribe(() => {
|
||||
if (this.activityForm.controls['searchSymbol'].invalid) {
|
||||
this.activityForm.get('searchSymbol').valueChanges.subscribe(() => {
|
||||
if (this.activityForm.get('searchSymbol').invalid) {
|
||||
this.data.activity.SymbolProfile = null;
|
||||
} else if (
|
||||
['BUY', 'DIVIDEND', 'SELL'].includes(
|
||||
this.activityForm.controls['type'].value
|
||||
this.activityForm.get('type').value
|
||||
)
|
||||
) {
|
||||
this.activityForm.controls['dataSource'].setValue(
|
||||
this.activityForm.controls['searchSymbol'].value.dataSource
|
||||
);
|
||||
this.activityForm
|
||||
.get('dataSource')
|
||||
.setValue(this.activityForm.get('searchSymbol').value.dataSource);
|
||||
|
||||
this.updateSymbol();
|
||||
}
|
||||
@ -282,130 +276,127 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
this.filteredTagsObservable = this.activityForm.controls[
|
||||
'tags'
|
||||
].valueChanges.pipe(
|
||||
startWith(this.activityForm.controls['tags'].value),
|
||||
startWith(this.activityForm.get('tags').value),
|
||||
map((aTags: Tag[] | null) => {
|
||||
return aTags ? this.filterTags(aTags) : this.tags.slice();
|
||||
})
|
||||
);
|
||||
|
||||
this.activityForm.controls['type'].valueChanges
|
||||
.pipe(takeUntil(this.unsubscribeSubject))
|
||||
this.activityForm
|
||||
.get('type')
|
||||
.valueChanges.pipe(takeUntil(this.unsubscribeSubject))
|
||||
.subscribe((type: Type) => {
|
||||
if (type === 'ITEM') {
|
||||
this.activityForm.controls['accountId'].removeValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['accountId'].updateValueAndValidity();
|
||||
this.activityForm
|
||||
.get('accountId')
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('accountId').updateValueAndValidity();
|
||||
|
||||
const currency =
|
||||
this.data.accounts.find(({ id }) => {
|
||||
return id === this.activityForm.controls['accountId'].value;
|
||||
return id === this.activityForm.get('accountId').value;
|
||||
})?.currency ?? this.data.user.settings.baseCurrency;
|
||||
|
||||
this.activityForm.controls['currency'].setValue(currency);
|
||||
this.activityForm.controls['currencyOfUnitPrice'].setValue(currency);
|
||||
this.activityForm.get('currency').setValue(currency);
|
||||
this.activityForm.get('currencyOfUnitPrice').setValue(currency);
|
||||
|
||||
this.activityForm.controls['dataSource'].removeValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['dataSource'].updateValueAndValidity();
|
||||
this.activityForm.controls['feeInCustomCurrency'].reset();
|
||||
this.activityForm.controls['name'].setValidators(Validators.required);
|
||||
this.activityForm.controls['name'].updateValueAndValidity();
|
||||
this.activityForm.controls['quantity'].setValue(1);
|
||||
this.activityForm.controls['searchSymbol'].removeValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['searchSymbol'].updateValueAndValidity();
|
||||
this.activityForm.controls['updateAccountBalance'].disable();
|
||||
this.activityForm.controls['updateAccountBalance'].setValue(false);
|
||||
this.activityForm
|
||||
.get('dataSource')
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('dataSource').updateValueAndValidity();
|
||||
this.activityForm.get('feeInCustomCurrency').reset();
|
||||
this.activityForm.get('name').setValidators(Validators.required);
|
||||
this.activityForm.get('name').updateValueAndValidity();
|
||||
this.activityForm.get('quantity').setValue(1);
|
||||
this.activityForm
|
||||
.get('searchSymbol')
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('searchSymbol').updateValueAndValidity();
|
||||
this.activityForm.get('updateAccountBalance').disable();
|
||||
this.activityForm.get('updateAccountBalance').setValue(false);
|
||||
} else if (
|
||||
type === 'FEE' ||
|
||||
type === 'INTEREST' ||
|
||||
type === 'LIABILITY'
|
||||
) {
|
||||
this.activityForm.controls['accountId'].removeValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['accountId'].updateValueAndValidity();
|
||||
this.activityForm
|
||||
.get('accountId')
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('accountId').updateValueAndValidity();
|
||||
|
||||
const currency =
|
||||
this.data.accounts.find(({ id }) => {
|
||||
return id === this.activityForm.controls['accountId'].value;
|
||||
return id === this.activityForm.get('accountId').value;
|
||||
})?.currency ?? this.data.user.settings.baseCurrency;
|
||||
|
||||
this.activityForm.controls['currency'].setValue(currency);
|
||||
this.activityForm.controls['currencyOfUnitPrice'].setValue(currency);
|
||||
this.activityForm.get('currency').setValue(currency);
|
||||
this.activityForm.get('currencyOfUnitPrice').setValue(currency);
|
||||
|
||||
this.activityForm.controls['dataSource'].removeValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['dataSource'].updateValueAndValidity();
|
||||
this.activityForm
|
||||
.get('dataSource')
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('dataSource').updateValueAndValidity();
|
||||
|
||||
if (
|
||||
(type === 'FEE' &&
|
||||
this.activityForm.controls['feeInCustomCurrency'].value === 0) ||
|
||||
this.activityForm.get('feeInCustomCurrency').value === 0) ||
|
||||
type === 'INTEREST' ||
|
||||
type === 'LIABILITY'
|
||||
) {
|
||||
this.activityForm.controls['feeInCustomCurrency'].reset();
|
||||
this.activityForm.get('feeInCustomCurrency').reset();
|
||||
}
|
||||
|
||||
this.activityForm.controls['name'].setValidators(Validators.required);
|
||||
this.activityForm.controls['name'].updateValueAndValidity();
|
||||
this.activityForm.get('name').setValidators(Validators.required);
|
||||
this.activityForm.get('name').updateValueAndValidity();
|
||||
|
||||
if (type === 'FEE') {
|
||||
this.activityForm.controls['quantity'].setValue(0);
|
||||
this.activityForm.get('quantity').setValue(0);
|
||||
} else if (type === 'INTEREST' || type === 'LIABILITY') {
|
||||
this.activityForm.controls['quantity'].setValue(1);
|
||||
this.activityForm.get('quantity').setValue(1);
|
||||
}
|
||||
|
||||
this.activityForm.controls['searchSymbol'].removeValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['searchSymbol'].updateValueAndValidity();
|
||||
this.activityForm
|
||||
.get('searchSymbol')
|
||||
.removeValidators(Validators.required);
|
||||
this.activityForm.get('searchSymbol').updateValueAndValidity();
|
||||
|
||||
if (type === 'FEE') {
|
||||
this.activityForm.controls['unitPriceInCustomCurrency'].setValue(0);
|
||||
this.activityForm.get('unitPriceInCustomCurrency').setValue(0);
|
||||
}
|
||||
|
||||
if (
|
||||
['FEE', 'INTEREST'].includes(type) &&
|
||||
this.activityForm.controls['accountId'].value
|
||||
this.activityForm.get('accountId').value
|
||||
) {
|
||||
this.activityForm.controls['updateAccountBalance'].enable();
|
||||
this.activityForm.get('updateAccountBalance').enable();
|
||||
} else {
|
||||
this.activityForm.controls['updateAccountBalance'].disable();
|
||||
this.activityForm.controls['updateAccountBalance'].setValue(false);
|
||||
this.activityForm.get('updateAccountBalance').disable();
|
||||
this.activityForm.get('updateAccountBalance').setValue(false);
|
||||
}
|
||||
} else {
|
||||
this.activityForm.controls['accountId'].setValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['accountId'].updateValueAndValidity();
|
||||
this.activityForm.controls['dataSource'].setValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['dataSource'].updateValueAndValidity();
|
||||
this.activityForm.controls['name'].removeValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['name'].updateValueAndValidity();
|
||||
this.activityForm.controls['searchSymbol'].setValidators(
|
||||
Validators.required
|
||||
);
|
||||
this.activityForm.controls['searchSymbol'].updateValueAndValidity();
|
||||
this.activityForm.controls['updateAccountBalance'].enable();
|
||||
this.activityForm.get('accountId').setValidators(Validators.required);
|
||||
this.activityForm.get('accountId').updateValueAndValidity();
|
||||
this.activityForm
|
||||
.get('dataSource')
|
||||
.setValidators(Validators.required);
|
||||
this.activityForm.get('dataSource').updateValueAndValidity();
|
||||
this.activityForm.get('name').removeValidators(Validators.required);
|
||||
this.activityForm.get('name').updateValueAndValidity();
|
||||
this.activityForm
|
||||
.get('searchSymbol')
|
||||
.setValidators(Validators.required);
|
||||
this.activityForm.get('searchSymbol').updateValueAndValidity();
|
||||
this.activityForm.get('updateAccountBalance').enable();
|
||||
}
|
||||
|
||||
this.changeDetectorRef.markForCheck();
|
||||
});
|
||||
|
||||
this.activityForm.controls['type'].setValue(this.data.activity?.type);
|
||||
this.activityForm.get('type').setValue(this.data.activity?.type);
|
||||
|
||||
if (this.data.activity?.id) {
|
||||
this.activityForm.controls['searchSymbol'].disable();
|
||||
this.activityForm.controls['type'].disable();
|
||||
this.activityForm.get('searchSymbol').disable();
|
||||
this.activityForm.get('type').disable();
|
||||
}
|
||||
|
||||
if (this.data.activity?.SymbolProfile?.symbol) {
|
||||
@ -425,14 +416,14 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
|
||||
public applyCurrentMarketPrice() {
|
||||
this.activityForm.patchValue({
|
||||
currencyOfUnitPrice: this.activityForm.controls['currency'].value,
|
||||
currencyOfUnitPrice: this.activityForm.get('currency').value,
|
||||
unitPriceInCustomCurrency: this.currentMarketPrice
|
||||
});
|
||||
}
|
||||
|
||||
public onAddTag(event: MatAutocompleteSelectedEvent) {
|
||||
this.activityForm.controls['tags'].setValue([
|
||||
...(this.activityForm.controls['tags'].value ?? []),
|
||||
this.activityForm.get('tags').setValue([
|
||||
...(this.activityForm.get('tags').value ?? []),
|
||||
this.tags.find(({ id }) => {
|
||||
return id === event.option.value;
|
||||
})
|
||||
@ -445,8 +436,8 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
}
|
||||
|
||||
public onRemoveTag(aTag: Tag) {
|
||||
this.activityForm.controls['tags'].setValue(
|
||||
this.activityForm.controls['tags'].value.filter(({ id }) => {
|
||||
this.activityForm.get('tags').setValue(
|
||||
this.activityForm.get('tags').value.filter(({ id }) => {
|
||||
return id !== aTag.id;
|
||||
})
|
||||
);
|
||||
@ -454,25 +445,24 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
|
||||
public async onSubmit() {
|
||||
const activity: CreateOrderDto | UpdateOrderDto = {
|
||||
accountId: this.activityForm.controls['accountId'].value,
|
||||
assetClass: this.activityForm.controls['assetClass'].value,
|
||||
assetSubClass: this.activityForm.controls['assetSubClass'].value,
|
||||
comment: this.activityForm.controls['comment'].value,
|
||||
currency: this.activityForm.controls['currency'].value,
|
||||
customCurrency: this.activityForm.controls['currencyOfUnitPrice'].value,
|
||||
date: this.activityForm.controls['date'].value,
|
||||
dataSource: this.activityForm.controls['dataSource'].value,
|
||||
fee: this.activityForm.controls['fee'].value,
|
||||
quantity: this.activityForm.controls['quantity'].value,
|
||||
accountId: this.activityForm.get('accountId').value,
|
||||
assetClass: this.activityForm.get('assetClass').value,
|
||||
assetSubClass: this.activityForm.get('assetSubClass').value,
|
||||
comment: this.activityForm.get('comment').value || null,
|
||||
currency: this.activityForm.get('currency').value,
|
||||
customCurrency: this.activityForm.get('currencyOfUnitPrice').value,
|
||||
date: this.activityForm.get('date').value,
|
||||
dataSource: this.activityForm.get('dataSource').value,
|
||||
fee: this.activityForm.get('fee').value,
|
||||
quantity: this.activityForm.get('quantity').value,
|
||||
symbol:
|
||||
this.activityForm.controls['searchSymbol'].value?.symbol ===
|
||||
undefined ||
|
||||
isUUID(this.activityForm.controls['searchSymbol'].value?.symbol)
|
||||
? this.activityForm.controls['name'].value
|
||||
: this.activityForm.controls['searchSymbol'].value.symbol,
|
||||
tags: this.activityForm.controls['tags'].value,
|
||||
type: this.activityForm.controls['type'].value,
|
||||
unitPrice: this.activityForm.controls['unitPrice'].value
|
||||
this.activityForm.get('searchSymbol').value?.symbol === undefined ||
|
||||
isUUID(this.activityForm.get('searchSymbol').value?.symbol)
|
||||
? this.activityForm.get('name').value
|
||||
: this.activityForm.get('searchSymbol').value.symbol,
|
||||
tags: this.activityForm.get('tags').value,
|
||||
type: this.activityForm.get('type').value,
|
||||
unitPrice: this.activityForm.get('unitPrice').value
|
||||
};
|
||||
|
||||
try {
|
||||
@ -485,9 +475,11 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
ignoreFields: ['dataSource', 'date'],
|
||||
object: activity as UpdateOrderDto
|
||||
});
|
||||
|
||||
this.dialogRef.close(activity as UpdateOrderDto);
|
||||
} else {
|
||||
(activity as CreateOrderDto).updateAccountBalance =
|
||||
this.activityForm.controls['updateAccountBalance'].value;
|
||||
this.activityForm.get('updateAccountBalance').value;
|
||||
|
||||
await validateObjectForForm({
|
||||
classDto: CreateOrderDto,
|
||||
@ -495,9 +487,9 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
ignoreFields: ['dataSource', 'date'],
|
||||
object: activity
|
||||
});
|
||||
}
|
||||
|
||||
this.dialogRef.close({ activity });
|
||||
this.dialogRef.close(activity as CreateOrderDto);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
@ -524,8 +516,8 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
|
||||
this.dataService
|
||||
.fetchSymbolItem({
|
||||
dataSource: this.activityForm.controls['dataSource'].value,
|
||||
symbol: this.activityForm.controls['searchSymbol'].value.symbol
|
||||
dataSource: this.activityForm.get('dataSource').value,
|
||||
symbol: this.activityForm.get('searchSymbol').value.symbol
|
||||
})
|
||||
.pipe(
|
||||
catchError(() => {
|
||||
@ -540,9 +532,9 @@ export class CreateOrUpdateActivityDialog implements OnDestroy {
|
||||
takeUntil(this.unsubscribeSubject)
|
||||
)
|
||||
.subscribe(({ currency, dataSource, marketPrice }) => {
|
||||
this.activityForm.controls['currency'].setValue(currency);
|
||||
this.activityForm.controls['currencyOfUnitPrice'].setValue(currency);
|
||||
this.activityForm.controls['dataSource'].setValue(dataSource);
|
||||
this.activityForm.get('currency').setValue(currency);
|
||||
this.activityForm.get('currencyOfUnitPrice').setValue(currency);
|
||||
this.activityForm.get('dataSource').setValue(dataSource);
|
||||
|
||||
this.currentMarketPrice = marketPrice;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
<mat-label i18n>Type</mat-label>
|
||||
<mat-select formControlName="type">
|
||||
<mat-select-trigger>{{
|
||||
typesTranslationMap[activityForm.controls['type'].value]
|
||||
typesTranslationMap[activityForm.get('type').value]
|
||||
}}</mat-select-trigger>
|
||||
<mat-option value="BUY">
|
||||
<span
|
||||
@ -83,9 +83,7 @@
|
||||
<mat-select formControlName="accountId">
|
||||
<mat-option
|
||||
*ngIf="
|
||||
!activityForm.controls['accountId'].hasValidator(
|
||||
Validators.required
|
||||
)
|
||||
!activityForm.get('accountId').hasValidator(Validators.required)
|
||||
"
|
||||
[value]="null"
|
||||
/>
|
||||
@ -113,9 +111,9 @@
|
||||
<div
|
||||
class="mb-3"
|
||||
[ngClass]="{
|
||||
'd-none': !activityForm.controls['searchSymbol'].hasValidator(
|
||||
Validators.required
|
||||
)
|
||||
'd-none': !activityForm
|
||||
.get('searchSymbol')
|
||||
.hasValidator(Validators.required)
|
||||
}"
|
||||
>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
@ -129,9 +127,7 @@
|
||||
<div
|
||||
class="mb-3"
|
||||
[ngClass]="{
|
||||
'd-none': !activityForm.controls['name'].hasValidator(
|
||||
Validators.required
|
||||
)
|
||||
'd-none': !activityForm.get('name').hasValidator(Validators.required)
|
||||
}"
|
||||
>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
@ -173,10 +169,10 @@
|
||||
class="mb-3"
|
||||
[ngClass]="{
|
||||
'd-none':
|
||||
activityForm.controls['type']?.value === 'FEE' ||
|
||||
activityForm.controls['type']?.value === 'INTEREST' ||
|
||||
activityForm.controls['type']?.value === 'ITEM' ||
|
||||
activityForm.controls['type']?.value === 'LIABILITY'
|
||||
activityForm.get('type')?.value === 'FEE' ||
|
||||
activityForm.get('type')?.value === 'INTEREST' ||
|
||||
activityForm.get('type')?.value === 'ITEM' ||
|
||||
activityForm.get('type')?.value === 'LIABILITY'
|
||||
}"
|
||||
>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
@ -186,12 +182,12 @@
|
||||
</div>
|
||||
<div
|
||||
class="mb-3"
|
||||
[ngClass]="{ 'd-none': activityForm.controls['type']?.value === 'FEE' }"
|
||||
[ngClass]="{ 'd-none': activityForm.get('type')?.value === 'FEE' }"
|
||||
>
|
||||
<div class="align-items-start d-flex">
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label
|
||||
><ng-container [ngSwitch]="activityForm.controls['type']?.value">
|
||||
><ng-container [ngSwitch]="activityForm.get('type')?.value">
|
||||
<ng-container *ngSwitchCase="'DIVIDEND'" i18n
|
||||
>Dividend</ng-container
|
||||
>
|
||||
@ -211,7 +207,7 @@
|
||||
<div
|
||||
class="ml-2"
|
||||
matTextSuffix
|
||||
[ngClass]="{ 'd-none': !activityForm.controls['currency']?.value }"
|
||||
[ngClass]="{ 'd-none': !activityForm.get('currency')?.value }"
|
||||
>
|
||||
<mat-select formControlName="currencyOfUnitPrice">
|
||||
<mat-option
|
||||
@ -224,16 +220,14 @@
|
||||
</div>
|
||||
<mat-error
|
||||
*ngIf="
|
||||
activityForm.controls['unitPriceInCustomCurrency'].hasError(
|
||||
'invalid'
|
||||
)
|
||||
activityForm.get('unitPriceInCustomCurrency').hasError('invalid')
|
||||
"
|
||||
><ng-container i18n
|
||||
>Oops! Could not get the historical exchange rate
|
||||
from</ng-container
|
||||
>
|
||||
{{
|
||||
activityForm.controls['date']?.value | date: defaultDateFormat
|
||||
activityForm.get('date')?.value | date: defaultDateFormat
|
||||
}}</mat-error
|
||||
>
|
||||
</mat-form-field>
|
||||
@ -241,7 +235,7 @@
|
||||
*ngIf="
|
||||
currentMarketPrice &&
|
||||
(data.activity.type === 'BUY' || data.activity.type === 'SELL') &&
|
||||
isToday(activityForm.controls['date']?.value)
|
||||
isToday(activityForm.get('date')?.value)
|
||||
"
|
||||
class="ml-2 mt-1 no-min-width"
|
||||
mat-button
|
||||
@ -256,7 +250,7 @@
|
||||
<div class="d-none">
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label
|
||||
><ng-container [ngSwitch]="activityForm.controls['type']?.value">
|
||||
><ng-container [ngSwitch]="activityForm.get('type')?.value">
|
||||
<ng-container *ngSwitchCase="'DIVIDEND'" i18n
|
||||
>Dividend</ng-container
|
||||
>
|
||||
@ -269,7 +263,7 @@
|
||||
</mat-label>
|
||||
<input formControlName="unitPrice" matInput type="number" />
|
||||
<span class="ml-2" matTextSuffix>{{
|
||||
activityForm.controls['currency'].value
|
||||
activityForm.get('currency').value
|
||||
}}</span>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@ -277,9 +271,9 @@
|
||||
class="mb-3"
|
||||
[ngClass]="{
|
||||
'd-none':
|
||||
activityForm.controls['type']?.value === 'INTEREST' ||
|
||||
activityForm.controls['type']?.value === 'ITEM' ||
|
||||
activityForm.controls['type']?.value === 'LIABILITY'
|
||||
activityForm.get('type')?.value === 'INTEREST' ||
|
||||
activityForm.get('type')?.value === 'ITEM' ||
|
||||
activityForm.get('type')?.value === 'LIABILITY'
|
||||
}"
|
||||
>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
@ -288,19 +282,17 @@
|
||||
<div
|
||||
class="ml-2"
|
||||
matTextSuffix
|
||||
[ngClass]="{ 'd-none': !activityForm.controls['currency']?.value }"
|
||||
[ngClass]="{ 'd-none': !activityForm.get('currency')?.value }"
|
||||
>
|
||||
{{ activityForm.controls['currencyOfUnitPrice'].value }}
|
||||
{{ activityForm.get('currencyOfUnitPrice').value }}
|
||||
</div>
|
||||
<mat-error
|
||||
*ngIf="
|
||||
activityForm.controls['feeInCustomCurrency'].hasError('invalid')
|
||||
"
|
||||
*ngIf="activityForm.get('feeInCustomCurrency').hasError('invalid')"
|
||||
><ng-container i18n
|
||||
>Oops! Could not get the historical exchange rate from</ng-container
|
||||
>
|
||||
{{
|
||||
activityForm.controls['date']?.value | date: defaultDateFormat
|
||||
activityForm.get('date')?.value | date: defaultDateFormat
|
||||
}}</mat-error
|
||||
>
|
||||
</mat-form-field>
|
||||
@ -310,7 +302,7 @@
|
||||
<mat-label i18n>Fee</mat-label>
|
||||
<input formControlName="fee" matInput type="number" />
|
||||
<span class="ml-2" matTextSuffix>{{
|
||||
activityForm.controls['currency'].value
|
||||
activityForm.get('currency').value
|
||||
}}</span>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
@ -328,7 +320,7 @@
|
||||
</div>
|
||||
<div
|
||||
class="mb-3"
|
||||
[ngClass]="{ 'd-none': activityForm.controls['type']?.value !== 'ITEM' }"
|
||||
[ngClass]="{ 'd-none': activityForm.get('type')?.value !== 'ITEM' }"
|
||||
>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Asset Class</mat-label>
|
||||
@ -344,7 +336,7 @@
|
||||
</div>
|
||||
<div
|
||||
class="mb-3"
|
||||
[ngClass]="{ 'd-none': activityForm.controls['type']?.value !== 'ITEM' }"
|
||||
[ngClass]="{ 'd-none': activityForm.get('type')?.value !== 'ITEM' }"
|
||||
>
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Asset Sub Class</mat-label>
|
||||
@ -363,7 +355,7 @@
|
||||
<mat-label i18n>Tags</mat-label>
|
||||
<mat-chip-grid #tagsChipList>
|
||||
<mat-chip-row
|
||||
*ngFor="let tag of activityForm.controls['tags']?.value"
|
||||
*ngFor="let tag of activityForm.get('tags')?.value"
|
||||
matChipRemove
|
||||
[removable]="true"
|
||||
(removed)="onRemoveTag(tag)"
|
||||
@ -399,8 +391,7 @@
|
||||
[isCurrency]="true"
|
||||
[locale]="data.user?.settings?.locale"
|
||||
[unit]="
|
||||
activityForm.controls['currency']?.value ??
|
||||
data.user?.settings?.baseCurrency
|
||||
activityForm.get('currency')?.value ?? data.user?.settings?.baseCurrency
|
||||
"
|
||||
[value]="total"
|
||||
/>
|
||||
|
@ -85,7 +85,7 @@ export class ImportActivitiesDialog implements OnDestroy {
|
||||
|
||||
this.dialogTitle = $localize`Import Dividends`;
|
||||
this.mode = 'DIVIDEND';
|
||||
this.uniqueAssetForm.controls['uniqueAsset'].disable();
|
||||
this.uniqueAssetForm.get('uniqueAsset').disable();
|
||||
|
||||
this.dataService
|
||||
.fetchPositions({
|
||||
@ -102,7 +102,7 @@ export class ImportActivitiesDialog implements OnDestroy {
|
||||
this.holdings = sortBy(positions, ({ name }) => {
|
||||
return name.toLowerCase();
|
||||
});
|
||||
this.uniqueAssetForm.controls['uniqueAsset'].enable();
|
||||
this.uniqueAssetForm.get('uniqueAsset').enable();
|
||||
|
||||
this.isLoading = false;
|
||||
|
||||
@ -167,10 +167,10 @@ export class ImportActivitiesDialog implements OnDestroy {
|
||||
}
|
||||
|
||||
public onLoadDividends(aStepper: MatStepper) {
|
||||
this.uniqueAssetForm.controls['uniqueAsset'].disable();
|
||||
this.uniqueAssetForm.get('uniqueAsset').disable();
|
||||
|
||||
const { dataSource, symbol } =
|
||||
this.uniqueAssetForm.controls['uniqueAsset'].value;
|
||||
this.uniqueAssetForm.get('uniqueAsset').value;
|
||||
|
||||
this.dataService
|
||||
.fetchDividendsImport({
|
||||
@ -193,7 +193,7 @@ export class ImportActivitiesDialog implements OnDestroy {
|
||||
this.details = [];
|
||||
this.errorMessages = [];
|
||||
this.importStep = ImportStep.SELECT_ACTIVITIES;
|
||||
this.uniqueAssetForm.controls['uniqueAsset'].enable();
|
||||
this.uniqueAssetForm.get('uniqueAsset').enable();
|
||||
|
||||
aStepper.reset();
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
<mat-label i18n>Holding</mat-label>
|
||||
<mat-select formControlName="uniqueAsset">
|
||||
<mat-select-trigger>{{
|
||||
uniqueAssetForm.controls['uniqueAsset']?.value?.name
|
||||
uniqueAssetForm.get('uniqueAsset')?.value?.name
|
||||
}}</mat-select-trigger>
|
||||
<mat-option
|
||||
*ngFor="let holding of holdings"
|
||||
|
@ -348,8 +348,8 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
|
||||
name: position.name
|
||||
};
|
||||
|
||||
if (position.assetClass !== AssetClass.CASH) {
|
||||
// Prepare analysis data by continents, countries and sectors except for cash
|
||||
if (position.assetClass !== AssetClass.LIQUIDITY) {
|
||||
// Prepare analysis data by continents, countries and sectors except for liquidity
|
||||
|
||||
if (position.countries.length > 0) {
|
||||
this.markets.developedMarkets.value +=
|
||||
|
@ -32,6 +32,14 @@ export async function validateObjectForForm<T>({
|
||||
validationError: Object.values(constraints)[0]
|
||||
});
|
||||
}
|
||||
|
||||
const formControlInCustomCurrency = form.get(`${property}InCustomCurrency`);
|
||||
|
||||
if (formControlInCustomCurrency) {
|
||||
formControlInCustomCurrency.setErrors({
|
||||
validationError: Object.values(constraints)[0]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(nonIgnoredErrors);
|
||||
|
@ -1266,7 +1266,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -3036,7 +3036,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -3048,7 +3048,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4550487415324294802" datatype="html">
|
||||
@ -3252,7 +3252,7 @@
|
||||
<target state="translated">Immobilien</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -3260,7 +3260,7 @@
|
||||
<target state="translated">Anleihe</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -3268,7 +3268,7 @@
|
||||
<target state="translated">Kryptowährung</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -3276,7 +3276,7 @@
|
||||
<target state="translated">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -3284,7 +3284,7 @@
|
||||
<target state="translated">Investmentfonds</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -3292,7 +3292,7 @@
|
||||
<target state="translated">Edelmetall</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -3300,7 +3300,7 @@
|
||||
<target state="translated">Privates Beteiligungskapital</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -3308,7 +3308,7 @@
|
||||
<target state="translated">Aktie</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6268646680388419543" datatype="html">
|
||||
@ -3348,7 +3348,7 @@
|
||||
<target state="translated">Nordamerika</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -3356,7 +3356,7 @@
|
||||
<target state="translated">Afrika</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -3364,7 +3364,7 @@
|
||||
<target state="translated">Asien</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -3372,7 +3372,7 @@
|
||||
<target state="translated">Europa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -3380,7 +3380,7 @@
|
||||
<target state="translated">Ozeanien</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -3388,7 +3388,7 @@
|
||||
<target state="translated">Südamerika</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6f9fd3da06dc9000eef0d4dcbb37747b303048e9" datatype="html">
|
||||
@ -10076,7 +10076,7 @@
|
||||
<target state="translated">Sterne auf GitHub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10088,7 +10088,7 @@
|
||||
<target state="translated">Downloads auf Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10188,7 +10188,7 @@
|
||||
<target state="translated"> Verwalte dein Vermögen wie ein Profi </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -10196,7 +10196,7 @@
|
||||
<target state="translated"> Ghostfolio ist ein Open Source Dashboard für deine persönlichen Finanzen mit Fokus auf Datenschutz. Analysiere deine Vermögensverteilung, ermittle dein Nettovermögen und treffe fundierte, datengestützte Investitionsentscheidungen. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -10204,11 +10204,11 @@
|
||||
<target state="translated"> Jetzt loslegen </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -10216,7 +10216,7 @@
|
||||
<target state="translated"> oder </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -10224,7 +10224,7 @@
|
||||
<target state="translated">Monatlich aktive Nutzer</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9c7ee452b83c7458f6ffdd49837daf95b1d5f34e" datatype="html">
|
||||
@ -10232,7 +10232,7 @@
|
||||
<target state="translated">Bekannt aus</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -10240,7 +10240,7 @@
|
||||
<target state="translated"> Schützen Sie Ihr <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Vermögen<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Optimieren Sie Ihre <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>persönliche Anlagestrategie<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -10248,7 +10248,7 @@
|
||||
<target state="translated"> Ghostfolio ermöglicht es geschäftigen Leuten, den Überblick über Aktien, ETFs oder Kryptowährungen zu behalten, ohne überwacht zu werden. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -10256,7 +10256,7 @@
|
||||
<target state="translated">360° Ansicht</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -10264,7 +10264,7 @@
|
||||
<target state="translated">Web3 ready</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -10272,7 +10272,7 @@
|
||||
<target state="translated"> Nutze Ghostfolio ganz anonym und behalte deine Finanzdaten. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -10280,7 +10280,7 @@
|
||||
<target state="translated">Open Source</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -10288,7 +10288,7 @@
|
||||
<target state="translated"> Profitiere von kontinuierlichen Verbesserungen durch eine aktive Community. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -10296,7 +10296,7 @@
|
||||
<target state="translated">Warum <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -10304,7 +10304,7 @@
|
||||
<target state="translated"> Ghostfolio ist für dich geeignet, wenn du... </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -10312,7 +10312,7 @@
|
||||
<target state="translated">Aktien, ETFs oder Kryptowährungen auf unterschiedlichen Plattformen handelst</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -10320,7 +10320,7 @@
|
||||
<target state="translated">eine Buy & Hold Strategie verfolgst</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -10328,7 +10328,7 @@
|
||||
<target state="translated">dich für die Zusammensetzung deines Portfolios interessierst</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -10336,7 +10336,7 @@
|
||||
<target state="translated">Privatsphäre und Datenhoheit wertschätzt</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -10344,7 +10344,7 @@
|
||||
<target state="translated">zum Frugalismus oder Minimalismus neigst</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -10352,7 +10352,7 @@
|
||||
<target state="translated">dich um die Diversifizierung deiner finanziellen Mittel kümmerst</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -10360,7 +10360,7 @@
|
||||
<target state="translated">Interesse an finanzieller Freiheit hast</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -10368,7 +10368,7 @@
|
||||
<target state="translated">Nein sagst zu Excel-Tabellen im Jahr <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -10376,7 +10376,7 @@
|
||||
<target state="translated">diese Liste bis zum Ende liest</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -10384,7 +10384,7 @@
|
||||
<target state="translated">Erfahre mehr über Ghostfolio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -10392,7 +10392,7 @@
|
||||
<target state="translated"> Was unsere <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Nutzer<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> sagen </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -10400,7 +10400,7 @@
|
||||
<target state="translated"> Nutzer aus aller Welt verwenden <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -10408,7 +10408,7 @@
|
||||
<target state="translated"> Wie funktioniert <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> ? </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -10416,7 +10416,7 @@
|
||||
<target state="translated">Registriere dich anonym*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -10424,7 +10424,7 @@
|
||||
<target state="translated"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* Keine E-Mail-Adresse oder Kreditkarte erforderlich<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -10432,7 +10432,7 @@
|
||||
<target state="translated"> Füge historische Transaktionen hinzu </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -10440,7 +10440,7 @@
|
||||
<target state="translated"> Erhalte nützliche Erkenntnisse über die Zusammensetzung deines Portfolios </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -10448,7 +10448,7 @@
|
||||
<target state="translated">Bist <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>du<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> bereit?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -10456,7 +10456,7 @@
|
||||
<target state="translated"> Melde dich jetzt an <x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> oder probiere die Live Demo aus<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -10464,11 +10464,11 @@
|
||||
<target state="translated">Live Demo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -10476,7 +10476,7 @@
|
||||
<target state="translated"> Verschaffe dir einen vollständigen Überblick deiner persönlichen Finanzen über mehrere Plattformen hinweg. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -10484,7 +10484,7 @@
|
||||
<target state="translated">Beginne mit nur 3 Schritten</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4656883433287439415" datatype="html">
|
||||
@ -13199,14 +13199,6 @@
|
||||
<context context-type="linenumber">127</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="translated">Neu</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fc47ae80c47144eb6250979fe927a010da3aee5" datatype="html">
|
||||
<source>Choose or drop a file here</source>
|
||||
<target state="translated">Wählen Sie eine Datei aus oder ziehen Sie sie hierhin</target>
|
||||
@ -13744,7 +13736,7 @@
|
||||
<target state="translated">Ups, der Cash-Bestand Transfer ist fehlgeschlagen.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2356316679035829946" datatype="html">
|
||||
@ -13768,7 +13760,7 @@
|
||||
<target state="translated">Extreme Angst</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13776,7 +13768,7 @@
|
||||
<target state="translated">Extreme Gier</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13784,7 +13776,7 @@
|
||||
<target state="translated">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7183719827884539616" datatype="html">
|
||||
@ -15043,6 +15035,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="translated">Liquidität</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1267,7 +1267,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -3034,7 +3034,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -3046,7 +3046,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4550487415324294802" datatype="html">
|
||||
@ -3250,7 +3250,7 @@
|
||||
<target state="translated">Propiedad inmobiliaria</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -3258,7 +3258,7 @@
|
||||
<target state="translated">Bono</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -3266,7 +3266,7 @@
|
||||
<target state="translated">Criptomoneda</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -3274,7 +3274,7 @@
|
||||
<target state="translated">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -3282,7 +3282,7 @@
|
||||
<target state="translated">Fondo de inversión</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -3290,7 +3290,7 @@
|
||||
<target state="translated">Metal precioso</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -3298,7 +3298,7 @@
|
||||
<target state="translated">Capital riesgo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -3306,7 +3306,7 @@
|
||||
<target state="translated">Acción</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6268646680388419543" datatype="html">
|
||||
@ -3346,7 +3346,7 @@
|
||||
<target state="translated">América del Norte</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -3354,7 +3354,7 @@
|
||||
<target state="translated">África</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -3362,7 +3362,7 @@
|
||||
<target state="translated">Asia</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -3370,7 +3370,7 @@
|
||||
<target state="translated">Europa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -3378,7 +3378,7 @@
|
||||
<target state="translated">Oceanía</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -3386,7 +3386,7 @@
|
||||
<target state="translated">América del Sur</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6f9fd3da06dc9000eef0d4dcbb37747b303048e9" datatype="html">
|
||||
@ -10074,7 +10074,7 @@
|
||||
<target state="new">Stars on GitHub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10086,7 +10086,7 @@
|
||||
<target state="new">Pulls on Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10186,7 +10186,7 @@
|
||||
<target state="new"> Manage your wealth like a boss </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -10194,7 +10194,7 @@
|
||||
<target state="new"> Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -10202,11 +10202,11 @@
|
||||
<target state="new"> Get Started </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -10214,7 +10214,7 @@
|
||||
<target state="new"> or </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -10222,7 +10222,7 @@
|
||||
<target state="new">Monthly Active Users</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9c7ee452b83c7458f6ffdd49837daf95b1d5f34e" datatype="html">
|
||||
@ -10230,7 +10230,7 @@
|
||||
<target state="new">As seen in</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -10238,7 +10238,7 @@
|
||||
<target state="new"> Protect your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>assets<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Refine your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>personal investment strategy<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -10246,7 +10246,7 @@
|
||||
<target state="new"> Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -10254,7 +10254,7 @@
|
||||
<target state="new">360° View</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -10262,7 +10262,7 @@
|
||||
<target state="new">Web3 Ready</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -10270,7 +10270,7 @@
|
||||
<target state="new"> Use Ghostfolio anonymously and own your financial data. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -10278,7 +10278,7 @@
|
||||
<target state="new">Open Source</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -10286,7 +10286,7 @@
|
||||
<target state="new"> Benefit from continuous improvements through a strong community. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -10294,7 +10294,7 @@
|
||||
<target state="new">Why <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -10302,7 +10302,7 @@
|
||||
<target state="new"> Ghostfolio is for you if you are... </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -10310,7 +10310,7 @@
|
||||
<target state="new">trading stocks, ETFs or cryptocurrencies on multiple platforms</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -10318,7 +10318,7 @@
|
||||
<target state="new">pursuing a buy & hold strategy</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -10326,7 +10326,7 @@
|
||||
<target state="new">interested in getting insights of your portfolio composition</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -10334,7 +10334,7 @@
|
||||
<target state="new">valuing privacy and data ownership</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -10342,7 +10342,7 @@
|
||||
<target state="new">into minimalism</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -10350,7 +10350,7 @@
|
||||
<target state="new">caring about diversifying your financial resources</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -10358,7 +10358,7 @@
|
||||
<target state="new">interested in financial independence</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -10366,7 +10366,7 @@
|
||||
<target state="new">saying no to spreadsheets in <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -10374,7 +10374,7 @@
|
||||
<target state="new">still reading this list</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -10382,7 +10382,7 @@
|
||||
<target state="new">Learn more about Ghostfolio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -10390,7 +10390,7 @@
|
||||
<target state="new"> What our <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>users<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> are saying </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -10398,7 +10398,7 @@
|
||||
<target state="new"> Members from around the globe are using <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -10406,7 +10406,7 @@
|
||||
<target state="new"> How does <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> work? </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -10414,7 +10414,7 @@
|
||||
<target state="new">Sign up anonymously*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -10422,7 +10422,7 @@
|
||||
<target state="new"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* no e-mail address nor credit card required<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -10430,7 +10430,7 @@
|
||||
<target state="new"> Add any of your historical transactions </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -10438,7 +10438,7 @@
|
||||
<target state="new"> Get valuable insights of your portfolio composition </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -10446,7 +10446,7 @@
|
||||
<target state="new">Are <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>you<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> ready?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -10454,7 +10454,7 @@
|
||||
<target state="new"> Join now<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> or check out the example account<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -10462,11 +10462,11 @@
|
||||
<target state="new">Live Demo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -10474,7 +10474,7 @@
|
||||
<target state="new"> Get the full picture of your personal finances across multiple platforms. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -10482,7 +10482,7 @@
|
||||
<target state="new">Get started in only 3 steps</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4656883433287439415" datatype="html">
|
||||
@ -13197,14 +13197,6 @@
|
||||
<context context-type="linenumber">127</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="new">New</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fc47ae80c47144eb6250979fe927a010da3aee5" datatype="html">
|
||||
<source>Choose or drop a file here</source>
|
||||
<target state="new">Choose or drop a file here</target>
|
||||
@ -13742,7 +13734,7 @@
|
||||
<target state="new">Oops, cash balance transfer has failed.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2356316679035829946" datatype="html">
|
||||
@ -13766,7 +13758,7 @@
|
||||
<target state="new">Extreme Fear</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13774,7 +13766,7 @@
|
||||
<target state="new">Extreme Greed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13782,7 +13774,7 @@
|
||||
<target state="new">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7183719827884539616" datatype="html">
|
||||
@ -15041,6 +15033,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1550,7 +1550,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -1562,7 +1562,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ce718ababbce63d776cf8b1f91412beb4c0a6e04" datatype="html">
|
||||
@ -1642,7 +1642,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -3445,7 +3445,7 @@
|
||||
<target state="translated">Immobilier</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -3453,7 +3453,7 @@
|
||||
<target state="translated">Obligation</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -3461,7 +3461,7 @@
|
||||
<target state="translated">Cryptomonnaie</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -3469,7 +3469,7 @@
|
||||
<target state="translated">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -3477,7 +3477,7 @@
|
||||
<target state="translated">SICAV</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -3485,7 +3485,7 @@
|
||||
<target state="translated">Métal Précieux</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -3493,7 +3493,7 @@
|
||||
<target state="translated">Capital Propre</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -3501,7 +3501,7 @@
|
||||
<target state="translated">Action</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -3509,7 +3509,7 @@
|
||||
<target state="translated">Afrique</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -3517,7 +3517,7 @@
|
||||
<target state="translated">Asie</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -3525,7 +3525,7 @@
|
||||
<target state="translated">Europe</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1228771048078164312" datatype="html">
|
||||
@ -3533,7 +3533,7 @@
|
||||
<target state="translated">Amérique du Nord</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -3541,7 +3541,7 @@
|
||||
<target state="translated">Océanie</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -3549,7 +3549,7 @@
|
||||
<target state="translated">Amérique du Sud</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c004f99bac91f7dc28e87d458f80e5035ae99884" datatype="html">
|
||||
@ -10073,7 +10073,7 @@
|
||||
<target state="new">Stars on GitHub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10085,7 +10085,7 @@
|
||||
<target state="new">Pulls on Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10185,7 +10185,7 @@
|
||||
<target state="new"> Manage your wealth like a boss </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -10193,7 +10193,7 @@
|
||||
<target state="new"> Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -10201,11 +10201,11 @@
|
||||
<target state="new"> Get Started </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -10213,7 +10213,7 @@
|
||||
<target state="new"> or </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -10221,7 +10221,7 @@
|
||||
<target state="new">Monthly Active Users</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9c7ee452b83c7458f6ffdd49837daf95b1d5f34e" datatype="html">
|
||||
@ -10229,7 +10229,7 @@
|
||||
<target state="new">As seen in</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -10237,7 +10237,7 @@
|
||||
<target state="new"> Protect your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>assets<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Refine your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>personal investment strategy<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -10245,7 +10245,7 @@
|
||||
<target state="new"> Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -10253,7 +10253,7 @@
|
||||
<target state="new">360° View</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -10261,7 +10261,7 @@
|
||||
<target state="new">Web3 Ready</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -10269,7 +10269,7 @@
|
||||
<target state="new"> Use Ghostfolio anonymously and own your financial data. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -10277,7 +10277,7 @@
|
||||
<target state="new">Open Source</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -10285,7 +10285,7 @@
|
||||
<target state="new"> Benefit from continuous improvements through a strong community. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -10293,7 +10293,7 @@
|
||||
<target state="new">Why <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -10301,7 +10301,7 @@
|
||||
<target state="new"> Ghostfolio is for you if you are... </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -10309,7 +10309,7 @@
|
||||
<target state="new">trading stocks, ETFs or cryptocurrencies on multiple platforms</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -10317,7 +10317,7 @@
|
||||
<target state="new">pursuing a buy & hold strategy</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -10325,7 +10325,7 @@
|
||||
<target state="new">interested in getting insights of your portfolio composition</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -10333,7 +10333,7 @@
|
||||
<target state="new">valuing privacy and data ownership</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -10341,7 +10341,7 @@
|
||||
<target state="new">into minimalism</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -10349,7 +10349,7 @@
|
||||
<target state="new">caring about diversifying your financial resources</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -10357,7 +10357,7 @@
|
||||
<target state="new">interested in financial independence</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -10365,7 +10365,7 @@
|
||||
<target state="new">saying no to spreadsheets in <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -10373,7 +10373,7 @@
|
||||
<target state="new">still reading this list</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -10381,7 +10381,7 @@
|
||||
<target state="new">Learn more about Ghostfolio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -10389,7 +10389,7 @@
|
||||
<target state="new"> What our <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>users<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> are saying </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -10397,7 +10397,7 @@
|
||||
<target state="new"> Members from around the globe are using <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -10405,7 +10405,7 @@
|
||||
<target state="new"> How does <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> work? </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -10413,7 +10413,7 @@
|
||||
<target state="new">Sign up anonymously*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -10421,7 +10421,7 @@
|
||||
<target state="new"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* no e-mail address nor credit card required<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -10429,7 +10429,7 @@
|
||||
<target state="new"> Add any of your historical transactions </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -10437,7 +10437,7 @@
|
||||
<target state="new"> Get valuable insights of your portfolio composition </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -10445,7 +10445,7 @@
|
||||
<target state="new">Are <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>you<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> ready?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -10453,7 +10453,7 @@
|
||||
<target state="new"> Join now<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> or check out the example account<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -10461,11 +10461,11 @@
|
||||
<target state="new">Live Demo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -10473,7 +10473,7 @@
|
||||
<target state="new"> Get the full picture of your personal finances across multiple platforms. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -10481,7 +10481,7 @@
|
||||
<target state="new">Get started in only 3 steps</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4656883433287439415" datatype="html">
|
||||
@ -13196,14 +13196,6 @@
|
||||
<context context-type="linenumber">127</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="new">New</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fc47ae80c47144eb6250979fe927a010da3aee5" datatype="html">
|
||||
<source>Choose or drop a file here</source>
|
||||
<target state="new">Choose or drop a file here</target>
|
||||
@ -13741,7 +13733,7 @@
|
||||
<target state="new">Oops, cash balance transfer has failed.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2356316679035829946" datatype="html">
|
||||
@ -13765,7 +13757,7 @@
|
||||
<target state="new">Extreme Fear</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13773,7 +13765,7 @@
|
||||
<target state="new">Extreme Greed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13781,7 +13773,7 @@
|
||||
<target state="new">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7183719827884539616" datatype="html">
|
||||
@ -15040,6 +15032,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1267,7 +1267,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -3034,7 +3034,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -3046,7 +3046,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4550487415324294802" datatype="html">
|
||||
@ -3250,7 +3250,7 @@
|
||||
<target state="translated">Immobiliare</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -3258,7 +3258,7 @@
|
||||
<target state="translated">Obbligazioni</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -3266,7 +3266,7 @@
|
||||
<target state="translated">Criptovaluta</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -3274,7 +3274,7 @@
|
||||
<target state="translated">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -3282,7 +3282,7 @@
|
||||
<target state="translated">Fondo comune di investimento</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -3290,7 +3290,7 @@
|
||||
<target state="translated">Metalli preziosi</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -3298,7 +3298,7 @@
|
||||
<target state="translated">Azione ordinaria privata</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -3306,7 +3306,7 @@
|
||||
<target state="translated">Azione</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6268646680388419543" datatype="html">
|
||||
@ -3346,7 +3346,7 @@
|
||||
<target state="translated">Nord America</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -3354,7 +3354,7 @@
|
||||
<target state="translated">Africa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -3362,7 +3362,7 @@
|
||||
<target state="translated">Asia</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -3370,7 +3370,7 @@
|
||||
<target state="translated">Europa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -3378,7 +3378,7 @@
|
||||
<target state="translated">Oceania</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -3386,7 +3386,7 @@
|
||||
<target state="translated">Sud America</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6f9fd3da06dc9000eef0d4dcbb37747b303048e9" datatype="html">
|
||||
@ -10074,7 +10074,7 @@
|
||||
<target state="translated">Stelle su GitHub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10086,7 +10086,7 @@
|
||||
<target state="translated">Estrazioni su Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10186,7 +10186,7 @@
|
||||
<target state="translated"> Gestisci la tua ricchezza come un capo </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -10194,7 +10194,7 @@
|
||||
<target state="translated"> Ghostfolio è uno strumento open source e rispettoso della privacy per la gestione delle tue finanze personali. Analizza la tua allocazione degli asset, conosci il tuo patrimonio netto e prendi decisioni di investimento solide e basate sui dati. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -10202,11 +10202,11 @@
|
||||
<target state="translated"> Inizia </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -10214,7 +10214,7 @@
|
||||
<target state="translated"> o </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -10222,7 +10222,7 @@
|
||||
<target state="translated">Utenti attivi mensili</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9c7ee452b83c7458f6ffdd49837daf95b1d5f34e" datatype="html">
|
||||
@ -10230,7 +10230,7 @@
|
||||
<target state="translated">Come si vede su</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -10238,7 +10238,7 @@
|
||||
<target state="translated"> Proteggi i tuoi <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>asset<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Perfeziona la tua <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>strategia di investimento personale<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -10246,7 +10246,7 @@
|
||||
<target state="translated"> Ghostfolio permette alle persone impegnate di tenere traccia di azioni, ETF o criptovalute senza essere tracciate. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -10254,7 +10254,7 @@
|
||||
<target state="translated">Vista a 360°</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -10262,7 +10262,7 @@
|
||||
<target state="translated">Pronto per il Web3</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -10270,7 +10270,7 @@
|
||||
<target state="translated"> Usa Ghostfolio in modo anonimo e possiedi i tuoi dati finanziari. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -10278,7 +10278,7 @@
|
||||
<target state="translated">Open source</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -10286,7 +10286,7 @@
|
||||
<target state="translated"> Beneficia dei continui miglioramenti grazie a una forte comunità. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -10294,7 +10294,7 @@
|
||||
<target state="translated">Perché <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -10302,7 +10302,7 @@
|
||||
<target state="translated"> Ghostfolio è per te se... </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -10310,7 +10310,7 @@
|
||||
<target state="translated">fai trading di azioni, ETF o criptovalute su più piattaforme</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -10318,7 +10318,7 @@
|
||||
<target state="translated">persegui una strategia buy & hold</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -10326,7 +10326,7 @@
|
||||
<target state="translated">sei interessato a conoscere la composizione del tuo portafoglio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -10334,7 +10334,7 @@
|
||||
<target state="translated">valorizzi la privacy e la proprietà dei dati</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -10342,7 +10342,7 @@
|
||||
<target state="translated">sei per il minimalismo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -10350,7 +10350,7 @@
|
||||
<target state="translated">ti interessa diversificare le tue risorse finanziarie</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -10358,7 +10358,7 @@
|
||||
<target state="translated">sei interessato all'indipendenza finanziaria</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -10366,7 +10366,7 @@
|
||||
<target state="translated">non vuoi utilizzare il foglio elettronico nel <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -10374,7 +10374,7 @@
|
||||
<target state="translated">stai ancora leggendo questo elenco</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -10382,7 +10382,7 @@
|
||||
<target state="translated">Ulteriori informazioni su Ghostfolio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -10390,7 +10390,7 @@
|
||||
<target state="translated"> Cosa dicono i nostri <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>utenti<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -10398,7 +10398,7 @@
|
||||
<target state="translated"> Membri da tutto il mondo utilizzano <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -10406,7 +10406,7 @@
|
||||
<target state="translated"> Come funziona <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -10414,7 +10414,7 @@
|
||||
<target state="translated">Iscriviti in modo anonimo*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -10422,7 +10422,7 @@
|
||||
<target state="translated"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* non è richiesto alcun indirizzo email né la carta di credito<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -10430,7 +10430,7 @@
|
||||
<target state="translated"> Aggiungi le tue transazioni storiche </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -10438,7 +10438,7 @@
|
||||
<target state="translated"> Ottieni informazioni preziose sulla composizione del tuo portafoglio </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -10446,7 +10446,7 @@
|
||||
<target state="translated"><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Sei<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>pronto?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -10454,7 +10454,7 @@
|
||||
<target state="translated"> Iscriviti adesso<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> o consulta l'account di esempio<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -10462,11 +10462,11 @@
|
||||
<target state="translated">Demo in tempo reale</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -10474,7 +10474,7 @@
|
||||
<target state="translated"> Ottieni un quadro completo delle tue finanze personali su più piattaforme. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -10482,7 +10482,7 @@
|
||||
<target state="translated">Inizia in soli 3 passi</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4656883433287439415" datatype="html">
|
||||
@ -13197,14 +13197,6 @@
|
||||
<context context-type="linenumber">127</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="new">Nuovo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fc47ae80c47144eb6250979fe927a010da3aee5" datatype="html">
|
||||
<source>Choose or drop a file here</source>
|
||||
<target state="new">Choose or drop a file here</target>
|
||||
@ -13742,7 +13734,7 @@
|
||||
<target state="new">Oops, cash balance transfer has failed.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2356316679035829946" datatype="html">
|
||||
@ -13766,7 +13758,7 @@
|
||||
<target state="new">Extreme Fear</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13774,7 +13766,7 @@
|
||||
<target state="new">Extreme Greed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13782,7 +13774,7 @@
|
||||
<target state="new">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7183719827884539616" datatype="html">
|
||||
@ -15041,6 +15033,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1266,7 +1266,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -3033,7 +3033,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -3045,7 +3045,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4550487415324294802" datatype="html">
|
||||
@ -3249,7 +3249,7 @@
|
||||
<target state="translated">Vastgoed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -3257,7 +3257,7 @@
|
||||
<target state="translated">Obligatie</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -3265,7 +3265,7 @@
|
||||
<target state="translated">Cryptovaluta</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -3273,7 +3273,7 @@
|
||||
<target state="translated">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -3281,7 +3281,7 @@
|
||||
<target state="translated">Beleggingsfonds</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -3289,7 +3289,7 @@
|
||||
<target state="translated">Edelmetaal</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -3297,7 +3297,7 @@
|
||||
<target state="translated">Private equity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -3305,7 +3305,7 @@
|
||||
<target state="translated">Aandeel</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6268646680388419543" datatype="html">
|
||||
@ -3345,7 +3345,7 @@
|
||||
<target state="translated">Noord-Amerika</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -3353,7 +3353,7 @@
|
||||
<target state="translated">Afrika</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -3361,7 +3361,7 @@
|
||||
<target state="translated">Azië</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -3369,7 +3369,7 @@
|
||||
<target state="translated">Europa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -3377,7 +3377,7 @@
|
||||
<target state="translated">Oceanië</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -3385,7 +3385,7 @@
|
||||
<target state="translated">Zuid-Amerika</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6f9fd3da06dc9000eef0d4dcbb37747b303048e9" datatype="html">
|
||||
@ -10073,7 +10073,7 @@
|
||||
<target state="translated">Sterren op GitHub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10085,7 +10085,7 @@
|
||||
<target state="translated">Pulls op Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10185,7 +10185,7 @@
|
||||
<target state="translated"> Beheer je vermogen als een baas </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -10193,7 +10193,7 @@
|
||||
<target state="translated"> Ghostfolio is een privacygericht, open source dashboard voor je persoonlijke financiën. Analyseer je asset-allocatie, ken je nettowaarde en neem gefundeerde, datagedreven investeringsbeslissingen. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -10201,11 +10201,11 @@
|
||||
<target state="translated"> Aan de slag </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -10213,7 +10213,7 @@
|
||||
<target state="translated"> of </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -10221,7 +10221,7 @@
|
||||
<target state="translated">Maandelijkse actieve gebruikers</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9c7ee452b83c7458f6ffdd49837daf95b1d5f34e" datatype="html">
|
||||
@ -10229,7 +10229,7 @@
|
||||
<target state="translated">Zoals te zien in</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -10237,7 +10237,7 @@
|
||||
<target state="translated"> Bescherm je <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>financiële bezittingen<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Verfijn je <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>persoonlijke investeringsstrategie<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -10245,7 +10245,7 @@
|
||||
<target state="translated"> Ghostfolio stelt drukbezette mensen in staat om aandelen, ETF's of cryptocurrencies bij te houden zonder gevolgd te worden. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -10253,7 +10253,7 @@
|
||||
<target state="translated">360°-overzicht</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -10261,7 +10261,7 @@
|
||||
<target state="translated">Klaar voor Web3</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -10269,7 +10269,7 @@
|
||||
<target state="translated"> Gebruik Ghostfolio anoniem en bezit je financiële gegevens.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -10277,7 +10277,7 @@
|
||||
<target state="translated">Open Source</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -10285,7 +10285,7 @@
|
||||
<target state="translated"> Profiteer van voortdurende verbeteringen door een sterke gemeenschap. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -10293,7 +10293,7 @@
|
||||
<target state="translated">Waarom <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -10301,7 +10301,7 @@
|
||||
<target state="translated"> Ghostfolio is iets voor je als je... </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -10309,7 +10309,7 @@
|
||||
<target state="translated">handelt in aandelen, ETF's of cryptocurrencies op meerdere platforms</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -10317,7 +10317,7 @@
|
||||
<target state="translated">streeft naar een buy & hold strategie</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -10325,7 +10325,7 @@
|
||||
<target state="translated">geïnteresseerd bent in het krijgen van inzicht in je portefeuillesamenstelling</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -10333,7 +10333,7 @@
|
||||
<target state="translated">privacy en eigendom van gegevens waardeert</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -10341,7 +10341,7 @@
|
||||
<target state="translated">houdt van een minimalistisch ontwerp</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -10349,7 +10349,7 @@
|
||||
<target state="translated">zorgdraagt voor het diversifiëren van je financiële middelen</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -10357,7 +10357,7 @@
|
||||
<target state="translated">geïnteresseerd bent in financiële onafhankelijkheid</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -10365,7 +10365,7 @@
|
||||
<target state="translated">"nee" zegt tegen spreadsheets in <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -10373,7 +10373,7 @@
|
||||
<target state="translated">nog steeds deze lijst aan het lezen bent</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -10381,7 +10381,7 @@
|
||||
<target state="translated">Leer meer over Ghostfolio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -10389,7 +10389,7 @@
|
||||
<target state="translated"> Wat onze <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>gebruikers<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> zeggen </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -10397,7 +10397,7 @@
|
||||
<target state="translated"> Leden van over de hele wereld gebruiken<x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -10405,7 +10405,7 @@
|
||||
<target state="translated"> Hoe <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> werkt? </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -10413,7 +10413,7 @@
|
||||
<target state="translated">Anoniem aanmelden*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -10421,7 +10421,7 @@
|
||||
<target state="translated"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* geen e-mailadres of creditcard nodig<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -10429,7 +10429,7 @@
|
||||
<target state="translated"> Voeg al je historische transacties toe </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -10437,7 +10437,7 @@
|
||||
<target state="translated"> Krijg waardevolle inzichten in de samenstelling van je portefeuille </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -10445,7 +10445,7 @@
|
||||
<target state="translated">Ben <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>je er<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> klaar voor?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -10453,7 +10453,7 @@
|
||||
<target state="translated"> Nu lid worden<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> of bekijk het voorbeeld account<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -10461,11 +10461,11 @@
|
||||
<target state="new">Live Demo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -10473,7 +10473,7 @@
|
||||
<target state="translated"> Krijg een volledig beeld van je persoonlijke financiën op meerdere platforms. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -10481,7 +10481,7 @@
|
||||
<target state="translated">Aan de slag in slechts 3 stappen</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4656883433287439415" datatype="html">
|
||||
@ -13196,14 +13196,6 @@
|
||||
<context context-type="linenumber">127</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="new">New</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fc47ae80c47144eb6250979fe927a010da3aee5" datatype="html">
|
||||
<source>Choose or drop a file here</source>
|
||||
<target state="new">Choose or drop a file here</target>
|
||||
@ -13741,7 +13733,7 @@
|
||||
<target state="new">Oops, cash balance transfer has failed.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2356316679035829946" datatype="html">
|
||||
@ -13765,7 +13757,7 @@
|
||||
<target state="new">Extreme Fear</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13773,7 +13765,7 @@
|
||||
<target state="new">Extreme Greed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13781,7 +13773,7 @@
|
||||
<target state="new">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7183719827884539616" datatype="html">
|
||||
@ -15040,6 +15032,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -3026,7 +3026,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -3038,7 +3038,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ce718ababbce63d776cf8b1f91412beb4c0a6e04" datatype="html">
|
||||
@ -3202,7 +3202,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -4140,7 +4140,7 @@
|
||||
<target state="new">Oops, cash balance transfer has failed.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="220a4641dcde60d1d86ceec62886b1878f1578d3" datatype="html">
|
||||
@ -4523,20 +4523,12 @@
|
||||
<context context-type="linenumber">14</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="new">New</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7b3c319feef05dcc1f487d09dd2a59eb4c50e6d6" datatype="html">
|
||||
<source> Manage your wealth like a boss </source>
|
||||
<target state="new"> Manage your wealth like a boss </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -4544,7 +4536,7 @@
|
||||
<target state="new"> Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -4552,11 +4544,11 @@
|
||||
<target state="new"> Get Started </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -4564,7 +4556,7 @@
|
||||
<target state="new"> or </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -4572,11 +4564,11 @@
|
||||
<target state="new">Live Demo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -4584,7 +4576,7 @@
|
||||
<target state="new">Monthly Active Users</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d3932a9eba50bc101c2b8c329e7b4ea033cde97" datatype="html">
|
||||
@ -4592,7 +4584,7 @@
|
||||
<target state="new">Stars on GitHub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4604,7 +4596,7 @@
|
||||
<target state="new">Pulls on Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4616,7 +4608,7 @@
|
||||
<target state="new">As seen in</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -4624,7 +4616,7 @@
|
||||
<target state="new"> Protect your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>assets<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Refine your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>personal investment strategy<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -4632,7 +4624,7 @@
|
||||
<target state="new"> Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -4640,7 +4632,7 @@
|
||||
<target state="new">360° View</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -4648,7 +4640,7 @@
|
||||
<target state="new"> Get the full picture of your personal finances across multiple platforms. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -4656,7 +4648,7 @@
|
||||
<target state="new">Web3 Ready</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -4664,7 +4656,7 @@
|
||||
<target state="new"> Use Ghostfolio anonymously and own your financial data. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -4672,7 +4664,7 @@
|
||||
<target state="new">Open Source</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -4680,7 +4672,7 @@
|
||||
<target state="new"> Benefit from continuous improvements through a strong community. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -4688,7 +4680,7 @@
|
||||
<target state="new">Why <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -4696,7 +4688,7 @@
|
||||
<target state="new"> Ghostfolio is for you if you are... </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -4704,7 +4696,7 @@
|
||||
<target state="new">trading stocks, ETFs or cryptocurrencies on multiple platforms</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -4712,7 +4704,7 @@
|
||||
<target state="new">pursuing a buy & hold strategy</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -4720,7 +4712,7 @@
|
||||
<target state="new">interested in getting insights of your portfolio composition</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -4728,7 +4720,7 @@
|
||||
<target state="new">valuing privacy and data ownership</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -4736,7 +4728,7 @@
|
||||
<target state="new">into minimalism</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -4744,7 +4736,7 @@
|
||||
<target state="new">caring about diversifying your financial resources</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -4752,7 +4744,7 @@
|
||||
<target state="new">interested in financial independence</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -4760,7 +4752,7 @@
|
||||
<target state="new">saying no to spreadsheets in <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -4768,7 +4760,7 @@
|
||||
<target state="new">still reading this list</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -4776,7 +4768,7 @@
|
||||
<target state="new">Learn more about Ghostfolio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -4784,7 +4776,7 @@
|
||||
<target state="new"> What our <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>users<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> are saying </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -4792,7 +4784,7 @@
|
||||
<target state="new"> Members from around the globe are using <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -4800,7 +4792,7 @@
|
||||
<target state="new"> How does <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> work? </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -4808,7 +4800,7 @@
|
||||
<target state="new">Get started in only 3 steps</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -4816,7 +4808,7 @@
|
||||
<target state="new">Sign up anonymously*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -4824,7 +4816,7 @@
|
||||
<target state="new"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* no e-mail address nor credit card required<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -4832,7 +4824,7 @@
|
||||
<target state="new"> Add any of your historical transactions </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -4840,7 +4832,7 @@
|
||||
<target state="new"> Get valuable insights of your portfolio composition </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -4848,7 +4840,7 @@
|
||||
<target state="new">Are <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>you<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> ready?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -4856,7 +4848,7 @@
|
||||
<target state="new"> Join now<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> or check out the example account<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d0f35e084b3902a5b04ee86cfde0d4b991a93af" datatype="html">
|
||||
@ -13636,7 +13628,7 @@
|
||||
<target state="new">Real Estate</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -13644,7 +13636,7 @@
|
||||
<target state="new">Bond</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -13652,7 +13644,7 @@
|
||||
<target state="new">Cryptocurrency</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -13660,7 +13652,7 @@
|
||||
<target state="new">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -13668,7 +13660,7 @@
|
||||
<target state="new">Mutual Fund</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -13676,7 +13668,7 @@
|
||||
<target state="new">Precious Metal</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -13684,7 +13676,7 @@
|
||||
<target state="new">Private Equity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -13692,7 +13684,7 @@
|
||||
<target state="new">Stock</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -13700,7 +13692,7 @@
|
||||
<target state="new">Africa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -13708,7 +13700,7 @@
|
||||
<target state="new">Asia</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -13716,7 +13708,7 @@
|
||||
<target state="new">Europe</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1228771048078164312" datatype="html">
|
||||
@ -13724,7 +13716,7 @@
|
||||
<target state="new">North America</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -13732,7 +13724,7 @@
|
||||
<target state="new">Oceania</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -13740,7 +13732,7 @@
|
||||
<target state="new">South America</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1189482335778578193" datatype="html">
|
||||
@ -13748,7 +13740,7 @@
|
||||
<target state="new">Extreme Fear</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13756,7 +13748,7 @@
|
||||
<target state="new">Extreme Greed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13764,7 +13756,7 @@
|
||||
<target state="new">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3c33a66194384cf8c14e25170416767efa56fd98" datatype="html">
|
||||
@ -15043,6 +15035,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -1418,7 +1418,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -1430,7 +1430,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ce718ababbce63d776cf8b1f91412beb4c0a6e04" datatype="html">
|
||||
@ -1518,7 +1518,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -3293,7 +3293,7 @@
|
||||
<target state="translated">Imobiliário</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -3301,7 +3301,7 @@
|
||||
<target state="translated">Obrigação</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -3309,7 +3309,7 @@
|
||||
<target state="translated">Criptomoedas</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -3317,7 +3317,7 @@
|
||||
<target state="translated">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -3325,7 +3325,7 @@
|
||||
<target state="translated">Fundo de Investimento</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -3333,7 +3333,7 @@
|
||||
<target state="translated">Metal Precioso</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -3341,7 +3341,7 @@
|
||||
<target state="translated">Private Equity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -3349,7 +3349,7 @@
|
||||
<target state="translated">Ação</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -3357,7 +3357,7 @@
|
||||
<target state="translated">África</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -3365,7 +3365,7 @@
|
||||
<target state="translated">Ásia</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -3373,7 +3373,7 @@
|
||||
<target state="translated">Europa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1228771048078164312" datatype="html">
|
||||
@ -3381,7 +3381,7 @@
|
||||
<target state="translated">América do Norte</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -3389,7 +3389,7 @@
|
||||
<target state="translated">Oceânia</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -3397,7 +3397,7 @@
|
||||
<target state="translated">América do Sul</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c004f99bac91f7dc28e87d458f80e5035ae99884" datatype="html">
|
||||
@ -10073,7 +10073,7 @@
|
||||
<target state="new">Stars on GitHub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10085,7 +10085,7 @@
|
||||
<target state="new">Pulls on Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -10185,7 +10185,7 @@
|
||||
<target state="new"> Manage your wealth like a boss </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -10193,7 +10193,7 @@
|
||||
<target state="new"> Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -10201,11 +10201,11 @@
|
||||
<target state="new"> Get Started </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -10213,7 +10213,7 @@
|
||||
<target state="new"> or </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -10221,7 +10221,7 @@
|
||||
<target state="new">Monthly Active Users</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9c7ee452b83c7458f6ffdd49837daf95b1d5f34e" datatype="html">
|
||||
@ -10229,7 +10229,7 @@
|
||||
<target state="new">As seen in</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -10237,7 +10237,7 @@
|
||||
<target state="new"> Protect your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>assets<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Refine your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>personal investment strategy<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -10245,7 +10245,7 @@
|
||||
<target state="new"> Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -10253,7 +10253,7 @@
|
||||
<target state="new">360° View</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -10261,7 +10261,7 @@
|
||||
<target state="new">Web3 Ready</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -10269,7 +10269,7 @@
|
||||
<target state="new"> Use Ghostfolio anonymously and own your financial data. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -10277,7 +10277,7 @@
|
||||
<target state="new">Open Source</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -10285,7 +10285,7 @@
|
||||
<target state="new"> Benefit from continuous improvements through a strong community. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -10293,7 +10293,7 @@
|
||||
<target state="new">Why <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -10301,7 +10301,7 @@
|
||||
<target state="new"> Ghostfolio is for you if you are... </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -10309,7 +10309,7 @@
|
||||
<target state="new">trading stocks, ETFs or cryptocurrencies on multiple platforms</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -10317,7 +10317,7 @@
|
||||
<target state="new">pursuing a buy & hold strategy</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -10325,7 +10325,7 @@
|
||||
<target state="new">interested in getting insights of your portfolio composition</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -10333,7 +10333,7 @@
|
||||
<target state="new">valuing privacy and data ownership</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -10341,7 +10341,7 @@
|
||||
<target state="new">into minimalism</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -10349,7 +10349,7 @@
|
||||
<target state="new">caring about diversifying your financial resources</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -10357,7 +10357,7 @@
|
||||
<target state="new">interested in financial independence</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -10365,7 +10365,7 @@
|
||||
<target state="new">saying no to spreadsheets in <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -10373,7 +10373,7 @@
|
||||
<target state="new">still reading this list</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -10381,7 +10381,7 @@
|
||||
<target state="new">Learn more about Ghostfolio</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -10389,7 +10389,7 @@
|
||||
<target state="new"> What our <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>users<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> are saying </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -10397,7 +10397,7 @@
|
||||
<target state="new"> Members from around the globe are using <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -10405,7 +10405,7 @@
|
||||
<target state="new"> How does <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> work? </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -10413,7 +10413,7 @@
|
||||
<target state="new">Sign up anonymously*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -10421,7 +10421,7 @@
|
||||
<target state="new"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* no e-mail address nor credit card required<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -10429,7 +10429,7 @@
|
||||
<target state="new"> Add any of your historical transactions </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -10437,7 +10437,7 @@
|
||||
<target state="new"> Get valuable insights of your portfolio composition </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -10445,7 +10445,7 @@
|
||||
<target state="new">Are <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>you<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> ready?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -10453,7 +10453,7 @@
|
||||
<target state="new"> Join now<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> or check out the example account<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -10461,11 +10461,11 @@
|
||||
<target state="new">Live Demo</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -10473,7 +10473,7 @@
|
||||
<target state="new"> Get the full picture of your personal finances across multiple platforms. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -10481,7 +10481,7 @@
|
||||
<target state="new">Get started in only 3 steps</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4656883433287439415" datatype="html">
|
||||
@ -13196,14 +13196,6 @@
|
||||
<context context-type="linenumber">127</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="new">New</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fc47ae80c47144eb6250979fe927a010da3aee5" datatype="html">
|
||||
<source>Choose or drop a file here</source>
|
||||
<target state="new">Choose or drop a file here</target>
|
||||
@ -13741,7 +13733,7 @@
|
||||
<target state="new">Oops, cash balance transfer has failed.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2356316679035829946" datatype="html">
|
||||
@ -13765,7 +13757,7 @@
|
||||
<target state="new">Extreme Fear</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13773,7 +13765,7 @@
|
||||
<target state="new">Extreme Greed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13781,7 +13773,7 @@
|
||||
<target state="new">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7183719827884539616" datatype="html">
|
||||
@ -15040,6 +15032,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -2878,7 +2878,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -2890,7 +2890,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ce718ababbce63d776cf8b1f91412beb4c0a6e04" datatype="html">
|
||||
@ -3054,7 +3054,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -4065,7 +4065,7 @@
|
||||
<target state="translated">Servetinizi bir patron gibi yönetin</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -4073,7 +4073,7 @@
|
||||
<target state="translated">Ghostfolio, mali durumunuz için gizlilik odaklı, açık kaynaklı bir kontrol panelidi. Varlık dağılımınızı analiz edin, net değerinizi öğrenin ve sağlam, veriye dayalı yatırım kararları alın.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -4081,11 +4081,11 @@
|
||||
<target state="translated">Başla</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -4093,7 +4093,7 @@
|
||||
<target state="translated">veya</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -4101,11 +4101,11 @@
|
||||
<target state="translated">Canlı Deneme</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -4113,7 +4113,7 @@
|
||||
<target state="translated">Aylık Aktif Kullanıcılar</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d3932a9eba50bc101c2b8c329e7b4ea033cde97" datatype="html">
|
||||
@ -4121,7 +4121,7 @@
|
||||
<target state="translated">GitHub'daki Beğeniler</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4133,7 +4133,7 @@
|
||||
<target state="translated">Docker Hub'ta Çekmeler</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4145,7 +4145,7 @@
|
||||
<target state="translated">Şurada görüldüğü gibi</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -4153,7 +4153,7 @@
|
||||
<target state="translated"> <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>varlıklarınızı koruyun<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Kişisel yatırım stratejinizi geliştirin<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -4161,7 +4161,7 @@
|
||||
<target state="translated">Ghostfolio, takip edilmeden hisse senetleri, ETF'ler veya kripto paraları izlemek isteyen yoğun insanlara güç verir.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -4169,7 +4169,7 @@
|
||||
<target state="translated">360° Görünüm</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -4177,7 +4177,7 @@
|
||||
<target state="translated">Kişisel finansınızın tam resmini birden fazla platformda edinin.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -4185,7 +4185,7 @@
|
||||
<target state="translated">Web3 Hazır</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -4193,7 +4193,7 @@
|
||||
<target state="translated">Ghostfolio'yu anonim olarak kullanın ve finansal verilerinize sahip çıkın.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -4201,7 +4201,7 @@
|
||||
<target state="translated">Açık Kaynak</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -4209,7 +4209,7 @@
|
||||
<target state="translated">Güçlü bir topluluk aracılığıyla sürekli gelişmelerden faydalanın.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -4217,7 +4217,7 @@
|
||||
<target state="new">Why <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -4225,7 +4225,7 @@
|
||||
<target state="translated"> Ghostfolio tam size göre, </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -4233,7 +4233,7 @@
|
||||
<target state="translated">Birden fazla platformda hisse senedi, ETF veya kripto para ticareti yapıyorsanız, </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -4241,7 +4241,7 @@
|
||||
<target state="translated">al ve tut stratejisi izliyorsanız, </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -4249,7 +4249,7 @@
|
||||
<target state="translated">Portföy bileşimine dair içgörüleri edinmek istiyorsanız,</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -4257,7 +4257,7 @@
|
||||
<target state="translated">Gizliliğe ve verilerinize sahip çıkmayı önemsiyorsanız</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -4265,7 +4265,7 @@
|
||||
<target state="translated">minimalizme ilgi duyuyorsanız</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -4273,7 +4273,7 @@
|
||||
<target state="translated">finansal kaynaklarınızı çeşitlendirmeye önem veriyorsanız</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -4281,7 +4281,7 @@
|
||||
<target state="translated">finansal özgürlük peşindeyseniz</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -4289,7 +4289,7 @@
|
||||
<target state="translated">elektronik tablo uygulamalarına hayır diyorsanız <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -4297,7 +4297,7 @@
|
||||
<target state="translated">bu listeyi hala okuyorsanız</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -4305,7 +4305,7 @@
|
||||
<target state="translated">Ghostfolio hakkında daha fazla bilgi edinin</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -4313,7 +4313,7 @@
|
||||
<target state="new"> What our <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>users<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> are saying </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -4321,7 +4321,7 @@
|
||||
<target state="new"> Members from around the globe are using <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -4329,7 +4329,7 @@
|
||||
<target state="new"> How does <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> work? </target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -4337,7 +4337,7 @@
|
||||
<target state="translated">Sadece 3 adımda başlayın</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -4345,7 +4345,7 @@
|
||||
<target state="translated">Anonim olarak kaydolun*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -4353,7 +4353,7 @@
|
||||
<target state="translated"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* e-posta adresi veya kredi kartı gerekmez<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -4361,7 +4361,7 @@
|
||||
<target state="translated">Herhangi bir geçmiş işleminizi ekleyin</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -4369,7 +4369,7 @@
|
||||
<target state="translated">Portföy bileşiminizle ilgili değerli bilgiler edinin</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -4377,7 +4377,7 @@
|
||||
<target state="new">Are <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>you<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> ready?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -4385,7 +4385,7 @@
|
||||
<target state="new"> Join now<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> or check out the example account<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d0f35e084b3902a5b04ee86cfde0d4b991a93af" datatype="html">
|
||||
@ -13041,7 +13041,7 @@
|
||||
<target state="new">Real Estate</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -13049,7 +13049,7 @@
|
||||
<target state="new">Bond</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -13057,7 +13057,7 @@
|
||||
<target state="new">Cryptocurrency</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -13065,7 +13065,7 @@
|
||||
<target state="new">ETF</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -13073,7 +13073,7 @@
|
||||
<target state="new">Mutual Fund</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -13081,7 +13081,7 @@
|
||||
<target state="new">Precious Metal</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -13089,7 +13089,7 @@
|
||||
<target state="new">Private Equity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -13097,7 +13097,7 @@
|
||||
<target state="new">Stock</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -13105,7 +13105,7 @@
|
||||
<target state="new">Africa</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -13113,7 +13113,7 @@
|
||||
<target state="new">Asia</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -13121,7 +13121,7 @@
|
||||
<target state="new">Europe</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1228771048078164312" datatype="html">
|
||||
@ -13129,7 +13129,7 @@
|
||||
<target state="new">North America</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -13137,7 +13137,7 @@
|
||||
<target state="new">Oceania</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -13145,7 +13145,7 @@
|
||||
<target state="new">South America</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c004f99bac91f7dc28e87d458f80e5035ae99884" datatype="html">
|
||||
@ -13184,14 +13184,6 @@
|
||||
<context context-type="linenumber">312</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="new">New</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7db7ee6941e96fe86681e5fb785c69d66da006d7" datatype="html">
|
||||
<source>(Last 24 hours)</source>
|
||||
<target state="new">(Last 24 hours)</target>
|
||||
@ -13741,7 +13733,7 @@
|
||||
<target state="new">Oops, cash balance transfer has failed.</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2356316679035829946" datatype="html">
|
||||
@ -13765,7 +13757,7 @@
|
||||
<target state="new">Extreme Fear</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -13773,7 +13765,7 @@
|
||||
<target state="new">Extreme Greed</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -13781,7 +13773,7 @@
|
||||
<target state="new">Neutral</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7183719827884539616" datatype="html">
|
||||
@ -15040,6 +15032,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -2893,7 +2893,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -2904,7 +2904,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ce718ababbce63d776cf8b1f91412beb4c0a6e04" datatype="html">
|
||||
@ -3050,7 +3050,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -3892,7 +3892,7 @@
|
||||
<source>Oops, cash balance transfer has failed.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="220a4641dcde60d1d86ceec62886b1878f1578d3" datatype="html">
|
||||
@ -4237,68 +4237,61 @@
|
||||
<context context-type="linenumber">14</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7b3c319feef05dcc1f487d09dd2a59eb4c50e6d6" datatype="html">
|
||||
<source> Manage your wealth like a boss </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
<source> Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
<source> Get Started </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
<source> or </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
<source>Live Demo</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
<source>Monthly Active Users</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d3932a9eba50bc101c2b8c329e7b4ea033cde97" datatype="html">
|
||||
<source>Stars on GitHub</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4309,7 +4302,7 @@
|
||||
<source>Pulls on Docker Hub</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4320,217 +4313,217 @@
|
||||
<source>As seen in</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
<source> Protect your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>assets<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. Refine your <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>personal investment strategy<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
<source> Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
<source>360° View</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
<source> Get the full picture of your personal finances across multiple platforms. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
<source>Web3 Ready</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
<source> Use Ghostfolio anonymously and own your financial data. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
<source>Open Source</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
<source> Benefit from continuous improvements through a strong community. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
<source>Why <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
<source> Ghostfolio is for you if you are... </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
<source>trading stocks, ETFs or cryptocurrencies on multiple platforms</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
<source>pursuing a buy & hold strategy</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
<source>interested in getting insights of your portfolio composition</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
<source>valuing privacy and data ownership</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
<source>into minimalism</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
<source>caring about diversifying your financial resources</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
<source>interested in financial independence</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
<source>saying no to spreadsheets in <x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
<source>still reading this list</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
<source>Learn more about Ghostfolio</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
<source> What our <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>users<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> are saying </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
<source> Members from around the globe are using <x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio Premium<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
<source> How does <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> work? </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
<source>Get started in only 3 steps</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
<source>Sign up anonymously*</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
<source><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* no e-mail address nor credit card required<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
<source> Add any of your historical transactions </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
<source> Get valuable insights of your portfolio composition </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
<source>Are <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>you<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/> ready?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
<source> Join now<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/> or check out the example account<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d0f35e084b3902a5b04ee86cfde0d4b991a93af" datatype="html">
|
||||
@ -13918,119 +13911,119 @@
|
||||
<source>Real Estate</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
<source>Bond</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
<source>Cryptocurrency</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
<source>ETF</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
<source>Mutual Fund</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
<source>Precious Metal</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
<source>Private Equity</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
<source>Stock</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
<source>Africa</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
<source>Asia</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
<source>Europe</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1228771048078164312" datatype="html">
|
||||
<source>North America</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
<source>Oceania</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
<source>South America</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1189482335778578193" datatype="html">
|
||||
<source>Extreme Fear</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
<source>Extreme Greed</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
<source>Neutral</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3c33a66194384cf8c14e25170416767efa56fd98" datatype="html">
|
||||
@ -14412,6 +14405,13 @@
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -3043,7 +3043,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6844699413925472826" datatype="html">
|
||||
@ -3055,7 +3055,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">70</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ce718ababbce63d776cf8b1f91412beb4c0a6e04" datatype="html">
|
||||
@ -3219,7 +3219,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">429</context>
|
||||
<context context-type="linenumber">423</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html</context>
|
||||
@ -4157,7 +4157,7 @@
|
||||
<target state="translated">糟糕,现金余额转账失败。</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/accounts/accounts-page.component.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="220a4641dcde60d1d86ceec62886b1878f1578d3" datatype="html">
|
||||
@ -4540,20 +4540,12 @@
|
||||
<context context-type="linenumber">14</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d81f00c85d3b507f3e3d78bfc617a2c66e028391" datatype="html">
|
||||
<source>New</source>
|
||||
<target state="translated">新的</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">7</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7b3c319feef05dcc1f487d09dd2a59eb4c50e6d6" datatype="html">
|
||||
<source> Manage your wealth like a boss </source>
|
||||
<target state="translated">像老板一样管理您的财富</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">11</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f251aca95a00756de48b14172b02d33f175661fc" datatype="html">
|
||||
@ -4561,7 +4553,7 @@
|
||||
<target state="translated">Ghostfolio 是一个隐私优先、开源的个人财务仪表板。分解您的资产配置,了解您的净资产并做出可靠的、数据驱动的投资决策。</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">9</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="50fefcca3f8b7dd5a34141329118014a8c4b7d1b" datatype="html">
|
||||
@ -4569,11 +4561,11 @@
|
||||
<target state="translated">开始使用</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">425</context>
|
||||
<context context-type="linenumber">419</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c4b553bb0e33c675cd6a34e2e295b984f9ee8381" datatype="html">
|
||||
@ -4581,7 +4573,7 @@
|
||||
<target state="translated">或</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="195d2d6475819f55cf73287f97752093b7721ade" datatype="html">
|
||||
@ -4589,11 +4581,11 @@
|
||||
<target state="translated">现场演示</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">430</context>
|
||||
<context context-type="linenumber">424</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1d6f11238819cf97ea87ab54714deda567d83f5c" datatype="html">
|
||||
@ -4601,7 +4593,7 @@
|
||||
<target state="translated">每月活跃用户数</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d3932a9eba50bc101c2b8c329e7b4ea033cde97" datatype="html">
|
||||
@ -4609,7 +4601,7 @@
|
||||
<target state="translated">GitHub 上的星星</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">93</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4621,7 +4613,7 @@
|
||||
<target state="translated">拉动 Docker Hub</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">111</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/open/open-page.html</context>
|
||||
@ -4633,7 +4625,7 @@
|
||||
<target state="translated">如图所示</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c8ef12032b654cfd51b9ae1082fde84247945e03" datatype="html">
|
||||
@ -4641,7 +4633,7 @@
|
||||
<target state="translated">保护你的<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>资产<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>。完善你的<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>个人投资策略<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>。</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">221</context>
|
||||
<context context-type="linenumber">215</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9dd7364c5dcf1b010bfa80e824ba80eb67cc2b57" datatype="html">
|
||||
@ -4649,7 +4641,7 @@
|
||||
<target state="translated">Ghostfolio 使忙碌的人们能够在不被追踪的情况下跟踪股票、ETF 或加密货币。</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">225</context>
|
||||
<context context-type="linenumber">219</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="70a1ed4b69a5a2cefa86b16c94ff2799a6566b4f" datatype="html">
|
||||
@ -4657,7 +4649,7 @@
|
||||
<target state="translated">360° 视角</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">236</context>
|
||||
<context context-type="linenumber">230</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dbe66b4824faaff93249a96c9ce23c237b446ed5" datatype="html">
|
||||
@ -4665,7 +4657,7 @@
|
||||
<target state="translated">跨多个平台全面了解您的个人财务状况。</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">238</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e0840e61fd65397c9dd8c0aa35ec19778c79b73d" datatype="html">
|
||||
@ -4673,7 +4665,7 @@
|
||||
<target state="translated">Web3 就绪</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">247</context>
|
||||
<context context-type="linenumber">241</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a82bf107b3693ed6bdba551a97ce92494921513" datatype="html">
|
||||
@ -4681,7 +4673,7 @@
|
||||
<target state="translated">匿名使用 Ghostfolio 并拥有您的财务数据。</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">249</context>
|
||||
<context context-type="linenumber">243</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebc1c2623f53ce48c714e00161a2f31f732c815b" datatype="html">
|
||||
@ -4689,7 +4681,7 @@
|
||||
<target state="translated">开源</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">257</context>
|
||||
<context context-type="linenumber">251</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3756fe4769648222e9a3143d6a140e55afd7424b" datatype="html">
|
||||
@ -4697,7 +4689,7 @@
|
||||
<target state="translated">通过强大的社区不断改进,从中受益。</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">259</context>
|
||||
<context context-type="linenumber">253</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="e7360ce972bb10156736d042a15c6c939fea123d" datatype="html">
|
||||
@ -4705,7 +4697,7 @@
|
||||
<target state="translated">为什么使用<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">268</context>
|
||||
<context context-type="linenumber">262</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b2466b29949bb745c1f96f2d82e5dab9061f8efe" datatype="html">
|
||||
@ -4713,7 +4705,7 @@
|
||||
<target state="translated">如果您符合以下条件,那么 Ghostfolio 适合您...</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">269</context>
|
||||
<context context-type="linenumber">263</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2fe7c768f92932a3a6c9b460dd5d72e53deb9cfe" datatype="html">
|
||||
@ -4721,7 +4713,7 @@
|
||||
<target state="translated">在多个平台上交易股票、ETF 或加密货币</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
<context context-type="linenumber">270</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe71658bf131fad393a7ce618908e246617ded26" datatype="html">
|
||||
@ -4729,7 +4721,7 @@
|
||||
<target state="translated">采取买入并持有策略</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">282</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2e95d2cbc69d45e5ecf3eb92c2972e8cb4ff3ec6" datatype="html">
|
||||
@ -4737,7 +4729,7 @@
|
||||
<target state="translated">有兴趣深入了解您的投资组合构成</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">287</context>
|
||||
<context context-type="linenumber">281</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4093027d62fd4125e36fe21bdd44475fc7499d02" datatype="html">
|
||||
@ -4745,7 +4737,7 @@
|
||||
<target state="translated">重视隐私和数据所有权</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
<context context-type="linenumber">286</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5fae4f4ad7de60db18a5c52ccf5e7e8c7b194a9c" datatype="html">
|
||||
@ -4753,7 +4745,7 @@
|
||||
<target state="translated">进入极简主义</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="18bb2c16577866572e3656986d9660d2db012565" datatype="html">
|
||||
@ -4761,7 +4753,7 @@
|
||||
<target state="translated">关心您的财务资源多元化</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0a6c37c2d3a8c41e7e44f020aefb1c667ac150dc" datatype="html">
|
||||
@ -4769,7 +4761,7 @@
|
||||
<target state="translated">对财务独立感兴趣</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="81fbb4e2cd3d3079d790bdddbfcc73ec3b600d22" datatype="html">
|
||||
@ -4777,7 +4769,7 @@
|
||||
<target state="translated">对电子表格说不<x id="INTERPOLATION" equiv-text="{{ currentYear }}"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="92cef868de56015b451e7eee26c9eaef54f41d37" datatype="html">
|
||||
@ -4785,7 +4777,7 @@
|
||||
<target state="translated">仍在阅读此列表</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8c11c506c55700ca9883f360c52df5a432a51dcf" datatype="html">
|
||||
@ -4793,7 +4785,7 @@
|
||||
<target state="translated">了解有关 Ghostfolio 的更多信息</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ae508ae33a02ae69247d9e4d84e98b610209ef3b" datatype="html">
|
||||
@ -4801,7 +4793,7 @@
|
||||
<target state="translated">我们的什么<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>用户<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>正在说</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="f9e4d441f5fed560c87d2f1f061eaa826ed271cd" datatype="html">
|
||||
@ -4809,7 +4801,7 @@
|
||||
<target state="translated">来自世界各地的会员正在使用<x id="START_LINK" ctype="x-a" equiv-text="<a href="pricing">"/><x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>Ghostfolio 高级版<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">355</context>
|
||||
<context context-type="linenumber">349</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="abc6737537d65639f566a7068d0e5dde19c9d220" datatype="html">
|
||||
@ -4817,7 +4809,7 @@
|
||||
<target state="translated">如何<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>幽灵作品集<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>工作?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">367</context>
|
||||
<context context-type="linenumber">361</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9454b3758f67cb4d178570e8bfb3e0d684e2353e" datatype="html">
|
||||
@ -4825,7 +4817,7 @@
|
||||
<target state="translated">只需 3 步即可开始</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
<context context-type="linenumber">364</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="969974097ecdfff6cb04b4cb71efccd717da1ce8" datatype="html">
|
||||
@ -4833,7 +4825,7 @@
|
||||
<target state="translated">匿名注册*</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">376</context>
|
||||
<context context-type="linenumber">370</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="ebca1c496ea9caf6acf2a7ee5c4fa2b3f5aee1fe" datatype="html">
|
||||
@ -4841,7 +4833,7 @@
|
||||
<target state="translated"><x id="START_SMALL_TEXT" ctype="x-small" equiv-text="<small>"/>* 无需电子邮件地址或信用卡<x id="CLOSE_SMALL_TEXT" ctype="x-small" equiv-text="</small>"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">378</context>
|
||||
<context context-type="linenumber">372</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2039f449cf4ee0c26a9211de9d057c1002293917" datatype="html">
|
||||
@ -4849,7 +4841,7 @@
|
||||
<target state="translated">添加您的任何历史交易</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">389</context>
|
||||
<context context-type="linenumber">383</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="d6a2cfef5de5fd13ceb051a8725b1414c2ad9a69" datatype="html">
|
||||
@ -4857,7 +4849,7 @@
|
||||
<target state="translated">获取有关您的投资组合构成的宝贵见解</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">401</context>
|
||||
<context context-type="linenumber">395</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="b19d6b55a61fe4b3a9594fe87d504667cae32d8e" datatype="html">
|
||||
@ -4865,7 +4857,7 @@
|
||||
<target state="translated">是<x id="START_TAG_STRONG" ctype="x-strong" equiv-text="<strong>"/>你<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="</strong>"/>准备好?</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">413</context>
|
||||
<context context-type="linenumber">407</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="31d1cab2469b1cd9d7105900f3bf2781873282ad" datatype="html">
|
||||
@ -4873,7 +4865,7 @@
|
||||
<target state="translated">立即加入<x id="START_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="<ng-container *ngIf="hasPermissionForDemo">"/>或查看示例帐户<x id="CLOSE_TAG_NG_CONTAINER" ctype="x-ng_container" equiv-text="</ng-container >"/></target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.html</context>
|
||||
<context context-type="linenumber">414</context>
|
||||
<context context-type="linenumber">408</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8d0f35e084b3902a5b04ee86cfde0d4b991a93af" datatype="html">
|
||||
@ -14485,7 +14477,7 @@
|
||||
<target state="translated">房地产</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8977365084844053365" datatype="html">
|
||||
@ -14493,7 +14485,7 @@
|
||||
<target state="translated">纽带</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">46</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2893204435511484886" datatype="html">
|
||||
@ -14501,7 +14493,7 @@
|
||||
<target state="translated">加密货币</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">47</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9071695492820527473" datatype="html">
|
||||
@ -14509,7 +14501,7 @@
|
||||
<target state="translated">交易所交易基金</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">48</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5734784563242233466" datatype="html">
|
||||
@ -14517,7 +14509,7 @@
|
||||
<target state="translated">共同基金</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">49</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1270654249046226808" datatype="html">
|
||||
@ -14525,7 +14517,7 @@
|
||||
<target state="translated">贵金属</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">50</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1346519036036997811" datatype="html">
|
||||
@ -14533,7 +14525,7 @@
|
||||
<target state="translated">私人产权</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">51</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4613338085351943838" datatype="html">
|
||||
@ -14541,7 +14533,7 @@
|
||||
<target state="translated">库存</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
<context context-type="linenumber">53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1413778527796351850" datatype="html">
|
||||
@ -14549,7 +14541,7 @@
|
||||
<target state="translated">非洲</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">59</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3345512471687795386" datatype="html">
|
||||
@ -14557,7 +14549,7 @@
|
||||
<target state="translated">亚洲</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">60</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8350109327144196614" datatype="html">
|
||||
@ -14565,7 +14557,7 @@
|
||||
<target state="translated">欧洲</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">61</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1228771048078164312" datatype="html">
|
||||
@ -14573,7 +14565,7 @@
|
||||
<target state="translated">北美</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">62</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3228811828827738441" datatype="html">
|
||||
@ -14581,7 +14573,7 @@
|
||||
<target state="translated">大洋洲</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">63</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5957846001261659229" datatype="html">
|
||||
@ -14589,7 +14581,7 @@
|
||||
<target state="translated">南美洲</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
<context context-type="linenumber">65</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1189482335778578193" datatype="html">
|
||||
@ -14597,7 +14589,7 @@
|
||||
<target state="translated">极度恐惧</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2634398159221205491" datatype="html">
|
||||
@ -14605,7 +14597,7 @@
|
||||
<target state="translated">极度贪婪</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">68</context>
|
||||
<context context-type="linenumber">69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3511545370905854666" datatype="html">
|
||||
@ -14613,7 +14605,7 @@
|
||||
<target state="translated">中性的</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3c33a66194384cf8c14e25170416767efa56fd98" datatype="html">
|
||||
@ -15044,6 +15036,14 @@
|
||||
<context context-type="linenumber">70</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="67933701892581429" datatype="html">
|
||||
<source>Liquidity</source>
|
||||
<target state="new">Liquidity</target>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">libs/ui/src/lib/i18n.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
9
libs/common/src/lib/class-transformer.ts
Normal file
9
libs/common/src/lib/class-transformer.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Big } from 'big.js';
|
||||
|
||||
export function transformToBig({ value }: { value: string }): Big {
|
||||
if (value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Big(value);
|
||||
}
|
@ -4,7 +4,6 @@ import ms from 'ms';
|
||||
|
||||
export const ghostfolioPrefix = 'GF';
|
||||
export const ghostfolioScraperApiSymbolPrefix = `_${ghostfolioPrefix}_`;
|
||||
export const ghostfolioCashSymbol = `${ghostfolioScraperApiSymbolPrefix}CASH`;
|
||||
export const ghostfolioFearAndGreedIndexDataSource = DataSource.RAPID_API;
|
||||
export const ghostfolioFearAndGreedIndexSymbol = `${ghostfolioScraperApiSymbolPrefix}FEAR_AND_GREED_INDEX`;
|
||||
|
||||
|
@ -48,7 +48,6 @@ import type { Subscription } from './subscription.interface';
|
||||
import type { SymbolMetrics } from './symbol-metrics.interface';
|
||||
import type { SystemMessage } from './system-message.interface';
|
||||
import type { TabConfiguration } from './tab-configuration.interface';
|
||||
import type { TimelinePosition } from './timeline-position.interface';
|
||||
import type { UniqueAsset } from './unique-asset.interface';
|
||||
import type { UserSettings } from './user-settings.interface';
|
||||
import type { User } from './user.interface';
|
||||
@ -102,7 +101,6 @@ export {
|
||||
Subscription,
|
||||
SymbolMetrics,
|
||||
TabConfiguration,
|
||||
TimelinePosition,
|
||||
UniqueAsset,
|
||||
User,
|
||||
UserSettings
|
||||
|
@ -8,7 +8,7 @@ export interface PortfolioPosition {
|
||||
allocationInPercentage: number;
|
||||
assetClass?: AssetClass;
|
||||
assetClassLabel?: string;
|
||||
assetSubClass?: AssetSubClass | 'CASH';
|
||||
assetSubClass?: AssetSubClass;
|
||||
assetSubClassLabel?: string;
|
||||
countries: Country[];
|
||||
currency: string;
|
||||
|
@ -1,31 +0,0 @@
|
||||
import { DataSource, Tag } from '@prisma/client';
|
||||
import { Big } from 'big.js';
|
||||
|
||||
export interface TimelinePosition {
|
||||
averagePrice: Big;
|
||||
currency: string;
|
||||
dataSource: DataSource;
|
||||
dividend: Big;
|
||||
dividendInBaseCurrency: Big;
|
||||
fee: Big;
|
||||
firstBuyDate: string;
|
||||
grossPerformance: Big;
|
||||
grossPerformancePercentage: Big;
|
||||
grossPerformancePercentageWithCurrencyEffect: Big;
|
||||
grossPerformanceWithCurrencyEffect: Big;
|
||||
investment: Big;
|
||||
investmentWithCurrencyEffect: Big;
|
||||
marketPrice: number;
|
||||
marketPriceInBaseCurrency: number;
|
||||
netPerformance: Big;
|
||||
netPerformancePercentage: Big;
|
||||
netPerformancePercentageWithCurrencyEffect: Big;
|
||||
netPerformanceWithCurrencyEffect: Big;
|
||||
quantity: Big;
|
||||
symbol: string;
|
||||
tags?: Tag[];
|
||||
timeWeightedInvestment: Big;
|
||||
timeWeightedInvestmentWithCurrencyEffect: Big;
|
||||
transactionCount: number;
|
||||
valueInBaseCurrency: Big;
|
||||
}
|
4
libs/common/src/lib/models/index.ts
Normal file
4
libs/common/src/lib/models/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { PortfolioSnapshot } from './portfolio-snapshot';
|
||||
import { TimelinePosition } from './timeline-position';
|
||||
|
||||
export { PortfolioSnapshot, TimelinePosition };
|
82
libs/common/src/lib/models/portfolio-snapshot.ts
Normal file
82
libs/common/src/lib/models/portfolio-snapshot.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import { transformToBig } from '@ghostfolio/common/class-transformer';
|
||||
import { UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||
import { TimelinePosition } from '@ghostfolio/common/models';
|
||||
|
||||
import { Big } from 'big.js';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
|
||||
export class PortfolioSnapshot {
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
currentValueInBaseCurrency: Big;
|
||||
errors?: UniqueAsset[];
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformance: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformanceWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformancePercentage: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformancePercentageWithCurrencyEffect: Big;
|
||||
|
||||
hasErrors: boolean;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netAnnualizedPerformance?: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netAnnualizedPerformanceWithCurrencyEffect?: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformance: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformanceWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformancePercentage: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformancePercentageWithCurrencyEffect: Big;
|
||||
|
||||
@Type(() => TimelinePosition)
|
||||
positions: TimelinePosition[];
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalFeesWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalInterestWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalInvestment: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalInvestmentWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalLiabilitiesWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalValuablesWithCurrencyEffect: Big;
|
||||
}
|
92
libs/common/src/lib/models/timeline-position.ts
Normal file
92
libs/common/src/lib/models/timeline-position.ts
Normal file
@ -0,0 +1,92 @@
|
||||
import { transformToBig } from '@ghostfolio/common/class-transformer';
|
||||
|
||||
import { DataSource, Tag } from '@prisma/client';
|
||||
import { Big } from 'big.js';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
|
||||
export class TimelinePosition {
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
averagePrice: Big;
|
||||
|
||||
currency: string;
|
||||
dataSource: DataSource;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
dividend: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
dividendInBaseCurrency: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
fee: Big;
|
||||
|
||||
firstBuyDate: string;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformance: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformancePercentage: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformancePercentageWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformanceWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
investment: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
investmentWithCurrencyEffect: Big;
|
||||
|
||||
marketPrice: number;
|
||||
marketPriceInBaseCurrency: number;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformance: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformancePercentage: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformancePercentageWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformanceWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
quantity: Big;
|
||||
|
||||
symbol: string;
|
||||
tags?: Tag[];
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
timeWeightedInvestment: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
timeWeightedInvestmentWithCurrencyEffect: Big;
|
||||
|
||||
transactionCount: number;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
valueInBaseCurrency: Big;
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import { getLocale } from '@ghostfolio/common/helper';
|
||||
import { AccountBalancesResponse } from '@ghostfolio/common/interfaces';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
CUSTOM_ELEMENTS_SCHEMA,
|
||||
ChangeDetectionStrategy,
|
||||
@ -36,7 +35,6 @@ import { GfValueComponent } from '../value';
|
||||
@Component({
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [
|
||||
CommonModule,
|
||||
GfValueComponent,
|
||||
MatButtonModule,
|
||||
MatDatepickerModule,
|
||||
|
@ -2,7 +2,6 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module';
|
||||
import { ISearchResultItem } from '@ghostfolio/ui/assistant/interfaces/interfaces';
|
||||
|
||||
import { FocusableOption } from '@angular/cdk/a11y';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
@ -19,7 +18,7 @@ import { Params, RouterModule } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [CommonModule, GfSymbolModule, RouterModule],
|
||||
imports: [GfSymbolModule, RouterModule],
|
||||
selector: 'gf-assistant-list-item',
|
||||
standalone: true,
|
||||
styleUrls: ['./assistant-list-item.scss'],
|
||||
|
@ -9,9 +9,9 @@
|
||||
>
|
||||
<br />
|
||||
<small class="text-muted"
|
||||
>{{ item?.symbol | gfSymbol }} · {{ item?.currency
|
||||
}}<ng-container *ngIf="item?.assetSubClassString">
|
||||
· {{ item?.assetSubClassString }}</ng-container
|
||||
></small
|
||||
></a
|
||||
>{{ item?.symbol | gfSymbol }} · {{ item?.currency }}
|
||||
@if (item?.assetSubClassString) {
|
||||
· {{ item.assetSubClassString }}
|
||||
}
|
||||
</small></a
|
||||
>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { FocusKeyManager } from '@angular/cdk/a11y';
|
||||
import { LEFT_ARROW, RIGHT_ARROW, TAB } from '@angular/cdk/keycodes';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
AfterContentInit,
|
||||
CUSTOM_ELEMENTS_SCHEMA,
|
||||
@ -22,7 +21,7 @@ import { CarouselItem } from './carousel-item.directive';
|
||||
|
||||
@Component({
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [CommonModule, MatButtonModule],
|
||||
imports: [MatButtonModule],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
selector: 'gf-carousel',
|
||||
standalone: true,
|
||||
|
@ -2,7 +2,6 @@ import { Currency } from '@ghostfolio/common/interfaces';
|
||||
import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field';
|
||||
|
||||
import { FocusMonitor } from '@angular/cdk/a11y';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
CUSTOM_ELEMENTS_SCHEMA,
|
||||
ChangeDetectionStrategy,
|
||||
@ -41,7 +40,6 @@ import { map, startWith, takeUntil } from 'rxjs/operators';
|
||||
'[id]': 'id'
|
||||
},
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
MatAutocompleteModule,
|
||||
MatFormFieldModule,
|
||||
|
@ -31,10 +31,7 @@
|
||||
<mat-form-field appearance="outline" class="w-100">
|
||||
<mat-label i18n>Retirement Date</mat-label>
|
||||
<div>
|
||||
{{
|
||||
calculatorForm.controls['retirementDate'].value
|
||||
| date: 'MMMM YYYY'
|
||||
}}
|
||||
{{ calculatorForm.get('retirementDate').value | date: 'MMMM YYYY' }}
|
||||
</div>
|
||||
<input
|
||||
class="d-none"
|
||||
|
@ -109,7 +109,7 @@
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="performance">
|
||||
<ng-container matColumnDef="performance" stickyEnd>
|
||||
<th
|
||||
*matHeaderCellDef
|
||||
class="justify-content-end px-1"
|
||||
|
@ -23,7 +23,7 @@ import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatSort, MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
||||
import { Router, RouterModule } from '@angular/router';
|
||||
import { AssetClass } from '@prisma/client';
|
||||
import { AssetClass, AssetSubClass } from '@prisma/client';
|
||||
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
|
||||
@ -66,7 +66,7 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy, OnInit {
|
||||
public dataSource: MatTableDataSource<PortfolioPosition> =
|
||||
new MatTableDataSource();
|
||||
public displayedColumns = [];
|
||||
public ignoreAssetSubClasses = [AssetClass.CASH];
|
||||
public ignoreAssetSubClasses = [AssetSubClass.CASH];
|
||||
public isLoading = true;
|
||||
public routeQueryParams: Subscription;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user