- {renderTooltipWithLinks(tWithDefaults(t, 'standardVdTooltip', {
+
{formatContent(tWithDefaults(t, 'standardVdTooltip', {
...defaultsForT,
standardVdValue: pkParams.advanced.standardVd?.preset === 'adult' ? '377' : pkParams.advanced.standardVd?.preset === 'child' ? '175' : pkParams.advanced.standardVd?.customValue || '377',
standardVdPreset: t(`standardVdPreset${pkParams.advanced.standardVd?.preset?.charAt(0).toUpperCase()}${pkParams.advanced.standardVd?.preset?.slice(1)}` || 'standardVdPresetAdult')
@@ -891,7 +853,7 @@ const Settings = ({
- {renderTooltipWithLinks(tWithDefaults(t, 'bodyWeightTooltip', defaultsForT))}
+ {formatContent(tWithDefaults(t, 'bodyWeightTooltip', defaultsForT))}
@@ -929,7 +891,7 @@ const Settings = ({
- {renderTooltipWithLinks(tWithDefaults(t, 'tmaxDelayTooltip', defaultsForT))}
+ {formatContent(tWithDefaults(t, 'tmaxDelayTooltip', defaultsForT))}
@@ -967,7 +929,7 @@ const Settings = ({
- {tWithDefaults(t, 'urinePHTooltip', defaultsForT)}
+ {formatContent(tWithDefaults(t, 'urinePHTooltip', defaultsForT))}
@@ -1009,7 +971,7 @@ const Settings = ({
- {renderTooltipWithLinks(tWithDefaults(t, 'ageGroupTooltip', defaultsForT))}
+ {formatContent(tWithDefaults(t, 'ageGroupTooltip', defaultsForT))}
@@ -1061,7 +1023,7 @@ const Settings = ({
- {renderTooltipWithLinks(tWithDefaults(t, 'renalFunctionTooltip', defaultsForT))}
+ {formatContent(tWithDefaults(t, 'renalFunctionTooltip', defaultsForT))}
@@ -1111,7 +1073,7 @@ const Settings = ({
- {renderTooltipWithLinks(tWithDefaults(t, 'oralBioavailabilityTooltip', defaultsForT))}
+ {formatContent(tWithDefaults(t, 'oralBioavailabilityTooltip', defaultsForT))}
diff --git a/src/components/ui/form-numeric-input.tsx b/src/components/ui/form-numeric-input.tsx
index 7c2890a..f6eacca 100644
--- a/src/components/ui/form-numeric-input.tsx
+++ b/src/components/ui/form-numeric-input.tsx
@@ -30,8 +30,8 @@ interface NumericInputProps extends Omit(
diff --git a/src/locales/de.ts b/src/locales/de.ts
index b47a9ba..adc9e3a 100644
--- a/src/locales/de.ts
+++ b/src/locales/de.ts
@@ -67,7 +67,7 @@ export const de = {
refLineMax: "Max",
pinChart: "Diagramm oben fixieren",
unpinChart: "Diagramm freigeben",
- stickyChartTooltip: "Diagramm beim Scrollen durch die Einstellungen sichtbar halten, um Änderungen in Echtzeit zu sehen. Standard: aus.",
+ stickyChartTooltip: "Diagramm beim Scrollen durch die Einstellungen sichtbar halten, um Änderungen in Echtzeit zu sehen.\\n\\n__Standard:__ **aus**",
chartViewDamphTooltip: "Nur den aktiven Metaboliten (d-Amphetamin) im Konzentrationsverlauf anzeigen",
chartViewLdxTooltip: "Nur das Prodrug (Lisdexamfetamin) im Konzentrationsverlauf anzeigen",
chartViewBothTooltip: "Sowohl d-Amphetamin als auch Lisdexamfetamin gemeinsam anzeigen",
@@ -79,13 +79,13 @@ export const de = {
advancedSettings: "Erweiterte Einstellungen",
advancedSettingsWarning: "⚠️ Diese Parameter beeinflussen die Simulationsgenauigkeit und können von Bevölkerungsdurchschnitten abweichen. Nur anpassen, wenn spezifische klinische Daten oder Forschungsreferenzen vorliegen.",
standardVolumeOfDistribution: "Verteilungsvolumen (Vd)",
- standardVdTooltip: "Definiert wie sich der Wirkstoff im Körper verteilt. Erwachsene: 377L (Roberts 2015), Kinder: ~150-200L. Gewichtsbasierte Skalierung: ~5,4 L/kg (für Erwachsene >18 Jahre basierend auf [Populations-Pharmakokinetik](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/)). Beeinflusst alle Konzentrationsberechnungen. Nur für pädiatrische oder spezialisierte Simulationen ändern. Standard: {{standardVdValue}}L ({{standardVdPreset}}).",
+ standardVdTooltip: "Definiert wie sich der Wirkstoff im Körper verteilt.\\n\\n__Voreinstellungen:__\\n• Erwachsene: 377L (Roberts 2015)\\n• Kinder: ~150-200L\\n• Gewichtsbasiert: ~5,4 L/kg (für Erwachsene >18 Jahre basierend auf [Populations-Pharmakokinetik](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/))\\n\\nBeeinflusst alle Konzentrationsberechnungen. Nur für pädiatrische oder spezialisierte Simulationen ändern.\\n\\n__Standard:__ **{{standardVdValue}}L** ({{standardVdPreset}})",
standardVdPresetAdult: "Erwachsene (377L)",
standardVdPresetChild: "Kinder (175L)",
standardVdPresetCustom: "Benutzerdefiniert",
standardVdPresetWeightBased: "Gewichtsbasiert (~5,4 L/kg)",
customVdValue: "Benutzerdefiniertes Vd (L)",
- weightBasedVdInfo: "Gewichtsbasiertes Vd passt Plasmakonzentrationen basierend auf Körpergewicht an (~5,4 L/kg). Leichtere Personen → höhere Spitzen, schwerere → niedrigere Spitzen. Diese Option ist für Erwachsene (>18 Jahre) basierend auf der Populations-PK-Studie vorgesehen. Für pädiatrische Patienten verwenden Sie die Voreinstellung 'Kinder'.",
+ weightBasedVdInfo: "Gewichtsbasiertes Vd passt Plasmakonzentrationen basierend auf Körpergewicht an (~5,4 L/kg). Leichtere Personen → höhere Spitzen, schwerere → niedrigere Spitzen.\\n\\nDiese Option ist für Erwachsene (>18 Jahre) basierend auf der Populations-PK-Studie vorgesehen.\\n\\nFür pädiatrische Patienten verwenden Sie die Voreinstellung 'Kinder'.",
xAxisTimeFormat: "Zeitformat",
xAxisFormatContinuous: "Fortlaufend",
xAxisFormatContinuousDesc: "Endlose Sequenz (0h, 6h, 12h...)",
@@ -94,75 +94,75 @@ export const de = {
xAxisFormat12h: "Tageszeit (12h AM/PM)",
xAxisFormat12hDesc: "Wiederholend 12h Zyklus im AM/PM Format",
showTemplateDayInChart: "Regulären Plan kontinuierlich anzeigen",
- showTemplateDayTooltip: "Medikationsplan als Referenz-Overlay jederzeit anzeigen (Standard: aktiviert).",
+ showTemplateDayTooltip: "Medikationsplan als Referenz-Overlay jederzeit anzeigen.\\n\\n__Standard:__ **aktiviert**",
simulationSettings: "Simulations-Einstellungen",
showDayReferenceLines: "Tagestrenner anzeigen",
- showDayReferenceLinesTooltip: "Vertikale Linien und Statusanzeigen zwischen Tagen anzeigen (Standard: aktiviert).",
+ showDayReferenceLinesTooltip: "Vertikale Linien und Statusanzeigen zwischen Tagen anzeigen.\\n\\n__Standard:__ **aktiviert**",
showTherapeuticRangeLines: "Therapeutischen Bereich anzeigen ",
- showTherapeuticRangeLinesTooltip: "Horizontale Referenzlinien für therapeutisches Min/Max anzeigen (Standard: aktiviert).",
+ showTherapeuticRangeLinesTooltip: "Horizontale Referenzlinien für therapeutisches Min/Max anzeigen.\\n\\n__Standard:__ **aktiviert**",
simulationDuration: "Simulationsdauer",
- simulationDurationTooltip: "Anzahl der zu simulierenden Tage. Längere Zeiträume zeigen Steady-State. Standard: {{simulationDays}} Tage.",
+ simulationDurationTooltip: "Anzahl der zu simulierenden Tage. Längere Zeiträume zeigen Steady-State.\\n\\n__Standard:__ **{{simulationDays}} Tage**",
displayedDays: "Sichtbare Tage (im Fokus)",
- displayedDaysTooltip: "Wie viele Tage auf einmal angezeigt werden. Kleinere Werte zoomen in Details. Standard: {{displayedDays}} Tag(e).",
+ displayedDaysTooltip: "Wie viele Tage auf einmal angezeigt werden. Kleinere Werte zoomen in Details.\\n\\n__Standard:__ **{{displayedDays}} Tag(e)**",
yAxisRange: "Y-Achsen-Bereich (Konzentrations-Zoom)",
- yAxisRangeTooltip: "Vertikale Achse manuell festlegen (Konzentrationsskala). Leer lassen für automatische Anpassung. Standard: auto.",
+ yAxisRangeTooltip: "Vertikale Achse manuell festlegen (Konzentrationsskala). Leer lassen für automatische Anpassung.\\n\\n__Standard:__ **auto**",
yAxisRangeAutoButton: "A",
yAxisRangeAutoButtonTitle: "Bereich automatisch anhand des Datenbereichs bestimmen",
auto: "Auto",
therapeuticRange: "Therapeutischer Bereich (d-Amphetamin)",
- therapeuticRangeTooltip: "Personalisierte Konzentrationsziele basierend auf DEINER individuellen Reaktion. Setze diese nachdem du beobachtet hast, welche Werte Symptomkontrolle vs. Nebenwirkungen bieten. Referenzbereiche (stark variabel): Erwachsene ~10-80 ng/mL, Kinder ~20-120 ng/mL (aufgrund geringeren Körpergewichts/Vd). Leer lassen wenn unsicher. Konsultiere deinen Arzt.",
+ therapeuticRangeTooltip: "Personalisierte Konzentrationsziele basierend auf DEINER individuellen Reaktion. Setze diese nachdem du beobachtet hast, welche Werte Symptomkontrolle vs. Nebenwirkungen bieten.\\n\\n**Referenzbereiche** (stark variabel):\\n• __Erwachsene:__ **~10-80 ng/mL**\\n• __Kinder:__ **~20-120 ng/mL** (aufgrund geringeren Körpergewichts/Vd)\\n\\nLeer lassen wenn unsicher.\\n\\n***Konsultiere deinen Arzt.***",
dAmphetamineParameters: "d-Amphetamin Parameter",
halfLife: "Eliminations-Halbwertszeit",
- halfLifeTooltip: "Zeit bis der Körper die Hälfte des d-Amphetamins aus dem Blut ausscheidet. Beeinflusst durch Urin-pH: sauer (<6) → 7-9h, neutral (6-7,5) → 10-12h, alkalisch (>7,5) → 13-15h. Siehe [therapeutische Referenzbereiche](https://www.thieme-connect.com/products/ejournals/pdf/10.1055/a-2689-4911.pdf). Standard: {{damphHalfLife}}h.",
+ halfLifeTooltip: "Zeit bis der Körper die Hälfte des d-Amphetamins aus dem Blut ausscheidet.\\n\\n__Beeinflusst durch Urin-pH:__\\n• __Sauer (<6):__ **7-9h**\\n• __Neutral (6-7,5)__ → **10-12h**\\n• __Alkalisch (>7,5)__ → **13-15h**\\n\\nSiehe [therapeutische Referenzbereiche](https://www.thieme-connect.com/products/ejournals/pdf/10.1055/a-2689-4911.pdf).\\n\\n__Standard:__ **{{damphHalfLife}}h**",
lisdexamfetamineParameters: "Lisdexamfetamin (LDX) Parameter",
conversionHalfLife: "LDX→d-Amph Umwandlungs-Halbwertszeit",
- conversionHalfLifeTooltip: "Zeit bis rote Blutkörperchen die Hälfte des inaktiven LDX-Prodrugs in aktives d-Amphetamin umwandeln. Typisch: 0,7-1,2h. Standard: {{ldxHalfLife}}h.",
+ conversionHalfLifeTooltip: "Zeit bis rote Blutkörperchen die Hälfte des inaktiven LDX-Prodrugs in aktives d-Amphetamin umwandeln.\\n\\nTypischer Bereich: **0,7-1,2h**.\\n\\n__Standard:__ **{{ldxHalfLife}}h**",
absorptionHalfLife: "Absorptions-Halbwertszeit",
- absorptionHalfLifeTooltip: "Zeit bis der Darm die Hälfte des LDX vom Magen ins Blut aufnimmt. Durch Nahrung verzögert (~1h Verschiebung). Typisch: 0,7-1,2h. Standard: {{ldxAbsorptionHalfLife}}h.",
+ absorptionHalfLifeTooltip: "Zeit bis der Darm die Hälfte des LDX vom Magen ins Blut aufnimmt.\\n\\nDurch Nahrung verzögert (**~1h Verschiebung**).\\n\\nTypischer Bereich: **0,7-1,2h**.\\n\\n__Standard:__ **{{ldxAbsorptionHalfLife}}h**",
faster: "(schneller >)",
// Advanced Settings
weightBasedVdScaling: "Gewichtsbasiertes Verteilungsvolumen",
- weightBasedVdTooltip: "Passt Plasmakonzentrationen basierend auf Körpergewicht an (proportional zu ~5,4 L/kg). Leichtere → höhere Spitzen, schwerere → niedrigere. Bei Deaktivierung: 70 kg Erwachsener.",
+ weightBasedVdTooltip: "Passt Plasmakonzentrationen basierend auf Körpergewicht an (proportional zu **~5,4 L/kg**).\\n\\n__Effekte:__\\n• Leichtere Personen → ***höhere*** Konzentrationsspitzen\\n• __Schwerere Personen__ → ***niedrigere*** Konzentrationsspitzen\\n\\n__Bei Deaktivierung:__ **70 kg Erwachsene Person**",
bodyWeight: "Körpergewicht",
- bodyWeightTooltip: "Dein Körpergewicht für Konzentrationsanpassung. Verwendet zur Berechnung des Verteilungsvolumens (Vd = Gewicht × 5,4). Siehe [Populations-Pharmakokinetik](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/). Standard: {{bodyWeight}} kg.",
+ bodyWeightTooltip: "Dein Körpergewicht für Konzentrationsanpassung. Verwendet zur Berechnung des Verteilungsvolumens:\\n\\n**Vd = Gewicht × 5,4**\\n\\nSiehe [Populations-Pharmakokinetik](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/).\\n\\n__Standard:__ **{{bodyWeight}} kg**",
bodyWeightUnit: "kg",
foodEffectEnabled: "Mit Mahlzeit eingenommen",
foodEffectDelay: "Nahrungseffekt-Verzögerung",
- foodEffectTooltip: "Fettreiche Mahlzeiten verzögern die Absorption ohne die Gesamtaufnahme zu ändern. Verlangsamt Wirkungseintritt (~1h Verzögerung). Hinweis: Die in dieser Studie verwendete fettreiche Mahlzeit bestand aus 1 englischem Muffin mit Butter, 1 Spiegelei, 1 Scheibe amerikanischem Käse, 1 Scheibe kanadischem Speck, 57 g Bratkartoffeln und 240 ml Vollmilch. Deaktiviert nimmt nüchternen Zustand an.",
+ foodEffectTooltip: "Fettreiche Mahlzeiten verzögern die Absorption **ohne die Gesamtaufnahme zu ändern**.\\n\\nVerlangsamt Wirkungseintritt um **~1 Stunde**.\\n\\nDeaktiviert nimmt nüchternen Zustand an.",
tmaxDelay: "Absorptions-Verzögerung",
- tmaxDelayTooltip: "Zeitverzögerung bei Einnahme mit fettreicher Mahlzeit. Wird durch Einzel-Dosis Nahrungsschalter (🍴 Symbol) im Zeitplan angewendet. Forschung zeigt ~1h Verzögerung ohne Spitzenreduktion. Siehe [Studie](https://pmc.ncbi.nlm.nih.gov/articles/PMC4823324/). Standard: {{tmaxDelay}}h.",
+ tmaxDelayTooltip: "Zeitverzögerung bei Einnahme mit **fettreicher Mahlzeit**. Wird durch Einzel-Dosis Nahrungsschalter (🍴 Symbol) im Zeitplan angewendet.\\n\\nForschung zeigt ~1h Verzögerung ohne Spitzenreduktion. Siehe [Studie](https://pmc.ncbi.nlm.nih.gov/articles/PMC4823324/).\\n\\n__Hinweis:__ Die in dieser Studie verwendete fettreiche Mahlzeit bestand aus 1 englischem Muffin mit Butter, 1 Spiegelei, 1 Scheibe amerikanischem Käse, 1 Scheibe kanadischem Speck, 57 g Bratkartoffeln und 240 ml Vollmilch.\\n\\n__Standard:__ **{{tmaxDelay}}h**",
tmaxDelayUnit: "h",
urinePHTendency: "Urin-pH-Effekte",
- urinePHTooltip: "Urin-pH beeinflusst Nierenrückresorption von Amphetamin. Saurer Urin (<6) erhöht Elimination (schnellere Ausscheidung, t½ ~7-9h). Normaler pH (6-7,5) hält Basis-Elimination (~11h). Alkalischer Urin (>7,5) reduziert Elimination (langsamere Ausscheidung, t½ ~13-15h). Typischer Bereich: 5,5-8,0. Standard: Normaler pH (6-7,5).",
+ urinePHTooltip: "Urin-pH beeinflusst Nierenrückresorption von Amphetamin.\\n\\n__Effekte auf die Elimination:__\\n• __Sauer__ (<6): ***Erhöhte*** Elimination (***schnellere*** Ausscheidung), **t½ ~7-9h**\\n• __Normal__ (6-7,5): ***Basis***-Elimination (**t½ ~11h**)\\n• __Alkalisch__ (>7,5) → ***Reduzierte*** Elimination (***langsamere*** Ausscheidung), **t½ ~13-15h**\\n\\nTypischer Bereich: 5,5-8,0.\\n\\n__Standard:__ **Normaler pH** (6-7,5)",
urinePHMode: "pH-Effekt",
urinePHModeNormal: "Normal (pH 6-7,5, t½ 11h)",
urinePHModeAcidic: "Sauer (pH <6, schnellere Elimination)",
urinePHModeAlkaline: "Alkalisch (pH >7,5, langsamere Elimination)",
urinePHValue: "pH-Wert",
- urinePHValueTooltip: "Dein typischer Urin-pH (sauer=schnellere Ausscheidung, alkalisch=langsamer). Standard: {{phTendency}}. Bereich: 5,5-8,0.",
+ urinePHValueTooltip: "Dein typischer Urin-pH (sauer=schnellere Ausscheidung, alkalisch=langsamer).\\n\\nBereich: **5,5-8,0**.\\n\\n__Standard:__ **{{phTendency}}**",
phValue: "pH-Wert",
phUnit: "(5,5-8,0)",
oralBioavailability: "Orale Bioverfügbarkeit",
- oralBioavailabilityTooltip: "Anteil der LDX-Dosis, der ins Blut gelangt. Siehe [Bioverfügbarkeitsstudie](https://www.frontiersin.org/journals/pharmacology/articles/10.3389/fphar.2022.881198/full) (FDA-Label: 96,4%). Selten Anpassung nötig, außer bei dokumentierten Absorptionsproblemen. Standard: {{fOral}} ({{fOralPercent}}%).",
+ oralBioavailabilityTooltip: "Anteil der LDX-Dosis, der ins Blut gelangt.\\n\\nSiehe [Bioverfügbarkeitsstudie](https://www.frontiersin.org/journals/pharmacology/articles/10.3389/fphar.2022.881198/full) — **FDA-Label: 96,4%**.\\n\\nSelten Anpassung nötig, außer bei dokumentierten Absorptionsproblemen.\\n\\n__Standard:__ **{{fOral}} ({{fOralPercent}}%)**",
steadyStateDays: "Medikationshistorie",
- steadyStateDaysTooltip: "Anzahl vorheriger Tage stabiler Medikamentendosis zur Simulation der Akkumulation/Steady-State. 0 setzen für \"erster Tag ohne Vorgeschichte.\" Standard: {{steadyStateDays}} Tage. Max: 7.",
+ steadyStateDaysTooltip: "Anzahl vorheriger Tage stabiler Medikamentendosis zur Simulation der Akkumulation/Steady-State.\\n\\nWird diese Option ausgeschaltet, beginnt die Simulation an Tag eins ohne vorherige Medikationshistorie. Dasselbe gilt für den Wert **0**.\\n\\nMax: **7 Tage**.\\n\\n__Standard:__ **{{steadyStateDays}} Tage**",
// Age-specific pharmacokinetics
ageGroup: "Altersgruppe",
- ageGroupTooltip: "Pädiatrische Personen (6-12 J.) zeigen schnellere d-Amphetamin-Elimination (t½ ~9h) verglichen mit Erwachsenen (~11h) aufgrund höherer gewichtsnormalisierter Stoffwechselrate. Siehe [Forschungsdokument](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#52-pediatric-vs-adult-modeling) Abschnitt 5.2. 'Benutzerdefiniert' wählen, um manuell konfigurierte Halbwertszeit zu verwenden. Standard: Erwachsener.",
+ ageGroupTooltip: "Pädiatrische Personen (6-12 J.) zeigen **schnellere d-Amphetamin-Elimination** (t½ ~9h) verglichen mit Erwachsenen (~11h) aufgrund höherer gewichtsnormalisierter Stoffwechselrate.\\n\\nSiehe [Forschungsdokument](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#52-pediatric-vs-adult-modeling) Abschnitt 5.2.\\n\\n'Benutzerdefiniert' wählen, um manuell konfigurierte Halbwertszeit zu verwenden.\\n\\n__Standard:__ **Erwachsener**",
ageGroupAdult: "Erwachsener (t½ 11h)",
ageGroupChild: "Kind 6-12 J. (t½ 9h)",
ageGroupCustom: "Benutzerdefiniert (manuelle t½)",
// Renal function effects
renalFunction: "Niereninsuffizienz",
- renalFunctionTooltip: "Schwere Niereninsuffizienz verlängert d-Amphetamin-Halbwertszeit um ~50% (von 11h auf 16,5h). FDA-Label empfiehlt Dosierungsobergrenzen: 50mg bei schwerer Insuffizienz, 30mg bei Nierenversagen (ESRD). Siehe [FDA-Label Abschnitt 8.6](https://www.accessdata.fda.gov/drugsatfda_docs/label/2017/021977s049lbl.pdf) und [Forschungsdokument](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#82-renal-function) Abschnitt 8.2. Standard: deaktiviert.",
+ renalFunctionTooltip: "Schwere Niereninsuffizienz verlängert d-Amphetamin-Halbwertszeit um **~50%** (von 11h auf 16,5h).\\n\\n__FDA-Label Dosierungsobergrenzen:__\\n• __Schwere Insuffizienz:__ **50mg**\\n• __Nierenversagen (ESRD):__ **30mg**\\n\\nSiehe [FDA-Label Abschnitt 8.6](https://www.accessdata.fda.gov/drugsatfda_docs/label/2017/021977s049lbl.pdf) und [Forschungsdokument](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#82-renal-function) Abschnitt 8.2.\\n\\n__Standard:__ **deaktiviert**",
renalFunctionSeverity: "Schweregrad der Insuffizienz",
renalFunctionNormal: "Normal (keine Anpassung)",
renalFunctionMild: "Leicht (keine Anpassung)",
diff --git a/src/locales/en.ts b/src/locales/en.ts
index b4ea73d..b256c07 100644
--- a/src/locales/en.ts
+++ b/src/locales/en.ts
@@ -67,7 +67,7 @@ export const en = {
refLineMax: "Max",
pinChart: "Pin chart to top",
unpinChart: "Unpin chart",
- stickyChartTooltip: "Keep chart visible while scrolling through settings for real-time feedback. Default: off.",
+ stickyChartTooltip: "Keep chart visible while scrolling through settings for real-time feedback.\\n\\n__Default:__ **off**",
chartViewDamphTooltip: "Show only the active metabolite (d-Amphetamine) concentration profile",
chartViewLdxTooltip: "Show only the prodrug (Lisdexamfetamine) concentration profile",
chartViewBothTooltip: "Show both d-Amphetamine and Lisdexamfetamine profiles together",
@@ -78,13 +78,13 @@ export const en = {
advancedSettings: "Advanced Settings",
advancedSettingsWarning: "⚠️ These parameters affect simulation accuracy and may deviate from population averages. Adjust only if you have specific clinical data or research references.",
standardVolumeOfDistribution: "Volume of Distribution (Vd)",
- standardVdTooltip: "Defines how drug disperses in body. Adult: 377L (Roberts 2015), Child: ~150-200L. Weight-based scaling: ~5.4 L/kg (intended for adults >18 years based on [population PK analysis](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/)). Affects all concentration calculations. Change only for pediatric or specialized simulations. Default: {{standardVdValue}}L ({{standardVdPreset}}).",
+ standardVdTooltip: "Defines how drug disperses in body.\\n\\n__Presets:__\\n• __Adult:__ **377L** (Roberts 2015)\\n• __Child:__ **~150-200L**\\n• __Weight-based:__ **~5.4 L/kg** (intended for adults >18 years based on [population PK analysis](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/))\\n\\nAffects all concentration calculations. Change only for pediatric or specialized simulations.\\n\\n__Default:__ **{{standardVdValue}}L** ({{standardVdPreset}})",
standardVdPresetAdult: "Adult (377L)",
standardVdPresetChild: "Child (175L)",
standardVdPresetCustom: "Custom",
standardVdPresetWeightBased: "Weight-Based (~5.4 L/kg)",
customVdValue: "Custom Vd (L)",
- weightBasedVdInfo: "Weight-based Vd adjusts plasma concentrations based on body weight (~5.4 L/kg). Lighter persons → higher peaks, heavier → lower peaks. This option is intended for adults (>18 years) based on the population PK study. For pediatric patients, use the 'Child' preset.",
+ weightBasedVdInfo: "Weight-based Vd adjusts plasma concentrations based on body weight (~5.4 L/kg).\\n\\nLighter persons → higher peaks, heavier → lower peaks.\\n\\nThis option is intended for adults (>18 years) based on the population PK study. For pediatric patients, use the 'Child' preset.",
xAxisTimeFormat: "Time Format",
xAxisFormatContinuous: "Continuous",
xAxisFormatContinuousDesc: "Endless sequence (0h, 6h, 12h...)",
@@ -93,74 +93,74 @@ export const en = {
xAxisFormat12h: "Time of Day (12h AM/PM)",
xAxisFormat12hDesc: "Repeating 12h cycle in AM/PM format",
showTemplateDayInChart: "Continuously Show Regular Plan",
- showTemplateDayTooltip: "Display the regular medication plan as reference overlay at all times (default: enabled).",
+ showTemplateDayTooltip: "Display the regular medication plan as reference overlay at all times.\\n\\n__Default:__ **enabled**",
simulationSettings: "Simulation Settings",
showDayReferenceLines: "Show Day Separators",
- showDayReferenceLinesTooltip: "Display vertical lines and status indicators separating days (default: enabled).",
+ showDayReferenceLinesTooltip: "Display vertical lines and status indicators separating days.\\n\\n__Default:__ **enabled**",
showTherapeuticRangeLines: "Show Therapeutic Range",
- showTherapeuticRangeLinesTooltip: "Display horizontal reference lines for therapeutic min/max concentrations (default: enabled).",
+ showTherapeuticRangeLinesTooltip: "Display horizontal reference lines for therapeutic min/max concentrations.\\n\\n__Default:__ **enabled**",
simulationDuration: "Simulation Duration",
- simulationDurationTooltip: "Number of days to simulate. Longer periods allow steady-state observation. Default: {{simulationDays}} days.",
+ simulationDurationTooltip: "Number of days to simulate. Longer periods allow steady-state observation.\\n\\n__Default:__ **{{simulationDays}} days**",
displayedDays: "Visible Days (in Focus)",
- displayedDaysTooltip: "How many days to display on screen at once. Smaller values zoom in on details. Default: {{displayedDays}} day(s).",
+ displayedDaysTooltip: "How many days to display on screen at once. Smaller values zoom in on details.\\n\\n__Default:__ **{{displayedDays}} day(s)**",
yAxisRange: "Y-Axis Range (Concentration Zoom)",
- yAxisRangeTooltip: "Manually set vertical axis limits (concentration scale). Leave empty for automatic scaling based on data. Default: auto.",
+ yAxisRangeTooltip: "Manually set vertical axis limits (concentration scale). Leave empty for automatic scaling based on data.\\n\\n__Default:__ **auto**",
yAxisRangeAutoButton: "A",
yAxisRangeAutoButtonTitle: "Determine range automatically based on data range",
auto: "Auto",
therapeuticRange: "Therapeutic Range (d-Amphetamine)",
- therapeuticRangeTooltip: "Personalized concentration targets based on YOUR individual response. Set these after observing which levels provide symptom control vs. side effects. Reference ranges (highly variable): Adults ~10-80 ng/mL, Children ~20-120 ng/mL (due to lower body weight/Vd). Leave empty if unsure. Consult your physician.",
+ therapeuticRangeTooltip: "Personalized concentration targets based on **YOUR individual response**.\\n\\nSet these after observing which levels provide symptom control vs. side effects.\\n\\n**Reference ranges** (highly variable):\\n• __Adults:__ **~10-80 ng/mL**\\n• __Children:__ **~20-120 ng/mL** (due to lower body weight/Vd)\\n\\nLeave empty if unsure. ***Consult your physician.***",
dAmphetamineParameters: "d-Amphetamine Parameters",
halfLife: "Elimination Half-life",
- halfLifeTooltip: "Time for body to clear half the d-amphetamine from blood. Affected by urine pH: acidic (<6) → 7-9h, neutral (6-7.5) → 10-12h, alkaline (>7.5) → 13-15h. See [therapeutic reference ranges](https://www.thieme-connect.com/products/ejournals/pdf/10.1055/a-2689-4911.pdf). Default: {{damphHalfLife}}h.",
+ halfLifeTooltip: "Time for body to clear half the d-amphetamine from blood.\\n\\n__Affected by urine pH:__\\n• __Acidic__ (<6) → **7-9h**\\n• __Neutral__ (6-7.5) → **10-12h**\\n• __Alkaline__ (>7.5) → **13-15h**\\n\\n*See* [therapeutic reference ranges](https://www.thieme-connect.com/products/ejournals/pdf/10.1055/a-2689-4911.pdf).\\n\\n__Default:__ **{{damphHalfLife}}h**",
lisdexamfetamineParameters: "Lisdexamfetamine (LDX) Parameters",
conversionHalfLife: "LDX→d-Amph Conversion Half-life",
- conversionHalfLifeTooltip: "Time for red blood cells to convert half the inactive LDX prodrug into active d-amphetamine. Typical: 0.7-1.2h. Default: {{ldxHalfLife}}h.",
+ conversionHalfLifeTooltip: "Time for red blood cells to convert half the inactive LDX prodrug into active d-amphetamine.\\n\\n__Typical range:__ **0.7-1.2h**.\\n__Default:__ **{{ldxHalfLife}}h**",
absorptionHalfLife: "Absorption Half-life",
- absorptionHalfLifeTooltip: "Time for intestines to absorb half the LDX from stomach to blood. Delayed by food (~1h shift). Typical: 0.7-1.2h. Default: {{ldxAbsorptionHalfLife}}h.",
+ absorptionHalfLifeTooltip: "Time for intestines to absorb half the LDX from stomach to blood.\\n\\nDelayed by food (**~1h shift**).\\n\\n__Typical range:__ **0.7-1.2h**.\\n__Default:__ **{{ldxAbsorptionHalfLife}}h**",
faster: "(faster >)",
// Advanced Settings
weightBasedVdScaling: "Weight-Based Volume of Distribution",
- weightBasedVdTooltip: "Adjusts plasma concentrations based on body weight (proportional to ~5.4 L/kg). Lighter persons → higher peaks, heavier → lower peaks. When disabled, assumes 70 kg adult.",
+ weightBasedVdTooltip: "Adjusts plasma concentrations based on body weight (proportional to **~5.4 L/kg**).\\n\\n__Effects:__\\n• __Lighter persons__ → ***higher*** concentration peaks\\n• __Heavier persons__ → ***lower*** concentration peaks\\n\\n__When disabled:__ assumes **70 kg adult**",
bodyWeight: "Body Weight",
- bodyWeightTooltip: "Your body weight for concentration scaling. Used to calculate volume of distribution (Vd = weight × 5.4). See [population PK analysis](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/). Default: {{bodyWeight}} kg.",
+ bodyWeightTooltip: "Your body weight for concentration scaling.\\n\\nUsed to calculate volume of distribution:\\n**Vd = weight × 5.4**\\n\\nSee [population PK analysis](https://pmc.ncbi.nlm.nih.gov/articles/PMC5572767/).\\n\\n__Default:__ **{{bodyWeight}} kg**",
bodyWeightUnit: "kg",
foodEffectEnabled: "Taken With Meal",
foodEffectDelay: "Food Effect Delay",
- foodEffectTooltip: "High-fat meals delay absorption without changing total exposure. Slows onset of effects (~1h delay). When disabled, assumes fasted state.",
+ foodEffectTooltip: "High-fat meals delay absorption **without changing total exposure**.\\n\\nSlows onset of effects by **~1 hour**.\\n\\nWhen disabled, assumes fasted state.",
tmaxDelay: "Absorption Delay",
- tmaxDelayTooltip: "Time delay when dose is taken with high-fat meal. Applied using per-dose food toggles (🍴 icon) in schedule. Research shows ~1h delay without peak reduction. See [study](https://pmc.ncbi.nlm.nih.gov/articles/PMC4823324/). Note: The high-fat meal used in this study consisted of 1 English muffin with butter, 1 fried egg, 1 slice of American cheese, 1 slice of Canadian bacon, 2 oz (57 g) of hash brown potatoes, and 8 fl oz (240 mL) of whole milk. Default: {{tmaxDelay}}h.",
+ tmaxDelayTooltip: "Time delay when dose is taken with **high-fat meal**. Applied using per-dose food toggles (🍴 icon) in schedule.\\n\\nResearch shows ~1h delay without peak reduction. *See* [study](https://pmc.ncbi.nlm.nih.gov/articles/PMC4823324/).\\n\\n__Note:__ The high-fat meal used in this study consisted of 1 English muffin with butter, 1 fried egg, 1 slice of American cheese, 1 slice of Canadian bacon, 2 oz (57 g) of hash brown potatoes, and 8 fl oz (240 mL) of whole milk.\\n\\n__Default:__ **{{tmaxDelay}}h**",
tmaxDelayUnit: "h",
urinePHTendency: "Urine pH Effects",
- urinePHTooltip: "Urine pH affects kidney reabsorption of amphetamine. Acidic urine (<6) increases elimination (faster clearance, t½ ~7-9h). Normal pH (6-7.5) maintains baseline elimination (~11h). Alkaline urine (>7.5) reduces elimination (slower clearance, t½ ~13-15h). Typical range: 5.5-8.0. Default: Normal pH (6-7.5).",
+ urinePHTooltip: "Urine pH affects kidney reabsorption of amphetamine.\\n\\n__Effects on elimination:__\\n• __Acidic__ (<6) → ***Faster*** clearance, **t½ ~7-9h**\\n• __Normal__ (6-7.5) → ***Baseline*** elimination **~11h**\\n• __Alkaline__ (>7.5) → ***Slower*** clearance, **t½ ~13-15h**\\n\\n__Typical range:__ **5.5-8.0**\\n\\n__Default:__ **Normal pH** (6-7.5)",
urinePHMode: "pH Effect",
urinePHModeNormal: "Normal (pH 6-7.5, t½ 11h)",
urinePHModeAcidic: "Acidic (pH <6, faster elimination)",
urinePHModeAlkaline: "Alkaline (pH >7.5, slower elimination)",
urinePHValue: "pH Value",
- urinePHValueTooltip: "Your typical urine pH (acidic=faster clearance, alkaline=slower). Default: {{phTendency}}. Range: 5.5-8.0.",
+ urinePHValueTooltip: "Your typical urine pH (acidic=faster clearance, alkaline=slower).\\n\\nRange: **5.5-8.0**.\\n\\n__Default:__ **{{phTendency}}**",
phValue: "pH Value",
phUnit: "(5.5-8.0)",
oralBioavailability: "Oral Bioavailability",
- oralBioavailabilityTooltip: "Fraction of LDX dose that reaches bloodstream. See [bioavailability study](https://www.frontiersin.org/journals/pharmacology/articles/10.3389/fphar.2022.881198/full) (FDA label: 96.4%). Rarely needs adjustment unless you have documented absorption issues. Default: {{fOral}} ({{fOralPercent}}%).",
+ oralBioavailabilityTooltip: "Fraction of LDX dose that reaches bloodstream.\\n\\n*See* [bioavailability study](https://www.frontiersin.org/journals/pharmacology/articles/10.3389/fphar.2022.881198/full) — **FDA label: 96.4%**.\\n\\nRarely needs adjustment unless you have documented absorption issues.\\n\\n__Default:__ **{{fOral}} ({{fOralPercent}}%)**",
steadyStateDays: "Medication History",
- steadyStateDaysTooltip: "Number of prior days on stable medication dose to simulate accumulation/steady-state. Set 0 for \"first day from scratch.\" Default: {{steadyStateDays}} days. Max: 7.",
+ steadyStateDaysTooltip: "Number of prior days on stable medication dose to simulate accumulation/steady-state.\\n\\If this option is disabled, the simulation will begin from day one with no prior medication history. The same applies for the value is **0**.\\n\\nMax: **7 days**.\\n\\n__Default:__ **{{steadyStateDays}} days**.",
// Age-specific pharmacokinetics
ageGroup: "Age Group",
- ageGroupTooltip: "Pediatric subjects (6-12y) exhibit faster d-amphetamine elimination (t½ ~9h) compared to adults (~11h) due to higher weight-normalized metabolic rate. See [research document](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#52-pediatric-vs-adult-modeling) Section 5.2. Select 'custom' to use your manually configured half-life. Default: adult.",
+ ageGroupTooltip: "Pediatric subjects (6-12y) exhibit **faster d-amphetamine elimination** (t½ ~9h) compared to adults (~11h) due to higher weight-normalized metabolic rate.\\n\\n*See* [research document](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#52-pediatric-vs-adult-modeling) *Section 5.2.*\\n\\nSelect 'custom' to use your manually configured half-life.\\n\\n__Default:__ **adult**.",
ageGroupAdult: "Adult (t½ 11h)",
ageGroupChild: "Child 6-12y (t½ 9h)",
ageGroupCustom: "Custom (use manual t½)",
// Renal function effects
renalFunction: "Renal Impairment",
- renalFunctionTooltip: "Severe renal impairment extends d-amphetamine half-life by ~50% (from 11h to 16.5h). FDA label recommends dose caps: 50mg for severe impairment, 30mg for ESRD. See [FDA Label Section 8.6](https://www.accessdata.fda.gov/drugsatfda_docs/label/2017/021977s049lbl.pdf) and [research document](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#82-renal-function) Section 8.2. Default: disabled.",
+ renalFunctionTooltip: "Severe renal impairment extends d-amphetamine half-life by **~50%** (from 11h to 16.5h).\\n\\n__FDA label dose caps:__\\n• __Severe impairment__: **50mg**\\n• __ESRD__: **30mg**\\n*See* [FDA Label Section 8.6](https://www.accessdata.fda.gov/drugsatfda_docs/label/2017/021977s049lbl.pdf) *and* [research document](https://git.11001001.org/cbaoth/med-plan-assistant/src/branch/main/docs/2026-01-17_AI-Reseach_SimulatingLDXandD-AmphetaminePlasmaLevels.md#82-renal-function) *Section 8.2.*\\n\\n__Default:__ **disabled**.",
renalFunctionSeverity: "Impairment Severity",
renalFunctionNormal: "Normal (no adjustment)",
renalFunctionMild: "Mild (no adjustment)",
@@ -292,10 +292,10 @@ export const en = {
// Field validation - Warnings
warningDuplicateTime: "⚠️ Multiple doses at same time.",
warningZeroDose: "⚠️ Zero dose has no effect on simulation.",
- warningAbsorptionOutOfRange: "⚠️ Typical range: 0.7-1.2h. Current value may be outside clinical norms.",
- warningConversionOutOfRange: "⚠️ Typical range: 0.7-1.2h. Current value may be outside clinical norms.",
- warningEliminationOutOfRange: "⚠️ Typical range: 9-12h (normal pH). Extended range 7-15h (pH effects). Current value is unusual.",
- warningDoseAbove70mg: "⚠️ FDA-approved maximum: 70 mg. Higher doses lack safety data and increase cardiovascular risk.",
+ warningAbsorptionOutOfRange: "⚠️ Current value may be outside clinical norms.\\n\\n__Typical range:__ **0.7-1.2h**.",
+ warningConversionOutOfRange: "⚠️ Current value may be outside clinical norms.\\n\\n__Typical range:__ **0.7-1.2h**.",
+ warningEliminationOutOfRange: "⚠️ Current value may be outside clinical norms.\\n\\n__Typical range:__ **9-12h** (normal pH).\\nExtended range 7-15h (pH effects).",
+ warningDoseAbove70mg: "⚠️ Higher doses lack safety data and increase cardiovascular risk.\\n\\n__FDA-approved maximum:__ **70 mg**.\\n\\nConsult your physician before exceeding this dose.",
// Time picker
timePickerHour: "Hour",
diff --git a/src/utils/contentFormatter.tsx b/src/utils/contentFormatter.tsx
new file mode 100644
index 0000000..8a48035
--- /dev/null
+++ b/src/utils/contentFormatter.tsx
@@ -0,0 +1,230 @@
+/**
+ * Content Formatting Utilities
+ *
+ * Provides markdown-style formatting capabilities for various UI content including:
+ * - Tooltips
+ * - Error/warning messages
+ * - Info boxes
+ * - Help text
+ *
+ * Supported formatting (processed in this order):
+ * 1. Links: [text](url)
+ * 2. Bold+Italic: ***text***
+ * 3. Bold: **text**
+ * 4. Italic: *text*
+ * 5. Underline: __text__
+ * 6. Line breaks: \n
+ *
+ * @author Andreas Weyer
+ * @license MIT
+ */
+
+import * as React from 'react';
+
+/**
+ * Renders formatted formatContent with markdown-style formatting support.
+ * Can be used for tooltips, error messages, info boxes, and other UI text.
+ *
+ * Processing order: Links → Bold+Italic (***) → Bold (**) → Italic (*) → Underline (__) → Line breaks (\n)
+ *
+ * @example
+ * ```typescript
+ * // In tooltip
+ * formatContent("See [study](https://example.com)\\n__Important:__ **Take with food**.")
+ *
+ * // In error message
+ * formatContent("**Error:** Value must be between *5* and *50*.")
+ *
+ * // In info box
+ * formatContent("***Note:*** This setting affects accuracy.\\n\\nSee [docs](https://example.com).")
+ * ```
+ *
+ * @param text - The text to format with markdown-style syntax
+ * @returns Formatted React nodes ready for rendering
+ */
+export const formatContent = (text: string): React.ReactNode => {
+ // Helper to process text segments with bold/italic/underline formatting
+ const processFormatting = (segment: string, keyPrefix: string): React.ReactNode[] => {
+ const parts: React.ReactNode[] = [];
+ let remaining = segment;
+ let partIndex = 0;
+
+ // Process bold+italic first (***text***)
+ const boldItalicRegex = /\*\*\*([^*]+)\*\*\*/g;
+ let lastIdx = 0;
+ let boldItalicMatch;
+
+ while ((boldItalicMatch = boldItalicRegex.exec(remaining)) !== null) {
+ // Add text before bold+italic
+ if (boldItalicMatch.index > lastIdx) {
+ const beforeBoldItalic = remaining.substring(lastIdx, boldItalicMatch.index);
+ parts.push(...processBoldItalicAndUnderline(beforeBoldItalic, `${keyPrefix}-bi${partIndex++}`));
+ }
+ // Add bold+italic text
+ parts.push(
+
+ {boldItalicMatch[1]}
+
+ );
+ lastIdx = boldItalicRegex.lastIndex;
+ }
+
+ // Add remaining text with bold/italic/underline processing
+ if (lastIdx < remaining.length) {
+ parts.push(...processBoldItalicAndUnderline(remaining.substring(lastIdx), `${keyPrefix}-bi${partIndex++}`));
+ }
+
+ return parts.length > 0 ? parts : [remaining];
+ };
+
+ // Helper to process bold/italic/underline (after bold+italic ***)
+ const processBoldItalicAndUnderline = (segment: string, keyPrefix: string): React.ReactNode[] => {
+ const parts: React.ReactNode[] = [];
+ const boldRegex = /\*\*([^*]+)\*\*/g;
+ let lastIdx = 0;
+ let boldMatch;
+
+ while ((boldMatch = boldRegex.exec(segment)) !== null) {
+ // Add text before bold
+ if (boldMatch.index > lastIdx) {
+ const beforeBold = segment.substring(lastIdx, boldMatch.index);
+ parts.push(...processItalicAndUnderline(beforeBold, `${keyPrefix}-b${lastIdx}`));
+ }
+ // Add bold text
+ parts.push(
+
+ {boldMatch[1]}
+
+ );
+ lastIdx = boldRegex.lastIndex;
+ }
+
+ // Add remaining text with italic/underline processing
+ if (lastIdx < segment.length) {
+ parts.push(...processItalicAndUnderline(segment.substring(lastIdx), `${keyPrefix}-b${lastIdx}`));
+ }
+
+ return parts.length > 0 ? parts : [segment];
+ };
+
+ // Helper to process italic and underline (*text* and __text__)
+ const processItalicAndUnderline = (segment: string, keyPrefix: string): React.ReactNode[] => {
+ const parts: React.ReactNode[] = [];
+ // Match single * that's not part of ** or inside links
+ const italicRegex = /(? lastIdx) {
+ const beforeItalic = segment.substring(lastIdx, italicMatch.index);
+ parts.push(...processUnderline(beforeItalic, `${keyPrefix}-i${lastIdx}`));
+ }
+ // Add italic text
+ parts.push(
+
+ {italicMatch[1]}
+
+ );
+ lastIdx = italicRegex.lastIndex;
+ }
+
+ // Add remaining text with underline processing
+ if (lastIdx < segment.length) {
+ parts.push(...processUnderline(segment.substring(lastIdx), `${keyPrefix}-i${lastIdx}`));
+ }
+
+ return parts.length > 0 ? parts : [segment];
+ };
+
+ // Helper to process underline (__text__) - final level of formatting
+ const processUnderline = (segment: string, keyPrefix: string): React.ReactNode[] => {
+ const parts: React.ReactNode[] = [];
+ const underlineRegex = /__([^_]+)__/g;
+ let lastIdx = 0;
+ let underlineMatch;
+
+ while ((underlineMatch = underlineRegex.exec(segment)) !== null) {
+ // Add text before underline (plain text)
+ if (underlineMatch.index > lastIdx) {
+ parts.push(segment.substring(lastIdx, underlineMatch.index));
+ }
+ // Add underlined text
+ parts.push(
+
+ {underlineMatch[1]}
+
+ );
+ lastIdx = underlineRegex.lastIndex;
+ }
+
+ // Add remaining plain text
+ if (lastIdx < segment.length) {
+ parts.push(segment.substring(lastIdx));
+ }
+
+ return parts.length > 0 ? parts : [segment];
+ };
+
+ // Split by line breaks first
+ const lines = text.split('\\n');
+ const result: React.ReactNode[] = [];
+
+ lines.forEach((line, lineIndex) => {
+ const lineParts: React.ReactNode[] = [];
+ const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
+ let lastIndex = 0;
+ let match;
+
+ while ((match = linkRegex.exec(line)) !== null) {
+ // Add text before link with formatting
+ if (match.index > lastIndex) {
+ const beforeLink = line.substring(lastIndex, match.index);
+ lineParts.push(...processFormatting(beforeLink, `line${lineIndex}-seg${lastIndex}`));
+ }
+ // Add link
+ lineParts.push(
+
+ {match[1]}
+
+ );
+ lastIndex = linkRegex.lastIndex;
+ }
+
+ // Add remaining text with formatting
+ if (lastIndex < line.length) {
+ const remaining = line.substring(lastIndex);
+ lineParts.push(...processFormatting(remaining, `line${lineIndex}-seg${lastIndex}`));
+ }
+
+ // Add line content
+ if (lineParts.length > 0) {
+ result.push(...lineParts);
+ } else {
+ result.push(line);
+ }
+
+ // Add line break if not the last line
+ if (lineIndex < lines.length - 1) {
+ result.push(
);
+ }
+ });
+
+ return result.length > 0 ? result : text;
+};
+
+/**
+ * Alias for renderContent for use in non-tooltip contexts (error messages, info boxes, etc.).
+ * Provides the same markdown-style formatting capabilities.
+ *
+ * @param text - The text to format with markdown-style syntax
+ * @returns Formatted React nodes ready for rendering
+ */
+export const formatText = formatContent; // Alias for non-tooltip contexts