@dodi-education/cli 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1616 @@
1
+ #!/usr/bin/env node
2
+ import "./chunk-LMSPDGSC.js";
3
+
4
+ // ../../core/intl/messages/en.json
5
+ var common = {
6
+ signIn: "Sign in",
7
+ signUp: "Sign up",
8
+ signOut: "Sign out",
9
+ cancel: "Cancel",
10
+ save: "Save changes",
11
+ delete: "Delete",
12
+ loading: "Loading...",
13
+ saved: "Changes saved",
14
+ openCalendar: "Open calendar",
15
+ details: "Details",
16
+ done: "Done",
17
+ chooseFile: "Choose file"
18
+ };
19
+ var auth = {
20
+ welcomeBack: "Welcome back",
21
+ signInDescription: "Sign in to your dodi account",
22
+ email: "Email",
23
+ emailPlaceholder: "parent@example.com",
24
+ password: "Password",
25
+ confirmPassword: "Confirm password",
26
+ passwordPlaceholder: "At least 8 characters",
27
+ showPassword: "Show password",
28
+ hidePassword: "Hide password",
29
+ signingIn: "Signing in...",
30
+ forgotPassword: "Forgot your password?",
31
+ noAccount: "Don't have an account?",
32
+ createAccountTitle: "Create your account",
33
+ createAccountDescription: "Sign up to start using dodi with your kids",
34
+ creatingAccount: "Creating account...",
35
+ createAccount: "Create account",
36
+ alreadyHaveAccount: "Already have an account?",
37
+ passwordsNoMatch: "Passwords do not match",
38
+ passwordTooShort: "Password must be at least 8 characters",
39
+ loadingRegistration: "Loading\u2026",
40
+ registrationClosedTitle: "Registration is closed",
41
+ registrationClosed: "New sign-ups are paused right now. Please check back later.",
42
+ inviteCode: "Invite code",
43
+ inviteCodePlaceholder: "Enter your invite code",
44
+ inviteRequired: "Please enter your invite code.",
45
+ invalidInviteCode: "That invite code is invalid or no longer active.",
46
+ enterCodeTitle: "Enter your code",
47
+ enterCodeDescription: "We emailed a 6-digit code to {email}. Enter it to confirm your address.",
48
+ enterCodeResetDescription: "We emailed a 6-digit code to {email}. Enter it to reset your password.",
49
+ codeLabel: "Verification code",
50
+ verifyButton: "Verify",
51
+ verifyingCode: "Verifying\u2026",
52
+ resendCode: "Resend code",
53
+ resendCodeIn: "Resend code in {seconds}s",
54
+ codeResent: "We sent a new code.",
55
+ resendFailed: "We couldn't send a new code. Please try again.",
56
+ wrongCode: "That code isn't right. Check it and try again.",
57
+ codeExpired: "That code has expired. Request a new one.",
58
+ tooManyAttempts: "Too many wrong attempts. Request a new code.",
59
+ backToDifferentEmail: "Use a different email",
60
+ tryAgain: "Try again",
61
+ genericSignupError: "We couldn't complete your registration. Please check your details and try again.",
62
+ captchaFailed: "We couldn't confirm you're not a robot. Please try again.",
63
+ captchaUnavailable: "The security check couldn't load. Check your connection or ad blocker and try again.",
64
+ vaultSetupFailed: "Account created, but we couldn't set up your secure vault. Please sign in to finish setup.",
65
+ finishSetupTitle: "Finish setting up your account",
66
+ finishSetupDescription: "Your email is confirmed. Enter your password to secure your data and get your account key.",
67
+ finishSetupSubmit: "Continue",
68
+ finishSetupWrongPassword: "That password doesn't match your account. Please try again.",
69
+ resetPasswordTitle: "Reset your password",
70
+ resetPasswordDescription: "Enter your email and we'll send you a reset code",
71
+ sending: "Sending...",
72
+ sendResetCode: "Send reset code",
73
+ backToSignIn: "Back to sign in",
74
+ updatePasswordTitle: "Set a new password",
75
+ updatePasswordDescription: "Choose a new password for your account.",
76
+ updatePasswordWithNsecHint: "Choose a new password. Because your data is end-to-end encrypted, enter your account key (nsec) so we can re-encrypt it under the new password.",
77
+ newPassword: "New password",
78
+ accountKey: "Account key (nsec)",
79
+ accountKeyPlaceholder: "nsec1\u2026",
80
+ invalidAccountKey: "That doesn't look like a valid account key (nsec).",
81
+ importNsecToggle: "I already have a Nostr key",
82
+ importNsecLabel: "Your Nostr secret key (nsec)",
83
+ importNsecHint: "Optional: use an existing Nostr key as your account key instead of getting a new one. Paste it as nsec1\u2026 or hex.",
84
+ nsecTaken: "This Nostr key is already linked to another account.",
85
+ unlockAfterLoginFailed: "Signed in, but we couldn't unlock your encrypted data. If you recently changed your password, you'll need your account key (nsec).",
86
+ updatePassword: "Update password",
87
+ updatingPassword: "Updating...",
88
+ updatePasswordFailed: "We couldn't update your password. Please try again.",
89
+ termsConsent: "I am a parent or legal guardian, at least 18 years old, and I accept the <terms>Terms of service</terms>. I have read the <privacy>Privacy policy</privacy>.",
90
+ termsRequired: "Please confirm that you are a parent or guardian and accept the terms of service.",
91
+ accountDeleted: "Your account and all of your family's data have been deleted."
92
+ };
93
+ var vault = {
94
+ saveKeyTitle: "Save your account key",
95
+ saveKeyDescription: "This key is the ONLY way to recover your account if you forget your password and lose your devices. We can't see it and can't reset it. Save it in a password manager or write it down \u2014 never share it.",
96
+ copyKey: "Copy key",
97
+ keyCopied: "Copied",
98
+ savedItConfirm: "I saved my account key somewhere safe",
99
+ continue: "Continue",
100
+ setupTitle: "Set up your secure vault",
101
+ setupDescription: "Choose a password to encrypt your family's data on this device.",
102
+ unlockTitle: "Unlock your data",
103
+ unlockPasswordDescription: "Enter your password to decrypt your data on this device.",
104
+ unlockNsecDescription: "Enter your account key (nsec) to restore access.",
105
+ passwordLabel: "Password",
106
+ nsecLabel: "Account key (nsec)",
107
+ nsecPlaceholder: "nsec1\u2026",
108
+ createVault: "Create vault",
109
+ unlock: "Unlock",
110
+ unlocking: "Unlocking\u2026",
111
+ unlockFailed: "Couldn't unlock the vault",
112
+ forgotPasswordUseKey: "Forgot password? Use your account key",
113
+ usePasswordInstead: "Use password instead",
114
+ unlockingVault: "Unlocking your secure vault\u2026"
115
+ };
116
+ var onboarding = {
117
+ prefsTitle: "A few basics",
118
+ prefsDescription: "Pick the language and the date and time formats for your family. You can change all of this later in Settings.",
119
+ continue: "Continue",
120
+ skip: "Skip for now",
121
+ saving: "Saving...",
122
+ saveFailed: "Couldn't save your preferences. Please try again."
123
+ };
124
+ var dashboard = {
125
+ title: "Dashboard",
126
+ subtitle: "What your kids have been up to with dodi",
127
+ overview: "Overview",
128
+ addGame: "Create game",
129
+ noKidsTitle: "No kid profiles yet",
130
+ addKid: "Add kid",
131
+ noKidsDescription: "Add a kid profile to get started with dodi",
132
+ born: "Born: {date}",
133
+ birthdateNotSet: "Birthdate not set",
134
+ statSessionsToday: "Voice sessions today",
135
+ statSessionsWeek: "Sessions this week",
136
+ statGamesCreated: "Games created",
137
+ recentSessions: "Recent sessions",
138
+ recentSessionsDesc: "Game tasks dodi worked on recently",
139
+ noRecentSessions: "No sessions yet. They appear when you create games with dodi.",
140
+ kidsGlance: "Kids at a glance",
141
+ viewAll: "View all",
142
+ ageYears: "{age} yrs",
143
+ aiSetupTitle: "Connect an AI provider",
144
+ aiSetupDescription: "No AI provider is set up yet, so voice chat and game creation are still switched off. Add your own API key to turn them on.",
145
+ aiSetupCta: "Set up AI"
146
+ };
147
+ var kids = {
148
+ title: "Kids",
149
+ subtitle: "Manage your kids",
150
+ yourKids: "Your kids",
151
+ addKid: "Add kid",
152
+ noKids: "No kid profiles yet. Add one to get started.",
153
+ personaSet: "Persona set",
154
+ default: "Default",
155
+ born: "Born: {date}",
156
+ birthdateNotSet: "Birthdate not set",
157
+ dateTimeOverrideHint: `Override the account's date & time display for this child. "Inherit" keeps the family default.`,
158
+ createTitle: "Add kid",
159
+ createDescription: "Add a new kid to use with dodi",
160
+ displayName: "Display name",
161
+ displayNamePlaceholder: "Name",
162
+ socialId: "Social ID",
163
+ socialIdPlaceholder: "auto-generated",
164
+ socialIdHint: "A public handle for friend requests \u2014 randomly generated and safe to share. It isn't your child's name.",
165
+ regenerate: "Regenerate",
166
+ birthdate: "Birthdate",
167
+ birthdateOptional: "Birthdate (optional)",
168
+ birthdateHint: "Helps dodi adapt language and content to your child's age.",
169
+ language: "Language",
170
+ languageHint: "The language used when this child is in kid view.",
171
+ creating: "Adding...",
172
+ editTitle: "Edit kid",
173
+ editDescription: "Update {name}'s settings",
174
+ saving: "Saving...",
175
+ loadingKid: "Loading kid...",
176
+ kidNotFound: "Kid not found",
177
+ failedToCreate: "Kid could not be added",
178
+ failedToUpdate: "Kid could not be saved",
179
+ failedToDelete: "Kid could not be removed",
180
+ memoryTitle: "Memory & Notes",
181
+ memoryDescription: "View what dodi remembers about this child and add parent notes.",
182
+ viewMemory: "View memory & notes",
183
+ dangerZone: "Danger zone",
184
+ dangerZoneDescription: "Permanently remove this kid and all associated data.",
185
+ deleteKid: "Remove kid",
186
+ confirmDelete: "Are you sure you want to remove this kid? This cannot be undone.",
187
+ pinPuzzleTitle: "Pin puzzle",
188
+ pinPuzzleDesc: "An avatar puzzle {name} must solve before switching into this kid in kid view",
189
+ pinPuzzleToggle: "Require a secret puzzle",
190
+ pinPuzzleToggleHint: "{name} taps 3 secret animals in the right order to unlock kid view",
191
+ pinPuzzleSetHint: "Tap 3 animals in the order {name} must repeat",
192
+ pinPuzzleIncomplete: "Pick all 3 secret animals"
193
+ };
194
+ var settings = {
195
+ title: "Settings",
196
+ subtitle: "Manage your account settings",
197
+ back: "Back",
198
+ navGeneral: "General",
199
+ navSecurity: "Security",
200
+ navAiProviders: "AI Providers",
201
+ navAccess: "Access",
202
+ navNotifications: "Notifications",
203
+ navGameStudio: "Game Studio",
204
+ accountTitle: "Account",
205
+ accountDescription: "Your account information",
206
+ email: "Email",
207
+ language: "Language",
208
+ subscription: "Subscription",
209
+ tierLabel: "{tier} tier",
210
+ accountId: "Account ID",
211
+ interfaceTitle: "Interface",
212
+ interfaceDescription: "Look and feel of the app.",
213
+ enable3d: "3D character",
214
+ enable3dHint: "Show dodi as the animated 3D character. Turn off to use the 2D artwork, for example on older tablets.",
215
+ interfaceSaveFailed: "Couldn't save. Please try again.",
216
+ dateTimeTitle: "Date & time",
217
+ dateTimeDescription: "Choose how dates and times are displayed across the app.",
218
+ timezone: "Timezone",
219
+ timezoneHint: "Times are shown in this zone. Stored privately \u2014 the server never sees it.",
220
+ timezoneAuto: "Automatic (device)",
221
+ dateFormat: "Date format",
222
+ dateFormatLocale: "Locale default",
223
+ dateFormatLong: "Long",
224
+ timeFormat: "Time format",
225
+ timeFormat24h: "24-hour",
226
+ timeFormat12h: "12-hour",
227
+ timeFormatNone: "No time",
228
+ dateInherit: "Inherit from account",
229
+ datePreviewLabel: "Preview",
230
+ dateVaultLocked: "Your secure vault is locked. Please reload and try again.",
231
+ dateSaveFailed: "Couldn't save date settings. Please try again.",
232
+ notificationsEmailTitle: "Email notifications",
233
+ notificationsEmailDescription: "Choose which emails dodi sends you.",
234
+ notifyFriendApproval: "Friend request approvals",
235
+ notifyFriendApprovalHint: "Email me when one of my children has a friend request waiting for my approval.",
236
+ notifyPublicationOutcome: "Game publication results",
237
+ notifyPublicationOutcomeHint: "Email me when a game I submitted to dodi Discover has been reviewed.",
238
+ notificationsSaveFailed: "Couldn't save. Please try again.",
239
+ gameStudioVisualTitle: "Visual checks",
240
+ gameStudioVisualDescription: "Let dodi look at real screenshots of a game while building it, so it can fix what looks wrong or is broken before you see it.",
241
+ screenshotServiceLabel: "Screenshot service",
242
+ screenshotServiceOff: "Off",
243
+ screenshotServiceOffHint: "No game code leaves your browser. dodi finishes each game without seeing it.",
244
+ screenshotServiceDodi: "Use dodi screenshot service",
245
+ screenshotServiceDodiHint: "Increases game quality by sending the game code to dodi to create a screenshot which the agent can visually verify. The code is sent unencrypted for rendering only and is not stored.",
246
+ screenshotServiceCustom: "Use custom screenshot service",
247
+ screenshotServiceCustomHint: "Send the game code to a service you run yourself instead, for example the dodi screenshot worker on your own server. It must implement the dodi screenshot contract.",
248
+ screenshotServiceUrlLabel: "Service URL",
249
+ screenshotServiceUrlHint: "The full render endpoint, stored privately: the server never sees it. Must use https, or http://localhost for local testing.",
250
+ screenshotServiceUrlPlaceholder: "https://screenshots.example.com/render",
251
+ screenshotServiceUrlInvalid: "Enter an https URL (or http://localhost for local testing).",
252
+ screenshotServiceVaultLocked: "Your secure vault is locked. Please reload and try again.",
253
+ screenshotServiceSaveFailed: "Couldn't save. Please try again.",
254
+ aiConfigTitle: "AI Provider Configuration",
255
+ aiConfigDescription: "Configure AI providers to give dodi a voice and enable game creation.",
256
+ addProvider: "Add provider",
257
+ addProviderTitle: "Add AI Provider",
258
+ addProviderDescription: "Select a provider and enter your API key.",
259
+ selectProvider: "Select provider",
260
+ apiKey: "API key",
261
+ apiKeyPlaceholder: "Enter your API key",
262
+ validateAndSave: "Validate & Save",
263
+ validating: "Validating...",
264
+ keyValid: "API key is valid",
265
+ keyInvalid: "API key is invalid",
266
+ removeProvider: "Remove",
267
+ confirmRemoveProvider: "Remove this provider? dodi will no longer be able to use it.",
268
+ noProviders: "No AI providers configured yet. Add one to give dodi a voice.",
269
+ byokHelpLink: "How does bring your own key work?",
270
+ providerAdded: "Provider added successfully",
271
+ providerRemoved: "Provider removed",
272
+ voiceConfig: "Voice Configuration",
273
+ voiceConfigDescription: "Choose your voice and speaking style.",
274
+ voiceProvider: "Voice provider",
275
+ voiceModel: "Voice model",
276
+ voiceName: "Voice",
277
+ thinkingProvider: "Thinking model provider",
278
+ thinkingModel: "Thinking model",
279
+ thinkingModelDescription: "Gives dodi thinking capabilities.",
280
+ thinkingProviderFallback: "Select provider/model",
281
+ gameConfig: "Game Generation",
282
+ gameConfigDescription: "Choose the model dodi uses to create and edit games. It needs a model that supports tool use.",
283
+ gameProvider: "Game generation provider",
284
+ gameModel: "Game generation model",
285
+ gameProviderFallback: "Select provider/model",
286
+ imageConfig: "Image Generation",
287
+ imageConfigDescription: "Choose an image model to let dodi draw coloring sheets in the Drawing game.",
288
+ imageProvider: "Image model provider",
289
+ imageModel: "Image model",
290
+ imageProviderFallback: "Select provider/model",
291
+ configSaved: "Configuration saved",
292
+ keyEnding: "Key ending in ...{preview}",
293
+ added: "Added {date}",
294
+ aiTabManaged: "dodi AI",
295
+ aiTabByok: "Your own keys",
296
+ managedIntro: "The simplest way to power dodi \u2014 one switch, no API keys, no setup.",
297
+ managedTitle: "dodi AI",
298
+ managedEnableDescription: "Turn it on and dodi picks the best model for every task. You can fine-tune everything afterwards.",
299
+ managedActiveDescription: "dodi manages the AI models and keys for you \u2014 nothing else to set up.",
300
+ managedEnable: "Turn on dodi AI",
301
+ managedEnabling: "Setting up\u2026",
302
+ managedActive: "Active",
303
+ managedDisable: "Turn off dodi AI",
304
+ managedJustEnabled: "All set \u2014 dodi picked the best models for you. You can change any of them below.",
305
+ managedCustomized: "You've customized some model choices.",
306
+ managedResetRecommended: "Reset to dodi's recommended",
307
+ managedBalanceAsOf: "Balance {amount} \xB7 as of {date}",
308
+ managedNeedsCredits: "Your dodi AI credit balance is empty.",
309
+ managedNeedsCreditsHint: "Add credits to start using dodi AI. Top-ups are coming soon \u2014 until then, please use your own keys.",
310
+ managedEnableFailed: "Could not turn on dodi AI. Please try again.",
311
+ managedUnavailable: "dodi AI is not available right now. Please try again later.",
312
+ managedProviderOption: "dodi AI (recommended)",
313
+ serviceVoice: "dodi Voice",
314
+ serviceThinking: "dodi Thinking",
315
+ serviceCode: "dodi Code",
316
+ serviceImage: "dodi Image",
317
+ changePasswordTitle: "Password",
318
+ changePasswordDescription: "Change the password that unlocks your encrypted data.",
319
+ newPassword: "New password",
320
+ confirmNewPassword: "Confirm new password",
321
+ updatePassword: "Update password",
322
+ updatingPassword: "Updating...",
323
+ passwordChanged: "Password updated",
324
+ passwordsNoMatch: "Passwords do not match",
325
+ passwordTooShort: "Password must be at least 8 characters",
326
+ changePasswordFailed: "We couldn't update your password. Please try again.",
327
+ showApiKey: "Show API key",
328
+ hideApiKey: "Hide API key",
329
+ legalTitle: "Legal",
330
+ legalDescription: "How your family's data is handled and the rules for using the service.",
331
+ legalPrivacy: "Privacy policy",
332
+ legalTerms: "Terms of service",
333
+ legalImprint: "Imprint",
334
+ deleteAccountTitle: "Delete account",
335
+ deleteAccountRowTitle: "Delete your account",
336
+ deleteAccountRowMeta: "Permanently removes your account, every kid profile and all of your family's data. This cannot be undone.",
337
+ deleteAccountButton: "Delete account",
338
+ deleteAccountDialogTitle: "Delete your account permanently?",
339
+ deleteAccountDialogDescription: "Your account and everything your family stored are erased from our servers right away, and every device is signed out.",
340
+ deleteAccountConsequenceData: "All kid profiles, memories, conversations, games, snapshots and settings are deleted.",
341
+ deleteAccountConsequenceDiscover: "Games you published leave Discover. Copies other families remixed stay with them.",
342
+ deleteAccountConsequenceFriends: "Friendships end, and snapshots your kids sent to friends are removed.",
343
+ deleteAccountConsequenceCredits: "Any remaining dodi AI credits are lost.",
344
+ deleteAccountPasswordLabel: "Enter your password to confirm",
345
+ deleteAccountConfirm: "Delete permanently",
346
+ deleteAccountDeleting: "Deleting\u2026",
347
+ deleteAccountPasswordRequired: "Enter your password to confirm.",
348
+ deleteAccountWrongPassword: "That password is not correct.",
349
+ deleteAccountRateLimited: "Too many attempts. Please wait a few minutes and try again.",
350
+ deleteAccountFailed: "Your account could not be deleted. Please try again, or write to us if it keeps failing.",
351
+ aiSharingConsent: "I agree that my family's AI requests go to {provider}: my kids' voice while they talk to the companion, their first names, ages and memories, my notes about them, and the games and prompts I create. Details in the <privacy>privacy policy</privacy>.",
352
+ aiSharingConsentManaged: "I agree that my family's AI requests go to the providers behind dodi AI (currently xAI and Venice.ai): my kids' voice while they talk to the companion, their first names, ages and memories, my notes about them, and the games and prompts I create. Details in the <privacy>privacy policy</privacy>.",
353
+ aiSharingConsentThisProvider: "this provider"
354
+ };
355
+ var parentPin = {
356
+ settingsTitle: "Parent PIN",
357
+ settingsDescription: "Require a 4-digit PIN to open the parent area from kid view.",
358
+ statusOn: "PIN is on",
359
+ statusOff: "No PIN set",
360
+ set: "Set PIN",
361
+ change: "Change PIN",
362
+ remove: "Remove PIN",
363
+ newLabel: "New PIN",
364
+ confirmLabel: "Confirm PIN",
365
+ saving: "Saving\u2026",
366
+ saved: "PIN updated",
367
+ removing: "Removing\u2026",
368
+ removed: "PIN removed",
369
+ mismatch: "PINs don't match",
370
+ invalid: "Enter all 4 digits",
371
+ saveFailed: "We couldn't update the PIN. Please try again.",
372
+ promptTitle: "Enter parent PIN",
373
+ promptSubtitle: "Enter your 4-digit PIN to open the parent area.",
374
+ wrong: "Wrong PIN. Try again.",
375
+ forgot: "Forgot PIN?",
376
+ usePassword: "Use account password instead",
377
+ passwordLabel: "Account password",
378
+ passwordWrong: "Incorrect password.",
379
+ unlock: "Unlock",
380
+ checking: "Checking\u2026"
381
+ };
382
+ var personas = {
383
+ title: "Personas",
384
+ subtitle: "Customize dodi's personality and behavior",
385
+ yourPersonas: "Your personas",
386
+ createPersona: "Create persona",
387
+ createTitle: "Create persona",
388
+ createDescription: "Define a new personality for dodi with a soul document",
389
+ editTitle: "Edit persona",
390
+ editDescription: "Update {name}'s soul document",
391
+ import: "Import SOUL.md",
392
+ importTitle: "Import persona",
393
+ importDescription: "Import a persona from a .soul.md file",
394
+ export: "Export",
395
+ clone: "Clone",
396
+ cloneNameLabel: "Name for the clone",
397
+ nameLabel: "Name",
398
+ namePlaceholder: "e.g., Professor dodi",
399
+ soulLabel: "Soul document",
400
+ soulPlaceholder: "# My Persona\n\n## Identity\n- ...\n\n## Personality\n- ...",
401
+ soulHint: "Markdown document with sections: Identity, Personality, Communication Style, Learning Approach, Boundaries, Rules.",
402
+ fileLabel: "SOUL.md file",
403
+ default: "Default",
404
+ custom: "Custom",
405
+ defaultHint: "This is the built-in dodi persona. It cannot be edited or deleted, but you can clone it.",
406
+ customHint: "Custom persona \u2014 click to edit",
407
+ noDescription: "No description",
408
+ selectorLabel: "Persona",
409
+ selectorHint: "Choose which persona dodi uses when talking to this child.",
410
+ useDefault: "Use default (dodi)",
411
+ saving: "Saving...",
412
+ notFound: "Persona not found",
413
+ soulTooLong: "Soul document is too long (max 50,000 characters)",
414
+ failedToCreate: "Failed to create persona",
415
+ failedToUpdate: "Failed to update persona",
416
+ failedToClone: "Failed to clone persona",
417
+ failedToDelete: "Failed to delete persona",
418
+ dangerZone: "Danger zone",
419
+ dangerZoneDescription: "Permanently delete this persona. Kids using it will revert to the default dodi persona.",
420
+ deletePersona: "Delete persona",
421
+ confirmDelete: "Are you sure you want to delete this persona? Kids using it will revert to the default."
422
+ };
423
+ var companions = {
424
+ tabCompanions: "Companions",
425
+ tabPersonas: "Personas",
426
+ kidCompanions: "{name}'s companions",
427
+ addCompanion: "Add companion",
428
+ active: "Active",
429
+ personaLine: "Persona: {persona}",
430
+ noKids: "Add a kid first. Every kid starts with a dodi companion.",
431
+ createTitle: "New companion",
432
+ createDescription: "A new friend for your kid. They can style it and teach it tricks in the Playground.",
433
+ editTitle: "Companion",
434
+ editDescription: "One of {name}'s companions",
435
+ kidLabel: "Kid",
436
+ nameLabel: "Name",
437
+ nameHint: "Leave empty to use the avatar's own name. Kids can rename it in the Playground.",
438
+ personaHint: "The personality this companion talks with.",
439
+ activeLabel: "Active companion",
440
+ activeHint: "The companion {name} sees and talks to right now.",
441
+ isActive: "This is the active companion",
442
+ makeActive: "Make active",
443
+ notFound: "Companion not found",
444
+ failedToCreate: "Failed to add the companion",
445
+ failedToUpdate: "Failed to update the companion",
446
+ failedToDelete: "Failed to delete the companion",
447
+ dangerZone: "Danger zone",
448
+ deleteCompanion: "Delete companion",
449
+ dangerZoneDescription: "Deletes this companion with its look and its custom tricks.",
450
+ lastCompanionHint: "Every kid keeps at least one companion.",
451
+ confirmDelete: "Delete this companion with its look and custom tricks?",
452
+ kidRowLabel: "Companions",
453
+ kidRowHint: "Who your kid talks and plays with. Manage companions and their personas.",
454
+ canChangeAvatar: "Can change the avatar",
455
+ canChangeAvatarHint: "Lets your kid swap a companion's avatar in the Playground. Colors, accessories, names and tricks are always open."
456
+ };
457
+ var playground = {
458
+ open: "Open the Playground",
459
+ close: "Close the Playground",
460
+ title: "Playground",
461
+ tagline: "Play with your buddy",
462
+ panelLook: "Look",
463
+ panelTricks: "Tricks",
464
+ panelTeach: "Teach a trick",
465
+ colors: "Colors",
466
+ accessories: "Accessories",
467
+ avatar: "Avatar",
468
+ name: "Name",
469
+ namePlaceholder: "Give your buddy a name",
470
+ switchCompanion: "Your companions",
471
+ reset: "Start over",
472
+ saved: "Saved",
473
+ saveFailed: "That didn't save. Try again?",
474
+ colorFor: "{part} color",
475
+ trickNeedsBones: "This avatar can't do this trick",
476
+ noCustomTricks: "No tricks of your own yet. Teach your buddy one!",
477
+ yourTricks: "Your tricks",
478
+ builtInTricks: "Tricks everyone knows",
479
+ deleteTrick: "Forget this trick",
480
+ confirmDeleteTrick: 'Forget "{name}"?',
481
+ teachPrompt: "What should your buddy learn?",
482
+ teachPlaceholder: "A happy dance",
483
+ teachButton: "Teach it",
484
+ teaching: "Learning\u2026",
485
+ keepIt: "Keep it",
486
+ tryAgain: "Try again",
487
+ teachFailed: "Your buddy couldn't figure that one out. Try saying it another way.",
488
+ teachNoThinking: "Ask a grown-up to set up a thinking model first.",
489
+ teachLimit: "Your buddy knows so many tricks! Forget one to learn a new one.",
490
+ noCharacter: "Turn on the 3D character to play here.",
491
+ suggestions: {
492
+ spin: "A spin",
493
+ jump: "A big jump",
494
+ bow: "A bow",
495
+ dance: "A little dance",
496
+ flap: "Flap like a bird"
497
+ },
498
+ parts: {
499
+ skin: "Body",
500
+ suit: "Hood & wings",
501
+ beak: "Beak"
502
+ },
503
+ accessoryNames: {
504
+ headphones: "Headphones",
505
+ partyHat: "Party hat",
506
+ glasses: "Glasses",
507
+ scarf: "Scarf"
508
+ },
509
+ avatars: {
510
+ dodi: "dodi"
511
+ },
512
+ tricks: {
513
+ pirouette: "Pirouette",
514
+ backflip: "Backflip",
515
+ wave: "Wave"
516
+ }
517
+ };
518
+ var memory = {
519
+ title: "{name}'s Memory",
520
+ subtitle: "dodi's knowledge about this child and your notes for dodi",
521
+ structuredTitle: "Memory entries",
522
+ structuredHint: "Individual observations with sources from conversations. Discard anything that should no longer apply.",
523
+ noStructured: "No memory entries yet. They appear after dodi processes a day's conversations.",
524
+ sourceCount: "{count, plural, one {# source} other {# sources}}",
525
+ discard: "Discard",
526
+ discardedTitle: "Discarded memories",
527
+ discardedHint: "History of observations that were dropped \u2014 by you or automatically when contradicted.",
528
+ discardedByParent: "Discarded by parent",
529
+ discardedBySystem: "Discarded by system",
530
+ discardSource: "Trigger source",
531
+ failedToDiscard: "Failed to discard memory",
532
+ vaultLocked: "Your secure vault is locked. Please reload and try again.",
533
+ memoryTitle: "Briefing dossier",
534
+ memoryHint: "Markdown briefing dodi reads before each session. Updated from structured memories after conversations.",
535
+ memoryHintCited: "Markdown briefing with {count, plural, one {# source citation} other {# source citations}} \u2014 tap a [n] marker to see the conversation moment behind it.",
536
+ memoryPlaceholder: "No dossier yet. dodi will start building this after the first conversation.",
537
+ citationLabel: "Source {num}",
538
+ citationMissing: "The conversation moment behind this source is no longer available.",
539
+ emptyMemory: "No dossier yet. dodi will start building this after the first conversation.",
540
+ edit: "Edit",
541
+ parentNotesTitle: "Parent Notes",
542
+ parentNotesHint: "Write notes for dodi to read. Use this to share context about your child that dodi should know (allergies, sensitivities, current topics at school, etc.). dodi reads these but never modifies them.",
543
+ parentNotesPlaceholder: "e.g., Emma is currently learning multiplication at school. She's shy about making mistakes.",
544
+ failedToSave: "Failed to save changes",
545
+ kidNotFound: "Kid not found"
546
+ };
547
+ var games = {
548
+ title: "Games",
549
+ subtitle: "Play games picked just for you.",
550
+ kidRequired: "Choose a kid first to use games.",
551
+ backToLibrary: "Back to library",
552
+ backToPlay: "Back to play",
553
+ searchPlaceholder: "Search games...",
554
+ filterSubject: "Filter by subject",
555
+ allGamesFilter: "All games",
556
+ loading: "Loading games...",
557
+ favoriteGames: "Favorites",
558
+ allGames: "Games",
559
+ noGames: "No games found.",
560
+ addFavorite: "Add to favorites",
561
+ removeFavorite: "Remove from favorites",
562
+ systemLabel: "System",
563
+ customLabel: "Custom",
564
+ playAction: "Play",
565
+ back: "Back",
566
+ assistantFailed: "dodi could not answer right now.",
567
+ companionTitle: "dodi Companion",
568
+ companionSubtitle: "Ask for help or tell dodi what to draw.",
569
+ modeText: "Text",
570
+ modeVoice: "Voice",
571
+ companionEmptyState: "Say hi to dodi to get started.",
572
+ companionInputPlaceholder: "Ask dodi for help...",
573
+ unsupportedCommandsDropped: "Skipped {count} unsupported command(s).",
574
+ liveState: "Live game state",
575
+ gameCommandFailedLabel: "Game command error",
576
+ resetGame: "Start over",
577
+ snapshotButton: "Snapshot",
578
+ chipSavePhoto: "Take a snapshot",
579
+ chipShareFriend: "Share with a friend",
580
+ chipExplain: "Explain the game",
581
+ chipHint: "Get a hint",
582
+ chipSharePrompt: "I want to share a photo of my game with a friend.",
583
+ chipExplainPrompt: "Can you explain this game to me?",
584
+ chipHintPrompt: "Can you give me a hint?",
585
+ voiceStart: "Start voice",
586
+ voiceStop: "Stop voice",
587
+ voiceMute: "Mute mic",
588
+ voiceUnmute: "Unmute mic",
589
+ voiceVolume: "Volume",
590
+ voiceVolumeOpen: "Change dodi's volume",
591
+ voiceMuteAll: "Turn dodi's sound off",
592
+ voiceUnmuteAll: "Turn dodi's sound on",
593
+ voiceAriaConnecting: "dodi is connecting",
594
+ voiceAriaStopListening: "Turn dodi's listening off",
595
+ voiceAriaStartListening: "Turn dodi's listening on",
596
+ voiceAriaWake: "Tap to wake dodi",
597
+ voiceAriaReconnect: "Tap to reconnect dodi",
598
+ voiceAriaStart: "Tap to start dodi",
599
+ voiceAriaAsleep: "Sleeping",
600
+ voiceThinkingAlt: "dodi is thinking",
601
+ voiceConnecting: "Waking up...",
602
+ voiceSpeaking: "Talking...",
603
+ voiceListening: "Listening...",
604
+ voiceMicOff: "Microphone is muted.",
605
+ voiceHeard: "I heard: {text}",
606
+ voiceSessionFailed: "Voice session failed.",
607
+ tapToReconnect: "Tap dodi to reconnect",
608
+ micUnavailable: "Microphone is unavailable.",
609
+ sandboxNotReady: "Game is still loading. Try again.",
610
+ unsupportedCommand: "Unsupported command: {command}",
611
+ unknownCommandError: "Unknown command error.",
612
+ voiceCreatingImage: "I'm drawing your picture\u2026",
613
+ voiceWritingText: "I'm writing that for you\u2026",
614
+ voiceThinking: "Hmm, let me think\u2026",
615
+ offline: "No internet connection.",
616
+ offlineNotAvailable: "This game isn't saved for offline yet.",
617
+ noImageModel: "Ask a grown-up to set up an image model in Settings so dodi can draw.",
618
+ drawingFailed: "dodi could not draw that right now. Try again.",
619
+ noThinkingModel: "Ask a grown-up to set up a thinking model in Settings so dodi can write.",
620
+ textGenerationFailed: "dodi could not write that right now. Try again.",
621
+ snapshotSaveFailed: "The snapshot could not be saved.",
622
+ snapshotShareFailed: "The snapshot could not be shared."
623
+ };
624
+ var tags = {
625
+ alphabet: "Alphabet",
626
+ numbers: "Numbers",
627
+ math: "Math",
628
+ writing: "Writing",
629
+ grammar: "Grammar",
630
+ reading: "Reading",
631
+ drawing: "Drawing",
632
+ music: "Music",
633
+ coding: "Coding",
634
+ reasoning: "Reasoning",
635
+ discernment: "Discernment",
636
+ philosophy: "Philosophy",
637
+ physics: "Physics",
638
+ chemistry: "Chemistry",
639
+ biology: "Biology",
640
+ ai: "AI",
641
+ "ai-image": "AI Images"
642
+ };
643
+ var kid = {
644
+ greeting: "Hi there!",
645
+ introMessage: "I'm dodi, your learning buddy.",
646
+ greetingWithName: "Hi {name}!",
647
+ needsVoice: "Your parents need to give me a voice!",
648
+ firstVoice: "Now I have a voice!",
649
+ connecting: "Waking up...",
650
+ dodiSpeaking: "I'm talking...",
651
+ listening: "I'm listening...",
652
+ retry: "Try again",
653
+ connectionError: "Oops! I lost my voice.",
654
+ needsSetup: "Ask a grown-up to check my voice in the settings.",
655
+ offline: "No internet connection.",
656
+ offlineHint: "I can't talk right now, but you can play your games!",
657
+ micPermissionNeeded: "I need to hear you! Please allow microphone access.",
658
+ secureContextRequired: "I can't hear you here. Ask a grown-up to open the app over HTTPS.",
659
+ tapToWake: "Tap to wake me up!",
660
+ tapToTalk: "Tap to talk to me!",
661
+ sessionEnded: "Session ended",
662
+ gamesTitle: "Games",
663
+ friendsTitle: "Friends",
664
+ noKidSelected: "No kid selected"
665
+ };
666
+ var activities = {
667
+ title: "Activities",
668
+ subtitle: "Games, sessions, snapshots, and friend activity",
669
+ heading: "Recent activity",
670
+ filterKid: "All kids",
671
+ filterPersona: "All personas",
672
+ filterEvent: "All events",
673
+ loadMore: "Load more",
674
+ noLogs: "No activity yet. Entries appear here as kids play and interact.",
675
+ noResults: "No entries match your filters.",
676
+ sessionStart: "Session started",
677
+ gameStarted: "Game started",
678
+ gameCommandExecuted: "Command executed",
679
+ gameCommandFailed: "Command failed",
680
+ snapshotCreated: "Snapshot created",
681
+ snapshotShared: "Snapshot shared",
682
+ friendRequestSent: "Friend request sent",
683
+ friendRequestAccepted: "Friend request accepted"
684
+ };
685
+ var agentSessions = {
686
+ title: "Agent Sessions",
687
+ subtitle: "AI code generation tasks, progress, and history",
688
+ heading: "Sessions",
689
+ filterKid: "All kids",
690
+ filterStatus: "All statuses",
691
+ statusActive: "Active",
692
+ statusCompleted: "Completed",
693
+ statusFailed: "Failed",
694
+ statusDeactivated: "Deactivated",
695
+ taskGenerate: "Generate Game",
696
+ taskUpdate: "Update Game",
697
+ progressPlanning: "Planning",
698
+ progressBuilding: "Building",
699
+ progressTesting: "Testing",
700
+ progressDone: "Done",
701
+ deactivate: "Deactivate",
702
+ deactivateConfirm: "Stop this agent task? The child will see the task as stopped.",
703
+ noSessions: "No agent sessions yet. Sessions appear when you create games with dodi.",
704
+ noResults: "No sessions match the current filters.",
705
+ loadMore: "Load more",
706
+ elapsed: "Elapsed"
707
+ };
708
+ var gameStudio = {
709
+ title: "Games",
710
+ subtitle: "Create and edit games for your kids \u2014 just describe them and dodi builds them.",
711
+ tabGame: "Game",
712
+ tabDodi: "dodi",
713
+ addGame: "Create game",
714
+ yourGames: "Your games",
715
+ yourGamesDesc: "Open a game to keep editing it with dodi.",
716
+ noGames: "No games yet. Describe one above and dodi will build it.",
717
+ edit: "Edit",
718
+ export: "Export",
719
+ publish: "Publish",
720
+ delete: "Delete",
721
+ gameActions: "Actions for {title}",
722
+ deleteTitle: "Delete this game?",
723
+ deleteDescription: `"{title}" and its version history will be deleted for everyone in your family. Saved snapshots of it stay in your kids' collections. This can't be undone.`,
724
+ deleteCancel: "Cancel",
725
+ deleteConfirm: "Delete game",
726
+ deleteFailedGeneric: "Deleting failed. Please try again.",
727
+ editedToday: "Edited today",
728
+ editedDaysAgo: "Edited {days}d ago",
729
+ editedWeeksAgo: "Edited {weeks}w ago",
730
+ emptyTitle: "Make a game with dodi",
731
+ emptyDesc: 'Describe a game in plain words \u2014 "a counting game with apples." dodi designs it, builds a live preview, and writes the code.',
732
+ startBuilding: "Start building",
733
+ editing: "Editing game",
734
+ newGameHeading: "New game",
735
+ preview: "Preview",
736
+ previewLanguage: "Preview language",
737
+ code: "Code",
738
+ settings: "Settings",
739
+ infos: "Infos",
740
+ copy: "Copy",
741
+ copied: "Copied",
742
+ showChanges: "Show changes",
743
+ revertVersion: "Revert",
744
+ restoreVersion: "Restore",
745
+ noPreviousVersion: "No previous version to compare yet",
746
+ unchangedLines: "{count, plural, one {# unchanged line} other {# unchanged lines}}",
747
+ editCode: "Edit",
748
+ editCodeSave: "Save",
749
+ editCodeCancel: "Cancel",
750
+ codeSearchFind: "Find",
751
+ codeSearchReplace: "Replace",
752
+ codeSearchNext: "next",
753
+ codeSearchPrevious: "previous",
754
+ codeSearchMatchCase: "match case",
755
+ codeSearchRegexp: "regexp",
756
+ codeSearchByWord: "by word",
757
+ codeSearchReplaceNext: "replace",
758
+ codeSearchReplaceAll: "replace all",
759
+ codeSearchClose: "close",
760
+ codeSearchCurrentMatch: "current match",
761
+ codeSearchOnLine: "on line",
762
+ codeSearchReplacedMatches: "replaced $ matches",
763
+ codeSearchReplacedOnLine: "replaced match on line $",
764
+ codeSearchToggleReplace: "Toggle replace",
765
+ codeSearchNoResults: "No results",
766
+ codeSearchOf: "of",
767
+ versionSelector: "Version",
768
+ saveEditTitle: "Save code changes?",
769
+ saveEditDescription: "Your edited code replaces the game's current code.",
770
+ saveEditNewVersion: "Create a new version",
771
+ saveEditCancel: "Cancel",
772
+ saveEditConfirm: "Save",
773
+ save: "Save",
774
+ saveChanges: "Save changes",
775
+ saved: "Saved",
776
+ saving: "Saving\u2026",
777
+ saveFailed: "Couldn't save the game: {reason}",
778
+ saveFailedGeneric: "Couldn't save the game. Please try again.",
779
+ previewEmpty: "Your game preview will appear here once dodi builds it.",
780
+ codeEmpty: "The generated game code will appear here.",
781
+ gameName: "Game name",
782
+ gameNamePlaceholder: "e.g. Apple Orchard",
783
+ forKid: "Who can play",
784
+ forKidPlaceholder: "Choose a child",
785
+ forLabel: "For",
786
+ family: "Family",
787
+ needProviderKey: "Add an AI provider key in Settings before building games.",
788
+ needThinkingProvider: "Choose a Game generation model in Settings before building games. dodi needs it to create and edit games.",
789
+ learningGoal: "Learning goal",
790
+ learningGoalPlaceholder: "What should this game help with?",
791
+ tags: "Tags",
792
+ tagsHint: "Pick the subjects and themes this game fits.",
793
+ tagsNone: "No tags yet.",
794
+ tagsAdd: "Add tags",
795
+ tagsEdit: "Edit",
796
+ tagsDone: "Done",
797
+ listingTranslations: "Translations",
798
+ listingTranslationsHint: "How your game's title and description appear on dodi Discover in other languages. Fix a translation here, save, and then resubmit the game. Clear a title to have it translated again on your next submit.",
799
+ listingTranslationTitlePlaceholder: "Title",
800
+ listingTranslationGameLanguage: "(game language)",
801
+ listingSameDescription: "{languages} have the same description. One of them is probably not translated yet, and the review would ask you to fix it. Please check before submitting.",
802
+ recommendedAge: "Recommended age",
803
+ recommendedAgeHint: "The age range this game suits best \u2014 shown on dodi Discover and used to recommend it.",
804
+ ageMinLabel: "Youngest recommended age",
805
+ ageMaxLabel: "Oldest recommended age",
806
+ ageRangeInvalid: "Enter an age range between 1 and 25 \u2014 the youngest age can't be above the oldest.",
807
+ perspectiveLabel: "Perspective",
808
+ perspectiveHint: "The camera angle dodi designs the game around. Leave it unspecified to let dodi pick the best fit.",
809
+ perspectiveUnspecified: "Unspecified",
810
+ perspectiveBird: "Bird's eye",
811
+ perspectiveSide: "Side-on",
812
+ perspectiveIsometric: "Isometric 2.5D",
813
+ attachImage: "Attach a reference image",
814
+ attachUpload: "Upload an image",
815
+ attachLimitReached: "Up to 3 images per message",
816
+ dropImages: "Drop images here",
817
+ dropImagesHint: "Attached as reference images for dodi",
818
+ removeImage: "Remove image",
819
+ attachedImage: "Attached image {n}",
820
+ backgroundImageLabel: "Background image",
821
+ backgroundImageToggle: "Generate a background image with AI",
822
+ backgroundImageHint: "dodi creates an illustrated backdrop for the game with your image model.",
823
+ backgroundImageNeedsProvider: "Add an image model to use AI backgrounds.",
824
+ stepGeneratingImage: "Painting the background\u2026",
825
+ bgSkippedNotice: 'dodi built the game without generating a background image this time. Ask dodi to "add a generated background" if you want one.',
826
+ bgFailedNotice: "Background image generation failed \u2014 the game was built without it. Check your image model in Settings and try again.",
827
+ previewImageLabel: "Preview image",
828
+ previewImageToggle: "Generate a preview image with AI",
829
+ previewImageHint: "After each build, dodi creates a square game icon from the finished game and its background image, shown in game lists.",
830
+ stepGeneratingPreview: "Creating the preview image\u2026",
831
+ previewSkippedNotice: 'dodi finished without generating a preview image this time. Ask dodi to "create a preview image" if you want one.',
832
+ previewFailedNotice: "Preview image generation failed. Check your image model in Settings and try again.",
833
+ visualCheckFailedNotice: "The screenshot service didn't answer, so dodi built this game without seeing it.",
834
+ previewUpdatedMessage: "I created a fresh preview image, you can see it in your game list.",
835
+ buildSummaryTitle: "Build summary:",
836
+ previewUpdateFailedMessage: "I couldn't create a new preview image. Check your image model in Settings and try again.",
837
+ successDefinition: "Success definition",
838
+ successPlaceholder: 'How does dodi know a child succeeded? e.g. "Counts to the target 3 times in a row without help."',
839
+ progressKindGoal: "Goal-based \u2014 dodi tracks success",
840
+ progressKindOpen: "Open-ended \u2014 free play",
841
+ designerName: "dodi",
842
+ designerRole: "Game designer",
843
+ working: "Working\u2026",
844
+ composerPlaceholderEmpty: "Describe the game you want\u2026",
845
+ composerPlaceholder: "Ask dodi to change something\u2026",
846
+ welcomeTitle: "What should we make?",
847
+ welcomeDesc: "Describe a game in your own words. dodi designs it, builds a live preview, and writes the code.",
848
+ send: "Send",
849
+ footer: "dodi tests every game in a safe environment before your kids play.",
850
+ buildFailed: "Game build failed. Please try again.",
851
+ saveAndBuild: "Save & start building",
852
+ plan: "Plan",
853
+ plannerRole: "Planning partner",
854
+ planThinking: "Thinking it through\u2026",
855
+ planTakePhoto: "Take a photo",
856
+ planAttachSketch: "Attach to chat",
857
+ planAnalyzePhotoPrompt: "Analyze the attached image and suggest how it could become a learning game.",
858
+ planAnalyzeSketchPrompt: "Here is my sketch of the game I have in mind. Please read the layout and suggest how the game could work.",
859
+ planChipPersonalize: "Personalize this to match my kids' preferences.",
860
+ planStarterIdea: "Help me find a good game idea.",
861
+ planDrawSketch: "Draw a sketch",
862
+ planDraw: "Draw",
863
+ planPhoto: "Photo",
864
+ planBack: "Back to the conversation",
865
+ planWelcomeTitle: "How should we start?",
866
+ planWelcomeDesc: "Tell dodi what your child should practise, or add a sketch or photo. You get a plan to approve before anything is built.",
867
+ planComposerPlaceholder: "Describe how the game should work\u2026",
868
+ planCardTitle: "The plan",
869
+ planCardEmpty: "No plan yet. Describe your idea or add a sketch or photo, and dodi proposes one here.",
870
+ planModify: "Modify",
871
+ planDoneEditing: "Done",
872
+ planAccept: "Accept plan",
873
+ planAccepting: "Preparing settings\u2026",
874
+ planSkip: "Skip planning",
875
+ planProposedFallback: "I have put a plan together for you.",
876
+ planUpdatedNote: "The plan is updated.",
877
+ planFailed: "Planning failed. Please try again.",
878
+ aiUnavailable: "The dodi AI service is temporarily unavailable. Please try again later.",
879
+ planSettingsFailed: "The plan is saved, but the settings could not be filled in automatically. Please check them.",
880
+ planBuildIntro: "Build the game we planned:",
881
+ planBuildHint: "Saving starts the build with the plan you accepted.",
882
+ savingSettings: "Saving your settings, then dodi starts building.",
883
+ sketchColor: "Pen color",
884
+ sketchThin: "Thin pen",
885
+ sketchThick: "Thick pen",
886
+ sketchEraser: "Eraser",
887
+ sketchUndo: "Undo",
888
+ sketchClear: "Clear sketch",
889
+ sketchCanvas: "Sketch of your game",
890
+ composerPlaceholderNoThinking: "Choose a Game generation model in Settings to start building\u2026",
891
+ openSettings: "Open Settings",
892
+ saveBeforeBuild: "Save your game settings before building.",
893
+ stop: "Stop",
894
+ stopped: "Stopped \u2014 your game is unchanged.",
895
+ building: "dodi is building\u2026",
896
+ agentRunningWarning: "Keep this tab open \u2014 leaving or closing it stops dodi mid-build.",
897
+ leaveWhileRunningConfirm: "dodi is still building this game. If you leave now it stops and this build is lost. Leave anyway?",
898
+ clearHistory: "Clear conversation",
899
+ clearHistoryConfirmTitle: "Clear this conversation?",
900
+ clearHistoryConfirmDescription: "This removes every message in this game's conversation for good. Your game itself isn't changed. You can also clear by typing /clear.",
901
+ clearHistoryConfirmButton: "Clear conversation",
902
+ clearHistoryCancel: "Cancel",
903
+ active: "Active",
904
+ inactive: "Inactive",
905
+ planning: "Planning",
906
+ untitledPlan: "Untitled game",
907
+ visibilityLabel: "Visibility",
908
+ activeHint: "Inactive games are hidden from kids until you activate them.",
909
+ stepThinking: "Thinking\u2026",
910
+ stepReadingDocs: "Reviewing game specifications\u2026",
911
+ stepWritingCode: "Writing the game code\u2026",
912
+ stepValidating: "Testing the game",
913
+ stepFixingValidation: "Fixing validation issues\u2026",
914
+ stepVisualCheck: "Looking at the game\u2026",
915
+ stepFinalizing: "Finishing up\u2026",
916
+ writeProgress: "{chars, number} characters written\u2026",
917
+ runLogSummary: "How dodi built this",
918
+ runLogChecks: "{count, plural, one {# visual check} other {# visual checks}}",
919
+ runLogOutcomeCompleted: "done in {duration}",
920
+ runLogOutcomeValidationFailed: "done in {duration}, some checks still failed",
921
+ runLogOutcomeStopped: "stopped after {duration}",
922
+ runLogOutcomeFailed: "failed after {duration}",
923
+ runLogEmpty: "Nothing was recorded for this build.",
924
+ runLogStepThinking: "Thinking",
925
+ runLogStepReadingDocs: "Reviewing the game specifications",
926
+ runLogStepGeneratingImage: "Painting the background",
927
+ runLogStepGeneratingPreview: "Creating the preview image",
928
+ runLogStepWritingCode: "Writing code",
929
+ runLogStepValidating: "Validating the game",
930
+ runLogStepFixingValidation: "Fixing validation errors",
931
+ runLogStepVisualCheck: "Visual check",
932
+ runLogStepFinalizing: "Finishing up",
933
+ runLogCheckTitle: "Screenshots",
934
+ runLogCheckReady: "game started",
935
+ runLogCheckNotReady: "game did not start in time",
936
+ runLogCheckRequested: "Asked to show: {steps}",
937
+ runLogCheckFailed: "The screenshot service did not answer, so no screenshots were taken.",
938
+ runLogNoFrames: "No screenshot could be captured.",
939
+ runLogFramesDropped: "Screenshots are only kept for the most recent builds.",
940
+ runLogFramesPartlyDropped: "Some screenshots of this check are no longer kept.",
941
+ runLogErrors: "Errors in the game",
942
+ runLogLayoutIssues: "Layout problems",
943
+ runLogWarnings: "Warnings",
944
+ runLogOpenFrame: "Open screenshot: {label}",
945
+ runLogFrameTitle: "Screenshot",
946
+ starterCounting: "A counting game with apples",
947
+ starterMath: "An adding game, numbers up to 10",
948
+ starterStory: "A gentle bedtime story about a brave snail",
949
+ starterDrawing: "A drawing game about outer space",
950
+ publishTitle: "Publish to dodi Discover",
951
+ publishDescription: "Share this game with other dodi families. Publishing sends a copy out of end-to-end encryption so dodi can review it for safety \u2014 your own game and its history stay encrypted and private.",
952
+ publishSubmitted: "Your game is waiting for its safety check. There's nothing else you need to do.",
953
+ publishSubmit: "Submit for review",
954
+ publishResubmit: "Resubmit latest version",
955
+ publishWithdraw: "Withdraw submission",
956
+ publishInReview: "In review",
957
+ publishLive: "Published",
958
+ publishNeedsBuild: "Build the game first. There's nothing to publish yet.",
959
+ publishRecommendedAgeHint: "Check the recommended age. An accurate range helps your game pass review and reach the right families.",
960
+ publishHandleLabel: "Publisher name",
961
+ publishHandlePlaceholder: "fun_games",
962
+ publishHandleHint: "Shown publicly on everything you publish. Lowercase letters, numbers and underscores.",
963
+ publishHandleFormat: "Use 3\u201315 lowercase letters, numbers or underscores \u2014 no spaces.",
964
+ publishHandleReserved: "That name is reserved. Please pick another.",
965
+ publishHandleTaken: "That name is already taken. Please pick another.",
966
+ publishHandleInvalid: "That publisher name can't be used. Please pick another.",
967
+ publishFailedGeneric: "Publishing failed. Please try again.",
968
+ publishChangesRequested: "Changes requested",
969
+ publishRejected: "Rejected",
970
+ publishReasonsIntro: "The review found things to fix. Update your game in the studio, then resubmit it.",
971
+ publishRejectedHardNotice: "The review rejected this game permanently. It can't be submitted again.",
972
+ publishLimitReached: "You've reached this month's publishing limit. Try again next month.",
973
+ publishHardBlocked: "This game was rejected permanently and can't be submitted again.",
974
+ publishTranslating: "Translating...",
975
+ publishReviewTranslations: "Your game will be published in every dodi language. The translations were saved into your game, so you can test them in the studio preview or reuse them next time.",
976
+ publishReviewTranslationsHint: "Review each language's title and description below. You can edit them before submitting.",
977
+ publishTranslatedTitle: "Title ({locale})",
978
+ publishTranslatedDescription: "Description ({locale})",
979
+ publishReviewInStudio: "Review in studio",
980
+ publishConfirm: "Confirm and submit",
981
+ publishNeedsTranslations: "This game was does not contain translations. Open it in the studio and ask dodi to make it multilingual, then publish again.",
982
+ publishNeedsAiKey: "Publishing needs an AI model to translate your game. Set up a thinking model in your AI settings first.",
983
+ publishTooLargeForTranslation: "This game is too large to hold all its translations. Ask dodi to shorten its texts, then try again.",
984
+ publishTranslationsIncomplete: "Some languages are missing translations. Please try publishing again.",
985
+ publishReason_hard_security_violation: "Security violation",
986
+ publishReason_hard_forbidden_content: "Forbidden content",
987
+ publishReason_hard_child_safety: "Child-safety concern",
988
+ publishReason_hard_copyright_infringement: "Copyright or trademark infringement",
989
+ publishReason_soft_contains_personal_information: "Contains personal information",
990
+ publishReason_soft_bridge_protocol_mismatch: "Progress reporting isn't working",
991
+ publishReason_soft_age_appropriateness: "Doesn't fit the target age range",
992
+ publishReason_soft_misleading_metadata: "Title or description doesn't match the game",
993
+ publishReason_soft_translation_quality: "Translations don't match across languages",
994
+ publishReason_soft_quality_below_bar: "Game is broken or incomplete",
995
+ publishReason_soft_advertising_or_promotion: "Contains advertising or promotion",
996
+ publishLoading: "Checking the status of your game...",
997
+ publishStepSubmitted: "Submitted",
998
+ publishStepReview: "Safety review",
999
+ publishStepLive: "Live on Discover",
1000
+ publishProgressLabel: "Publishing progress",
1001
+ publishReviewEta: "dodi checks every game for safety before other families can see it. This usually takes a few minutes.",
1002
+ publishReviewSlow: "This is taking longer than usual. A dodi team member will take a look, so there's no need to resubmit.",
1003
+ publishNotifyEmail: "We'll email you the result, and you'll also see it here.",
1004
+ publishNotifyHere: "You'll see the result here once it's ready.",
1005
+ publishSubmittedMeta: "Submitted {date} \xB7 Ages {min} to {max}",
1006
+ publishLiveMeta: "Published version submitted {date} \xB7 Ages {min} to {max}",
1007
+ publishLiveDescription: "Your game is live on dodi Discover.",
1008
+ publishLiveBody: "Other families can now find your game, add it for their kids and play it.",
1009
+ publishViewOnDiscover: "View on Discover",
1010
+ publishEditedSinceSubmit: "You've changed this game since you submitted it. The review checks the submitted version.",
1011
+ publishEditedSinceLive: "You've changed this game since it was published. Discover keeps showing the published version until you resubmit.",
1012
+ publishUpdateToggle: "Made changes to your game?",
1013
+ publishUpdateToggleLive: "Want to publish an update?",
1014
+ publishUpdateInReviewHint: "To send your latest version instead, resubmit it. The review starts over, and each submission counts toward your limit of {limit} per month.",
1015
+ publishUpdateLiveHint: "While we check the update, your game is taken off Discover. If the update isn't approved, it stays off until you fix it. Each submission counts toward your limit of {limit} per month.",
1016
+ publishResubmitDescription: "Send your latest version for review. Check the recommended age first.",
1017
+ publishResubmitLiveWarning: "Your game leaves Discover while the update is reviewed, and only comes back once it's approved.",
1018
+ publishBack: "Back",
1019
+ publishDone: "Got it",
1020
+ publishClose: "Close",
1021
+ publishUnpublish: "Unpublish",
1022
+ publishWithdrawConfirm: "Withdraw this submission? You can submit your game again later.",
1023
+ publishUnpublishConfirm: "Take your game off Discover? Families who added it will lose it. You can submit it again later.",
1024
+ publishKeep: "Keep it",
1025
+ publishOpenInStudio: "Open in studio",
1026
+ discoverTitle: "Discover games",
1027
+ discoverSubtitle: "Official dodi games and games published by other dodi families.",
1028
+ discoverEmpty: "No published games yet \u2014 yours could be the first!",
1029
+ discoverBy: "by @{handle}",
1030
+ discoverByDodi: "by dodi",
1031
+ discoverAges: "Ages {min}\u2013{max}",
1032
+ discoverDuration: "{minutes} min",
1033
+ discoverAdded: "Added",
1034
+ discoverPlaysLabel: "Played {count, plural, =0 {never yet} one {# time} other {# times}}",
1035
+ discoverCopiesLabel: "Copied {count, plural, =0 {never yet} one {# time} other {# times}}",
1036
+ discoverShare: "Share with kids",
1037
+ discoverUnshare: "Remove share",
1038
+ discoverShareTitle: "Share with your kids",
1039
+ discoverShareDescription: "Choose who can play \u201C{title}\u201D. It appears in their library and plays right from dodi Discover \u2014 nothing is copied.",
1040
+ studioShareDescription: "Choose who can play \u201C{title}\u201D. It appears in their library \u2014 nothing is copied.",
1041
+ discoverShareConfirm: "Save",
1042
+ discoverRemix: "Create copy",
1043
+ discoverRemixTitle: "Create a copy",
1044
+ discoverRemixDescription: "Creates your own private, editable copy of \u201C{title}\u201D in your studio. Your copy is encrypted like any other game and starts inactive.",
1045
+ discoverRemixConfirm: "Create copy",
1046
+ discoverRemixNeedsKid: "Add a kid profile before copying games.",
1047
+ discoverLoadMore: "Show more",
1048
+ discoverFailedGeneric: "Something went wrong. Please try again.",
1049
+ exportTitle: "Export game",
1050
+ exportDescription: "Downloads a zip with this game's code, settings, and background image. It can be imported on another dodi account.",
1051
+ exportIncludeTranscript: "Include the dodi conversation (may contain attached photos)",
1052
+ exportTranscriptEmpty: "There is no conversation to include.",
1053
+ exportTranscriptLocked: "Unlock your vault and reopen the studio to include the conversation.",
1054
+ exportCancel: "Cancel",
1055
+ exportConfirm: "Download",
1056
+ exportFailed: "Export failed: {reason}",
1057
+ exportFailedGeneric: "Export failed. Please try again.",
1058
+ importGame: "Import game",
1059
+ importTitle: "Import game",
1060
+ importDescription: "Select a .dodi-game.zip exported from another dodi account.",
1061
+ importSelectFile: "Choose file",
1062
+ importPreviewUnbuilt: "Draft \u2014 not built yet",
1063
+ importAges: "Ages {min}\u2013{max}",
1064
+ importDuration: "{minutes} min",
1065
+ importDroppedTags: "Unknown tags were skipped: {tags}",
1066
+ importTranscriptIncluded: "Includes the dodi conversation \u2014 it will be re-encrypted for your account.",
1067
+ importTranscriptSkipped: "The included conversation can't be saved while your vault is locked \u2014 it will be skipped.",
1068
+ importInactiveNotice: "The game is imported as inactive so you can review it first.",
1069
+ importNeedsKid: "Add a kid profile before importing games.",
1070
+ importConfirm: "Import",
1071
+ importCancel: "Cancel",
1072
+ importAnotherFile: "Choose a different file",
1073
+ importFailed: "Import failed: {reason}",
1074
+ importFailedGeneric: "Import failed. Please try again.",
1075
+ importErrArchiveTooLarge: "The file is too large.",
1076
+ importErrArchiveInvalid: "This is not a valid game archive.",
1077
+ importErrManifest: "The archive's manifest is missing or invalid.",
1078
+ importErrVersion: "This archive was created by a newer dodi version.",
1079
+ importErrCode: "The archive's game code is missing or invalid.",
1080
+ importErrCodeTooLarge: "The game code exceeds the size limit.",
1081
+ importErrUnsafeCode: "The game code failed the safety check.",
1082
+ importErrBackground: "The background image is missing from the archive.",
1083
+ buildRunningHint: "You can keep using the app while dodi builds. If you close or reload this tab, the build pauses and you can continue it here.",
1084
+ buildRunningHintApp: "You can switch to other apps while dodi builds. The build keeps running in the background.",
1085
+ buildPaused: "Paused. dodi can continue this build where it stopped.",
1086
+ otherBuildRunning: "dodi is already building another game. Wait until it is done, then try again.",
1087
+ resumeBuildNotice: "dodi's last build of this game was interrupted. Continue where it stopped?",
1088
+ resumeBuild: "Continue building",
1089
+ discardResumableBuild: "Discard"
1090
+ };
1091
+ var friends = {
1092
+ title: "Friends",
1093
+ friendCount: "{count, plural, =0 {No friends yet} one {# friend} other {# friends}}",
1094
+ requestCount: "{count, plural, one {# request} other {# requests}}",
1095
+ addFriend: "Add a friend",
1096
+ searchPlaceholder: "Find a friend\u2026",
1097
+ tabAll: "All",
1098
+ tabFriends: "Friends",
1099
+ tabRequests: "Requests",
1100
+ tabBlocked: "Blocked",
1101
+ sectionIncoming: "Incoming requests",
1102
+ sectionOutgoing: "Outgoing requests",
1103
+ sectionWants: "Wants to be friends",
1104
+ sectionYourFriends: "Friends",
1105
+ sectionYouAsked: "You asked",
1106
+ wantsToBeFriends: "wants to be friends",
1107
+ requestSent: "Request sent",
1108
+ youAccepted: "You said yes",
1109
+ pending: "Pending",
1110
+ awaitingYourParent: "Waiting on your parent",
1111
+ awaitingFriendsParent: "Waiting on friend's parent",
1112
+ blocked: "Blocked",
1113
+ accept: "Accept",
1114
+ unblock: "Unblock",
1115
+ emptyFriends: "No friends yet \u2014 add your first one!",
1116
+ emptyFriendsSearch: "No friends match that.",
1117
+ emptyRequests: "No friend requests right now.",
1118
+ emptyBlocked: "You haven't blocked anyone.",
1119
+ kidBack: "Friends",
1120
+ friendBadge: "Friend",
1121
+ birthday: "Birthday",
1122
+ friendsSince: "Friends since",
1123
+ block: "Block",
1124
+ removeFriend: "Remove friend",
1125
+ confirmRemove: "Remove {name} from your friends?",
1126
+ confirmBlock: "Block {name}? They won't be able to reach you.",
1127
+ unknownValue: "\u2014",
1128
+ addTitle: "Add a friend",
1129
+ segCode: "My code",
1130
+ segScan: "Scan",
1131
+ segTag: "Add by code",
1132
+ myCodeHint: "Show this to a friend so they can scan it and add you.",
1133
+ shareCode: "Share my code",
1134
+ copied: "Copied!",
1135
+ scanHint: "Point at your friend's code",
1136
+ scanDenied: "Camera access is off. Allow the camera, or type the code instead.",
1137
+ scanNoCamera: "No camera found \u2014 type the code instead.",
1138
+ scanUnsupported: "Scanning isn't available here \u2014 type the code instead.",
1139
+ typeCodeInstead: "Type a code instead",
1140
+ tagLabel: "Type your friend's code",
1141
+ tagPlaceholder: "",
1142
+ tagHint: "A friend code has 8 chars. Ask your friend for theirs.",
1143
+ nicknameLabel: "Name or nickname",
1144
+ nicknamePlaceholder: "e.g. Tom from school",
1145
+ sendRequest: "Send request",
1146
+ sending: "Sending\u2026",
1147
+ sentTitle: "Request sent!",
1148
+ sentSub: "Your request is on its way. You'll see {name} under Requests until they say yes.",
1149
+ addAnother: "Add another",
1150
+ errorNotFound: "No kid found for that friend code.",
1151
+ errorGeneric: "Something went wrong. Please try again.",
1152
+ errorVaultLocked: "Your secure vault is locked. Reload and try again.",
1153
+ offlineUnavailable: "Friends need an internet connection.",
1154
+ errorNotAllowed: "Your parent hasn't turned on adding friends yet.",
1155
+ errorAlreadyFriends: "You're already friends with {name}!",
1156
+ errorRequestExists: "You already have a friend request with {name}.",
1157
+ errorBlocked: "{name} can't be added.",
1158
+ errorSelf: "You can't add yourself!",
1159
+ settingsTitle: "Friends",
1160
+ settingsDesc: "Control how {name} connects with other kids.",
1161
+ canInitiate: "Can add friends",
1162
+ canInitiateHint: "Let this child send friend requests to others.",
1163
+ canBeAdded: "Can be added by others",
1164
+ canBeAddedHint: "Let other kids find this child by their friend code.",
1165
+ incomingApproval: "Approve incoming requests",
1166
+ incomingApprovalHint: "When another kid asks to be friends, you give the final yes before it's accepted.",
1167
+ outgoingApproval: "Approve outgoing requests",
1168
+ outgoingApprovalHint: "When this child sends a friend request, you give the final yes before the friendship goes live.",
1169
+ approvalsIncomingTitle: "Incoming friend requests",
1170
+ approvalsOutgoingTitle: "Outgoing friend requests",
1171
+ approvalSummary: "{requester} wants to add {target}",
1172
+ sentOn: "Sent {date}",
1173
+ approvalsEmpty: "Nothing waiting for your approval.",
1174
+ approve: "Approve",
1175
+ reject: "Reject"
1176
+ };
1177
+ var breadcrumbs = {
1178
+ memory: "Memory",
1179
+ newPersona: "New persona",
1180
+ newCompanion: "New companion"
1181
+ };
1182
+ var nav = {
1183
+ dashboard: "Dashboard",
1184
+ kids: "Kids",
1185
+ companions: "Companions",
1186
+ personas: "Personas",
1187
+ gameStudio: "Games",
1188
+ activities: "Activities",
1189
+ usage: "Usage",
1190
+ agentSessions: "Agent Sessions",
1191
+ settings: "Settings",
1192
+ home: "Home",
1193
+ games: "Games",
1194
+ friends: "Friends",
1195
+ kidView: "Kid View",
1196
+ parent: "Parent",
1197
+ switchKid: "Switch kid",
1198
+ navGroupFamily: "Family",
1199
+ navGroupInsights: "Insights",
1200
+ navGroupAccount: "Account",
1201
+ openKidView: "Open Kid View",
1202
+ openMenu: "Open menu",
1203
+ closeMenu: "Close menu",
1204
+ snapshots: "Snapshots",
1205
+ parentSnapshots: "Snapshots",
1206
+ switchToParentView: "Switch to parent view",
1207
+ report: "Report a problem"
1208
+ };
1209
+ var usage = {
1210
+ title: "Usage",
1211
+ subtitle: "This month's AI usage. Costs are billed by your own provider.",
1212
+ voiceMinutes: "Voice minutes",
1213
+ gamesMade: "Games made",
1214
+ perModel: "By model",
1215
+ createsEdits: "{creates} created \xB7 {edits} edited \xB7 {plans} planned \xB7 {analyses} analyzed",
1216
+ perChild: "By child",
1217
+ childGames: "{count} games",
1218
+ childVoice: "{count} voice min",
1219
+ unknownChild: "A child",
1220
+ noUsage: "No AI usage yet this month. Usage appears here as dodi makes games and chats."
1221
+ };
1222
+ var kidProfile = {
1223
+ whosPlaying: "Who's playing?",
1224
+ close: "Close",
1225
+ secret: "{name}'s secret",
1226
+ secretHint: "Tap the 3 secret characters in order",
1227
+ solveToStart: "Solve your secret up top to start playing",
1228
+ cancel: "Cancel",
1229
+ look: "{name}'s look",
1230
+ lookHint: "Pick a color & a character",
1231
+ colorLabel: "Color {n}",
1232
+ slotLabel: "Slot {n}",
1233
+ group: {
1234
+ animals: "Animals",
1235
+ dinos: "Dinos",
1236
+ entities: "Entities",
1237
+ humans: "Characters"
1238
+ }
1239
+ };
1240
+ var snapshots = {
1241
+ title: "Snapshots",
1242
+ subtitle: "Saved game moments of yours and from friends.",
1243
+ kidRequired: "Pick a kid profile first to see snapshots.",
1244
+ loading: "Loading snapshots\u2026",
1245
+ offlineNotAvailable: "This snapshot isn't saved for offline yet.",
1246
+ empty: 'No snapshots yet. While playing, tell dodi "Save this!" to keep a moment.',
1247
+ loadFailed: "Snapshots could not be loaded.",
1248
+ locked: "Unlock the vault to see snapshots.",
1249
+ fromFriend: "From {name}",
1250
+ fromFriendUnknown: "From a friend",
1251
+ newBadge: "New",
1252
+ deleteAction: "Delete snapshot",
1253
+ deleteConfirm: "Delete this snapshot? This cannot be undone.",
1254
+ openAction: "Open",
1255
+ notFound: "This snapshot doesn't exist anymore.",
1256
+ openFailed: "This snapshot could not be opened.",
1257
+ sectionMine: "My snapshots",
1258
+ sectionFriends: "From friends"
1259
+ };
1260
+ var parentSnapshots = {
1261
+ heading: "All snapshots",
1262
+ filterKid: "All kids",
1263
+ filterKidOwn: "Own kids",
1264
+ filterKidOther: "Other",
1265
+ filterType: "All types",
1266
+ typeManual: "Manual",
1267
+ typeAutosave: "Autosave",
1268
+ filterUsage: "Any usage",
1269
+ usageStored: "Stored",
1270
+ usageSent: "Sent",
1271
+ usageReceived: "Received",
1272
+ sentTo: "Sent to {name}",
1273
+ sentToUnknown: "Sent to a friend",
1274
+ receivedFrom: "From {name}",
1275
+ receivedFromUnknown: "From a friend",
1276
+ unknownKid: "Unknown kid",
1277
+ unreadable: "Unreadable snapshot",
1278
+ noSnapshots: 'No snapshots yet. While playing, kids can tell dodi "Save this!" to keep a moment.',
1279
+ noResults: "No snapshots match your filters.",
1280
+ locked: "Unlock the vault to see snapshots.",
1281
+ loadFailed: "Snapshots could not be loaded.",
1282
+ snapshotActions: "Actions for {title}",
1283
+ export: "Export",
1284
+ exportTitle: "Export snapshot",
1285
+ exportDescription: "Downloads a zip with this snapshot's game, save state, and thumbnail. It can be imported on another dodi account.",
1286
+ exportCancel: "Cancel",
1287
+ exportConfirm: "Download",
1288
+ exportFailed: "Export failed: {reason}",
1289
+ exportFailedGeneric: "Export failed. Please try again.",
1290
+ importSnapshot: "Import snapshot",
1291
+ importTitle: "Import snapshot",
1292
+ importDescription: "Select a .dodi-snap.zip exported from another dodi account.",
1293
+ importSelectFile: "Choose file",
1294
+ importSavedBy: "Saved by {name}",
1295
+ importKidLabel: "Add to kid",
1296
+ importNeedsKid: "Add a kid profile before importing snapshots.",
1297
+ importLocked: "Unlock your vault to import snapshots.",
1298
+ importConfirm: "Import",
1299
+ importCancel: "Cancel",
1300
+ importAnotherFile: "Choose a different file",
1301
+ importFailed: "Import failed: {reason}",
1302
+ importFailedGeneric: "Import failed. Please try again.",
1303
+ importErrArchiveTooLarge: "The file is too large.",
1304
+ importErrArchiveInvalid: "This is not a valid snapshot archive.",
1305
+ importErrManifest: "The archive's manifest is missing or invalid.",
1306
+ importErrVersion: "This archive was created by a newer dodi version.",
1307
+ importErrCode: "The archive's game code is missing or invalid.",
1308
+ importErrUnsafeCode: "The game code failed the safety check.",
1309
+ importErrState: "The archive's save state is missing or invalid.",
1310
+ importErrPayload: "The archive's content failed validation."
1311
+ };
1312
+ var publicGames = {
1313
+ metaTitleSuffix: "Learning Game for Kids | dodi",
1314
+ introTitle: "Hi, I'm dodi!",
1315
+ introRole: "Your learning companion",
1316
+ introText: "<login>Sign in</login> or <register>create an account</register> so I can help you:",
1317
+ benefitCreate: "Create new games",
1318
+ benefitSave: "Save pictures & progress",
1319
+ benefitHelp: "Help with tricky tasks",
1320
+ learnMore: "Learn more about dodi.",
1321
+ popularTitle: "Popular games",
1322
+ popularAll: "All",
1323
+ aboutTitle: "About this game",
1324
+ bylineSystem: "System",
1325
+ bylineDodi: "dodi",
1326
+ ageFrom: "Ages {age}+",
1327
+ actionPhoto: "Take a photo",
1328
+ actionReset: "Reset game",
1329
+ signInToContinue: "Sign in to keep playing.",
1330
+ footerTagline: "A self-improving, privacy-first AI learning app for kids. Open source, and built by parents who wanted learning to be fun again.",
1331
+ footerProduct: "Product",
1332
+ footerApp: "App",
1333
+ footerCompanion: "Companion",
1334
+ footerPricing: "Pricing",
1335
+ footerOpenApp: "Open the app",
1336
+ footerGames: "Learning games",
1337
+ footerAllGames: "All learning games",
1338
+ footerCompany: "Company",
1339
+ footerAbout: "About dodi",
1340
+ footerGithub: "GitHub",
1341
+ footerHow: "How it works",
1342
+ footerMemory: "Self-improving memory",
1343
+ footerStudio: "Game studio",
1344
+ footerPrivacy: "Privacy & data",
1345
+ footerCopyright: "\xA9 {year} dodi. Made with care for curious kids.",
1346
+ footerOpenSource: "Open Source",
1347
+ footerPrivacyFirst: "Privacy first",
1348
+ footerPrivacyPolicy: "Privacy policy",
1349
+ footerTerms: "Terms of service",
1350
+ footerImprint: "Imprint"
1351
+ };
1352
+ var buildActivity = {
1353
+ building: "dodi is building a game",
1354
+ open: "View"
1355
+ };
1356
+ var backgroundBuild = {
1357
+ title: "Building your game",
1358
+ planTitle: "Planning your game",
1359
+ channelName: "Game builds",
1360
+ readyTitle: "Your game is ready",
1361
+ readyBody: "Tap to open it in the Game Studio.",
1362
+ pausedTitle: "Build paused",
1363
+ pausedBody: "Open the app and the build continues where it stopped.",
1364
+ failedTitle: "Build failed",
1365
+ failedBody: "Open the Game Studio to try again."
1366
+ };
1367
+ var report = {
1368
+ title: "Report a problem",
1369
+ description: "Tell us when something the AI said or made is not okay for your kids. We read every report and use it to make the companion and Game Studio safer.",
1370
+ kindLabel: "What do you want to report?",
1371
+ kinds: {
1372
+ companion_answer: "Something the companion said",
1373
+ game: "A game in your library",
1374
+ discover_game: "A game on Discover"
1375
+ },
1376
+ kidLabel: "Which kid was it?",
1377
+ kidNone: "Not about a specific kid",
1378
+ reasonLabel: "What was wrong?",
1379
+ reasons: {
1380
+ inappropriate: "Not okay for kids",
1381
+ upsetting: "Scary or upsetting",
1382
+ wrong: "Wrong or misleading",
1383
+ other: "Something else"
1384
+ },
1385
+ detailsLabel: "What happened? (optional)",
1386
+ detailsPlaceholder: "For example what the companion said, or what the game showed.",
1387
+ detailsHint: "Unlike your family's encrypted data, a report reaches our team in readable form. Leave out anything you don't want us to see.",
1388
+ gameAttached: "This report is about the game you opened.",
1389
+ submit: "Send report",
1390
+ sending: "Sending\u2026",
1391
+ sent: "Thank you. Your report reached our team, and we use it to make the AI safer for kids.",
1392
+ sendAnother: "Report something else",
1393
+ reasonRequired: "Choose what was wrong.",
1394
+ rateLimited: "You sent many reports in a short time. Please try again later.",
1395
+ failed: "The report could not be sent. Please try again.",
1396
+ reportGame: "Report this game"
1397
+ };
1398
+ var access = {
1399
+ subtitle: "Everything that can open your family's data.",
1400
+ thisDeviceTitle: "This device",
1401
+ thisDeviceUnlisted: "This device shows up here the next time you unlock.",
1402
+ browsersTitle: "Browsers & apps",
1403
+ browsersDesc: "Where you are signed in.",
1404
+ browsersEmpty: "No other browsers or apps yet.",
1405
+ robotTitle: "Robot",
1406
+ robotDesc: "Your dodi robot opens your family's data on its own once you allow it.",
1407
+ robotEmpty: "No robot connected yet.",
1408
+ connectRobot: "Connect a robot",
1409
+ agentsTitle: "Agents & access keys",
1410
+ agentsDesc: "Let your own AI assistant, like Claude Code or Cursor, build games for your family with the dodi CLI. You decide what each agent may do.",
1411
+ agentsEmpty: "No agents connected yet.",
1412
+ connectAgent: "Connect an agent",
1413
+ pairingCode: "Code",
1414
+ loading: "Loading...",
1415
+ unknownDevice: "Unknown device",
1416
+ kindBrowser: "Browser",
1417
+ kindApp: "App",
1418
+ kindRobot: "Robot",
1419
+ kindAgent: "Agent",
1420
+ statusSignedInOnly: "Signed in, no access to data yet",
1421
+ confirmRevoke: "Revoke access? It will no longer be able to open your family's data.",
1422
+ confirmRevokeCurrent: "Revoke access for this device? You will be signed out here.",
1423
+ revoked: "Access revoked.",
1424
+ authorizeTitle: "Allow access",
1425
+ authorizeDesc: "Enter the code your robot or agent shows, or open the link it sends you.",
1426
+ requestTitle: "{name} wants access",
1427
+ fingerprintHintAgent: "Check that it matches the fingerprint your agent shows. If it doesn't, decline.",
1428
+ fingerprintHintRobot: "Check that it matches the fingerprint your robot shows. If it doesn't, decline.",
1429
+ robotNote: "The robot can open your family's data on its own. Only allow a robot you own.",
1430
+ allow: "Allow",
1431
+ allowing: "Allowing...",
1432
+ allowed: "Access allowed.",
1433
+ allowedAgent: "Agent connected. You can go back to your agent now.",
1434
+ errorNotFound: "We couldn't find this code. Codes expire after a few minutes, so ask for a new one.",
1435
+ errorAllowFailed: "Access could not be allowed. Please try again.",
1436
+ scopeStudio: "Build with your AI providers",
1437
+ scopeStudioDesc: "Brief dodi's game agent and let it build games with backgrounds and previews, exactly like Game Studio.",
1438
+ studioWarning: "The agent gets your keys for {providers} on its machine, and builds are charged to those accounts.",
1439
+ studioNoProviders: "Set up a game model with a key under Settings > AI providers first.",
1440
+ errorNoBuildKeys: 'Building needs a game model with a key. Set one up under Settings > AI providers, or switch off "Build with your AI providers".',
1441
+ pairingCodePlaceholder: "e.g. KPLX-4821",
1442
+ lookUp: "Continue",
1443
+ lookingUp: "Looking up...",
1444
+ errorRateLimited: "Too many attempts. Please wait a minute and try again.",
1445
+ errorFailed: "Something went wrong. Please try again.",
1446
+ unnamedAgent: "Unnamed agent",
1447
+ fingerprint: "Fingerprint",
1448
+ scopesLabel: "What it may do",
1449
+ sensitiveWarning: "Your agent's AI provider will read your kid's memory. Only allow this if you trust that provider.",
1450
+ expiry: "Access ends",
1451
+ expiryDays: "After {days} days",
1452
+ expiryNever: "Never",
1453
+ decryptNote: "The agent can decrypt everything it is allowed to download. Only connect agents you trust.",
1454
+ noScopes: "Turn on at least one permission.",
1455
+ decline: "Decline",
1456
+ declining: "Declining...",
1457
+ declined: "Request declined.",
1458
+ declineFailed: "The request could not be declined. Please try again.",
1459
+ statusActive: "Active",
1460
+ statusPending: "Waiting for approval",
1461
+ statusExpired: "Expired",
1462
+ expiresOn: "Expires {date}",
1463
+ expiredOn: "Expired {date}",
1464
+ neverExpires: "Never expires",
1465
+ lastSeen: "Last used {date}",
1466
+ neverSeen: "Not used yet",
1467
+ noScopesGranted: "No permissions",
1468
+ revoke: "Revoke",
1469
+ revoking: "Revoking...",
1470
+ revokeFailed: "The agent could not be revoked. Please try again.",
1471
+ keyTitle: "Create access key",
1472
+ keyDesc: "For agents that run on their own, for example on a server, where nobody can open a link. Give the key to the agent as DODI_TOKEN.",
1473
+ keyName: "Name",
1474
+ keyNamePlaceholder: "e.g. Home server",
1475
+ createKey: "Create key",
1476
+ creatingKey: "Creating...",
1477
+ keyCreated: "Your access key",
1478
+ keyWarning: "Copy it now. For your safety it won't be shown again. Anyone with this key can act as this agent.",
1479
+ keyFailed: "The key could not be created. Please try again.",
1480
+ keyDone: "Done",
1481
+ startTitle: "Get started",
1482
+ startDesc: "Paste this into your AI assistant. It will set up the dodi CLI and send you a link to approve.",
1483
+ copy: "Copy",
1484
+ copied: "Copied",
1485
+ scopeGames: "Create and edit games",
1486
+ scopeGamesDesc: "Read, build and update your family's games.",
1487
+ scopeGamesPublish: "Submit games for publishing",
1488
+ scopeGamesPublishDesc: "Ask to share a game on Discover. Every submission is reviewed first.",
1489
+ scopeKidsBasic: "See kids' names and ages",
1490
+ scopeKidsBasicDesc: "So games can fit each kid. No memory or notes.",
1491
+ scopeKidsMemory: "Memory and your notes",
1492
+ scopeKidsMemoryDesc: "What your companion has learned about each kid, and your notes, so games match their interests and level.",
1493
+ scopeAssets: "Create companion looks",
1494
+ scopeAssetsDesc: "Add custom 3D looks and accessories for your kids' companions.",
1495
+ scopeAssetsPublish: "Submit looks for publishing",
1496
+ scopeAssetsPublishDesc: "Ask to share a look on Discover. Every submission is reviewed first."
1497
+ };
1498
+ var characterAssets = {
1499
+ title: "Your avatars and accessories",
1500
+ description: "Made with the dodi CLI and stored end-to-end encrypted. Kids can pick them in the Playground. Ones you added from Discover show up here too. Deleting or removing one puts companions wearing it back in their usual look.",
1501
+ kindAvatar: "Avatar",
1502
+ kindAccessory: "Accessory",
1503
+ size: "{size} KB",
1504
+ delete: "Delete",
1505
+ confirmDelete: "Delete for good?",
1506
+ deleting: "Deleting\u2026",
1507
+ deleteFailed: "Could not delete it. Please try again.",
1508
+ loadFailed: "Could not load your avatars and accessories.",
1509
+ sharedBy: "From Discover, by @{handle}",
1510
+ sharedFromDiscover: "From Discover",
1511
+ remove: "Remove",
1512
+ confirmRemove: "Remove from family?",
1513
+ removing: "Removing\u2026",
1514
+ removeFailed: "Could not remove it. Please try again.",
1515
+ share: "Share",
1516
+ shareLabel: "Share {name} on Discover",
1517
+ shareTitle: "Share on Discover",
1518
+ shareDescription: "Other families can add it to their companions once a person at our team has checked it. The shared copy is not encrypted; your own copy stays encrypted.",
1519
+ shareNameLabel: "Name on Discover",
1520
+ shareDescriptionLabel: "Description (optional)",
1521
+ shareDescriptionPlaceholder: "What makes it fun?",
1522
+ shareSubmit: "Submit for review",
1523
+ shareResubmit: "Submit again",
1524
+ shareSubmitting: "Submitting\u2026",
1525
+ shareWithdraw: "Take off Discover",
1526
+ shareConfirmWithdraw: "Families who added it lose it. Take it off?",
1527
+ shareClose: "Close",
1528
+ shareStateInReview: "In review",
1529
+ shareStateLive: "Live on Discover",
1530
+ shareStateRejected: "Not accepted",
1531
+ shareInReviewNotice: "Waiting for review. It goes live on Discover once it is approved.",
1532
+ shareLiveNotice: "Live on Discover. Other families can add it now.",
1533
+ shareRejectedNotice: "It was not accepted: {reason}",
1534
+ shareRejectedNoReason: "It was not accepted. You can change it with the CLI and submit it again.",
1535
+ shareHandleRequired: "Pick a publisher name first.",
1536
+ shareHandleTaken: "That name is already taken. Please pick another.",
1537
+ shareHandleInvalid: "That publisher name can't be used. Please pick another.",
1538
+ shareInvalidFile: "The file did not pass the check. Please fix it with the CLI and try again.",
1539
+ shareLimitReached: "You have reached this month's limit for submissions.",
1540
+ shareFailed: "Could not submit it. Please try again.",
1541
+ discoverTitle: "Discover avatars and accessories",
1542
+ discoverDescription: "Made by other families and checked by our team. Add one and your kids can wear it in the Playground.",
1543
+ discoverBy: "by @{handle}",
1544
+ discoverAdded: "Added",
1545
+ discoverAdd: "Add {name} to your family",
1546
+ discoverRemove: "Remove {name} from your family",
1547
+ discoverFailed: "Could not load avatars and accessories from Discover.",
1548
+ discoverActionFailed: "That did not work. Please try again."
1549
+ };
1550
+ var en_default = {
1551
+ common,
1552
+ auth,
1553
+ vault,
1554
+ onboarding,
1555
+ dashboard,
1556
+ kids,
1557
+ settings,
1558
+ parentPin,
1559
+ personas,
1560
+ companions,
1561
+ playground,
1562
+ memory,
1563
+ games,
1564
+ tags,
1565
+ kid,
1566
+ activities,
1567
+ agentSessions,
1568
+ gameStudio,
1569
+ friends,
1570
+ breadcrumbs,
1571
+ nav,
1572
+ usage,
1573
+ kidProfile,
1574
+ snapshots,
1575
+ parentSnapshots,
1576
+ publicGames,
1577
+ buildActivity,
1578
+ backgroundBuild,
1579
+ report,
1580
+ access,
1581
+ characterAssets
1582
+ };
1583
+ export {
1584
+ access,
1585
+ activities,
1586
+ agentSessions,
1587
+ auth,
1588
+ backgroundBuild,
1589
+ breadcrumbs,
1590
+ buildActivity,
1591
+ characterAssets,
1592
+ common,
1593
+ companions,
1594
+ dashboard,
1595
+ en_default as default,
1596
+ friends,
1597
+ gameStudio,
1598
+ games,
1599
+ kid,
1600
+ kidProfile,
1601
+ kids,
1602
+ memory,
1603
+ nav,
1604
+ onboarding,
1605
+ parentPin,
1606
+ parentSnapshots,
1607
+ personas,
1608
+ playground,
1609
+ publicGames,
1610
+ report,
1611
+ settings,
1612
+ snapshots,
1613
+ tags,
1614
+ usage,
1615
+ vault
1616
+ };