Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
d8ff189
feat(profile): add date-format preference column
MBombeck Jun 26, 2026
37e539d
feat(format): resolve and apply the date-format preference
MBombeck Jun 26, 2026
86a9ca2
feat(profile): persist and expose the date-format preference
MBombeck Jun 26, 2026
9b7980d
feat(settings): add the date-format profile control
MBombeck Jun 26, 2026
d643052
feat(ui): add the DateField date input
MBombeck Jun 26, 2026
8c09970
merge(DATEFMT-1): date-format preference foundation
MBombeck Jun 26, 2026
34ed1a0
feat(coach): add acute red-flag escalation to the shared safety contract
MBombeck Jun 26, 2026
9279b06
feat(coach): connect signals, confidence-ruler close, three-beat shape
MBombeck Jun 26, 2026
bf58d5d
feat(ui): render date inputs in the user's date-format preference
MBombeck Jun 26, 2026
291fb30
test(e2e): target the DateField overlay and ISO mirror in the medicat…
MBombeck Jun 26, 2026
b470a14
fix(insights): ground deterministic status fallbacks in the user's ow…
MBombeck Jun 26, 2026
5b406d5
fix(insights): close the deterministic score assessment with one grou…
MBombeck Jun 26, 2026
d22372e
fix(insights): warm the period retrospective to the shared house voice
MBombeck Jun 26, 2026
6de1f34
feat(coach): widen tool-mode data reach to every stored domain
MBombeck Jun 26, 2026
58376a0
feat(coach): verify Coach prose numbers against fetched figures
MBombeck Jun 26, 2026
ce07548
feat(coach): fold the coincident-deviation flag into the snapshot
MBombeck Jun 26, 2026
44796d1
feat(coach): carry metric scope into the Coach launch
MBombeck Jun 26, 2026
93433c3
feat(coach): add "ask the Coach about this" to insight cards
MBombeck Jun 26, 2026
a96ae9b
merge(COACHDATA): v1.21.0
MBombeck Jun 26, 2026
f12f349
merge(COACHPROMPT): v1.21.0
MBombeck Jun 26, 2026
a503160
merge(DF2): v1.21.0
MBombeck Jun 26, 2026
37dfce2
merge(COACHUI): v1.21.0
MBombeck Jun 26, 2026
490c9d2
merge(FALLBACK): v1.21.0
MBombeck Jun 26, 2026
8ed1d27
chore(openapi): regenerate for the date-format profile field
MBombeck Jun 26, 2026
9a3049a
fix(coach): phrase the daily-limit reset as midnight UTC
MBombeck Jun 26, 2026
3783348
fix(coach): make the daily token budget provider-aware
MBombeck Jun 26, 2026
8471384
merge(OAUTHFIX): provider-aware AI budget
MBombeck Jun 26, 2026
f2a9716
fix(safety): unify clinical floors into one source of truth
MBombeck Jun 26, 2026
b75cef9
fix(insights): key coincident-deviation 'today' in the user's timezone
MBombeck Jun 26, 2026
99a6163
feat(insights): gate discovered correlations on effect size and confi…
MBombeck Jun 26, 2026
b0be36c
feat(coach): carry discovered drivers in the no-tools snapshot
MBombeck Jun 26, 2026
0816b3b
feat(date): migrate remaining date inputs to DateField
MBombeck Jun 26, 2026
f493ff5
merge(RECON1): clinical-floors, coincident-tz, correlation quality, l…
MBombeck Jun 26, 2026
174c26a
refactor(coach): streamline the new-chat page composer
MBombeck Jun 26, 2026
86d917c
fix(insights): align cold-fallback slope window to the rollup day bou…
MBombeck Jun 26, 2026
ad74d25
merge(UI1): Coach new-chat composer redesign
MBombeck Jun 26, 2026
01b24c4
feat(date): add DateTimeField and migrate datetime inputs
MBombeck Jun 26, 2026
be7c5c5
perf(withings): batch the activity sync reads and writes
MBombeck Jun 26, 2026
f854b16
merge(DF3): date-format rollout completion + DateTimeField
MBombeck Jun 26, 2026
92fc164
chore(ui): drop the now-unused native date-input primitives
MBombeck Jun 26, 2026
9dcdf94
perf(medications): batch the intake slot-dedup reads
MBombeck Jun 26, 2026
f37d935
fix(illness): require calendar-adjacency for the stable-return run
MBombeck Jun 26, 2026
db7306f
fix(illness): sort the SpO2 red-flag day-points locally
MBombeck Jun 26, 2026
fe6d4c1
Add typed Learn-article link registry
MBombeck Jun 26, 2026
6ed5b55
Add discreet LearnMoreLink pointer component
MBombeck Jun 26, 2026
8c58b5b
Wire Learn pointers into vitals, glucose, resilience, and lab surfaces
MBombeck Jun 26, 2026
7093e46
merge(WS3PERF): A2-M2 boundary align + Withings/med-intake N+1 fixes
MBombeck Jun 26, 2026
5b22d69
merge(ILLNESSFIX): calendar-adjacency symptom return + SpO2 local sort
MBombeck Jun 26, 2026
03e1935
merge(LEARNUI): Learn-links registry, component, and surface wiring
MBombeck Jun 26, 2026
cf331db
Bind Coach safety thresholds to clinical floors and add an outlook co…
MBombeck Jun 26, 2026
8265abe
fix(rollups): rebase regression x-axis to a fixed origin for exact ac…
MBombeck Jun 26, 2026
1344b56
merge(DSTMIG): rollup x-rescale, un-quarantine the regression parity …
MBombeck Jun 26, 2026
d45d606
Narrow the tool-mode Coach to the metric it was launched from
MBombeck Jun 26, 2026
abceff0
Build the Coach snapshot once per turn and widen the round budget to …
MBombeck Jun 26, 2026
976ecf8
Surface the computed illness retrospective to the Coach
MBombeck Jun 26, 2026
d5cb1e4
Stop the Coach inventing a /learn link
MBombeck Jun 26, 2026
473b35e
Guard that get_labs carries each reading's value and unit
MBombeck Jun 26, 2026
21a5ead
merge(COACHFINAL): coach-core finalization — safety/scope/outlook/ill…
MBombeck Jun 26, 2026
aad72ea
feat(insights): add compliance and symptom severity to the correlatio…
MBombeck Jun 26, 2026
1fa02ce
merge(FDREXTEND): compliance + symptom as FDR correlation channels
MBombeck Jun 26, 2026
57682f8
fix(coach): build compliance + symptom channels in get_correlations
MBombeck Jun 26, 2026
1cee07b
merge(INTEGFIX): wire compliance/symptom FDR channels into the Coach …
MBombeck Jun 26, 2026
8c5ef5d
fix(medications): render intake datetime fields through the format-aw…
MBombeck Jun 26, 2026
e6ac604
chore(release): v1.21.0
MBombeck Jun 26, 2026
5f640e1
refactor(coach): collapse the duplicate daily-cap export to OPERATOR_…
MBombeck Jun 26, 2026
e818178
test(coach): seed the budget-refusal integration test at the user-pla…
MBombeck Jun 26, 2026
e366ebd
test(e2e): exempt visually-hidden inputs from the 44px target sweep
MBombeck Jun 26, 2026
5411bb3
test(e2e): measure the date-field wrapper for the 44px target sweep
MBombeck Jun 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@

