ADR 0044's step 6a (D42, D43, D45): accounts for programs, such as AI assistants, that an identified person makes from the Profile. halkyon_base keeps them on the instance's register, which its members ask: an agent is an account (agent_account: its owner, its name, its public keys, set by itself once) with one token (agent_token: 32 random bytes, kept as their SHA-256 alone, shown once). agents.create, mine, newToken, revoke, delete and setKeys serve its owner; agentSignIn.signIn exchanges the token for an ordinary server-side session of a day, with the scopes identified and agent, at most 60 sign-ins an hour from a network. Revoking a token or making a new one ends the agent's sessions; a token unused for 90 days lapses in every service's pruning. Up to 5 agents a person, where the operator didn't switch them off (AGENTS=off; said on the privacy page and in instance.basics). An agent makes no agents, creates or owns no shared space, is invited and raised as a Viewer alone, is never handed a space on, is named no operator and granted no assistants; each refusal has its test. Deleting a person deletes their agents first; an agent's public profile names whose agent it is. In the apps, every Profile has an Agents card (halkyon_app's AgentsSection): made with a name and a handle, its token shown once to copy, a new token, the token taken back, deleted. Learn's Share sheet marks an agent among the members and offers it no role above Viewer. The migrations, the module's and each host's (Learn, Meditate, Todo, Train), are additive alone: CREATE TABLE "agent_account" with a unique index on "agentId" (one row an agent account) and one on "ownerId" (a person's agents, and deleting them with the person), and CREATE TABLE "agent_token" with unique indexes on "agentId" (one token an agent) and "tokenHash" (the sign-in finds the token by its hash). No existing table is touched, so the server before the deploy keeps working on the migrated database. Whats-New: Make agents in your Profile: accounts for programs such as AI assistants, which sign in with a token and see only what you share with them. Whats-New-De: Leg in deinem Profil Agenten an: Konten für Programme wie KI-Assistenten, die sich mit einem Token anmelden und nur sehen, was du mit ihnen teilst. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
1652 lines
67 KiB
Text
1652 lines
67 KiB
Text
{
|
||
"@@locale": "en",
|
||
"tryAgain": "Try again",
|
||
"instanceWelcome": "Welcome to {app}",
|
||
"@instanceWelcome": {
|
||
"description": "Screen readers hear it for the wordmark on the first start.",
|
||
"placeholders": {
|
||
"app": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceBuiltInTagline": "Comes with the app",
|
||
"instanceAnother": "Another instance",
|
||
"instanceAnotherTagline": "Enter its address",
|
||
"instanceAddress": "Instance address",
|
||
"instanceAddressInvalid": "This isn't an address.",
|
||
"instanceAddressInsecure": "{app} reaches instances over HTTPS only, so that nobody on the way reads or changes what it sends. Ask for the instance's HTTPS address.",
|
||
"@instanceAddressInsecure": {
|
||
"placeholders": {
|
||
"app": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceInsecure": "{name} is reached over plain HTTP, where anyone on the way could read and change what {app} sends, so {app} no longer opens it. Its account stays on {name} and on this device. Use another instance, or remove it from this device.",
|
||
"@instanceInsecure": {
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
},
|
||
"app": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceInsecureUseAnother": "Use another instance",
|
||
"instanceInsecureRemove": "Remove from this device",
|
||
"instanceAddressRequired": "Enter the address of an instance.",
|
||
"instanceContinue": "Continue",
|
||
"instanceUnreachable": "No instance of {app} answers at {name}.",
|
||
"@instanceUnreachable": {
|
||
"placeholders": {
|
||
"app": {
|
||
"type": "String"
|
||
},
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceUseBuiltIn": "Use {name}",
|
||
"@instanceUseBuiltIn": {
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceOpenFailed": "Couldn't open the app on {name}.",
|
||
"@instanceOpenFailed": {
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceDataAndBackupsIn": "Data and backups: {place}",
|
||
"@instanceDataAndBackupsIn": {
|
||
"placeholders": {
|
||
"place": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceDataIn": "Data: {place}",
|
||
"@instanceDataIn": {
|
||
"placeholders": {
|
||
"place": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceBackupsIn": "Backups: {place}",
|
||
"@instanceBackupsIn": {
|
||
"placeholders": {
|
||
"place": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceNoBackups": "No backups",
|
||
"instanceEuropeanUnion": "European Union",
|
||
"instanceCountryInEu": "{country} (EU)",
|
||
"@instanceCountryInEu": {
|
||
"description": "A country of the European Union, where an instance keeps data: Germany (EU).",
|
||
"placeholders": {
|
||
"country": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"instanceSubdivisionOf": "{subdivision}, {country}",
|
||
"@instanceSubdivisionOf": {
|
||
"description": "A state or region with its country, where an instance keeps data: California, United States.",
|
||
"placeholders": {
|
||
"subdivision": {
|
||
"type": "String"
|
||
},
|
||
"country": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"accountsTitle": "Accounts",
|
||
"accountAdd": "Add account",
|
||
"accountAddSubtitle": "Choose the instance for the account to add.",
|
||
"accountSignedIn": "Signed in",
|
||
"accountRemoveTooltip": "Remove account",
|
||
"accountRemoveTitle": "Remove account?",
|
||
"accountRemoveMessage": "Removes the account on {name} from this device, with all the device holds of it. What it synced stays on {name}: sign in there again to have it.",
|
||
"@accountRemoveMessage": {
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"accountRemoveConfirm": "Remove",
|
||
"accountSignedInOn": "Signed in on {instance}",
|
||
"@accountSignedInOn": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"accountSwitch": "Switch account",
|
||
"accountSignOut": "Sign out",
|
||
"accountDelete": "Delete account",
|
||
"accountDeleteTitle": "Delete your account?",
|
||
"accountSignOutFailed": "Couldn't sign out on this device. Try again.",
|
||
"accountDeleteFailed": "Couldn't delete your account: the instance wasn't reached. Try again.",
|
||
"aboutSourceCode": "The source of what this instance runs:",
|
||
"aboutSourceUnreachable": "Couldn't reach this instance to ask where its source is.",
|
||
"sessionUnreachable": "Couldn't reach the server.",
|
||
"personDataFailed": "Couldn't open this device's data.",
|
||
"startSignedOut": "Signed out",
|
||
"startOn": "Start on {instance}:",
|
||
"@startOn": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"startOtherInstance": "Use another instance",
|
||
"startNoWay": "{instance} offers no way to create an account.",
|
||
"@startNoWay": {
|
||
"description": "On the start screen, where the instance offers neither SimpleLogin nor a password (ADR 0020, D4): nobody can make an account there.",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"startSignUpsApproved": "New accounts on {instance} wait until its operator approves them.",
|
||
"@startSignUpsApproved": {
|
||
"description": "On the start screen, where new accounts wait for the operator's approval (Halkyon Learn's ADR 0021, D19).",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"startSignUpsClosed": "{instance} takes no new accounts: sign in with yours.",
|
||
"@startSignUpsClosed": {
|
||
"description": "On the start screen, where the operator takes no new accounts (D19); Create an account is gone.",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"syncTitle": "Sync",
|
||
"syncNow": "Sync now",
|
||
"syncStateSyncing": "Syncing…",
|
||
"syncStateSynced": "Everything synced",
|
||
"syncStateFailing": "Sync is failing",
|
||
"syncStateNotYet": "Not synced yet",
|
||
"syncStateMismatch": "This app can't sync with {server}",
|
||
"@syncStateMismatch": {
|
||
"placeholders": {
|
||
"server": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"syncMismatchDetail": "Update the app. If it is up to date, the server needs an update. What you do meanwhile stays on this device and syncs afterwards.",
|
||
"syncLastCompleted": "Last completed at {time}",
|
||
"@syncLastCompleted": {
|
||
"placeholders": {
|
||
"time": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"syncLastFailed": "Last attempt failed at {time}",
|
||
"@syncLastFailed": {
|
||
"placeholders": {
|
||
"time": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"syncNoRunYet": "No sync has completed since the app started",
|
||
"syncPending": "{count, plural, =1{1 change waits to sync} other{{count} changes wait to sync}}",
|
||
"@syncPending": {
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"syncTroubleLabel": "Sync needs attention",
|
||
"syncMismatchBanner": "This app can't sync with {server} any more. Update it to keep syncing.",
|
||
"@syncMismatchBanner": {
|
||
"placeholders": {
|
||
"server": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"syncMismatchMore": "More",
|
||
"startSignIn": "Sign in",
|
||
"startCreateAccount": "Create an account",
|
||
"waitWaiting": "Your account waits until the operator of {instance} approves it.",
|
||
"@waitWaiting": {
|
||
"description": "On the wait screen of a new account (D31), under its handle.",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"waitSuspended": "The operator of {instance} has suspended your account. Only they can lift it.",
|
||
"@waitSuspended": {
|
||
"description": "On the wait screen of a suspended account (D31).",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"waitApproved": "The operator of {instance} has approved your account. Sign in once more, as you did before.",
|
||
"@waitApproved": {
|
||
"description": "On the wait screen once the account is approved (D31), above Sign in.",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"waitEnded": "This sign-up has ended: the operator of {instance} refused it, or it waited too long.",
|
||
"@waitEnded": {
|
||
"description": "On the wait screen once the instance knows the wait no more: refused, past its 14 days, or its pass past its 30 (D31).",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"waitBack": "Back to the start",
|
||
"@waitBack": {
|
||
"description": "The button of an ended wait: the start screen."
|
||
},
|
||
"waitMatchingCode": "Matching code",
|
||
"@waitMatchingCode": {
|
||
"description": "Above the four words the operator reads out for the person to match (D33)."
|
||
},
|
||
"waitMatchingNote": "When the operator of {instance} reads you four words, check that they are these. Never read them out yourself: Halkyon never asks anyone to.",
|
||
"@waitMatchingNote": {
|
||
"description": "Under the matching code (D33): the operator reads, the person confirms, so nobody posing as the operator learns the words.",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"waitCheckNow": "Check now",
|
||
"@waitCheckNow": {
|
||
"description": "Asks the instance at once where the wait stands; it asks every 30 seconds by itself."
|
||
},
|
||
"waitUnreachable": "{instance} couldn't be reached. It's asked again every 30 seconds.",
|
||
"@waitUnreachable": {
|
||
"description": "On the wait screen, when asking where the wait stands failed.",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"waitDelete": "Delete this account",
|
||
"@waitDelete": {
|
||
"description": "On the wait screen of a new account: deletes it with its pass (D31)."
|
||
},
|
||
"waitDeleteTitle": "Delete this account?",
|
||
"@waitDeleteTitle": {
|
||
"description": "The question before a waiting account is deleted."
|
||
},
|
||
"waitDeleteMessage": "It goes with everything it has, and nobody can sign in to it again.",
|
||
"@waitDeleteMessage": {
|
||
"description": "Under that question."
|
||
},
|
||
"waitDeleteFailed": "Couldn't delete the account. Try again.",
|
||
"@waitDeleteFailed": {
|
||
"description": "On the wait screen, when deleting the account failed."
|
||
},
|
||
"passwordAddress": "Email address",
|
||
"passwordPassword": "Password",
|
||
"passwordNewPassword": "New password",
|
||
"passwordCurrent": "Current password",
|
||
"passwordRepeat": "New password again",
|
||
"passwordsDiffer": "The two passwords differ.",
|
||
"passwordShow": "Show password",
|
||
"passwordHide": "Hide password",
|
||
"passwordContinue": "Continue",
|
||
"passwordBack": "Back",
|
||
"passwordDone": "Done",
|
||
"passwordSave": "Save as a file",
|
||
"passwordQrCode": "QR code for your authenticator app",
|
||
"passwordMailCode": "Code from the email",
|
||
"passwordMailCodeSent": "We emailed a code to {address}. It's valid for 15 minutes.",
|
||
"@passwordMailCodeSent": {
|
||
"placeholders": {
|
||
"address": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordHandleIntro": "A code is on its way to {address}. Meanwhile, choose your handle: others find you by it. It stays private until you publish something or fill in your profile, and can change until your first publish.",
|
||
"@passwordHandleIntro": {
|
||
"placeholders": {
|
||
"address": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordResendCode": "Send a new code",
|
||
"passwordTotpCode": "Code from your authenticator app",
|
||
"passwordRecoveryCode": "Recovery code",
|
||
"passwordUseRecoveryCode": "Use a recovery code instead",
|
||
"passwordUseTotpCode": "Use your authenticator app instead",
|
||
"passwordUnlocking": "Unlocking your password on this device…",
|
||
"passwordMakingKeys": "Making your keys on this device…",
|
||
"passwordSignInTitle": "Sign in",
|
||
"passwordSignInAction": "Sign in",
|
||
"passwordSignInIntro": "With the email address and password of your account on {instance}.",
|
||
"@passwordSignInIntro": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordSecondFactorIntro": "Enter the code your authenticator app shows for {instance}.",
|
||
"@passwordSecondFactorIntro": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordRecoveryCodeIntro": "Enter one of the recovery codes you kept. Each signs in once.",
|
||
"passwordForgot": "Forgot your password?",
|
||
"passwordOtherPassword": "Change the address or password",
|
||
"passwordLostAuthenticator": "Lost your authenticator?",
|
||
"passwordLostAuthenticatorTitle": "Lost authenticator",
|
||
"passwordLostAuthenticatorIntro": "With a recovery code you sign in as usual. Without one, ask to reset your authenticators: it takes effect 72 hours later, and signing in with a code before then stops it.",
|
||
"passwordResetWithMail": "Reset with a code by email",
|
||
"passwordResetWithMailHint": "We email a code to {address}.",
|
||
"@passwordResetWithMailHint": {
|
||
"placeholders": {
|
||
"address": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordResetWithPhrase": "Reset with your recovery phrase",
|
||
"passwordResetWithPhraseHint": "The 24 words you wrote down.",
|
||
"passwordSignInWithoutCode": "Sign in without a code",
|
||
"passwordSignInWithoutCodeHint": "Once a reset you asked for has taken effect.",
|
||
"passwordResetAction": "Reset",
|
||
"passwordAuthenticatorResetAt": "Your authenticators are reset on {date}. We emailed you: if it wasn't you, sign in with a code before then to stop it. After that, sign in with your password alone and set up a new authenticator.",
|
||
"@passwordAuthenticatorResetAt": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordUnfinishedIntro": "Your account was never finished. We emailed a code to {address}: with it, you sign in and set up an authenticator.",
|
||
"@passwordUnfinishedIntro": {
|
||
"placeholders": {
|
||
"address": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordPhraseField": "Recovery phrase",
|
||
"passwordPhraseFieldHint": "The 24 words, with spaces between them",
|
||
"passwordPhraseFieldIntro": "Enter your recovery phrase: it proves the account is yours.",
|
||
"passwordAuthenticatorTitle": "Set up an authenticator",
|
||
"passwordAuthenticatorIntro": "Every sign-in takes a code from an authenticator app, such as Aegis, 2FAS or Proton Authenticator. Scan this code with it, or type in the key.",
|
||
"passwordAuthenticatorKey": "Key",
|
||
"passwordAuthenticatorKeyCopied": "Key copied. It's taken off the clipboard again in a minute.",
|
||
"@passwordAuthenticatorKeyCopied": {
|
||
"description": "After the authenticator's key was copied during its setup; the app empties the clipboard 60 seconds later."
|
||
},
|
||
"passwordAuthenticatorOpen": "Open in your authenticator app",
|
||
"passwordAuthenticatorNoApp": "No app on this device opens it. Scan the code or type in the key.",
|
||
"passwordAuthenticatorCodeIntro": "Then enter the code it shows.",
|
||
"passwordAuthenticatorOwnerIntro": "To add it, confirm it is you: your password and a code from an authenticator you added before.",
|
||
"passwordExistingCode": "Code from an authenticator you added before",
|
||
"passwordRecoveryCodesTitle": "Recovery codes",
|
||
"passwordRecoveryCodesIntro": "Each signs in once in place of a code from your authenticator, should you lose it. Keep them where only you find them: they're shown only now.",
|
||
"passwordCodesKept": "I've kept them",
|
||
"passwordPhraseTitle": "Your recovery phrase",
|
||
"passwordPhraseIntro": "These 24 words open your account's keys should you forget your password: without them, what's encrypted is lost. Write them down in order, and keep them where only you find them. They're shown only now.",
|
||
"passwordPhraseWrittenDown": "I've written it down",
|
||
"passwordPhraseCheckTitle": "Check your recovery phrase",
|
||
"passwordPhraseCheckIntro": "Type the words asked for, from what you wrote down.",
|
||
"passwordPhraseWord": "Word {number}",
|
||
"@passwordPhraseWord": {
|
||
"placeholders": {
|
||
"number": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"passwordPhraseWrong": "These aren't the words. Look again at what you wrote down.",
|
||
"passwordPhraseNotAWord": "Not a word a recovery phrase is made of",
|
||
"passwordPhraseShowAgain": "Show the phrase again",
|
||
"passwordCreateTitle": "Create an account",
|
||
"passwordCreateIntro": "On {instance}, with your email address, a password, and an authenticator app for the code every sign-in takes.",
|
||
"@passwordCreateIntro": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordSetUpTitle": "Set up a password",
|
||
"passwordSetUpIntro": "Sign in with your email address, a password and an authenticator app, on this device and others. Everything you have stays.",
|
||
"passwordChooseIntro": "Choose a password. It never leaves this device: the instance can't read it, and can't reset it without what it protects being lost.",
|
||
"passwordFinishResetTitle": "Finish the reset",
|
||
"passwordFinishResetIntro": "72 hours after you asked to reset your account, finish it here with a new code by email.",
|
||
"passwordFinishResetHavePhrase": "I have my recovery phrase",
|
||
"passwordFinishResetKeepsKeys": "Your account keeps its keys: nothing encrypted is lost.",
|
||
"passwordFinishResetNewKeys": "Without your recovery phrase, your account gets new keys: what was encrypted with the old ones is lost.",
|
||
"passwordRecoveryTitle": "Get back into your account",
|
||
"passwordRecoveryWithPhrase": "I have my recovery phrase",
|
||
"passwordRecoveryWithPhraseHint": "Set a new password at once. Everything stays.",
|
||
"passwordRecoveryWithPhraseIntro": "Your recovery phrase opens your account's keys, which your new password then protects. A code from your authenticator, or a recovery code, confirms it.",
|
||
"passwordRecoveryNoCodeHint": "Lost your authenticator as well? Reset your account 72 hours later with your recovery phrase: it keeps everything.",
|
||
"passwordRecoveryWithoutPhrase": "Reset my account",
|
||
"passwordRecoveryWithoutPhraseHint": "Takes effect 72 hours later. Without your recovery phrase, what's encrypted is lost.",
|
||
"passwordRecoveryStartIntro": "We email a code to your address. Your account can then be reset 72 hours later; signing in with your password before then stops it.",
|
||
"passwordRecoveryFinish": "Finish a reset",
|
||
"passwordRecoveryFinishHint": "72 hours after you asked for it.",
|
||
"passwordResetStarted": "Your account can be reset from {date}. We emailed you: if it wasn't you, sign in with your password before then to stop it.",
|
||
"@passwordResetStarted": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordSectionTitle": "Password and authenticator",
|
||
"passwordSectionFailed": "Couldn't read how your account signs in.",
|
||
"passwordSectionSetUp": "Set up a password",
|
||
"passwordSectionSetUpHint": "Sign in with your email address, a password and an authenticator app.",
|
||
"passwordSectionUnfinished": "Finish setting up: add an authenticator",
|
||
"passwordSectionUnfinishedHint": "Your password signs in once an authenticator is set up.",
|
||
"passwordSectionChange": "Change password",
|
||
"passwordSectionKeysMissing": "Sign in on this device with your password to change it.",
|
||
"passwordSectionNotConfirmed": "Not set up yet",
|
||
"passwordSectionRemove": "Remove {name}?",
|
||
"@passwordSectionRemove": {
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordSectionRemoveIntro": "Enter your password and a code from one of your authenticators to confirm.",
|
||
"passwordSectionRemoveAction": "Remove",
|
||
"passwordSectionAddAuthenticator": "Add an authenticator",
|
||
"passwordSectionRecoveryCodes": "New recovery codes",
|
||
"passwordSectionRecoveryCodesHint": "The old ones stop working.",
|
||
"passwordSectionNewPhrase": "New recovery phrase",
|
||
"passwordSectionPhraseHint": "Your old phrase stops working.",
|
||
"passwordChangeTitle": "Change password",
|
||
"passwordChangeIntro": "Your other devices are signed out. Your keys stay: nothing is lost.",
|
||
"passwordChangeAction": "Change password",
|
||
"passwordChanged": "Password changed. Your other devices are signed out.",
|
||
"passwordNewCodesIntro": "Enter your password and a code from your authenticator app. Your old recovery codes stop working.",
|
||
"passwordNewPhraseIntro": "Your new recovery phrase. Write the 24 words down in order: once you confirm it, your old phrase opens nothing any more.",
|
||
"passwordPhraseKept": "New recovery phrase set. The old one no longer works.",
|
||
"passwordWrongCredentials": "The address, the password or the code isn't right.",
|
||
"passwordTooManyAttempts": "Too many attempts. Try again in an hour.",
|
||
"passwordSetupIncomplete": "Your account was never finished: set up an authenticator.",
|
||
"passwordNotDue": "This takes effect on {date}.",
|
||
"@passwordNotDue": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordNotDueYet": "This hasn't taken effect yet.",
|
||
"passwordNoReset": "No reset waits for this address.",
|
||
"passwordExists": "This address's account has a password already. Sign in with it, or get back in if you've forgotten it.",
|
||
"passwordAddressTaken": "This address belongs to another account.",
|
||
"passwordNoPassword": "This account has no password.",
|
||
"passwordWrongCode": "This code isn't right. Enter the one your app shows now.",
|
||
"passwordLastAuthenticator": "Your last authenticator can't go: every sign-in needs one.",
|
||
"passwordTooManyAuthenticators": "Your account has as many authenticators as it may. Remove one first.",
|
||
"passwordUnknownAuthenticator": "This authenticator is gone.",
|
||
"passwordInvalidSetup": "The instance didn't accept what this device made. Update the app, or try again.",
|
||
"passwordChallengeExpired": "That took too long. Try again.",
|
||
"passwordUnavailable": "This instance offers no password sign-in.",
|
||
"passwordNotAnAddress": "This isn't an email address.",
|
||
"passwordTooManyCodes": "Too many codes asked for. Try again in an hour.",
|
||
"passwordWrongMailCode": "This code isn't right.",
|
||
"passwordTooManyMailTries": "Too many wrong codes. Ask for a new one.",
|
||
"passwordMailCodeExpired": "This code is no longer valid. Ask for a new one.",
|
||
"passwordMailFailed": "The instance couldn't send the email. Try again later.",
|
||
"passwordOtherAddressLinked": "Your account has another email address.",
|
||
"passwordNotAPhrase": "This isn't a recovery phrase: check every word and their number.",
|
||
"passwordPhraseDoesNotFit": "The address or the recovery phrase isn't right.",
|
||
"passwordUnusable": "This password can't be used: it's empty, or holds characters that aren't text.",
|
||
"passwordInstanceUnproven": "The instance couldn't prove it knows your password, so this device trusts nothing it says. Try again; if it happens again, the instance isn't the one it claims to be.",
|
||
"passwordKeysMissing": "Your account's keys aren't on this device. Sign out and in again with your password here.",
|
||
"signUpsClosed": "This instance takes no new accounts.",
|
||
"@signUpsClosed": {
|
||
"description": "A sign-up refused: the operator takes no new accounts (D19)."
|
||
},
|
||
"signUpsTooManyWaiting": "Too many new accounts already wait for approval. Try again later.",
|
||
"@signUpsTooManyWaiting": {
|
||
"description": "A sign-up refused: ten new accounts wait for the operator's approval already (D19)."
|
||
},
|
||
"passwordUnsafeCosts": "The instance asked for your password to be checked in a way no account uses, so nothing was sent. If it happens again, the instance isn't the one it claims to be.",
|
||
"passwordFailed": "Couldn't reach the instance. Check the connection and try again.",
|
||
"passwordMinLength": "At least {count} characters",
|
||
"@passwordMinLength": {
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"passwordTooShort": "A new password needs at least {count} characters: should the instance's database ever leak, a short one is guessed first.",
|
||
"@passwordTooShort": {
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"passwordCodesWait": "Too many wrong codes in a row: no code is taken until {date}. If they weren't yours, someone knows your password: change it then.",
|
||
"@passwordCodesWait": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordDeleteIntro": "Your account goes with everything in it, in every service of this instance. To confirm, type your password and a code from your authenticator app.",
|
||
"passwordSessionEnded": "Too many wrong codes in a row from this device: it was signed out. Sign in again with your password and a code.",
|
||
"passwordAddressUnknown": "Enter your account's email address: the code goes there.",
|
||
"passwordDeleteIntroByMail": "Your account goes with everything in it, in every service of this instance. None of its authenticators works now, so a code by mail confirms it: type your password, then the code we email to your address.",
|
||
"passwordDeleteSendCode": "Email me a code",
|
||
"passwordAuthenticatorPasswordIntro": "To add it, confirm it is you with your password.",
|
||
"passwordWarningTitle": "Someone tried your password",
|
||
"passwordWarningBody": "On {date}, a device signed in to your account sent a wrong password or code ten times in a row, and was signed out. If that wasn't you, someone else may have that device or its session: change your password.",
|
||
"@passwordWarningBody": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordWarningDismiss": "Dismiss",
|
||
"passwordWarningLater": "Remind me later",
|
||
"passwordResetsTitle": "A reset is waiting",
|
||
"passwordResetsAuthenticator": "Your authenticators will be removed on {date}: someone asked with your password. If that wasn't you, call it off and change your password.",
|
||
"@passwordResetsAuthenticator": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordResetsAccount": "Your account will get a new password and new keys on {date}, and what is encrypted under the old ones will be lost: someone asked with a code by mail. If that wasn't you, call it off.",
|
||
"@passwordResetsAccount": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"passwordResetsCallOff": "Call it off",
|
||
"passwordCallOffTitle": "Call off the reset",
|
||
"passwordCallOffIntro": "Your password and a code call off every reset waiting.",
|
||
"passwordSignedInBefore": "Only a device signed in since then can dismiss this warning: sign in again on this one, or change your password.",
|
||
"simpleLoginContinue": "Continue with SimpleLogin",
|
||
"simpleLoginNote": "SimpleLogin is Proton's sign-in, and a Proton account works there too. It learns that you use {instance}, which keeps only your SimpleLogin ID: your name suggests a handle once, and nothing else is kept.",
|
||
"@simpleLoginNote": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginTitle": "Sign in with SimpleLogin",
|
||
"simpleLoginAddTitle": "Add SimpleLogin",
|
||
"simpleLoginInBrowser": "Continue in your browser.",
|
||
"simpleLoginNewcomerTitle": "New here?",
|
||
"simpleLoginNewcomerIntro": "Your SimpleLogin account has no account on {instance} yet.",
|
||
"@simpleLoginNewcomerIntro": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginCreateHint": "Choose a handle and a password; you get a recovery phrase.",
|
||
"simpleLoginHaveOne": "I already have one",
|
||
"simpleLoginHaveOneHint": "Link it again with your handle and your recovery phrase.",
|
||
"handleIntro": "Others find you by your handle. It stays private until you publish something or fill in your profile, and can change until your first publish.",
|
||
"handleLabel": "Handle",
|
||
"handleFree": "@{handle} is free",
|
||
"@handleFree": {
|
||
"placeholders": {
|
||
"handle": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"handleChecking": "Checking…",
|
||
"simpleLoginPasswordIntro": "Choose a password: you type it when you sign in on another device. It never leaves this device: the instance can't read it, and can't reset it without what it protects being lost.",
|
||
"simpleLoginCreate": "Create the account",
|
||
"simpleLoginUnlockTitle": "Your password",
|
||
"simpleLoginUnlockIntroAs": "Signed in with SimpleLogin as @{handle}. Your password opens your keys on this device.",
|
||
"@simpleLoginUnlockIntroAs": {
|
||
"placeholders": {
|
||
"handle": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginUnlockIntro": "Signed in with SimpleLogin. Your password opens your keys on this device.",
|
||
"simpleLoginOpen": "Open",
|
||
"simpleLoginMendTitle": "Link your account",
|
||
"simpleLoginMendIntro": "Your SimpleLogin account isn't the one your account knows any more. Link them again with your handle and your recovery phrase: your other devices are then signed out.",
|
||
"simpleLoginMend": "Link",
|
||
"simpleLoginWrongPassword": "The password isn't right.",
|
||
"simpleLoginMendDoesNotFit": "The handle or the recovery phrase isn't right.",
|
||
"simpleLoginForgotTitle": "A new password",
|
||
"simpleLoginForgotIntro": "Your recovery phrase opens your keys, which your new password then protects. Everything stays; your other devices are signed out.",
|
||
"simpleLoginForgotDoesNotFit": "The recovery phrase isn't right.",
|
||
"simpleLoginResetWaiting": "New keys were asked for: from {date}, a SimpleLogin sign-in can set them up. Your password opening your keys calls it off.",
|
||
"@simpleLoginResetWaiting": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginPhraseLost": "Lost your recovery phrase too?",
|
||
"simpleLoginResetTitle": "New keys",
|
||
"simpleLoginResetIntro": "Without your password or your recovery phrase, nobody can open your keys, not even {instance}. New ones can be set up 72 hours from now, when you sign in with SimpleLogin again. Your handle, your profile and what you published stay; what was encrypted under your old keys is lost, unless you finish on a device still signed in, which keeps them.",
|
||
"@simpleLoginResetIntro": {
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginResetIntroDevices": "Meanwhile your signed-in devices show the reset, and your password calls it off there, should someone else have asked for it.",
|
||
"simpleLoginResetAsk": "Ask for new keys",
|
||
"simpleLoginResetAskedTitle": "New keys asked for",
|
||
"simpleLoginResetAskedIntro": "From {date}, sign in with SimpleLogin again to set them up. Should you find your password or your recovery phrase before then, opening your keys with it calls the reset off.",
|
||
"@simpleLoginResetAskedIntro": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginResetDueTitle": "Your new keys",
|
||
"simpleLoginResetDueIntro": "The new keys you asked for can be set up now. Or open your old keys with your password, which calls the reset off.",
|
||
"simpleLoginResetNewKeys": "Set up new keys",
|
||
"simpleLoginResetNewKeysHint": "A new password and recovery phrase. What was encrypted under your old keys is lost, unless you finish on a device still signed in.",
|
||
"simpleLoginResetHavePassword": "I have my password",
|
||
"simpleLoginResetHavePasswordHint": "Your keys open, and stay.",
|
||
"simpleLoginResetKeepIntro": "Choose a new password: your keys stay, under it and a new recovery phrase, so nothing is lost. Your other devices are signed out.",
|
||
"simpleLoginResetFinish": "Set up the keys",
|
||
"simpleLoginProofKeyTitle": "Your password and a code",
|
||
"simpleLoginProofKeyIntroAs": "Signed in with SimpleLogin as @{handle}. Your account also signs in with a password: type it and a code from your authenticator once, and your password opens your keys after SimpleLogin from then on.",
|
||
"@simpleLoginProofKeyIntroAs": {
|
||
"placeholders": {
|
||
"handle": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginProofKeyIntro": "Your account also signs in with a password: type it and a code from your authenticator once, and your password opens your keys after SimpleLogin from then on.",
|
||
"simpleLoginResetBanner": "New keys were asked for with your SimpleLogin account: from {date}, whoever has it can set them up. Unless that was you, call it off with your password.",
|
||
"@simpleLoginResetBanner": {
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"simpleLoginResetBannerDue": "New keys were asked for with your SimpleLogin account, and whoever has it can set them up now. Unless that was you, call it off with your password.",
|
||
"simpleLoginResetBannerDueHere": "New keys were asked for with your SimpleLogin account and can be set up now. If that was you, finish here: your keys stay. If not, call it off with your password.",
|
||
"simpleLoginResetFinishHere": "Finish here",
|
||
"simpleLoginCallOffIntro": "Your password calls off the reset of your keys.",
|
||
"simpleLoginResetCalledOff": "Reset called off.",
|
||
"simpleLoginResetFinished": "New password and recovery phrase set.",
|
||
"simpleLoginUnavailable": "This instance doesn't offer sign-in with SimpleLogin.",
|
||
"simpleLoginDenied": "SimpleLogin's sign-in was declined, so nothing was shared.",
|
||
"simpleLoginNoBrowser": "There's no browser to open SimpleLogin's page in.",
|
||
"simpleLoginStartAgain": "The sign-in took too long, or another one took its place. Begin it again.",
|
||
"simpleLoginRejected": "SimpleLogin didn't confirm the sign-in. Begin it again.",
|
||
"simpleLoginProviderUnavailable": "The instance can't reach SimpleLogin right now. Try again later.",
|
||
"simpleLoginTakenByAnotherPerson": "This SimpleLogin account belongs to another account here.",
|
||
"simpleLoginOtherIdentityLinked": "Your account has another SimpleLogin account already.",
|
||
"simpleLoginTooManyAttempts": "Too many sign-ins began from this network. Try again in an hour.",
|
||
"handleInvalid": "A handle is 1 to 30 letters (a to z), digits or underscores.",
|
||
"handleReserved": "This handle is kept for the instance.",
|
||
"handleTaken": "Someone else has this handle.",
|
||
"handleTooManyChecks": "Too many handles were tried. Try again in an hour.",
|
||
"simpleLoginSectionTitle": "SimpleLogin",
|
||
"simpleLoginSignsYouIn": "Signs you in",
|
||
"simpleLoginAddHint": "Sign in with SimpleLogin, or with your Proton account.",
|
||
"simpleLoginAdded": "SimpleLogin added.",
|
||
"operatorTitle": "This instance",
|
||
"@operatorTitle": {
|
||
"description": "The card and screen for whoever operates the instance (ADR 0021, D34)."
|
||
},
|
||
"operatorAccounts": "Accounts and operators",
|
||
"@operatorAccounts": {
|
||
"description": "The tile leading to the operator's screen."
|
||
},
|
||
"operatorWaitingCount": "{count, plural, =0{Nobody waits for approval} =1{1 account waits for approval} other{{count} accounts wait for approval}}",
|
||
"@operatorWaitingCount": {
|
||
"description": "How many accounts wait for the operator; also the badge's label.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"operatorWaitingTitle": "Waiting",
|
||
"@operatorWaitingTitle": {
|
||
"description": "The card of accounts that wait for approval, new or suspended."
|
||
},
|
||
"operatorOperatorsCount": "{count, plural, =1{1 operator} other{{count} operators}}",
|
||
"@operatorOperatorsCount": {
|
||
"description": "How many operate the instance, in the overview's row.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"operatorAccountsTitle": "Accounts",
|
||
"@operatorAccountsTitle": {
|
||
"description": "The overview's row leading to every account, and that screen's title."
|
||
},
|
||
"operatorAccountsCount": "{count, plural, =1{1 account} other{{count} accounts}}",
|
||
"@operatorAccountsCount": {
|
||
"description": "How many accounts the instance has.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"operatorNobodyWaits": "Nobody waits.",
|
||
"@operatorNobodyWaits": {
|
||
"description": "The waiting card, empty."
|
||
},
|
||
"operatorNoHandle": "No handle yet",
|
||
"@operatorNoHandle": {
|
||
"description": "An account without a handle, where its handle would be."
|
||
},
|
||
"operatorNewSince": "New, waiting since {date}",
|
||
"@operatorNewSince": {
|
||
"description": "A new account that waits, and since when.",
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"operatorSuspendedSince": "Suspended since {date}",
|
||
"@operatorSuspendedSince": {
|
||
"description": "A suspended account, and since when.",
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"operatorApproveNote": "Read them these four words, and approve only once they confirm these are on their screen.",
|
||
"@operatorApproveNote": {
|
||
"description": "Before approving: the words prove it is their account that waits (D33)."
|
||
},
|
||
"operatorApprove": "Approve",
|
||
"@operatorApprove": {
|
||
"description": "Approves a waiting account."
|
||
},
|
||
"operatorRefuse": "Refuse",
|
||
"@operatorRefuse": {
|
||
"description": "Refuses a new account: deleted."
|
||
},
|
||
"operatorRefuseTitle": "Refuse this account?",
|
||
"@operatorRefuseTitle": {
|
||
"description": "The question before refusing."
|
||
},
|
||
"operatorRefuseMessage": "It is deleted with everything it has. They can sign up again.",
|
||
"@operatorRefuseMessage": {
|
||
"description": "What refusing does."
|
||
},
|
||
"operatorOperatorsTitle": "Operators",
|
||
"@operatorOperatorsTitle": {
|
||
"description": "The card of who operates the instance."
|
||
},
|
||
"operatorTakeBack": "Take back",
|
||
"@operatorTakeBack": {
|
||
"description": "Takes back the operator's role."
|
||
},
|
||
"operatorTakeBackTitle": "Take back the role?",
|
||
"@operatorTakeBackTitle": {
|
||
"description": "The question before taking the role back."
|
||
},
|
||
"operatorTakeBackMessage": "They keep their account, but no longer approve, refuse or suspend accounts here.",
|
||
"@operatorTakeBackMessage": {
|
||
"description": "What taking the role back does."
|
||
},
|
||
"operatorAppoint": "Name an operator",
|
||
"@operatorAppoint": {
|
||
"description": "Names an account an operator, by its handle."
|
||
},
|
||
"operatorAppointMessage": "They approve, refuse and suspend accounts here, and name operators, as you do.",
|
||
"@operatorAppointMessage": {
|
||
"description": "What an operator may do."
|
||
},
|
||
"operatorAppointConfirm": "Name",
|
||
"@operatorAppointConfirm": {
|
||
"description": "Confirms naming an operator."
|
||
},
|
||
"operatorHandle": "Handle",
|
||
"@operatorHandle": {
|
||
"description": "The field for an account's handle."
|
||
},
|
||
"operatorHandleSuggested": "Only handles there are here are suggested.",
|
||
"@operatorHandleSuggested": {
|
||
"description": "Below a field suggesting handles as they are typed."
|
||
},
|
||
"operatorFoundNone": "No account's handle starts like this.",
|
||
"@operatorFoundNone": {
|
||
"description": "A search that found nothing."
|
||
},
|
||
"operatorMadeOn": "Since {date}",
|
||
"@operatorMadeOn": {
|
||
"description": "When an account was made.",
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"operatorIsOperator": "Operator",
|
||
"@operatorIsOperator": {
|
||
"description": "A tag: the account operates the instance."
|
||
},
|
||
"operatorIsWaiting": "Waiting",
|
||
"@operatorIsWaiting": {
|
||
"description": "A tag: the account waits for approval."
|
||
},
|
||
"operatorIsSuspended": "Suspended",
|
||
"@operatorIsSuspended": {
|
||
"description": "A tag: the account is suspended."
|
||
},
|
||
"operatorSuspend": "Suspend",
|
||
"@operatorSuspend": {
|
||
"description": "Suspends an account."
|
||
},
|
||
"operatorSuspendTitle": "Suspend this account?",
|
||
"@operatorSuspendTitle": {
|
||
"description": "The question before suspending."
|
||
},
|
||
"operatorSuspendMessage": "They are signed out everywhere and can't sign in until you approve them again. Nothing they have is deleted.",
|
||
"@operatorSuspendMessage": {
|
||
"description": "What suspending does."
|
||
},
|
||
"operatorMakeOperator": "Name as operator",
|
||
"@operatorMakeOperator": {
|
||
"description": "Names a found account an operator."
|
||
},
|
||
"operatorNotFound": "That account isn't there any more, or doesn't wait.",
|
||
"@operatorNotFound": {
|
||
"description": "Refused: no such account, or it doesn't wait."
|
||
},
|
||
"operatorIsOperatorProblem": "An operator can't be suspended. Take back their role first.",
|
||
"@operatorIsOperatorProblem": {
|
||
"description": "Refused: suspending an operator."
|
||
},
|
||
"operatorLastOperator": "The instance needs at least one operator.",
|
||
"@operatorLastOperator": {
|
||
"description": "Refused: taking back the last operator's role."
|
||
},
|
||
"operatorNotAllowed": "Only the instance's operators can do this.",
|
||
"@operatorNotAllowed": {
|
||
"description": "Refused: the person doesn't operate the instance."
|
||
},
|
||
"operatorFailed": "That didn't work. Try again.",
|
||
"@operatorFailed": {
|
||
"description": "Any other failure."
|
||
},
|
||
"operatorAssistantNotSet": "That assistant isn't set up here any more.",
|
||
"@operatorAssistantNotSet": {
|
||
"description": "The assistant asked for is no longer in deploy/assistants.env."
|
||
},
|
||
"operatorInvalidLimit": "A limit can't be below zero.",
|
||
"@operatorInvalidLimit": {
|
||
"description": "A limit below 0 was refused."
|
||
},
|
||
"assistantGrantsTitle": "Assistants",
|
||
"@assistantGrantsTitle": {
|
||
"description": "The operator's card of the assistants granted (Halkyon Learn's ADR 0021)."
|
||
},
|
||
"assistantGrantsNone": "Nobody has an assistant yet.",
|
||
"@assistantGrantsNone": {
|
||
"description": "No assistant is granted to anyone."
|
||
},
|
||
"assistantSetCount": "{count, plural, =0{None set up} =1{1 assistant} other{{count} assistants}}",
|
||
"@assistantSetCount": {
|
||
"description": "How many assistants are set up, in the overview's row.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"assistantPeopleCount": "{count, plural, =0{nobody granted} =1{1 person} other{{count} people}}",
|
||
"@assistantPeopleCount": {
|
||
"description": "How many people have an assistant, after how many are set up.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"assistantSetUpTitle": "Set up here",
|
||
"@assistantSetUpTitle": {
|
||
"description": "The card of the assistants set up in deploy/assistants.env."
|
||
},
|
||
"assistantPeopleTitle": "People",
|
||
"@assistantPeopleTitle": {
|
||
"description": "The card, and the sheet section, of the people granted assistants."
|
||
},
|
||
"assistantGranteesFoundNone": "Nobody with an assistant has a handle starting like this.",
|
||
"@assistantGranteesFoundNone": {
|
||
"description": "No person granted one matches the start of a handle typed."
|
||
},
|
||
"assistantUnpriced": "No prices: counts its tokens only",
|
||
"@assistantUnpriced": {
|
||
"description": "An assistant set up without prices, which a budget counts in tokens alone."
|
||
},
|
||
"assistantEffort": "{effort, select, low{low} medium{medium} high{high} xhigh{extra high} max{max} other{{effort}}}",
|
||
"@assistantEffort": {
|
||
"description": "How much a model thinks before it answers, as a word in a sentence.",
|
||
"placeholders": {
|
||
"effort": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantEffortName": "{effort, select, low{Low} medium{Medium} high{High} xhigh{Extra high} max{Max} other{{effort}}}",
|
||
"@assistantEffortName": {
|
||
"description": "How much a model thinks before it answers, as a name standing alone, as in a menu.",
|
||
"placeholders": {
|
||
"effort": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantEffortSetUp": "Effort {effort}, up to {max}",
|
||
"@assistantEffortSetUp": {
|
||
"description": "An assistant's effort unless asked otherwise, and the highest a question may ask.",
|
||
"placeholders": {
|
||
"effort": {
|
||
"type": "String"
|
||
},
|
||
"max": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantEffortFixed": "Effort {effort}",
|
||
"@assistantEffortFixed": {
|
||
"description": "An assistant's effort, the only one it takes.",
|
||
"placeholders": {
|
||
"effort": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantNameUnset": "{name} (no longer set up)",
|
||
"@assistantNameUnset": {
|
||
"description": "An assistant granted that is no longer set up.",
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantNotAgreedCount": "{count, plural, =1{1 not agreed to yet} other{{count} not agreed to yet}}",
|
||
"@assistantNotAgreedCount": {
|
||
"description": "How many of a person's assistants they haven't agreed to yet.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"assistantGrant": "Grant assistants",
|
||
"@assistantGrant": {
|
||
"description": "Opens the sheet granting an assistant to an account."
|
||
},
|
||
"assistantGrantSave": "Grant",
|
||
"@assistantGrantSave": {
|
||
"description": "The grant sheet's button."
|
||
},
|
||
"assistantGrantChange": "Change assistants",
|
||
"@assistantGrantChange": {
|
||
"description": "The sheet changing a person's assistants and budget, and a person's menu item."
|
||
},
|
||
"assistantGrantLimitHelper": "Empty for none. Days and months are UTC's.",
|
||
"@assistantGrantLimitHelper": {
|
||
"description": "Under the limit fields: the instance counts by UTC days and months (D42)."
|
||
},
|
||
"assistantGrantBudget": "Budget, for all of them together",
|
||
"@assistantGrantBudget": {
|
||
"description": "The sheet's section of a person's budget."
|
||
},
|
||
"assistantGrantMoneyDaily": "Money a day",
|
||
"@assistantGrantMoneyDaily": {
|
||
"description": "A budget field."
|
||
},
|
||
"assistantGrantMoneyMonthly": "Money a month",
|
||
"@assistantGrantMoneyMonthly": {
|
||
"description": "A budget field."
|
||
},
|
||
"assistantGrantTokensDaily": "Tokens a day",
|
||
"@assistantGrantTokensDaily": {
|
||
"description": "A budget field."
|
||
},
|
||
"assistantGrantTokensMonthly": "Tokens a month",
|
||
"@assistantGrantTokensMonthly": {
|
||
"description": "A budget field."
|
||
},
|
||
"assistantGrantMoneyNote": "Money counts the assistants with prices, tokens count every one. Whichever runs out first stops them.",
|
||
"@assistantGrantMoneyNote": {
|
||
"description": "Below the budget fields."
|
||
},
|
||
"assistantGrantReplaces": "{count, plural, =1{Granting replaces the budget this person has:} other{Granting replaces the budgets these people have:}}",
|
||
"@assistantGrantReplaces": {
|
||
"description": "Before the people whose budget a grant replaces, each with theirs.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"assistantGrantUnsetDropped": "Saving takes back what is no longer set up: {names}.",
|
||
"@assistantGrantUnsetDropped": {
|
||
"description": "Changing a person's assistants drops those no longer set up.",
|
||
"placeholders": {
|
||
"names": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantGrantLimitInvalid": "Not a number this takes",
|
||
"@assistantGrantLimitInvalid": {
|
||
"description": "A limit typed that is no amount or number of tokens."
|
||
},
|
||
"assistantGrantTokens": "tokens",
|
||
"@assistantGrantTokens": {
|
||
"description": "After a limit in tokens, for an assistant without prices."
|
||
},
|
||
"assistantGrantNote": "They agree once to what goes where before they ask one. Assistants they have already stay. You see how much they use, never what they ask.",
|
||
"@assistantGrantNote": {
|
||
"description": "In the grant sheet: consent (D40) and what the operator sees (D3)."
|
||
},
|
||
"assistantPerDay": "{amount} a day",
|
||
"@assistantPerDay": {
|
||
"description": "A daily limit.",
|
||
"placeholders": {
|
||
"amount": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantPerMonth": "{amount} a month",
|
||
"@assistantPerMonth": {
|
||
"description": "A monthly limit.",
|
||
"placeholders": {
|
||
"amount": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantNoLimits": "No limits",
|
||
"@assistantNoLimits": {
|
||
"description": "A grant without limits."
|
||
},
|
||
"assistantRevoke": "Take back",
|
||
"@assistantRevoke": {
|
||
"description": "A grant's menu item."
|
||
},
|
||
"assistantRevokeAllTitle": "Take back every assistant?",
|
||
"@assistantRevokeAllTitle": {
|
||
"description": "Asks before taking every assistant back from a person."
|
||
},
|
||
"assistantRevokeMessage": "They can no longer ask any of them, and their budget goes. What they used stays counted.",
|
||
"@assistantRevokeMessage": {
|
||
"description": "Under the question taking a grant back."
|
||
},
|
||
"assistantUseByMonth": "Use by month",
|
||
"@assistantUseByMonth": {
|
||
"description": "Opens everyone's figures (D3)."
|
||
},
|
||
"assistantUseTitle": "Use of assistants",
|
||
"@assistantUseTitle": {
|
||
"description": "The title of the figures' screen and sheet."
|
||
},
|
||
"assistantUseNone": "Nothing used in this month.",
|
||
"@assistantUseNone": {
|
||
"description": "A month without use."
|
||
},
|
||
"assistantUseKept": "Counted per UTC day, kept for this month and the two before. Never what was asked.",
|
||
"@assistantUseKept": {
|
||
"description": "Under the figures: what is counted and for how long (D41, D42)."
|
||
},
|
||
"assistantRequests": "{count, plural, =1{1 request} other{{count} requests}}",
|
||
"@assistantRequests": {
|
||
"description": "How many requests were counted.",
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"assistantTokens": "{amount} tokens",
|
||
"@assistantTokens": {
|
||
"description": "How many tokens were counted, the number formatted.",
|
||
"placeholders": {
|
||
"amount": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantsTitle": "Assistants",
|
||
"@assistantsTitle": {
|
||
"description": "Settings' card of the assistants a person may ask (Halkyon Learn's ADR 0021, point 9)."
|
||
},
|
||
"assistantModelAt": "{model} at {host}",
|
||
"@assistantModelAt": {
|
||
"description": "Which model answers, and the host that receives what is asked.",
|
||
"placeholders": {
|
||
"model": {
|
||
"type": "String"
|
||
},
|
||
"host": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantLeftToday": "{left} of {limit} left today",
|
||
"@assistantLeftToday": {
|
||
"description": "What is left of a day's limit.",
|
||
"placeholders": {
|
||
"left": {
|
||
"type": "String"
|
||
},
|
||
"limit": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantLeftThisMonth": "{left} of {limit} left this month",
|
||
"@assistantLeftThisMonth": {
|
||
"description": "What is left of a month's limit.",
|
||
"placeholders": {
|
||
"left": {
|
||
"type": "String"
|
||
},
|
||
"limit": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantYourBudget": "Your budget, for all of them",
|
||
"@assistantYourBudget": {
|
||
"description": "The person's budget for all their assistants."
|
||
},
|
||
"assistantAgree": "Read and agree",
|
||
"@assistantAgree": {
|
||
"description": "Opens the consent sheet of an assistant not agreed to yet."
|
||
},
|
||
"assistantYourUse": "Your use",
|
||
"@assistantYourUse": {
|
||
"description": "Opens the person's own figures."
|
||
},
|
||
"assistantPrivacyPage": "What goes where on {instance}",
|
||
"@assistantPrivacyPage": {
|
||
"description": "Opens the instance's privacy page (D39).",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantOwnTitle": "With your own key",
|
||
"@assistantOwnTitle": {
|
||
"description": "Above a person's own assistants (point 10)."
|
||
},
|
||
"assistantOwnAdd": "Add an assistant with your own key",
|
||
"@assistantOwnAdd": {
|
||
"description": "Opens the sheet adding an assistant with a personal key."
|
||
},
|
||
"assistantOwnNote": "The app asks your provider directly: this instance sees neither your key nor your questions, and counts nothing. The key is kept in your settings, encrypted on your devices.",
|
||
"@assistantOwnNote": {
|
||
"description": "What a personal key means (D5, D6)."
|
||
},
|
||
"assistantOwnEdit": "Your own key",
|
||
"@assistantOwnEdit": {
|
||
"description": "The personal key sheet's title."
|
||
},
|
||
"assistantOwnName": "Name",
|
||
"@assistantOwnName": {
|
||
"description": "The name the person gives their assistant."
|
||
},
|
||
"assistantOwnProtocol": "API",
|
||
"@assistantOwnProtocol": {
|
||
"description": "Above the choice of protocol."
|
||
},
|
||
"assistantOwnBaseUrl": "Address",
|
||
"@assistantOwnBaseUrl": {
|
||
"description": "The provider's address field."
|
||
},
|
||
"assistantOwnBaseUrlHelper": "Empty for the provider's own. Mistral, OpenRouter or a model of your own: its address with /v1.",
|
||
"@assistantOwnBaseUrlHelper": {
|
||
"description": "Under the address field: which services take which address."
|
||
},
|
||
"assistantOwnBaseUrlInvalid": "Only https, or http on your own network",
|
||
"@assistantOwnBaseUrlInvalid": {
|
||
"description": "An address the app refuses: keys and questions would travel in the clear."
|
||
},
|
||
"assistantOwnModel": "Model",
|
||
"@assistantOwnModel": {
|
||
"description": "The model's name at the provider."
|
||
},
|
||
"assistantOwnKey": "Key",
|
||
"@assistantOwnKey": {
|
||
"description": "The API key field."
|
||
},
|
||
"assistantOwnKeyHelper": "Empty for a model of your own that takes none.",
|
||
"@assistantOwnKeyHelper": {
|
||
"description": "Under the key field."
|
||
},
|
||
"assistantOwnImages": "Reads images",
|
||
"@assistantOwnImages": {
|
||
"description": "Whether the model reads images (D12)."
|
||
},
|
||
"assistantOwnSave": "Save",
|
||
"@assistantOwnSave": {
|
||
"description": "The personal key sheet's button."
|
||
},
|
||
"assistantOwnRemove": "Remove",
|
||
"@assistantOwnRemove": {
|
||
"description": "Removes an assistant with a personal key."
|
||
},
|
||
"assistantOwnRemoveTitle": "Remove {name}?",
|
||
"@assistantOwnRemoveTitle": {
|
||
"description": "Asks before removing an assistant with a personal key.",
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantOwnRemoveMessage": "Its key goes from your settings on every device.",
|
||
"@assistantOwnRemoveMessage": {
|
||
"description": "Under the question removing a personal key."
|
||
},
|
||
"assistantOwnRefused": "The key wasn't kept: this device can't encrypt your settings yet. Open your account's keys here first.",
|
||
"@assistantOwnRefused": {
|
||
"description": "A personal key refused, as the settings wouldn't be sealed."
|
||
},
|
||
"assistantOwnNotAllowed": "Whoever runs {instance} doesn't allow own keys here, so the app doesn't ask these.",
|
||
"@assistantOwnNotAllowed": {
|
||
"description": "Below the person's own assistants, where the operator doesn't allow them (ADR 0021, D6).",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String",
|
||
"example": "learn.halkyon.eu"
|
||
}
|
||
}
|
||
},
|
||
"assistantConsentTitle": "Before you ask {name}",
|
||
"@assistantConsentTitle": {
|
||
"description": "The consent sheet's title (D40).",
|
||
"placeholders": {
|
||
"name": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantConsentModel": "It answers with the model {model} at {host}.",
|
||
"@assistantConsentModel": {
|
||
"description": "Who answers (D27).",
|
||
"placeholders": {
|
||
"model": {
|
||
"type": "String"
|
||
},
|
||
"host": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantConsentProvider": "It holds for every assistant at {host}.",
|
||
"@assistantConsentProvider": {
|
||
"description": "An agreement is to what goes where, so it covers every assistant of the provider (Halkyon Learn's ADR 0021, D66).",
|
||
"placeholders": {
|
||
"host": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantConsentWhatGoes": "Only what you send goes there: your question, what you pick of what it is about, and what it looks up where you let it. The provider's own terms apply to it.",
|
||
"@assistantConsentWhatGoes": {
|
||
"description": "What goes to the provider (D27)."
|
||
},
|
||
"assistantConsentImages": "It reads the images you add.",
|
||
"@assistantConsentImages": {
|
||
"description": "For an assistant that reads images (D12)."
|
||
},
|
||
"assistantConsentInstance": "It passes through {instance} on its way, which keeps none of it.",
|
||
"@assistantConsentInstance": {
|
||
"description": "The instance sees it in passing and keeps nothing (D27).",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantConsentOperator": "Whoever runs {instance} sees how much you use it (requests, tokens, cost), never what you ask.",
|
||
"@assistantConsentOperator": {
|
||
"description": "The operator's figures (D3).",
|
||
"placeholders": {
|
||
"instance": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantConsentConversations": "Your conversations are kept encrypted: only your devices can read them.",
|
||
"@assistantConsentConversations": {
|
||
"description": "Conversations are sealed on the devices (D13)."
|
||
},
|
||
"assistantConsentAgree": "Agree",
|
||
"@assistantConsentAgree": {
|
||
"description": "The consent sheet's button."
|
||
},
|
||
"assistantConsentAgreedOn": "You agreed on {date}.",
|
||
"@assistantConsentAgreedOn": {
|
||
"description": "An assistant agreed to, and when.",
|
||
"placeholders": {
|
||
"date": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantProblemNotGranted": "This assistant isn't granted to you any more.",
|
||
"@assistantProblemNotGranted": {
|
||
"description": "notGranted."
|
||
},
|
||
"assistantProblemNotAgreed": "Agree to what goes where first.",
|
||
"@assistantProblemNotAgreed": {
|
||
"description": "notAgreed."
|
||
},
|
||
"assistantProblemInvalidEffort": "It doesn't think at this effort.",
|
||
"@assistantProblemInvalidEffort": {
|
||
"description": "A question asked an effort its assistant does not take."
|
||
},
|
||
"assistantProblemLimitReached": "Its limit is reached until {time}.",
|
||
"@assistantProblemLimitReached": {
|
||
"description": "limitReached, with when it resets.",
|
||
"placeholders": {
|
||
"time": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"assistantProblemLimitReachedNow": "Its limit is reached for now.",
|
||
"@assistantProblemLimitReachedNow": {
|
||
"description": "Refused: a limit is reached, the instance not saying until when."
|
||
},
|
||
"assistantProblemImagesNotRead": "It reads no images.",
|
||
"@assistantProblemImagesNotRead": {
|
||
"description": "imagesNotRead."
|
||
},
|
||
"assistantProblemMalformed": "This question can't be sent.",
|
||
"@assistantProblemMalformed": {
|
||
"description": "malformed."
|
||
},
|
||
"assistantProblemTooLarge": "This question is too long, or holds too many or too large images.",
|
||
"@assistantProblemTooLarge": {
|
||
"description": "tooLarge."
|
||
},
|
||
"assistantProblemTooManyAtOnce": "Wait for the answers on their way first.",
|
||
"@assistantProblemTooManyAtOnce": {
|
||
"description": "tooManyAtOnce."
|
||
},
|
||
"assistantProblemProviderKey": "The provider refused the key.",
|
||
"@assistantProblemProviderKey": {
|
||
"description": "providerKey."
|
||
},
|
||
"assistantProblemProviderBusy": "The provider is busy. Try again in a moment.",
|
||
"@assistantProblemProviderBusy": {
|
||
"description": "providerBusy."
|
||
},
|
||
"assistantProblemProviderRefused": "The provider refused this question.",
|
||
"@assistantProblemProviderRefused": {
|
||
"description": "providerRefused."
|
||
},
|
||
"assistantProblemProviderFailed": "The provider failed. Try again.",
|
||
"@assistantProblemProviderFailed": {
|
||
"description": "providerFailed."
|
||
},
|
||
"assistantProblemNotAllowed": "Only people it is granted to can do this.",
|
||
"@assistantProblemNotAllowed": {
|
||
"description": "notAllowed."
|
||
},
|
||
"assistantProblemFailed": "That didn't work. Try again.",
|
||
"@assistantProblemFailed": {
|
||
"description": "failed."
|
||
},
|
||
"whatsNewTitle": "What's new",
|
||
"@whatsNewTitle": {
|
||
"description": "The sheet listing what changed in the app after an update, and its entry in Settings."
|
||
},
|
||
"whatsNewVersion": "Version {version}",
|
||
"@whatsNewVersion": {
|
||
"description": "Above a release's changes in What's new.",
|
||
"placeholders": {
|
||
"version": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"profileIdentified": "Your progress is kept with your account.",
|
||
"profileProblemAvatarInvalid": "This picture can't be used: choose a PNG, JPEG, WebP or GIF image.",
|
||
"profileProblemBioTooLong": "At most 500 characters.",
|
||
"profileProblemDisplayNameTooLong": "At most 30 characters.",
|
||
"profileProblemHandleInvalid": "A handle is 1 to 30 letters (a to z), digits or underscores.",
|
||
"profileProblemHandleReserved": "This handle is kept for the instance.",
|
||
"profileProblemHandleTaken": "Someone else has this handle.",
|
||
"profileProblemLinkInvalid": "Links start with https:// or http://.",
|
||
"profileProblemPublished": "You have published: your handle can't change, nor your profile go.",
|
||
"profileProblemTooManyHandleChecks": "Too many handles were tried. Try again in an hour.",
|
||
"profileProblemTooManyLinkChecks": "The links were checked too often. Try again in an hour.",
|
||
"profileProblemTooManyLinks": "At most 4 links.",
|
||
"profileSheetNotFound": "Nobody on this instance has this handle.",
|
||
"profileSheetTitle": "Profile",
|
||
"profileSheetUnreachable": "The profile couldn’t be loaded. Check your connection.",
|
||
"profileSignInWays": "Ways to sign in",
|
||
"profileTabProfile": "Profile",
|
||
"profileTitle": "Profile",
|
||
"profileWayEmail": "Email address",
|
||
"profileWayLinked": "Signs you in",
|
||
"publicProfileAddLink": "Add link",
|
||
"publicProfileAddress": "Others find you as @{address}",
|
||
"@publicProfileAddress": {
|
||
"placeholders": {
|
||
"address": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"publicProfileAddressPrivate": "Private until you fill in your profile or publish something; then others find you as @{address}.",
|
||
"@publicProfileAddressPrivate": {
|
||
"placeholders": {
|
||
"address": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"publicProfileBio": "Bio",
|
||
"publicProfileCheckLinks": "Check links",
|
||
"publicProfileChoosePicture": "Choose picture",
|
||
"publicProfileDisplayName": "Display name",
|
||
"publicProfileDisplayNameHint": "The name shown beside your handle",
|
||
"publicProfileFailed": "Couldn't reach the instance. Try again.",
|
||
"publicProfileHandle": "Handle",
|
||
"publicProfileHandleChangeTitle": "Change your handle",
|
||
"publicProfileHandleChecking": "Checking…",
|
||
"publicProfileHandleChoose": "Choose a handle",
|
||
"publicProfileHandleChooseTitle": "Choose your handle",
|
||
"publicProfileHandleConfirmChange": "Change",
|
||
"publicProfileHandleConfirmChoose": "Choose",
|
||
"publicProfileHandleDialogText": "Others find you by your handle. You can change it until you first publish a studyset.",
|
||
"publicProfileHandleFirst": "Choose your handle first: your profile is made with it, and saves as you write from then on.",
|
||
"publicProfileHandleFixed": "Fixed since you published: others refer to it.",
|
||
"publicProfileHandleFree": "@{handle} is free",
|
||
"@publicProfileHandleFree": {
|
||
"placeholders": {
|
||
"handle": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"publicProfileHandleHint": "Letters, digits and underscores, up to 30",
|
||
"publicProfileHandleYours": "This is your handle",
|
||
"publicProfileIntro": "How others see you once you publish: the handle they find you by, your name, a few words and links. It saves as you write, once you have chosen your handle.",
|
||
"publicProfileLinkHint": "https://…",
|
||
"publicProfileLinkVerified": "Links back to your profile",
|
||
"publicProfileLinks": "Links",
|
||
"publicProfileLinksChecked": "{count, plural, =1{Checked: {verified} of 1 link links back to your profile.} other{Checked: {verified} of {count} links link back to your profile.}}",
|
||
"@publicProfileLinksChecked": {
|
||
"placeholders": {
|
||
"count": {
|
||
"type": "int"
|
||
},
|
||
"verified": {
|
||
"type": "int"
|
||
}
|
||
}
|
||
},
|
||
"publicProfileLinksHint": "Your site or other accounts, up to 4.",
|
||
"publicProfilePage": "Your profile page: {url}",
|
||
"@publicProfilePage": {
|
||
"placeholders": {
|
||
"url": {
|
||
"type": "String"
|
||
}
|
||
}
|
||
},
|
||
"publicProfilePageCopied": "Address copied.",
|
||
"publicProfilePageCopy": "Copy the address",
|
||
"publicProfilePicture": "Picture",
|
||
"publicProfilePictureLater": "Choose your handle to add a picture.",
|
||
"publicProfilePictureType": "Images",
|
||
"publicProfileRemove": "Remove profile",
|
||
"publicProfileRemoveLink": "Remove link",
|
||
"publicProfileRemoveMessage": "Your display name, bio, links and picture are removed. Your handle stays yours and private until you fill in your profile again or publish something.",
|
||
"publicProfileRemovePicture": "Remove picture",
|
||
"publicProfileRemoveTitle": "Remove your public profile?",
|
||
"publicProfileRemoved": "Profile removed.",
|
||
"publicProfileRetry": "Retry",
|
||
"publicProfileSavedNow": "Saved",
|
||
"publicProfileSaving": "Saving…",
|
||
"publicProfileTitle": "Public profile",
|
||
"publicProfileUnreachable": "Your public profile can't be reached right now.",
|
||
"publicProfileVerifyHint": "A link gets a checkmark once its page links back to your profile page with rel=\"me\", as Mastodon checks links.",
|
||
"profileAccount": "Account",
|
||
"profileSheetLinkVerified": "Links back to this profile",
|
||
"speechNoRecognizer": "This device has no speech recognition installed. Install one, such as FUTO Voice Input or Google's speech services, then try again.",
|
||
"@speechNoRecognizer": {"description": "Shown when the microphone is tapped on a device without any speech recognition app (as GrapheneOS without Google's services), with a hint how to get one."},
|
||
"lookAppearance": "Appearance",
|
||
"lookAppearanceDevice": "Device theme",
|
||
"lookAppearanceLight": "Light",
|
||
"lookAppearanceDark": "Dark",
|
||
"lookLanguage": "Language",
|
||
"lookLanguageDevice": "Device language",
|
||
"syncStateHeldBack": "Held back on mobile data",
|
||
"@syncStateHeldBack": {"description": "The Sync card's state while sync waits for the person's answer or Wi-Fi (Halkyon's ADR 0042)."},
|
||
"syncFilesHeld": "Files wait for Wi-Fi",
|
||
"@syncFilesHeld": {"description": "The Sync card's line while rows sync on mobile data and files wait (ADR 0042)."},
|
||
"mobileDataTitle": "On mobile data",
|
||
"@mobileDataTitle": {"description": "The Sync card's setting: what the device syncs on a metered network unasked (ADR 0042, D5)."},
|
||
"mobileDataAsk": "Ask first",
|
||
"@mobileDataAsk": {"description": "A choice of mobileDataTitle: sync waits until the person answers the banner."},
|
||
"mobileDataWithoutFiles": "Sync without files",
|
||
"@mobileDataWithoutFiles": {"description": "A choice of mobileDataTitle: rows sync, files wait for Wi-Fi."},
|
||
"mobileDataEverything": "Sync everything",
|
||
"@mobileDataEverything": {"description": "A choice of mobileDataTitle."},
|
||
"mobileDataBanner": "On mobile data · {count, plural, =0{sync paused} =1{1 change waiting} other{{count} changes waiting}}",
|
||
"@mobileDataBanner": {"description": "The banner above every tab while sync is held back on mobile data (ADR 0042, D3); count is the changes made here not synced yet.", "placeholders": {"count": {"type": "int"}}},
|
||
"mobileDataBannerWithoutFiles": "Without files",
|
||
"@mobileDataBannerWithoutFiles": {"description": "The banner's action syncing the rows alone, files waiting for Wi-Fi."},
|
||
"mobileDataBannerNotNow": "Not now",
|
||
"@mobileDataBannerNotNow": {"description": "The banner's action hiding it until another change waits."},
|
||
"agentsTitle": "Agents",
|
||
"agentsIntro": "An agent is an account of yours for a program, such as an AI assistant. It signs in with a token, sees only what you invite it to, as a Viewer, and suggests changes rather than making them.",
|
||
"agentsNone": "No agents yet.",
|
||
"agentsMake": "Make an agent",
|
||
"agentsName": "Name",
|
||
"agentsMakeAction": "Make",
|
||
"agentsTokenTitle": "Token for @{handle}",
|
||
"@agentsTokenTitle": {"placeholders": {"handle": {"type": "String"}}},
|
||
"agentsTokenBody": "Give this token to the program the agent is for. It's shown only now: if it's lost, make a new one. Unused for 90 days, it lapses.",
|
||
"agentsTokenCopy": "Copy token",
|
||
"agentsTokenCopied": "Token copied",
|
||
"agentsDone": "Done",
|
||
"agentsLastUsed": "@{handle} · signed in {date}",
|
||
"@agentsLastUsed": {"placeholders": {"handle": {"type": "String"}, "date": {"type": "String"}}},
|
||
"agentsNeverUsed": "@{handle} · never signed in",
|
||
"@agentsNeverUsed": {"placeholders": {"handle": {"type": "String"}}},
|
||
"agentsNoToken": "@{handle} · no token",
|
||
"@agentsNoToken": {"placeholders": {"handle": {"type": "String"}}},
|
||
"agentsNewToken": "New token",
|
||
"agentsRevoke": "Take back token",
|
||
"agentsRevokeTitle": "Take back @{handle}'s token?",
|
||
"@agentsRevokeTitle": {"placeholders": {"handle": {"type": "String"}}},
|
||
"agentsRevokeMessage": "It signs in no more, and its sessions end, until you give it a new token.",
|
||
"agentsDelete": "Delete",
|
||
"agentsDeleteTitle": "Delete @{handle}?",
|
||
"@agentsDeleteTitle": {"placeholders": {"handle": {"type": "String"}}},
|
||
"agentsDeleteMessage": "Its account goes, and with it its memberships.",
|
||
"agentsActions": "Options for @{handle}",
|
||
"@agentsActions": {"placeholders": {"handle": {"type": "String"}}},
|
||
"agentProblemAgentsOff": "This instance doesn't allow agents.",
|
||
"agentProblemTooMany": "You have as many agents as you may ({count}).",
|
||
"@agentProblemTooMany": {"placeholders": {"count": {"type": "int"}}},
|
||
"agentProblemNameTooLong": "This name is too long.",
|
||
"agentProblemNotFound": "This agent is gone.",
|
||
"agentProblemFailed": "The instance couldn't be reached. Try again.",
|
||
"agentOf": "Agent of @{owner}",
|
||
"@agentOf": {"placeholders": {"owner": {"type": "String"}}},
|
||
"operatorIsAgent": "An agent can't be an operator or be granted assistants.",
|
||
"@operatorIsAgent": {"description": "Naming an agent an operator, or granting it an assistant, refused"}
|
||
}
|