Versie 0.3.3

This commit is contained in:
Atreides Assets committed 2026-10-30 12:28:48 +01:00
1 parent 1cf6eeed29
commit 6e741a51fe
57 files changed
+1362 -2135

No files matched your search

+60 -61
View File
@@ -1,4 +1,4 @@
// Generated, do not edit. sha256:a167e18e55f858b6191c5f1c50bdab5b3bf485873744837c0e096e77f639cd0e
// Generated, do not edit. sha256:b049624ea50293251291f47db3c7beed3e81db7ec2c5e36ca24f472c360c5f37
import { nl } from './nl.js';
export const en = {
@@ -13,6 +13,8 @@ export const en = {
requestTooLarge: 'The request is too large.',
fileTooLarge: 'The file is too large.',
invalidAmount: 'Invalid amount.',
create: 'Create',
rename: 'Rename',
},
splash: {
@@ -72,20 +74,14 @@ export const en = {
'why_unknown-version': 'The app version cannot be determined',
why_licensed: 'Valid license',
cardTitle: 'License',
cardFree: 'This installation runs the free version: no time limit, with a small set of records and '
+ 'without the connections, the source choice and the taxes page. Reading and exporting always '
+ 'keep working; nothing is ever removed.',
cardBuy: 'The paid version lifts those limits. If you have a license file, drop it below.',
cardFull: 'This installation runs the full version. All limits are lifted and every feature is '
+ 'available.',
cardDevelop: 'This is a development version: below 1.0.0 the app restricts nothing.',
cardFacts: 'The license is for {buyer}, issued on {issued} and valid for major versions {from} '
+ 'through {to}.',
cardOutOfRange: 'This app is version {version} and falls outside that range.',
cardFree: 'Free version: no time limit, with a small set of records. Nothing is ever removed.',
cardFull: 'Full version: all limits lifted.',
cardFor: 'This license is for {npub}',
cardFacts: 'Issued on {issued}, valid for major versions {from} through {to}.',
cardProblem: 'There is a license file, but the app cannot use it.',
cardVersion: 'Version {version}',
signInTitle: 'Sign in',
signInIntro: 'Your license belongs to a nostr key. Sign in to fetch the licenses for that key.',
signInIntro: 'Sign in with your nostr key to buy or fetch your license.',
signInLast: 'Last signed in as {npub}.',
signInExtension: 'With extension',
signInExtensionNone: 'No nostr extension found in this browser (such as Alby or nos2x).',
@@ -126,7 +122,6 @@ export const en = {
buyClosed: 'Sales are closed at the moment.',
buyAway: 'Atreides Services cannot be reached right now, so buying is not possible at the moment. '
+ 'Try again later.',
buySignInFirst: 'Sign in first: the license is issued to your key.',
buyButton: 'Buy',
buyInvoice: 'Pay this invoice with a Lightning wallet. It is valid until {time}.',
buyOpenWallet: 'Open in wallet',
@@ -183,8 +178,7 @@ export const en = {
+ 'ID check).',
payNote: 'As of October 2026: check the terms with the provider.',
nostrMore: 'About nostr and your key',
signInKnown: 'Your license is on {npub}. Sign with that key to fetch licenses, buy or ask for '
+ 'support; the npub alone does not prove it is you.',
signInKnown: 'Use the key this license is on.',
infoNostrHead: 'What is nostr?',
infoNostr: 'Nostr is an open protocol in which your identity is a key pair. The public key (npub) is '
+ 'like an address: anyone may see it. The secret key (nsec) is like a password that no one can '
@@ -211,17 +205,14 @@ export const en = {
+ 'made unrecognizable, so it can only be matched if you come forward with it yourself.',
name_fiatAccounts: 'Fiat accounts',
name_assets: 'Assets besides currencies',
name_valuations: 'Balances',
name_portfolios: 'Portfolios',
featTitle: 'What the editions include',
featFull: 'Full',
featFree: 'Free',
featFreeOpen: 'What the free edition includes is not settled yet.',
featNoShot: 'No screenshot of this feature yet.',
featIncluded: 'Included',
featExcluded: 'Not included',
featUndecided: 'Not decided yet',
featPartial: 'partly',
featPartialTitle: 'Part of it is included',
featGroup_overview: 'Overview and reports',
featGroup_bitcoin: 'Bitcoin and Lightning',
@@ -238,22 +229,19 @@ export const en = {
feat_balances: 'Balances and reconcile',
feat_ownMempool: 'Your own mempool node',
feat_priceHistory: 'Price history',
feat_sourceChoice: 'Source choice per asset',
feat_providerKeys: 'Your own price sources and API keys',
feat_sourceChoice: 'Source choice matrix',
feat_providerKeys: 'Managing your own integrations and API keys',
feat_signals: 'Bitcoin signals, charts and widget',
feat_netshare: 'Network share widget',
feat_portfolios: 'Multiple portfolios',
feat_ai: 'AI connection (MCP)',
feat_accountMerge: 'Merging accounts',
feat_import: 'Import and export',
feat_data: 'Data: the raw tables',
feat_health: 'Health: checks on your records',
feat_kiosk: 'The app in its own window',
feat_metals: 'Precious metals, coins and bars',
unlimited: 'unlimited',
dropHere: 'Drag the license file here',
dropOr: 'or click to choose one',
dropTooBig: 'That file is far too large for a license. The license file is a small JSON file of a '
+ 'few lines at most.',
installOk: 'License saved. The app is now the full version.',
installOkFuture: 'License saved, but it does not cover this major version. The app stays in the free '
+ 'version for now.',
@@ -332,14 +320,14 @@ export const en = {
nwcRelayRefusedNoReason: 'The relay refuses the request and does not say why.',
nwcDecryptFailed: 'Decrypting the response failed: {reden}',
kindMarket: 'Atreides Services',
usedByMarket: "The app's own price service, for prices, the license and support. Address and token apply to the whole installation, so to every portfolio. The app talks to the service through its own server; the token stays server-side and never comes back to the browser.",
usedByMarket: "The app's own price service, for prices, the license and support. Address and token apply to the whole installation, so to every portfolio.",
marketConfigure: 'Configure',
marketDialogTitle: 'Configure Atreides Services',
marketTokenUnset: 'no token',
marketTokenLicense: 'token from the license ({tier})',
marketTokenManual: 'custom token',
marketTokenPending: 'the app requests a token with the license',
marketTokenNoLicense: 'no license to request a token with',
marketTokenLicense: 'Token from the license ({tier})',
marketTokenManual: 'Custom token',
marketTokenPending: 'The app requests a token with the license',
marketTokenNoLicense: 'No license to request a token with',
marketOverrideUrl: 'development address',
marketTestOk: '{app} {version} · {n} instruments',
marketSpot: 'What the app fetches from the service',
@@ -436,14 +424,14 @@ export const en = {
addNoFit: 'Not enough space here for the remaining widgets',
addNone: 'Everything has been added',
profile: 'Layout',
profileNew: 'New layout…',
profileNew: 'New layout',
profileNewPrompt: 'Name of the new layout',
profileRename: 'Rename…',
profileRename: 'Rename',
profileRenamePrompt: 'New name for this layout',
profileDelete: 'Delete this layout…',
profileDelete: 'Delete this layout',
profileDeleteConfirm: 'Delete this layout and all its widgets? The other layouts remain.',
profileSystemHint: 'The default layout cannot be renamed.',
profileRestart: 'Start default layout over…',
profileRestart: 'Start default layout over',
profileRestartConfirm: 'Start the default layout over? What you placed yourself is removed and the default layout takes its place.',
nameRequired: 'A layout needs a name.',
unknownProfile: 'Layout #{id} does not exist.',
@@ -610,7 +598,7 @@ export const en = {
kindSourceChoice: 'Source choice',
sourceFirst: 'first',
sourceRemove: 'remove',
sourceChoiceNote: 'You can see the chain as it stands now on Integrations, Source choice, or on the Source tab of Price history.',
sourceChoiceNote: 'You can see the chain as it stands now on Integrations, Source choice, or on the Prices tab of Price history.',
unknownKind: 'Unknown kind of proposal',
ledger: 'ledger',
diff: 'difference',
@@ -928,7 +916,7 @@ export const en = {
finish: 'Set up',
persona_bitcoin: 'Bitcoin only',
persona_broad: 'Broader',
rerun: 'Set up…',
rerun: 'Set up',
},
notes: {
tab: 'Notes',
@@ -1236,9 +1224,7 @@ export const en = {
fiatHint: 'Traditional currency',
btcHint: 'Base unit · max 21 million',
hierarchy: 'Unit hierarchy',
satNote: 'The satoshi is the smallest on-chain unit. The millisatoshi exists only on the Lightning Network.',
footer: 'Live price from the selected price source',
},
satNote: 'The satoshi is the smallest on-chain unit. The millisatoshi exists only on the Lightning Network.', },
labels: {
title: 'Labels',
@@ -1301,6 +1287,7 @@ export const en = {
merge: 'Merge',
mergeTitle: 'Merge two accounts into one',
mergeNeedTwo: 'You need at least two accounts to merge.',
mergePaid: 'Merging accounts is part of the full edition.',
mergePick: '(choose an account)',
mergeKeep: 'Account to keep',
mergeDrop: 'Account to remove',
@@ -1544,7 +1531,6 @@ export const en = {
},
valuations: {
maxFree: 'The free version is limited to {max} balance. A license removes that limit; nothing is removed in the meantime.',
title: 'Balances',
needAsset: 'Create an asset first or migrate the data on the overview.',
colDate: 'Reference date',
@@ -1979,7 +1965,6 @@ export const en = {
provToGaps: 'Go to this gap under Gaps',
provSpotNote: 'up to {pct} off the closing price',
provCarriedNote: 'up to {n} days old',
tabSource: 'Source',
diagCard_noCoverage: 'No integration provides prices',
diagCard_allInactive: '{namen} is turned off',
diagCard_noChoice: 'No source selected',
@@ -2146,58 +2131,72 @@ export const en = {
archiveFull: 'The archive is full of folders named "{naam}"; clean up a few first.',
notInArchive: 'There is no "{naam}" in the archive.',
passwordRequired: 'Enter a password.',
intro: 'Each portfolio is a separate set of records: its own database and its own secrets, in its own folder. Exactly one is always open.',
intro: 'Each portfolio is a separate set of records: its own database and its own secrets, in its own folder. Exactly one is always open; its card comes first.',
openNow: 'Open now',
activate: 'Open…',
activate: 'Open',
activateConfirm: 'Switch to "{naam}"? The app restarts to do this.',
activateWaiting: 'The app is restarting…',
activateNoSupervisor: 'The choice is saved, but this app was started without the supervisor (npm run start:server). Close the app and start it again to work in "{naam}".',
create: 'New portfolio…',
create: 'New portfolio',
createConfirm: 'Create',
createName: 'Name',
createNameHint: 'The name becomes the folder name on disk.',
createCurrency: 'Base currency',
createDone: 'Portfolio "{naam}" created.',
copy: 'Copy…',
copy: 'Copy',
copyTitle: 'Copy of "{naam}"',
copyName: 'Name of the copy',
copyConfirm: 'Copy',
copyDone: 'Portfolio "{naam}" created as a copy of "{bron}".',
createHint: 'New portfolio gives fresh records without connections. You copy a portfolio from the list; a copy takes the database and the secrets along together, because a secret belongs to a row and only fits that database.',
createHint: 'New portfolio gives fresh records without connections. You copy a portfolio through the menu (…) on its card; a copy takes the database and the secrets along together, because a secret belongs to a row and only fits that database.',
createCurrencyHint: 'The base currency is the currency the portfolio calculates in and shows all amounts in. You choose it for a new portfolio and after that it is fixed; a copy keeps the currency of the original.',
rename: 'Rename…',
rename: 'Rename',
renameTo: 'New name',
renameDone: 'Renamed to "{naam}".',
renameActive: 'The portfolio that is open now cannot be renamed: its database is open. Switch to another one first.',
remove: 'Delete…',
remove: 'Delete',
removeConfirm: 'Delete portfolio "{naam}"? The folder moves to the archive; nothing is erased. Type the name to confirm.',
removeTypeLabel: 'Type the name',
removeMismatch: 'That is not the name; nothing was changed.',
removeDone: '"{naam}" is now in the archive.',
empty: 'There is no other portfolio yet.',
noDatabase: 'no database yet',
lastUsed: 'last used',
never: 'not used yet',
cardSince: '{munt}, since {jaar}',
factAssets: 'Assets in use',
factAccounts: 'Active accounts',
factEvents: 'Entries',
factValuations: 'Balances',
factLastUsed: 'Last used',
factBackup: 'Last backup',
backupNever: 'never',
more: 'More actions',
backupTitle: 'Backup',
backupLateHint: 'The last backup turns orange when it is older than {dagen} days or none was ever made. Restore and start empty sit in the menu (…) of the portfolio that is open and apply only to it.',
archiveCount: 'Archive ({n})',
demoBadge: 'Example',
demoHint: 'Demo is example records with bitcoin, an exchange, a wallet of your own and a bank account, filled over the past two and a half years. It does not count towards the limit of the free edition. Opening it is a restart; so is going back to your own portfolio.',
archiveTitle: 'Archive',
archiveIntro: 'Deleted portfolios are kept here. They no longer count anywhere, but the files still exist.',
archiveEmpty: 'The archive is empty.',
purge: 'Delete permanently…',
purge: 'Delete permanently',
purgeConfirm: 'Permanently delete the folder of "{naam}" and everything in it? The database, secrets and history will be gone. This cannot be undone. Type the name to confirm.',
purgeDone: '"{naam}" has been permanently deleted.',
settingsTitle: 'Settings of this portfolio',
settingsButton: 'Settings',
settingsOf: 'Settings of {naam}',
hintTitle: 'What you see here',
authTitle: 'Access to this portfolio',
authNone: 'No password set. The app can therefore only be reached from this machine.',
authNone: 'No password set.',
authSet: 'A password is set.',
authEnv: 'Set through the environment variable ASSETAPP_PASSWORD. As long as that is set, it overrides what you enter here.',
authChange: 'Set or change…',
authClear: 'Clear…',
authChange: 'Set password',
authSave: 'Save',
authClear: 'Clear',
authPassword: 'Password',
authClearConfirm: 'Remove the password of this portfolio? After that the app can only be reached from this machine.',
authDone: 'Saved. It applies from the next time the app starts.',
authClearedDone: 'Removed. It applies from the next time the app starts.',
authLogout: 'Sign out',
authLogoutConfirm: 'Sign out? You need to enter the password again to continue.',
authHint: 'Access from another device requires a certificate and sign-in credentials. The certificate belongs to this installation; the credentials to this portfolio.',
authHint: 'Without a password the app can only be reached from this machine. Access from another device requires a certificate and sign-in credentials. The certificate belongs to this installation; the credentials to this portfolio.',
startYearTitle: 'Start year of these records',
startYearLabel: 'Start reports at',
startYearAuto: 'Automatic (from the first entry)',
@@ -2214,7 +2213,6 @@ export const en = {
mwrHint: 'This changes the percentages on the taxes page. Modified Dietz always gives a figure; IRR is more accurate but does not always have a solution, for example with a position that drops to zero in between. The chosen method is always shown with the figure.',
},
dbfile: {
title: 'All records',
passTooShort: 'Choose a password of at least 8 characters for the backup.',
notABackup: 'This file is not an AssetApp backup (too short).',
notABackupUseRestore: 'This file is not an AssetApp backup. You restore a separate .sqlite file with "Restore".',
@@ -2231,20 +2229,21 @@ export const en = {
versionNewerThanApp: 'This database is version {versie} and therefore newer than the app ({app}). Update the app before you restore it.',
emptyFile: 'Empty file received.',
notSqlite: 'This is not an SQLite file (the file header does not match).',
backup: 'Back up…',
backup: 'Backup',
backupConfirm: 'Back up',
backupPass: 'Password for the backup',
backupPassAgain: 'Repeat password',
backupPassMismatch: 'The two passwords do not match.',
backupDone: 'Backup created. Keep the password safe: without the password the backup cannot be restored.',
export: 'Export database',
import: 'Restore…',
import: 'Restore',
confirmRestoreBackup: 'Restore this backup? This replaces the database AND the secrets (secrets.json in the folder of this portfolio). The previous version of both is kept as .previous.',
restoredSecrets: 'Secrets restored as well:',
confirmImport: 'Replace the current database with this file? The previous one is kept as .previous next to the database file.',
importDone: 'Database restored',
importOrphans: 'Note, orphaned references found:',
hint: 'The backup contains the database and the secrets, encrypted. The export is only the database: enough to read, not enough to restore everything.',
fresh: 'Start empty…',
fresh: 'Start empty',
confirmFresh: 'Start with empty records? A fresh database is put into use; the current one is kept as .previous next to the database file. Make a backup first if you might ever need it again.',
freshWord: 'empty',
freshTypeLabel: 'Type the word to confirm',
@@ -2266,7 +2265,7 @@ export const en = {
nSkipped: 'skipped',
account: 'Account (exchange) for this import',
chooseAccount: '(choose account)',
newAccount: '+ new exchange account…',
newAccount: '+ new exchange account',
newAccountPh: 'Name of new account',
assetsTitle: 'Assets',
assetOk: 'linked',