## [Unreleased]

## [1.21.0] — 2026-06-26 — Date-format preference, a far more connected Coach, and broad correctness work

A feature release. The Coach reaches every data domain on demand, surfaces the cross-metric patterns the analytics tier already discovers, opens in context from any screen, and speaks with a warmer, forward-looking voice on one shared set of safety thresholds. Dates render in your chosen format everywhere. Two additive migrations (`0193` rollup x-rescale, `0192` date format); no breaking changes.

### Added

- A date-format preference in the profile — automatic (follows the language), day-month-year, month-day-year, or ISO — honoured across the app, including every date and date-time field, which now render in your chosen order regardless of the browser's locale.
- The Coach answers from the full data picture: every metric domain on demand plus cycle and workouts, and it surfaces the discovered cross-metric correlations — medication adherence against symptoms, short sleep against the next morning's vitals, and so on — citing only what the analytics tier actually found.
- Open the Coach in context from any metric page or insight card and it arrives already scoped to what you were looking at, with a relevant opening question.
- "Learn more" pointers on the vitals tiles, the glucose panel, the resilience tile, and the lab biomarker detail link out to the matching guide; the Coach references the same guides and can no longer offer a link that doesn't exist.
- Medication compliance and symptom severity are now first-class signals in the correlation engine, so an adherence dip that tracks a symptom flare can finally be surfaced.

### Changed

- The Coach connects signals into one story instead of listing metrics, looks ahead with gentle, ranged outlooks, ends an action turn by checking your confidence and offering a single doable step, and keeps affirmation earned. A closed acute-symptom clause points to prompt medical attention for crisis signs.
- Critical-threshold numbers — blood pressure, fever, glucose — now come from one source, so the dashboard banner, the Coach, the status cards, and the notifications always state the same thresholds.
- The trend regression is composed on an origin-rescaled, mean-centred basis, removing a floating-point cancellation on long windows; the rollup now matches the live computation to the last digit.
- The daily AI usage budget is provider-aware: usage on your own OpenAI key, ChatGPT plan, or local model is no longer limited by the server-cost ceiling that applies to an operator-provided key.
- The Coach builds its data snapshot once per turn and may take an extra reasoning round for a deep cross-metric question.
- Discovered correlations are held to an effect-size floor and a confidence tier, and sparse personal signals are shrunk toward the baseline, so a real-but-trivial association is no longer stated as a confident driver.

### Fixed

- ChatGPT/OpenAI sign-in users no longer hit a spurious "daily limit reached" after only a couple of messages.
- The symptom journal's recovery-return and the SpO2 red-flag count consecutive calendar days and are order-independent; the "two or more vitals out of band today" flag is keyed to your calendar day rather than UTC.
- Withings activity sync and the medication-intake dedup issue far fewer queries on a long backfill.
- The trend read returns the same boundary day whether served from the rollup or from a live query.
- The native date primitives that ignored the locale are gone — every field routes through the format-aware inputs.

## [1.20.2] — 2026-06-26 — Hardening across insights, safety flags, and integrations

A patch release. A broad pass over the server tier and the AI surfaces: a few correctness and safety fixes, a numerical hardening of the trend tier, and several smaller robustness and cost improvements. No schema changes.
Expand Down
31 changes: 30 additions & 1 deletion docs/api/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: HealthLog API
version: 1.20.2
version: 1.21.0
description: >-
Self-hosted personal-health-tracking PWA — public API surface for the iOS native client and external ingest.

Expand Down Expand Up @@ -8184,6 +8184,15 @@ components:
- AUTO
- H12
- H24
dateFormat:
description: Date-order display preference. AUTO follows the locale convention, DMY pins day-month-year (dd.MM.yyyy),
MDY pins month-day-year (MM/dd/yyyy), YMD pins ISO yyyy-MM-dd.
type: string
enum:
- AUTO
- DMY
- MDY
- YMD
moodReminderEnabled:
type: boolean
fullName:
Expand Down Expand Up @@ -15784,6 +15793,15 @@ components:
- H12
- H24
description: Hour-cycle display preference. AUTO follows the locale convention, H12 forces AM/PM, H24 forces 24-hour.
dateFormat:
type: string
enum:
- AUTO
- DMY
- MDY
- YMD
description: Date-order display preference. AUTO follows the locale convention, DMY pins day-month-year (dd.MM.yyyy),
MDY pins month-day-year (MM/dd/yyyy), YMD pins ISO yyyy-MM-dd.
moodReminderEnabled:
type: boolean
fullName:
Expand Down Expand Up @@ -15815,6 +15833,7 @@ components:
- locale
- timezone
- timeFormat
- dateFormat
- moodReminderEnabled
- fullName
- insurerName
Expand Down Expand Up @@ -15885,6 +15904,15 @@ components:
- H12
- H24
description: Hour-cycle display preference. AUTO follows the locale convention, H12 forces AM/PM, H24 forces 24-hour.
dateFormat:
type: string
enum:
- AUTO
- DMY
- MDY
- YMD
description: Date-order display preference. AUTO follows the locale convention, DMY pins day-month-year (dd.MM.yyyy),
MDY pins month-day-year (MM/dd/yyyy), YMD pins ISO yyyy-MM-dd.
moodReminderEnabled:
type: boolean
fullName:
Expand Down Expand Up @@ -15912,6 +15940,7 @@ components:
- locale
- timezone
- timeFormat
- dateFormat
- moodReminderEnabled
- fullName
- insurerName
Expand Down
3 changes: 3 additions & 0 deletions e2e/medications-wizard-daily.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ test.describe("medication wizard — daily", () => {

// Step 4 — course window (today by default).
await expectStep(page, 4);
// `DateField` keeps the ISO value on a hidden native date input
// (data-slot), while the visible overlay paints the locale-formatted
// string. Assert the committed ISO value on the hidden input.
await expect(
page.locator('[data-slot="course-window-starts"]'),
).toHaveValue(/^\d{4}-\d{2}-\d{2}$/);
Expand Down
10 changes: 9 additions & 1 deletion e2e/medications-wizard-oneshot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,15 @@ test.describe("medication wizard — one-shot", () => {
// Step 4 — course window. Set startsOn to a deterministic date so
// the post body assertion below is stable.
await expectStep(page, 4);
await page.locator('[data-slot="course-window-starts"]').fill("2026-10-15");
// `DateField` rides a visible text overlay (the data-testid) that parses
// a typed ISO string back to the canonical value; the hidden native input
// (data-slot) carries the committed ISO. Type into the overlay, then blur
// so the parse commits.
await page.getByTestId("course-window-starts-field").fill("2026-10-15");
await page.getByTestId("course-window-starts-field").blur();
await expect(
page.locator('[data-slot="course-window-starts"]'),
).toHaveValue("2026-10-15");
await clickNext(page);

// Step 5 — pick Einmalig. The path compresses to 5 steps the
Expand Down
31 changes: 19 additions & 12 deletions e2e/settings-mobile-consistency.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,16 @@ test.describe("Settings mobile consistency (Pixel 5)", () => {
)
.evaluateAll((els) =>
els.map((el) => {
const rect = el.getBoundingClientRect();
// DateField / DateTimeField front an sr-only native input with a
// formatted overlay; the 44px tap target is the wrapper, while the
// overlay sits inside the wrapper's border (≈42px). Measure the
// wrapper for any input inside one so the target-size reflects the
// real affordance, not the inner content box.
const wrapper = el.closest(
'[data-slot="date-field"],[data-slot="date-time-field"]',
);
const measured = wrapper ?? el;
const rect = measured.getBoundingClientRect();
const style = getComputedStyle(el);
return {
id: el.id || el.getAttribute("name") || "",
Expand All @@ -64,17 +73,15 @@ test.describe("Settings mobile consistency (Pixel 5)", () => {
}),
)
).filter(
// The avatar profile-photo upload uses the accessible
// visually-hidden <input type="file"> pattern: the input itself
// is sr-only / zero-size and the real 44 px touch target is the
// styled label/button that triggers it. The touch-target sweep
// must measure that visible affordance, not the hidden input, so
// exempt file inputs that are hidden or collapsed to zero size.
(inp) =>
!(
inp.type === "file" &&
(inp.hidden || inp.height === 0 || inp.width === 0)
),
// Some inputs use the accessible visually-hidden pattern: the input
// itself is sr-only / zero-size and the real 44 px touch target is a
// sibling visible affordance — the styled label/button for the avatar
// <input type="file">, and the formatted overlay that fronts the
// sr-only native <input type="date"|"datetime-local"> inside DateField /
// DateTimeField. The touch-target sweep must measure those visible
// affordances, not the hidden input, so exempt any input that is
// visually hidden or collapsed to zero size.
(inp) => !(inp.hidden || inp.height === 0 || inp.width === 0),
);

expect(formInputs.length).toBeGreaterThan(0);
Expand Down
21 changes: 17 additions & 4 deletions messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"inactive": "Inaktiv",
"disabled": "Deaktiviert",
"networkError": "Netzwerkfehler",
"openDatePicker": "Datumsauswahl öffnen",
"unknownError": "Unbekannter Fehler",
"copied": "Kopiert!",
"or": "oder",
Expand All @@ -33,7 +34,8 @@
"retry": "Erneut versuchen",
"reportIssue": "Fehler melden",
"showPassword": "Passwort anzeigen",
"hidePassword": "Passwort verbergen"
"hidePassword": "Passwort verbergen",
"learnMore": "Mehr erfahren"
},
"doctorReport": {
"title": "Gesundheitsbericht",
Expand Down Expand Up @@ -2223,7 +2225,7 @@
"feedbackThanks": "Danke für das Signal.",
"feedbackError": "Feedback konnte nicht gespeichert werden",
"dailyLimitTitle": "Heute-Limit erreicht",
"dailyLimitBody": "Heute-Limit erreicht; Reset um 00:00 UTC.",
"dailyLimitBody": "Tageslimit erreicht. Das Budget setzt sich um Mitternacht (UTC) zurück.",
"providerRateLimitTitle": "Provider rate-limited",
"providerRateLimitBody": "Provider ist temporär überlastet; Reset in ~5 min.",
"cluster": {
Expand Down Expand Up @@ -2278,14 +2280,15 @@
"dictateError": "Spracheingabe konnte nicht gestartet werden. Prüfe die Mikrofonberechtigung und versuche es erneut.",
"showConversations": "Unterhaltungen anzeigen",
"hideConversations": "Unterhaltungen ausblenden",
"heroGreeting": "Wie kann ich dir helfen?",
"heroGreeting": "Frage mich etwas zu deinen Daten",
"heroSubline": "Frag nach deinen Verläufen, Medikamenten oder Messwerten.",
"thinkingElapsed": "{seconds}s",
"thinkingDuration": "Nachgedacht für {seconds}s",
"thinkingExpandAria": "Zeigen, was der Coach berücksichtigt hat",
"thinkingDetail": "Beantwortet aus deinem Gesundheits-Snapshot.",
"tokensUsed": "{count} Tokens",
"tokensUsedWithModel": "{count} Tokens · {model}"
"tokensUsedWithModel": "{count} Tokens · {model}",
"askAboutThis": "Den Coach dazu fragen"
},
"relativeJustNow": "gerade eben",
"relativeMinutesAgoOne": "vor {count} Minute",
Expand Down Expand Up @@ -4120,6 +4123,16 @@
"saved": "Stundenformat gespeichert.",
"saveError": "Speichern des Stundenformats fehlgeschlagen."
},
"dateFormat": {
"title": "Datumsformat",
"description": "Bestimmt die Reihenfolge von Tag, Monat und Jahr bei der Anzeige von Daten.",
"auto": "Automatisch (Sprache)",
"dmy": "TT.MM.JJJJ",
"mdy": "MM/TT/JJJJ",
"ymd": "JJJJ-MM-TT",
"saved": "Datumsformat gespeichert.",
"saveError": "Speichern des Datumsformats fehlgeschlagen."
},
"username": "Benutzername",
"height": "Körpergröße (cm)",
"dateOfBirth": "Geburtsdatum",
Expand Down
21 changes: 17 additions & 4 deletions messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"inactive": "Inactive",
"disabled": "Disabled",
"networkError": "Network error",
"openDatePicker": "Open date picker",
"unknownError": "Unknown error",
"copied": "Copied!",
"or": "or",
Expand All @@ -33,7 +34,8 @@
"retry": "Retry",
"reportIssue": "Report issue",
"showPassword": "Show password",
"hidePassword": "Hide password"
"hidePassword": "Hide password",
"learnMore": "Learn more"
},
"doctorReport": {
"title": "Health Report",
Expand Down Expand Up @@ -2223,7 +2225,7 @@
"feedbackThanks": "Thanks for the signal.",
"feedbackError": "Could not save feedback",
"dailyLimitTitle": "Daily limit reached",
"dailyLimitBody": "Daily limit reached; resets at 00:00 UTC.",
"dailyLimitBody": "Daily limit reached. The budget refreshes at midnight UTC.",
"providerRateLimitTitle": "Provider rate-limited",
"providerRateLimitBody": "Provider temporarily rate-limited; retry in ~5 min.",
"cluster": {
Expand Down Expand Up @@ -2278,14 +2280,15 @@
"dictateError": "Could not start voice input. Check microphone permission and try again.",
"showConversations": "Show conversations",
"hideConversations": "Hide conversations",
"heroGreeting": "How can I help you?",
"heroGreeting": "Ask me anything about your data",
"heroSubline": "Ask about your trends, medications, or readings.",
"thinkingElapsed": "{seconds}s",
"thinkingDuration": "Thought for {seconds}s",
"thinkingExpandAria": "Show what the Coach considered",
"thinkingDetail": "Answered from your health snapshot.",
"tokensUsed": "{count} tokens",
"tokensUsedWithModel": "{count} tokens · {model}"
"tokensUsedWithModel": "{count} tokens · {model}",
"askAboutThis": "Ask the coach about this"
},
"relativeJustNow": "just now",
"relativeMinutesAgoOne": "{count} minute ago",
Expand Down Expand Up @@ -4120,6 +4123,16 @@
"saved": "Hour format saved.",
"saveError": "Saving the hour format failed."
},
"dateFormat": {
"title": "Date format",
"description": "Controls the order of day, month and year when dates are shown.",
"auto": "Automatic (language)",
"dmy": "DD.MM.YYYY",
"mdy": "MM/DD/YYYY",
"ymd": "YYYY-MM-DD",
"saved": "Date format saved.",
"saveError": "Saving the date format failed."
},
"username": "Username",
"height": "Height (cm)",
"dateOfBirth": "Date of birth",
Expand Down
21 changes: 17 additions & 4 deletions messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"inactive": "Inactivo",
"disabled": "Desactivado",
"networkError": "Error de red",
"openDatePicker": "Abrir el selector de fecha",
"unknownError": "Error desconocido",
"copied": "¡Copiado!",
"or": "o",
Expand All @@ -33,7 +34,8 @@
"retry": "Reintentar",
"reportIssue": "Reportar problema",
"showPassword": "Mostrar contraseña",
"hidePassword": "Ocultar contraseña"
"hidePassword": "Ocultar contraseña",
"learnMore": "Más información"
},
"doctorReport": {
"title": "Informe de salud",
Expand Down Expand Up @@ -2221,7 +2223,7 @@
"feedbackThanks": "Gracias por la indicación.",
"feedbackError": "No se pudo guardar el comentario",
"dailyLimitTitle": "Límite diario alcanzado",
"dailyLimitBody": "Límite diario alcanzado; reinicio a las 00:00 UTC.",
"dailyLimitBody": "Límite diario alcanzado. El cupo se reinicia a medianoche (UTC).",
"providerRateLimitTitle": "Proveedor con límite de tasa",
"providerRateLimitBody": "El proveedor está temporalmente saturado; reinicio en ~5 min.",
"settingsContextLabel": "Enviar contexto",
Expand Down Expand Up @@ -2278,14 +2280,15 @@
"dictateError": "No se pudo iniciar la entrada de voz. Comprueba el permiso del micrófono e inténtalo de nuevo.",
"showConversations": "Mostrar conversaciones",
"hideConversations": "Ocultar conversaciones",
"heroGreeting": "¿En qué puedo ayudarte?",
"heroGreeting": "Pregúntame lo que quieras sobre tus datos",
"heroSubline": "Pregunta por tus tendencias, medicamentos o mediciones.",
"thinkingElapsed": "{seconds}s",
"thinkingDuration": "Pensó durante {seconds}s",
"thinkingExpandAria": "Mostrar lo que el Coach tuvo en cuenta",
"thinkingDetail": "Respondido a partir de tu resumen de salud.",
"tokensUsed": "{count} tokens",
"tokensUsedWithModel": "{count} tokens · {model}"
"tokensUsedWithModel": "{count} tokens · {model}",
"askAboutThis": "Pregúntale al coach sobre esto"
},
"relativeJustNow": "ahora mismo",
"relativeMinutesAgoOne": "hace {count} minuto",
Expand Down Expand Up @@ -4120,6 +4123,16 @@
"saved": "Formato horario guardado.",
"saveError": "No se pudo guardar el formato horario."
},
"dateFormat": {
"title": "Formato de fecha",
"description": "Determina el orden de día, mes y año al mostrar las fechas.",
"auto": "Automático (idioma)",
"dmy": "DD.MM.AAAA",
"mdy": "MM/DD/AAAA",
"ymd": "AAAA-MM-DD",
"saved": "Formato de fecha guardado.",
"saveError": "No se pudo guardar el formato de fecha."
},
"username": "Nombre de usuario",
"height": "Altura (cm)",
"dateOfBirth": "Fecha de nacimiento",
Expand Down
Loading
Loading